Reputation: 2807
Since Notes/Domino version 7 I have used the principles in Bob Balaban's "Two headed beast" (http://bobzblog.com/tuxedoguy.nsf/dx/the-2-headed-beast-debugging-domino-java-agents-with-eclipse) for writing Java agents in Eclipse that can be debugged! This works like a charm - the only thing is that I have had to copy/paste the code from Eclipse to the standard Notes agent.
With the current Eclipse version (8.5.3 FP2) of Domino Designer I tried to see if I could use the same setup to debug agents directly (as Java programs) in Domino Designer. It seems that I can make the code run, however, I cannot make it stop at any breakpoints. The message I get is:
Unable to install breakpoint in dk.domain.AgentTemplate due to missing line number attributes. Modify the compiler options to generate line number attributes.
I have tried to set the debug configuration to "Stop in main". And it does seem to stop. However, if I step over, it runs all of the code - and I cannot see where in the code I am, and of course I cannot see the variables nor their values.
The option in Preferences - Java - Compiler to "Add line number attributes to generated class files" has been selected. I have not found other compiler option to generate line numbers.
I am using Java 1.5 compliance in Designer.
Has anyone been able to set this up??
/John
Upvotes: 2
Views: 3434
Reputation: 2807
Well, sometimes you just have to explain your problem to find the solution.
In thoroughly describing the problem, I ended up trying to use a JDK 1.6 compiler compliance level (under preferences - Java compiler). And that actually worked!!!
So building an agent with a structure like this you can debug Java agents directly in Domino Designer:
package dk.dalsgaarddata;
import lotus.domino.AgentBase;
import lotus.domino.AgentContext;
import lotus.domino.Database;
import lotus.domino.DocumentCollection;
import lotus.domino.NotesException;
import lotus.domino.NotesFactory;
import lotus.domino.NotesThread;
import lotus.domino.Session;
import dk.dalsgaarddata.debug.DebugAgentContext;
/* ------------------------------------------------------------------------------------
Created: 2009.04.21/Jda
Revised: 2009.04.29/Jda - v.1.1
Agent template....
------------------------------------------------------------------------------------ */
public class AgentTemplate extends AgentBase {
// DEBUG: For Eclipse debugging - see main method at the end of this class.
// Beginning of "ordinary" Lotus Notes/Domino Agent....
private Session mySession = null;
private AgentContext myContext = null;
private DD_BackendLog myLog = null;
private void cleanUp() {
try {
if (null != myLog)
myLog.end();
if (null != mySession)
mySession.recycle();
} catch (NotesException ne) {
System.err.println("Error cleaning up log and Session.");
}
}
// Lotus Notes/Domino entry point...
public void NotesMain() {
try {
if (mySession == null) {
mySession = getSession();
myContext = mySession.getAgentContext();
}
SessionContext.getInstance(mySession, myContext);
myLog = SessionContext.getLog();
System.out.println("NotesMain Started....");
// Your code goes here....
myLog.information(".... completed!");
} catch (NotesException ne) {
myLog.error("Agent ERROR: NotesException = " + ne.text);
myLog.writeStackTrace(ne);
} catch (Exception e) {
myLog.error("Agent ERROR: Exception = " + e.getMessage());
myLog.writeStackTrace(e);
} finally {
cleanUp();
}
}
/* Instructions for debugging!!
// TODO - adjust run configuration
You need to add VM arguments, e.g.:
-Dsun.boot.library.path="c:\\Lotus\\Notes;c:\\Lotus\\Notes\\jvm\\bin"
... and you need to add a PATH environment variable, e.g.:
PATH c:\Lotus\Notes
*/
// Remember to rename these constructors when duplicating this code to a new agent!!!
// ... if not handled by Eclipse when pasting a copy ;-)
public AgentTemplate() {
}
public AgentTemplate(Session s, AgentContext c) {
this.mySession = s;
this.myContext = c;
}
// Entry point for Java program (when running from Eclipse)
public static void main(String[] args) {
// By example from Bob Balaban "The two-headed beast". See more at:
// http://www.bobzblog.com/tuxedoguy.nsf/dx/DominoAgents-Eclipse_v2.pdf/$file/DominoAgents-Eclipse_v2.pdf
System.out.println("main Starting....");
Session s = null;
Database d = null;
DocumentCollection dc = null;
AgentContext ctx = null;
System.out.println("NotesThread.sinitThread()....");
NotesThread.sinitThread();
try {
System.out.println("createSession....");
s = NotesFactory.createSession();
System.out.println("set database....");
d = s.getDatabase(DebugAgentContext.ECLIPSE_SERVER, DebugAgentContext.ECLIPSE_DATABASE);
System.out.println("Database: " + d.getFileName() + " on " + d.getServer());
System.out.println("set debug context....");
ctx = new DebugAgentContext(s, d, dc);
// Create the agent object, invoke it on NotesMain(), the way Domino does
System.out.println("create agent object....");
AgentTemplate agent = new AgentTemplate(s, ctx);
System.out.println("call agent....");
agent.NotesMain();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (s != null)
s.recycle();
} catch (Exception x) {
}
NotesThread.stermThread();
}
} // end main - and Eclipse entry point
}
I have left my "print" commands in the code for easier testing. Obviously, you would remove them from your real template.
Another thing that may have contributed to getting this to work is that I changed the case of the configuration parameters to match exactly the same upper/lower case as the directories are on the disk.
/John
Upvotes: 5