Wednesday, July 19, 2006

One of the differences in Java features between Notes R7 and Notes R6

After testing one of my Java applications in Notes/Domino R7 I discovered that it handled some of the Java operations differently than in Notes R6. The difference caused an error and could potentially lead to crash.

The old code was something similar to this:

MyClass MyObjects = new MyClass();
Document doc = MyObjects.db.getDocumentByUNID(unid32)


db is a public variable declared in MyClass. "MyObjects.db" is a valid object and is accessible from the code. The only thing that doesn't work is getDocumentByUNID function. This have however worked without problems in Notes R5 and R6.

The solution is to declare the database object in the same scope where you call the getDocumentByUNID function.

Database db = session.getDatabase(servername, dbpath);
Document doc = db.getDocumentByUNID(unid32)

3 comments:

Chuck Doucette said...

Can you be any more specific about exactly what you believe the problem was or exactly how you worked around it?
We do indeed cache references to Database objects, and we do call Database.getDocumentByUNID.
We may or may not be able to easily refactor our code to make those calls immediately sequentially (in the same scope).
Do you believe the Database object was garbage collected?

Thanks,
Chuck

Andrei Kouvchinnikov said...

Hello Chuck.
Here is a prototype example. I haven't tested if the latest R7 release works better. The problem is that the database object is received without errors and has all properties, but it's not possible to make getDocumentByUNID call on that object. It worked in R6 but not in R7. The database object is not garbage-collected as many (all?) other setter/getter methods seem to work fine.


class worker{
public void doThings(){
ObjectKeeper obk=new ObjectKeeper();
ObjectKeeper.setDB("names.nsf");
Database mydb=obk.db;
String title=mydb.getTitle(); //works fine, so the database is set correctly
Document doc=mydb.getDocumentByUNID("281732163782637838273827");
//the line above doesn't work
}
}

class ObjectKeeper{
public Database db;
public void setDB(String dbpath){
db=session.getDatabase("",dbpath);
}
}

Andrei Kouvchinnikov said...

P.S. In my case I could initiate the database object directly in the original class without going through ObjectKeeper class.