Return text from a Java agent to the callback javascript function

I am writing my first Java agent which posts data back to the browser. When using a LS agent to obtain data and send it back to the javascript function, I tend to do this:

Print "Cache-Control: no-cache"

Print {Content-Type: text/xml}	

Print {<?xml version="1.0" ?>}

Print {<creditorinfo>}	

Print {<message>}

Print strReturnMsg

Print {</message>}	

If strReturnResults <> "" Then

	Print strReturnResults

End If	

Print {</creditorinfo>}	

Exit Sub

How is this duplicated in Java? Do I need to use PrintWriter to write the output back to the browser or is there another method?

I use the following method to build the xml and return it to the method from which it is called in the agent. I guess I’m asking for the syntax from there to send this back to the javascript function that called the agent. Appreciate any input on this matter.

xmlString = buildXML(storenum, managerfieldname, directorfieldname, Manager, distDirector);

private String buildXML(String storenum, String managerfieldname, String directorfieldname, String Manager, String distDirector){



	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	

	xmlFromObj = "Content-Type: text/xml\n";

	xmlFromObj = "<?xml version=\"1.0\" ?>\n";

	xmlFromObj += "<storenum>" + storenum + "</storenum>\n";

	xmlFromObj += "<managerfieldname>" + managerfieldname + "</managerfieldname>\n";

	xmlFromObj += "<directorfieldname>" + directorfieldname + "</directorfieldname>\n";	

	xmlFromObj += "<manager>" + Manager + "</manager>\n";

	xmlFromObj += "<director>" + distDirector + "</director>\n";				

return xmlFromObj;

}

Subject: Return text from a Java agent to the callback javascript function.

Yes, you will need to use a PrintWriter.

May I suggest that you send the “Content-Type: text/xml” separately as the very first output.

I seem to remember I got problems when I tried to send it as part of the whole response.

Subject: RE: Return text from a Java agent to the callback javascript function.

Here is the updated version of my agent. I am simply getting Agent Done sent as the result. If I comment out the printwriter statements and use my client (thus the hard-coded values for other things), I can print the xml out in the Notes console (it is formatted correctly).

import lotus.domino.*;

import java.sql.*;

import java.util.Hashtable;

import java.util.StringTokenizer;

import java.util.Vector;

import java.util.Enumeration;

import java.io.PrintWriter;

public class JavaAgent extends AgentBase {

PrintWriter pw; // initialize globally

public void NotesMain(){

					

	try {

		Session session = getSession();



		//AgentContext agentContext = session.getAgentContext();

		//Document docContext = agentContext.getDocumentContext();



		String storenum = "";

		String xmlString = "";

		//String qsd = docContext.getItemValueString("Query_String_Decoded");

		

		//Testing only

		String qsd = "agtGetManagerInfo?openagent&storenum=1";

		

		Hashtable ht = parseQueryString(qsd) ;



		//You now have a hashtable of every querystring arguement that's been passed with the agent in the form agent?OpenAgent&param1=first&param2=second etc

		//To get any of them, use the get method hashtable in to pull out the pair. (remember to cast it to a string

		storenum = (String) ht.get( "storenum" );

		if (storenum == null){

			//Build an xml node with an error to return to javascript

			xmlString = buildXML(storenum, qsd);

		}else{



			String managerfieldname = (String) ht.get( "outputfield0" );

			String directorfieldname = (String) ht.get( "outputfield1" );

		

			String managerlookuplocation = (String) ht.get("location0");

			String directorlookuplocation = (String) ht.get("location1");

		

			//System.out.println(storenum + " " + managerfieldname + " " + directorfieldname + " " + managerlookuplocation + " " + directorlookuplocation + "\n"); 

		

			String Manager = "";

			String distDirector = "";

			Vector ManagerDirector = lookupFromAS400(storenum);

			//System.out.println("Break out the elements of the Vector");

					

			Manager = (String) ManagerDirector.elementAt(0);

			distDirector = (String) ManagerDirector.elementAt(1);

		

			//System.out.println(Manager + ", " + distDirector);



			//Call the function to build the xml							xmlString = buildXML(storenum, managerfieldname, directorfieldname, Manager, distDirector);

			

			ManagerDirector = null;

			ht = null;

		}

		

		//Return the results to the Javascript function

		String xmlHeader = "Content-Type: text/xml\n";

// System.out.println(xmlHeader);

// System.out.println(xmlString);

		pw.println(xmlHeader);

		pw.println(xmlString);

// System.out.println(xmlHeader);

// System.out.println(xmlString);

		session.recycle();

		session = null;

		

	}catch(Exception e){

		System.err.println("ERROR IN NotesMain: " + e.getMessage());

		e.printStackTrace(); 

		System.gc();

	}

}

private Vector lookupFromAS400(String storenum){

	//this method gets the district director from the AS400 and returns it as a string value to the calling method.



	String server		= "BSYS";

	String lib			= "ISPRDDTA";

	String file1			= "STORTBL00";

	String file2			= "DISTTBL00";

	

	String user			= "ODBCUSER";

	String word		= "odbcsmrt";



	String tmpDist = "";

	String tmpMgr = "";	//This is the store manager

	String tmpDistManager = "";

	String qry = "";

	Vector myVector = new Vector(2);

	

      Connection conn = null;

	Statement stmt = null;

	ResultSet rs1 = null;

      ResultSet rs2 = null;

              

	try {

// AgentContext agentContext = session.getAgentContext();

		//DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());						

		Class.forName("com.ibm.as400.access.AS400JDBCDriver");

		conn = DriverManager.getConnection("jdbc:as400://" + server, user, word);			

		conn.setReadOnly(true);

           stmt = conn.createStatement(); //error coming up here



           qry = "Select  DISTRICT, STMGR FROM " + lib + "." + file1 +  " WHERE location =  '" + storenum + "'";

          	rs1 = stmt.executeQuery(qry); 

// rs = stmt.executeQuery(“Select DISTRICT FROM ISPRDDTA.STORTBL00 WHERE location = ‘1’”);

           //System.out.println("ResultSet1 created");

		if (rs1.next()) {

 	          tmpDist = rs1.getString(1);

			if (tmpDist == null) {

				System.out.println("No district found . . ."); 

			} else {

				//System.out.println("First result returned = " + tmpDist);

			}

 	          tmpMgr = rs1.getString(2);

			if (tmpMgr == null) {

				System.out.println("No manager found . . ."); 

			} else {

				tmpMgr = tmpMgr.trim();

				//System.out.println("Second result returned = " + tmpMgr);

			}

			

		}               

		rs1.close(); 

		

          	rs2 = stmt.executeQuery("Select  dstmgr FROM " + lib + "." + file2 +  " WHERE district = '" + tmpDist + "'"); 

// ResultSet rs2 = stmt.executeQuery(“Select dstmgr FROM ISPRDDTA.DISTTBL00 WHERE district = ‘1’”);

		if (rs2.next()) {

 	          tmpDistManager = rs2.getString(1);

			if (tmpDistManager == null) {

				System.out.println("No district manager found . . ."); 

			}else {

				tmpDistManager = tmpDistManager.trim();

				//System.out.println("Third result returned = " + tmpDistManager);					

			}

		}               

		rs2.close(); 

			

	}catch (Throwable th) {

		conn = null;

		stmt = null;

		rs1 = null;

      	rs2 = null;

// System.err.println("ERROR IN lookupFromAS400: " + th.getMessage());

		System.gc();

	   	th.printStackTrace();

	

	}finally {



  		try {

			if (rs1 != null) {

// System.out.println(“Resultset closed . . .”);

              		rs1.close();

              		rs1 = null; 

			}

			if (rs2 != null) {

// System.out.println(“Resultset closed . . .”);

              		rs2.close();

              		rs2 = null; 

			}				

			if (stmt != null) {

// System.out.println(“Statement closed . . .”);

              		stmt.close();

              		stmt = null; 

			}

			if (conn != null) {

// System.out.println(“Connection closed . . .”);

              		conn.close();

              		conn = null;

			}

		} catch (Throwable th) {

			System.gc();				

			th.printStackTrace(); 

		}



		//add the store manager and district manager to the vector.  Order is important as I am not defining in the returned data which is which except by the index in the Vector

		//System.out.println("adding the store manager to the vector to be returned to the calling program. " + new String(tmpMgr));			

		myVector.addElement( new String(tmpMgr));

		//System.out.println("adding district manager: " + new String(tmpDistManager));

		myVector.addElement( new String (tmpDistManager));

		//System.out.println("returning to the calling program....");			

		return myVector;

	}

}



public static Hashtable parseQueryString(String queryString){



	StringTokenizer tokens = new StringTokenizer(queryString, "&");

	Hashtable params = new Hashtable();



	while (tokens.hasMoreTokens()){

		String token = tokens.nextToken();

		int equalIdx = token.indexOf('=');

		if (equalIdx != -1 && !token.equalsIgnoreCase("OpenAgent")){

			String name = token.substring(0, equalIdx);

			String value = token.substring(equalIdx + 1);

			params.put(name, value);

		}

	}



	return params;

}

private String buildXML(String storenum, String managerfieldname, String directorfieldname, String Manager, String distDirector){



	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	

	xmlFromObj = "<?xml version=\"1.0\" ?>\n";

	xmlFromObj += "<storenum>" + storenum + "</storenum>\n";

	xmlFromObj += "<managerfieldname>" + managerfieldname + "</managerfieldname>\n";

	xmlFromObj += "<directorfieldname>" + directorfieldname + "</directorfieldname>\n";	

	xmlFromObj += "<manager>" + Manager + "</manager>\n";

	xmlFromObj += "<director>" + distDirector + "</director>\n";				

/*

'The cache-control statement will prevent the xml from being cached on the page.

Print "Cache-Control: no-cache"



'Return the xml so it can be parsed by the javascript function on the form

Print {Content-Type: text/xml}	

Print {<?xml version="1.0" ?>}

Print {<managerdata>}	

Print {<message>}

Print strReturnMsg

Print {</message>}	

If strReturnResults <> "" Then

	Print strReturnResults

End If	

Print {</managerdata>}	

Msgbox {Content-Type: text/xml}	+ Chr$(10) + {<?xml version="1.0" ?>} + Chr$(10) + {<managerdata>}	 + Chr$(10) + {<message>} + Chr$(10)_

+ strReturnMsg + Chr$(10) + {</message>} + Chr$(10) + strReturnResults + Chr$(10) + {<managerdata>}

*/

	return xmlFromObj;

	

}



private String buildXML(String storenum, String qsd){

	//handle the error message if the store number is incorrect.

	

	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	

	xmlFromObj = "<?xml version=\"1.0\" ?>\n";

	xmlFromObj += "<error>\nStore number was not sent to the back-end program correctly.  Please verify that you have entered a store number and contact support:\n" + qsd + "\n</error>\n";



	return xmlFromObj;

	

}

}

Subject: RE: Return text from a Java agent to the callback javascript function.

Hmm, should have worked.

Before you go deeper into the code, simplify it by outputting (through the PrintWriter) content-type: text/html followed by some very basic message.

At least then you get a start and can use the statements as debug-statements as you include more and more code.

Subject: RE: Return text from a Java agent to the callback javascript function.

I have changed the lines of code as follows, but am still getting only “Agent Done” returned. If I comment out the printwriter lines and run the agent through the Notes interface, I can print the results correctly to the debug console.

		String xmlHeader = "Content-Type: text/html";

	

		pw.println(xmlHeader);

		

		pw.println("xmlString");

import lotus.domino.*;

import java.sql.*;

import java.util.Hashtable;

import java.util.StringTokenizer;

import java.util.Vector;

import java.util.Enumeration;

import java.io.PrintWriter;

public class JavaAgent extends AgentBase {

PrintWriter pw; // initialize globally

public void NotesMain(){

					

	try {

		Session session = getSession();



		AgentContext agentContext = session.getAgentContext();

		Document docContext = agentContext.getDocumentContext();



		String storenum = "";

		String xmlString = "";

		//String qsd = docContext.getItemValueString("Query_String_Decoded");

		

		//Testing only

		String qsd = "agtGetManagerInfo?openagent&storenum=5";

		

		Hashtable ht = parseQueryString(qsd) ;



		//You now have a hashtable of every querystring arguement that's been passed with the agent in the form agent?OpenAgent&param1=first&param2=second etc

		//To get any of them, use the get method hashtable in to pull out the pair. (remember to cast it to a string

		storenum = (String) ht.get( "storenum" );

		if (storenum == null){

			//Build an xml node with an error to return to javascript

			xmlString = buildXML(storenum, qsd);

		}else{



			String managerfieldname = (String) ht.get( "outputfield0" );

			String directorfieldname = (String) ht.get( "outputfield1" );

		

			String managerlookuplocation = (String) ht.get("location0");

			String directorlookuplocation = (String) ht.get("location1");

		

			//System.out.println(storenum + " " + managerfieldname + " " + directorfieldname + " " + managerlookuplocation + " " + directorlookuplocation + "\n"); 

		

			String Manager = "";

			String distDirector = "";

			Vector ManagerDirector = lookupFromAS400(storenum);

			//System.out.println("Break out the elements of the Vector");

					

			Manager = (String) ManagerDirector.elementAt(0);

			distDirector = (String) ManagerDirector.elementAt(1);

		

			//System.out.println(Manager + ", " + distDirector);



			//Call the function to build the xml			

//testing start

/*

	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	

	xmlFromObj = "<?xml version=\"1.0\" ?>\n";

	xmlFromObj += "<storenum>" + storenum + "</storenum>\n";

	xmlFromObj += "<manager>" + Manager + "</manager>\n";

	xmlFromObj += "<director>" + distDirector + "</director>\n";				

	

			xmlString = xmlFromObj;

*/

//testing end

			xmlString = buildXML(storenum, managerfieldname, directorfieldname, Manager, distDirector);

			

			ManagerDirector = null;

			ht = null;

		}

		

		//Return the results to the Javascript function

// String xmlHeader = “Content-Type: text/xml\n”;

		String xmlHeader = "Content-Type: text/html";

	

		pw.println(xmlHeader);

		pw.println("xmlString");

// System.out.println(xmlHeader);

// System.out.println(xmlString);

		session.recycle();

		session = null;

		

	}catch(Exception e){

		System.err.println("ERROR IN NotesMain: " + e.getMessage());

		e.printStackTrace(); 

		System.gc();

	}

}

private Vector lookupFromAS400(String storenum){

	//this method gets the district director from the AS400 and returns it as a string value to the calling method.



	String server		= "BSYS";

	String lib			= "ISPRDDTA";

	String file1			= "STORTBL00";

	String file2			= "DISTTBL00";

	

	String user			= "ODBCUSER";

	String word		= "odbcsmrt";



	String tmpDist = "";

	String tmpMgr = "";	//This is the store manager

	String tmpDistManager = "";

	String qry = "";

	Vector myVector = new Vector(2);

	

      Connection conn = null;

	Statement stmt = null;

	ResultSet rs1 = null;

      ResultSet rs2 = null;

              

	try {

// AgentContext agentContext = session.getAgentContext();

		//DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());						

		Class.forName("com.ibm.as400.access.AS400JDBCDriver");

		conn = DriverManager.getConnection("jdbc:as400://" + server, user, word);			

		conn.setReadOnly(true);

           stmt = conn.createStatement(); //error coming up here



           qry = "Select  DISTRICT, STMGR FROM " + lib + "." + file1 +  " WHERE location =  '" + storenum + "'";

          	rs1 = stmt.executeQuery(qry); 

// rs = stmt.executeQuery(“Select DISTRICT FROM ISPRDDTA.STORTBL00 WHERE location = ‘1’”);

           //System.out.println("ResultSet1 created");

		if (rs1.next()) {

 	          tmpDist = rs1.getString(1);

			if (tmpDist == null) {

				System.out.println("No district found . . ."); 

			} else {

				//System.out.println("First result returned = " + tmpDist);

			}

 	          tmpMgr = rs1.getString(2);

			if (tmpMgr == null) {

				System.out.println("No manager found . . ."); 

			} else {

				tmpMgr = tmpMgr.trim();

				//System.out.println("Second result returned = " + tmpMgr);

			}

			

		}               

		rs1.close(); 

		

          	rs2 = stmt.executeQuery("Select  dstmgr FROM " + lib + "." + file2 +  " WHERE district = '" + tmpDist + "'"); 

// ResultSet rs2 = stmt.executeQuery(“Select dstmgr FROM ISPRDDTA.DISTTBL00 WHERE district = ‘1’”);

		if (rs2.next()) {

 	          tmpDistManager = rs2.getString(1);

			if (tmpDistManager == null) {

				System.out.println("No district manager found . . ."); 

			}else {

				tmpDistManager = tmpDistManager.trim();

				//System.out.println("Third result returned = " + tmpDistManager);					

			}

		}               

		rs2.close(); 

			

	}catch (Throwable th) {

		conn = null;

		stmt = null;

		rs1 = null;

      	rs2 = null;

// System.err.println("ERROR IN lookupFromAS400: " + th.getMessage());

		System.gc();

	   	th.printStackTrace();

	

	}finally {



  		try {

			if (rs1 != null) {

// System.out.println(“Resultset closed . . .”);

              		rs1.close();

              		rs1 = null; 

			}

			if (rs2 != null) {

// System.out.println(“Resultset closed . . .”);

              		rs2.close();

              		rs2 = null; 

			}				

			if (stmt != null) {

// System.out.println(“Statement closed . . .”);

              		stmt.close();

              		stmt = null; 

			}

			if (conn != null) {

// System.out.println(“Connection closed . . .”);

              		conn.close();

              		conn = null;

			}

		} catch (Throwable th) {

			System.gc();				

			th.printStackTrace(); 

		}



		//add the store manager and district manager to the vector.  Order is important as I am not defining in the returned data which is which except by the index in the Vector

		//System.out.println("adding the store manager to the vector to be returned to the calling program. " + new String(tmpMgr));			

		myVector.addElement( new String(tmpMgr));

		//System.out.println("adding district manager: " + new String(tmpDistManager));

		myVector.addElement( new String (tmpDistManager));

		//System.out.println("returning to the calling program....");			

		return myVector;

	}

}



public static Hashtable parseQueryString(String queryString){



	StringTokenizer tokens = new StringTokenizer(queryString, "&");

	Hashtable params = new Hashtable();



	while (tokens.hasMoreTokens()){

		String token = tokens.nextToken();

		int equalIdx = token.indexOf('=');

		if (equalIdx != -1 && !token.equalsIgnoreCase("OpenAgent")){

			String name = token.substring(0, equalIdx);

			String value = token.substring(equalIdx + 1);

			params.put(name, value);

		}

	}



	return params;

}

private String buildXML(String storenum, String managerfieldname, String directorfieldname, String Manager, String distDirector){



	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	

	xmlFromObj = "<?xml version=\"1.0\" ?>\n";

	xmlFromObj += "<storenum>" + storenum + "</storenum>\n";

	xmlFromObj += "<managerfieldname>" + managerfieldname + "</managerfieldname>\n";

	xmlFromObj += "<directorfieldname>" + directorfieldname + "</directorfieldname>\n";	

	xmlFromObj += "<manager>" + Manager + "</manager>\n";

	xmlFromObj += "<director>" + distDirector + "</director>\n";				

/*

'The cache-control statement will prevent the xml from being cached on the page.

Print "Cache-Control: no-cache"



'Return the xml so it can be parsed by the javascript function on the form

Print {Content-Type: text/xml}	

Print {<?xml version="1.0" ?>}

Print {<managerdata>}	

Print {<message>}

Print strReturnMsg

Print {</message>}	

If strReturnResults <> "" Then

	Print strReturnResults

End If	

Print {</managerdata>}	

Msgbox {Content-Type: text/xml}	+ Chr$(10) + {<?xml version="1.0" ?>} + Chr$(10) + {<managerdata>}	 + Chr$(10) + {<message>} + Chr$(10)_

+ strReturnMsg + Chr$(10) + {</message>} + Chr$(10) + strReturnResults + Chr$(10) + {<managerdata>}

*/

	return xmlFromObj;

	

}



private String buildXML(String storenum, String qsd){

	//handle the error message if the store number is incorrect.

	

	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	

	xmlFromObj = "<?xml version=\"1.0\" ?>\n";

	xmlFromObj += "<error>\nStore number was not sent to the back-end program correctly.  Please verify that you have entered a store number and contact support:\n" + qsd + "\n</error>\n";



	return xmlFromObj;

	

}

}

Subject: Issue with JVM in Java agent when run multiple times (memory/resources not being re-allocated?)

It’s fixed… mostly. My question to throw out now, is what sort of things do I need to do to clean up and ensure the memory is all recycled properly? I appear to be missing a few things. When testing on my local workstation, I get a JVM error “Attempt to retrieve Java agent attachments failed” after running several times (happened consistently between 7 and 8 runs) and I had to restart Notes to clear the JVM on the client. I have set all of the objects to null and recycled the docContext, agentContext and system objects at the end of the NotesMain method.

import lotus.domino.*;

import java.sql.*;

import java.util.Hashtable;

import java.util.StringTokenizer;

import java.util.Vector;

public class JavaAgent extends AgentBase {

public void NotesMain() {



	try {

		Session session = getSession();

		AgentContext agentContext = session.getAgentContext();

		Document docContext = agentContext.getDocumentContext();

		

		String xmlString = null;

		String storenum = null;

					

		String Manager = null;

		String distDirector = null;	//the district director

		String dist = null; //the district

		String region = null; //the region

		

		java.io.PrintWriter pw = this.getAgentOutput();



		String qsd = docContext.getItemValueString("Query_String_Decoded");

		

		//Testing only

		//String qsd = "testxmlreturn?openagent&storenum=5";

		

		Hashtable ht = parseQueryString(qsd) ;

		

		storenum = (String) ht.get( "storenum" );

		if (storenum == null){

			//Build an xml node with an error to return to javascript

			xmlString = buildXML(storenum, qsd);

		}else{

		

			Vector ManagerDirector = lookupFromAS400(storenum);

			//System.out.println("Break out the elements of the Vector");

					

			Manager = (String) ManagerDirector.elementAt(0);

			if (Manager == null | Manager == ""){

				Manager = "No String was placed in the Manager Variable from the Vector.";	

			}

			

			distDirector = (String) ManagerDirector.elementAt(1);

			if (distDirector == null | distDirector == ""){

				distDirector = "No String was placed in the distDirector Variable from the Vector.";	

			}

			

			dist = (String) ManagerDirector.elementAt(2);

			if (dist == null | dist == ""){

				dist = "No String was placed in the dist Variable from the Vector.";

			}

			

			region = (String) ManagerDirector.elementAt(3);

			if (region == null | region == ""){

				region = "No String was placed in the region Variable from the Vector";

			}

			

			//Call the function to build the xml			

			xmlString = buildXML(storenum, Manager, distDirector, dist, region);

			ManagerDirector = null;

		}



		ht = null;

		qsd = null;

			

		pw.println("Cache-Control: no-cache");

		pw.println("Content-type: text/xml");

		pw.println("<?xml version=\"1.0\" ?>");

		pw.println(xmlString);

		

		pw = null;

		

		docContext.recycle();		//  = null;

		agentContext.recycle();	// = null;

		session.recycle();			// = null;

		System.gc();				

	} catch(Exception e) {

		e.printStackTrace();

	}

}



public static Hashtable parseQueryString(String queryString){



	StringTokenizer tokens = new StringTokenizer(queryString, "&");

	Hashtable params = new Hashtable();



	while (tokens.hasMoreTokens()){

		String token = tokens.nextToken();

		int equalIdx = token.indexOf('=');

		if (equalIdx != -1 && !token.equalsIgnoreCase("OpenAgent")){

			String name = token.substring(0, equalIdx);

			String value = token.substring(equalIdx + 1);

			params.put(name, value);

		}

	}



	return params;





}



private String buildXML(String storenum, String Manager, String distDirector, String distName, String region){

	

	String xmlFromObj = "<managerdirectordata>";

	xmlFromObj += "<storenum>" + storenum + "</storenum>";

// xmlFromObj += “<managerfieldname>” + managerfieldname + “</managerfieldname>
”;

// xmlFromObj += “<directorfieldname>” + directorfieldname + “</directorfieldname>
”;

	xmlFromObj += "<manager>" + Manager + "</manager>";

	xmlFromObj += "<director>" + distDirector + "</director>";

	xmlFromObj += "<district>" + distName + "</district>";

	xmlFromObj += "<region>" + region + "</region>";

	xmlFromObj += "</managerdirectordata>";

	return xmlFromObj;

	

}



private String buildXML(String storenum, String qsd){

	//handle the error message if the store number is incorrect.

	

	String xmlFromObj = "";	//this is the middle, mutable part of the xml string to be returned to the javascript callback function

	xmlFromObj += "<error>Store number was not sent to the back-end program correctly.  Please verify that you have entered a store number and contact support:\n" + qsd + "</error>";

	return xmlFromObj;

	

}	



private Vector lookupFromAS400(String storenum){

	//this method gets the district director from the AS400 and returns it as a string value to the calling method.



	String server		= "BSYS";

	String lib			= "ISPRDDTA";

	String file1		= "STORTBL00";

	String file2		= "DISTTBL00";

	

	String user			= "ODBCUSER";

	String word			= "odbcsmrt";



	String tmpDist = "";

	String tmpMgr = "";	//This is the store manager

	String tmpDistManager = "";

	String tmpRegion = "";

	String qry = "";

	Vector myVector = new Vector(2);

	

    Connection conn = null;

	Statement stmt = null;

	ResultSet rs1 = null;

    ResultSet rs2 = null;

              

	try {

// AgentContext agentContext = session.getAgentContext();

		//DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());						

		Class.forName("com.ibm.as400.access.AS400JDBCDriver");

		conn = DriverManager.getConnection("jdbc:as400://" + server, user, word);			

		conn.setReadOnly(true);

           stmt = conn.createStatement(); //error coming up here



           qry = "Select  DISTRICT, STMGR FROM " + lib + "." + file1 +  " WHERE location =  '" + storenum + "'";

          	rs1 = stmt.executeQuery(qry); 

// rs = stmt.executeQuery(“Select DISTRICT FROM ISPRDDTA.STORTBL00 WHERE location = ‘1’”);

           //System.out.println("ResultSet1 created");

		if (rs1.next()) {

 	          tmpDist = rs1.getString(1);

			if (tmpDist == null) {

				System.out.println("No district found . . ."); 

			} else {

				tmpDist = tmpDist.trim();

			}

 	          tmpMgr = rs1.getString(2);

			if (tmpMgr == null) {

				System.out.println("No manager found . . ."); 

			} else {

				tmpMgr = tmpMgr.trim();

				//System.out.println("Second result returned = " + tmpMgr);

			}

			

		}               

		rs1.close(); 

		

          	rs2 = stmt.executeQuery("Select dstmgr, region FROM " + lib + "." + file2 +  " WHERE district = '" + tmpDist + "'"); 

// ResultSet rs2 = stmt.executeQuery(“Select dstmgr FROM ISPRDDTA.DISTTBL00 WHERE district = ‘1’”);

		if (rs2.next()) {

 	          tmpDistManager = rs2.getString(1);

			if (tmpDistManager == null) {

				System.out.println("No district manager found . . ."); 

			}else {

				tmpDistManager = tmpDistManager.trim();

				//System.out.println("Third result returned = " + tmpDistManager);					

			}

			tmpRegion = rs2.getString(2);

			if (tmpRegion == null) {

				System.out.println("No region found . . ."); 

			}else {

				tmpRegion = tmpRegion.trim();

			}				

		}               

		rs2.close(); 

		

		if (rs1 != null) {

            System.out.println("Resultset closed . . .");

            rs1.close();

            rs1 = null; 

			}

		if (rs2 != null) {

// System.out.println(“Resultset closed . . .”);

            rs2.close();

            rs2 = null; 

		}				

		if (stmt != null) {

// System.out.println(“Statement closed . . .”);

			stmt.close();

            stmt = null; 

		}

		if (conn != null) {

// System.out.println(“Connection closed . . .”);

            conn.close();

            conn = null;

		}

//add the store manager and district manager to the vector. Order is important as I am not defining in the returned data which is which except by the index in the Vector

		myVector.addElement( new String(tmpMgr));

		myVector.addElement( new String (tmpDistManager));

		myVector.addElement(new String (tmpDist));

		myVector.addElement(new String (tmpRegion));

		return myVector;

		

	}catch (Throwable th) {

		conn = null;

		stmt = null;

		rs1 = null;

      	rs2 = null;

// System.err.println("ERROR IN lookupFromAS400: " + th.getMessage());

		System.gc();

	   	th.printStackTrace();

	   	return myVector;

	}



} //end method

}

Subject: RE: Issue with JVM in Java agent when run multiple times (memory/resources not being re-allocated?)

Testing has shown that the memory leak is occurring at this point in the code:

Class.forName(“com.ibm.as400.access.AS400JDBCDriver”); //THIS LINE CAUSING MEMORY LEAKS OF AROUND 10 MB EACH RUN!!!

I determined this by first registering the driver, but not using it at all. This caused a leak of around 11 mb. Next I commented out the code that registered the driver and found that I was leaking the same amount of memory with each run. when I commented out the method above, the memory gain essentially went away (increases of 1-2 mb, which I have attributed to javascript objects and normal form usage.