Jake Of All Trades: CMTI's Jake Ochs

Excuse me for the pedantic nature of this post, but I recently had an issue with developing a fairly complex agent for Notes coded in Java that caused me to revisit a basic understanding of how Java in Notes works. You see, the Java Virtual Machine, JVM for short, is essentially a stack-based emulator that runs bytecode compiled from the Java language source. Without getting into too much detail, the JVM has two memory pools to speak of, the stack and the heap, that can impact the performance and reliability of your Java program. The heap is where Java stores the expanding and contracting soup of objects any given Java program creates. Often, Notes Java programmers run into memory issues when calling too many native Notes classes from within Java, which merely reference native C objects. Not following best practices in ensuring that the objects are called as efficiently as possible and dereferenced properly can cause a program to eat away at the available resources assigned to the heap. (Best practices in this case being defined by the authority on the subject and originator of the Java Notes classes, Bob Balaban.) This is commonly referred to as a memory “leak” and will eventually cause the JVM to crash, if the program doesn’t terminate before the leak becomes fatal. Now, how this applies to my particular problem is precisely nothing: After compiling and running a program that does indeed use the Notes backend classes, running it flawlessly using Bob’s two-headed beast method and importing it into Notes, it would mysteriously die with a Java.lang out of memory error. Going through the excruciating, but very cool process of installing, running and staring at the results of Eclipse TPTP until my eyeballs hurt to analyze the memory usage,screenie I determined that the Notes backend classes –as I had expected- were not unduly taxing the system. They were not taxing the system at all, in fact, as I was reusing an extremely limited number of Notes objects and not creating new ones arbitrarily –in effect I was practicing good object hygiene. Thus all the tips&tricks pouring in from my lazyweb twitter request and nagging of old acquaintances centering around increasing the Notes JVM heap size at runtime had no effect. It wasn’t the heap that was the problem.

As you probably surmized by now, the answer lay in the JVM’s stack. Each thread in the JVM gets it own stack, a last in, first out (LIFO) piece of memory that handles local variables and such for the thread. (See Java VM Spec, scroll down to section 3.5.2)  Highly recursive calls tend to fill up this type of stack pretty quickly. I did notice in my tptp reports a disproportionate amount of char and byte arrays being instantiated and –upon further tracing and asking around- learned that a third-party library I am using to convert HTML  into PDF (PD4ML, highly recommended, BTW) would under a particular circumstance make use of the Java JAI classes to render images in a highly recursive manner. The JAI classes are quite good about cleaning up after themselves, but they do seem to need more room in the JVM’s stack than the default 409600 bytes that the Notes client assigns for anything more than trivial use cases of JAI. Increasing the stack size in the Notes client using the notes.ini variable JavaStackSize neatly solved the problem. Stress-testing the agent with 2500% of the previous load that caused a JVM failure proves out the theory that the the JAI calls just needed a little more headroom to run (I can empathize with that) and a more pernicious leak wasn’t the issue. Problem solved, crisis averted and sanity restored. Thank you for listening.

Oh, and getting Windows Live Writer fully functional as a blog posting tool using the Drupal BlogAPI, XML-RPC and WLW's nifty image editing sauce (check out the drop-shadow on the screenshot above) is uber-rewarding.

by jake

As an extension of Mikkel's post on how to get started with plugin development, I submit the following:

  1. Symphony Developer's Guide PDF (in Symphony SDK) -even though it's not Domino development, it can get a beginner up to speed on creating plugins in the Expeditor platform.
  2. Instantiations SWT Designer (for easily slogging through the GUI portions of the plugin development.)
  3.  On the Job: The Eclipse Jobs API - for when you start running into threading issues
by jake

I read with great interest David Leedy's research into code syntax highlighters for web use. Chris Toohey picks up the meme here and runs with it, explaining how to embed the CSS styles to format the output from the Quick Highlighter tool nicely on your weblog/webpage. It shouldn't have to be this hard. I'm using the GeSHiFilter plugin for my blog's Drupal underpinnings to provide code support. The GeSHiFilter plugin wraps the GeSHi project's code in a Drupal plugin in much the way custom controls can wrap custom Java/JavaScript into a unit that XPages designer can use. Quick Highlighter seems to be using GeSHi as its back end as well as evidenced by the CSS stylesheet header Chris provides. Here's what the interface for the GeSHi plugin looks like on my Drupal install:

GeSHI Filter Drupal plugin config

All I need to do is wrap the code block I want to style with the appropriate tag and the plugin does the rest for me. I really wanted to get Alex Gorbatchev's Syntax Highlighter to work because it has a nifty widget that allows you to view the unadulterated source of the code and to copy the code to the clipboard, but I threw up my hands working out the kinks on Drupal. Also, I would have had to create custom syntaxes for LotusScript and Macro Language (Although I bet the VB syntax would work fine for the former.)

by jake

When using LS2J to utilize Java classes from within LotusScript, you may be faced with needing to declare and bind to a method explicitly using its JNI signature. A common case where this is necesary is when your Java class has multiple overridden methods and you need to explicitly use one of them. Instead of wrestling with the JNI syntax, you can use this handy function to bind to the object and print out the signatures for you to copy:

  1. Function getMethodSignatures(jClass As Javaclass, l As noteslog)
  2. Dim msg$
  3. Dim methods As JavaMethodCollection
  4. Set methods = jclass.Getclassmethods()
  5. ForAll meth In methods
  6. msg$ = meth.Methodname & " - SIG: " & meth.Signature
  7. If Not(l Is Nothing) Then Call l.logaction(msg$)
  8. Print msg$
  9. End ForAll
  11. End Function

A sample output from the NotesLog looks like this:

  1. Started running agent 'LS Method Enumerator Test' on 01/21/2010 03:25:25 PM
  2. 01/21/2010 03:25:26 PM: equals - SIG: (Ljava/lang/Object;)Z
  3. 01/21/2010 03:25:26 PM: hashCode - SIG: ()I
  4. 01/21/2010 03:25:26 PM: toString - SIG: ()Ljava/lang/String;
  5. 01/21/2010 03:25:26 PM: generate - SIG: (Ljava/lang/String;Ljava/lang/String;Ljava/util/HashMap;)V
  6. 01/21/2010 03:25:26 PM: setPageOrientation - SIG: (Z)V
  7. 01/21/2010 03:25:26 PM: generate - SIG: (Ljava/lang/String;Ljava/lang/String;)V
  8. 01/21/2010 03:25:26 PM: addToRoot - SIG: (Ljava/lang/String;Ljava/lang/Object;)V
  9. 01/21/2010 03:25:26 PM: removeFromRoot - SIG: (Ljava/lang/String;)V
  10. 01/21/2010 03:25:26 PM: resetRoot - SIG: ()V
  11. 01/21/2010 03:25:26 PM: getClass - SIG: ()Ljava/lang/Class;
  12. 01/21/2010 03:25:26 PM: notify - SIG: ()V
  13. 01/21/2010 03:25:26 PM: notifyAll - SIG: ()V
  14. 01/21/2010 03:25:26 PM: wait - SIG: ()V
  15. 01/21/2010 03:25:26 PM: wait - SIG: (J)V
  16. 01/21/2010 03:25:26 PM: wait - SIG: (JI)V
  17. 01/21/2010 03:25:26 PM: main - SIG: ([Ljava/lang/String;)V
  18. Ran LotusScript code
  19. Done running agent 'LS Method Enumerator Test' on 01/21/2010 03:25:26 PM

Kindly rate this post using the star system below and/or rate my authoring abilities on Scribnia.

SHAMELESS PLUG: Like what you see? Hire Me! Contact info@critical-masses.com or use the contact page to learn more about engaging Jake Ochs for your development needs.
by jake

I am sitting on a draft of a rambling missive about folks noticing then increasing relevance of storage service offerings focusing on document-centric type of operations feeling vindicated by the Notes development model are missing the point. The point being?  It’s not that the model is suddenly relevant now, it’s just that it engenders the type of massive scaling that large sites and cloud services require. I’m referring to CouchDB, BigTable, S3/SimpleDB, Hadoop, Cassandra. –these data layers are all the engineering rage because they scale…massively. Their data API’s are ancillary and, in some cases, crude compared to Notes. But they also federate well, support eventual-consistency philosophies and are reliable in ways that the Notes datastore –in its current iteration- cannot hope to match. Having said all that, the Opening General Session at this year’s Lotusphere yesterday precisely stole the thunder out of the conclusion I was reaching for: Building on the Notes APIs and rich ecosystem of tools and developers, IBM would be wise to produce a cloud offering that would enable a developer with a (free) copy of Designer to publish an app to a cloud. This masterstroke accomplishes a lot: It provides a deployment opportunity for those driving fresh copies of the free Designer wondering how and where to deploy their new apps, thus delivering on the server side corollary to the free Designer giveaway; and it provides a compelling case for being able to deploy rich services into the cloud or hybrid scenarios – a place where the competition hasn’t quite staked out so forcefully yet. Sigh. Alas my thunderbolt was preempted by the OGS announcement. Woe unto those whose dreams come true.

by jake

On this eve of Lotusphere '10 (not going, thank you very much) has anyone compiled a list of the major pieces that are missing from a Domino developer's toolkit? This is not a rant, as IBM has more than fulfilled its pledges to make Notes and Domino technically relevant again, but there are glaring holes that are obvious candidates for a list. I’ll start things off by naming three easy ones:

  1. An integrated Java Debugger (remote&local)
  2. Complete XSP Taglib documentation
  3. Remote/Local XPages debugging

Please chime in with your suggestions and keep the topics general. While I agree with, say, Chris Toohey, that an @Password formula that optionally takes an encryption algorithm type as an argument would be a useful addition, such a suggestion is less a big picture requirement to fully contemporize our development environment portfolio than a feature request. By all means chime in with the URL’s of IdeaJam suggestions for participants to vote on as well.

by jake

Ever wonder what the deal with toxic fugue is? It's been a favorite topic of mine since the classic Simpsons Episode "One Fish, Two Fish, Blowfish, Blue Fish." This article in today's NYTimes is enlightening.

Develop web faff using firebug? (who doesn't) This post explains that you may be unwittingly slowing down your browser's performance, even when not using firebug.

Childlike fascination with airplanes? By all means follow @flightglobal&@flightblogger. I'm enthralled with the 787 and the second flight-test plane is scheduled to make it's first flight today. This plane has the potential to revolutionize travel comfort and may literally be around for an long time, due to its super-strong carbon-fiber fuselage. The 21st century's DC-3?

ANNOYING: Occasionally developing for Expeditor caused BSOD. Thought that was a thing of the past...

LAZYWEB: Anyone know how to get in on the Symphony beta program (is there one?

by jake

Before I close up shop for the weekend I leave a lazyweb request. I'm developing a Notes plugin using the Expeditor Toolkit for Eclipse (6.2.1) and I can't seem to figure out how to expose the Symphony objects in the IDE for me to code against. Any help is appreciated.

by jake

Got the Freemarker Eclipse Editor plugin to work inside of Domino Designer. Now I can edit and save a Freemarker template directly to a database (Resources\Files) all from within DD. To do this, follow this tip to enable the Eclipse update site feature in the Notes client, add the JBoss Tools update site to the Eclipse update site list, wait for the list to churn through the site and present the list of add-ons, drill into the list and select the Freemarker Editor, update, restart and presto!

According to this article, Google is abandoning Gears. Not too shocking as I don’t know of any widespread adoption of the technology. Of course, the only company to ever pay anything more than lip service to offline use is Lotus and it’s not an easy task. To revise my earlier post on the relevance of Chrome OS, it’s all about the eyeballs. Forget the underlying tech, Google just wants to make sure that it grabs as much advertising revenue for every click possible. Squeezing out competitor’s apps is one way to make that happen.

This spy shot indicates that the US government’s black programs are alive and well. Witness this stealthy UAV on the ground in Kandahar. Definitely cool stuff for an aviation anorak.

by jake

I'm doing some research for a client in using Freemarker to generate documents using templates and Notes data. It turns out that it’s deceptively simple to create a very basic Notes wrapper object to pass into Freemarker’s templating engine for merging document fields with a template. The closest abstract class to implement for a document is Freemarker’s TemplateHashModel. The idea is that for any given Notes field, you’d want the template to get the value by referencing the field's name. Assuming that we call getText() on any retrieved item (I said it was a BASIC Notes wrapper) and convert the string results to Freemarker’s expected SimpleScalar, here’s the wrapper:

  1. import lotus.domino.*;
  2. import freemarker.template.*;
  4. public class SimpleNotesDocumentWrapper implements TemplateHashModel {
  5. private Document doc;
  7. public SimpleNotesDocumentWrapper(Document note) {
  8. doc = note;
  9. }
  11. @Override
  12. public TemplateModel get(String key) throws TemplateModelException {
  13. Item item;
  14. try {
  15. if ((item = doc.getFirstItem(key)) != null) return new SimpleScalar(item.getText());
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }
  19. return null;
  20. }
  22. @Override
  23. public boolean isEmpty() throws TemplateModelException {
  24. // TODO Auto-generated method stub
  25. return (doc == null) ? true : false;
  26. }
  27. }

and you can then access document fields in your template like so: memo subject: ${doc.Subject}. (Assuming you've named the SimpleNotesDocumentWrapper object you placed in the root of the Freemarker object parse tree "doc.")

by jake
Syndicate content