0

I work with Domino server and develop java agents. Usually i put external jar files into script library, but periodically get OutOfMemory. I extracted jar's from script library to jvm/lib/ext. I can get classes via ClassLoader, but can't via import statement. What should i do to get it works via import statement?

vexan
  • 88
  • 4
  • Q: What's wrong with using the "import" statements shown in the Domino server javadoc, and leaving the classes in the same .jar files they were shipped with????? If you're getting "Out of Memory" errors, you need to look *elsewhere* for a solution. Perhaps different JVM switches, perhaps purchase more memory, perhaps use a 64-bit JVM. – paulsm4 Aug 04 '12 at 21:52
  • We use a 64-bit JVM with 4 GB RAM. Before i extracted jar's to jvm/lib/ext server periodically get OutOfMemory after 100-200 runs of agent. If i attach script library to agent i can import classes via import statement import org.apache.poi.POIXMLDocument but if i detach script library and extract jar's to the server i can't to get classes via import statement, so i get compilation error and can't compile the agent. But if i use ClassLoader.getSystemClassLoader().loadClass("org.apache.poi.POIXMLDocument").getMethods(); i can see all methods of class. – vexan Aug 04 '12 at 22:16
  • If you can (easily) rewrite the agent in LotusScript, I suggest you do that, unless it is a complex agent that has to be written in Java. If there are some points where you have to use Java, you could use LS2J functionality. – D.Bugger Aug 06 '12 at 07:50

2 Answers2

1

You can actually add the jar's to the Java Agent explicitly. Be aware that a Java Agent has no package name by default, and you'll need to quote the correct package name when quoting the package in the import statement. Importing jar's into agents is described here, and for version 8.5 here and here

Also, I suspect that you're not explicitly cleaning up you're java objects. The connection between the JVM and Domino memory heap is "weak". So you have to do you're own garbage collection on Domino objects in order to keep the server's memory clean. It's still black magic to me, but my understanding is that even though agents are supposed to "contain" the session and then release memory at termination, Domino objects not properly recycled can bleed Domino's heap memory. Below are my simple tips for keeping your memory clean:

1/ Keep the session object in a wrapper object. Create a class that has the Domino session object within it, (I called it SessionWrapper). Then declare the SessionWrapper object within the NotesMain method only, don't declare it at the class level. This SessionWrapper class will need to have it's own recycle method that calls Session.recycle(), and you'll need to call it at the end of NotesMain. The reason for this is explained in point #2. If you don't call any other methods within NotesMain, then you don't really need this wrapper. See point #4 about recycling the session.

2/ Pass the SessionWrapper to all methods where you require Domino access. Basically you're passing the session around in this wrapper class as a parameter. This is because we don't want to declare the session object at the class level. This is not ideal, but it will prevent memory leaks caused from keeping the session class at the class level.

3/ Agressive recycling. This has never made much sense to me until I saw this example loop

ViewEntryCollection vec = view.getAllEntries();
ViewEntry ve = vec.getFirstEntry();
While (ve!=null) {
 ViewEntry veNext = vec.getNextEntry(ve);
 // do stuff

 ve.recycle;
 ve = null;
 ve = veNext;
}

See how the "ve" object is getting recycled and veNext is getting the next object. Basically you need to recycle every object once you're finished working with it, the "getNext" methods doesn't actually recycle the object in the Domino heap memory, if you don't recycle it, it's orphaned and Domino won't clean it up, and the server will eventually run out of memory for Domino objects. Note that I am not recycling veNext. I don't need to because I assign ve => veNext. "ve" will have a link to the same Domino object and I call recycle ve at the end of the loop. From this, you can see that many java objects can point to the same Domino instance object in the back end. If I tried to call veNext.recycle after ve.recycle, I would get an "Object has been removed or recycle" error.

4/ Recylce session at the end of the NotesMain. Make sure you call SessionWrapper.recycle() at the end of NotesMain to ensure you're releasing that bit of memory back to the server.

5/ Ensure that you're providing enough memory for the JVM on the server. See this technote. Also be aware of "HTTPJVMMaxHeapSizeSet=1" which is a strange setting to ensure memory settings "stick".. More about it here.

For many years IBM hasn't provided the internal cleanup tasks of objects that is so deperately needed to eliminate this overhead on developers. You're then required to explicitly deallocate memory which is also a performance hit to, but it's a necessary compromise for stability. These points are by no means exhaustive, but I found that stability with agents and servlets greatly improved when observing these rules.

angryITguy
  • 9,332
  • 8
  • 54
  • 82
  • thanks! But this problem still exists. [Here](http://www-01.ibm.com/support/docview.wss?uid=swg1LO66223) is written that i should use jvm/lib/ext folder. I suppose that if jar is in script library or attached explicitly to agent then it is loaded every time i run agent and doesn't unload. But if i use jvm/lib/ext then jar is loaded only once. – vexan Aug 05 '12 at 08:26
  • ok. In terms of memory use, putting the jar's in the agent or the ext folder will not address the memory problem. The agent manager will load them up into memory with the same result. Putting the jar's in the agent as resources makes it easier for maintenance and distribution. Is the agent still crashing though ? I was originally hoping to address the import issue. It looks like you have solved that problem though. – angryITguy Aug 06 '12 at 23:53
1
  1. Close Lotus Notes client and Designer.
  2. Place the JARs to your local jvm/lib/ext.
  3. Open Lotus Notes Client and Designer.

Now you can import the classes.