Edit: While I wrote this post I had an idea which fixed the problem. So, no help needed, but it is an interesting phenomenon, and I am curious if someone has an explanation for this problem.
Hi,
I hav a little problem with my Java code, which was running flawless under 8.5.1
Ok, I have to explain the structure:
I have an XPage to test a logging module. It only contains a computed text in which I try to return a string from a non-existing document, to force an error log entry.
In this XPage I load a server side javascript library. The object is created in a dataContext variable. In the try {} catch block, I call "logger.logError("testScript", "testApp", "Errorlog", e.getMessage(), e);"
The logError method in the library checks whether the reference to my java class is valid. The java class is implemented in a synchronized Singleton pattern.
_logger = com.mnicklisch.collaboration.logging.AgentLogger.getInstance(ClassName, database, 1, sComponentName);
if (_logger) ret = true;
The program calls the following getInstance method of the java class:
public static synchronized Logger getInstance(String className,
Database db, int logLevel, String componentName) {
AgentLogger instance = (AgentLogger) allInstances.get(componentName);
if (instance == null) {
instance = new AgentLogger(db, logLevel, componentName);
allInstances.put(componentName, instance);
} else {
instance.setCurrentLoglevel(logLevel);
instance.setComponentName(componentName);
}
return instance;
}
This is the private constructor of the class:
private AgentLogger(Database db, int logLevel, String compName) {
componentName = compName;
loggingdb = db;
currentLoglevel = logLevel;
}
In my logError method in SSJS I check receive true or false whether the reference is valid. The javaclass is called with the class name of the current module, the current database (database object of SSJS, also tried session.getCurrentDatabase()), the current loglevel and the component in which the error was thrown.
Here I call the logError method of the java class if the reference is true:
_logger.logError(sClassName,sTitle,sMessage, e);
The method itself creates a new log document in the given database and fills in the information.
And now, finally, the problem starts.
If I call the XPage, on the first run, everything is running smoothly, everything works fine. But if I call it a second time, the method which creates the logDocument returns an error that my database object has been removed or recycled. I tried lots of things, but it is 100% sure that the problem is the database object of the java class.
It is declared as a private attribute of the class:
private Database loggingdb;
Problem is, the object, If I call this.loggingdb, it isn't null. The object is there, but it seems the reference to the database itself has gone lost in space, mor or less. I can call this.loggingdb.toString(), it returns the correct path to the database (maybe the good old caching bug, Nathan Freeman once had reported of), but everything else, for example, createDocument or isOpen or anything, throws the error that the object has been removed or recycled. I checked it not only once, I do not recycle manually, anywhere.
I have already wasted 6 hours of my life with this problem, the only explanation I can imagine is that Notes 8.5.3 is doing some nasty recycling in the background, shooting my database object to hell.
While writing this, I had the idea to set the database in the getInstance method. It works fine. Now everytime I try to write a log document it works. So the original purpose of this post is gone...
But it is stange anyway. This code works in 8.5.1, and now this strange problem.
Did IBM change something in the recycling behavior? Do you have an explanation on this?
Thanks.