Mar 24, 2012 3:17 PM
56 Posts
topic has been resolvedResolved

Disappearing notesDatabase reference in Java with 8.5.3

  • Category: Debugging
  • Platform: Linux
  • Release: 8.5.3
  • Role: Developer
  • Tags:
  • Replies: 2
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.
Mar 28, 2012 2:17 PM
56 Posts
Re: Disappearing notesDatabase reference in Java with 8.5.3
Yesterday I spoke with Philippe Riand, the Chief XPages Architect at IBM, about this problem. I posted it on my Blog. It is in German, but here is an explanation in english:
 
I save the NotesDatabase object in the instance of the Java class. But the credentials of the user, who fired the request, are saved within the NotesDatabase object. Therefore, a NotesDatabase object is recycled after every request. This makes perfect sense, because if this wouldn't happen, the following would occur:
 
User A makes the first request and initializes the class. The NotesDatabase object is saved with the credentials of user A is saved.
Now, User B makes a request and uses the same instance, and also the NotesDatabase object with the credentials of User A.
That means, that User B would access the referenced database with the rights of User A. That must not happen.
 
So, this is everything but no bug. Makes perfect sense, you only have to know what happens =)
 
It was strange though, that this wokred with 8.5.1. The only explanation we found was, this is a bug in 8.5.1. You should check this in your applications for potential security leaks.
Mar 29, 2012 12:35 AM
64 Posts
Re: Disappearing notesDatabase reference in Java with 8.5.3
Matthias, I believe I could no longer get the database directly by name (somewhere along those lines) when I converted from 8.5.1. to .2... if attempting to get a column by a key, on 8.5.2 projects did not work, my combo boxes were empty; learned a while ago, through training to use #{javascript:@DbColumn(@DbName(),"MyViewName",1)} in my combo boxes... All is well now, it was a little bit of a show-stopper for a while, poundering... Gotta be careful in there.  Thanks for posting.