Anyone gotten a large Java agent to run more than once?

We are attempting to import a Java application (jar file) as a Java agent, so we don’t have to rewrite all the code in LotusScript!

We have a Java agent, that gets a handle on the originating document, calls the jar (imported into Domino), and then writes the data correctly back to the document. The problem is that we can only get this to run ONCE. Subsequent times, we run out of memory. We are also not able to send existing data from the document to the jar.

Anyone tried to do this?

Subject: Make sure the Java code is cleaning up after itself

Subject: meaning?

What do you mean by “cleaning up itself”

Subject: Try changing JavaMaxHeapSize in notes.ini

If your program runs on a Notes client then you can increase the system memory available to the JVM using the JavaMaxHeapSize parameter in the notes.ini. The default value for 8.5.1 is 256MB so you might update it to 512MB:JavaMaxHeapSize=512MB

If your Java agent runs on the Domino server the notes.ini variable to update is HTTPJVMMaxHeapSize. The default for the server is also 256MB so you could update it to:

HTTPJVMMaxHeapSize=512MB

Beyond that, you’ll need to post some code to this forum for someone to be able to diagnose any problem there.

Subject: tried that, too

actually increased it to 1024M, BUT I’m not sure if that will help, as the server is still at version 7.0.2

would you like to see the Java agent code?

Subject: Yes, posting the code would likely help…

Some other things that are helpful for troubleshooting:

  1. Does the code actually do what it’s supposed to when it runs the first time?

  2. Are you seeing any errors (other than out of memory)?

  3. Are all of your .jar files included in the agent?

Subject: answers

  1. Does the code actually do what it’s supposed to when it runs the first time? yes2) Are you seeing any errors (other than out of memory)? no

  2. Are all of your .jar files included in the agent? we’ve tried it both ways - in the agent, and on the file system

Here’s the code (without the import stuff):

public class JavaAgent extends AgentBase implements PropertyChangeListener {

private Session session;

private AgentContext agentContext;

private Database db;

private Document doc;

private RichTextItem body;

private String noteID;

private boolean flag

private String encodedText;

public void NotesMain(){

try {

session = getSession();

agentContext = session.getAgentContext();

db = agentContext.getCurrentDatabase();

doc = agentContext.getDocumentContext();

noteID = doc.getNoteID();

doc.recycle();

doc = db.getDocumentByID(noteID);

flag = false;

//setLookAndFeel():

Icon leafIcon = UIManager.getIcon(“Tree.leafIcon”);

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

UIManager.put(“Tree.leafIcon”, leafIcon);

ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE);

//load object with data from doc, if not new

body = (RichTextItem)doc.getFirstItem(“fieldname”);

String nomText = body.getText();

System.out.println(nomText);

//showFrame():

JFrame frame = new NomFrame();

frame.addPropertyChangeListener(this);

frame.setBounds(5, 5, 1260, 1000);

frame.setVisible(true);

System.out.println(“After frame.”);

while (!flag) {

try { Thread.sleep(5000);} catch (Exception e){

e.printStackTrack();}

}

if (encodedText != null) {

body.remove(); // might have text to be replaced, so remove and recreate it

body = doc.createRichTextItem( “fieldname”);

body.appendText(encodedText);

doc.save();

System.out.println(“Saved.”);

doc.recycle();

}

} catch (Exception e) {

e.printStackTrace();

}

}

public foid propertyChange( PropertyChangeEvent evt) {

try {

encodedText = (String)evt.getNewValue();

flag = true;

} catch(Exception e) {

e.printStackTrace();

}

}

}

Subject: Suggestions

Ann,

If your end users are running a Notes client and you want to call your Java code to modify field data, try putting your code in a Notes agent, and calling it from the PostSave form event:

@Command([RunAgent]; “JavaAgent”)

Do you have to use Java for the UI? If not:

  1. Get rid of the Swing code and the “implements PropertyChangeListener”.

  2. Drop the propertyChange method.

  3. Drop the Thread.sleep loop (this may be causing your memory problem).

Also, don’t attempt to access an object you’ve already recycled (you’re recycling ‘doc’ at the top of the agent and then accessing it later).

Your agent should look similar to this:

import lotus.domino.*;

public class JavaAgent extends AgentBase {

public void NotesMain() {



try {

    Session session = getSession();

    AgentContext agentContext = session.getAgentContext();

    Document doc = agentContext.getDocumentContext();



    RichTextItem rtItem = (RichTextItem) doc.getFirstItem("Body");

    String text = rtItem.getUnformattedText();

    rtItem.remove();

    doc.save(true);



    String encodedText = encode(text);



    RichTextItem newRtItem = doc.createRichTextItem("Body");

    newRtItem.appendText("My encoded text: " + encodedText);

    doc.save(true);



} catch (Exception e) {

    e.printStackTrace();

}

}

}

Subject: more answers

Thanks! We do have the code I posted in a Java agent in the Domino database. It is something that users will launch on demand, so we have it on a button on the form.

But the UI is Java, because we are calling an existing jar. The Java developer we are working with doesn’t know the first thing about Domino, so she recommended the Thread.sleep loop.

Makes sense about the doc.recycle at the beginning of the code - I was wondering why she put that there. But we will need to recycle the Domino objects, and I have no idea where the best place to do that is (in the jar).

Thanks for your code, I’ll give it a try!

Subject: Have you recycle?

Do you have a large iteration?If so, try to call doc.recycle() to return memory resource to the OS.

Document doc;

for(int i=1; i<=dc.getCount(); i++){

doc=dc.getNthDocument(i);

process(doc);

doc.recycle(); //freeing memory to OS

}

Subject: yes

We are recycling in the Java agent … will have to check the applet, though. Does anyone have a large Java agent or an embedded applet working? I’d appreciate any sample code.