jankotek/JDBM3 — pull request #87 by joval (2012-06-27 02:00:41+00:00)
Title: Fixes for transient NullPointerExceptions

Greetings,

I've started using JDBM in my jOVAL project, and have experienced some NullPointerExceptions that I am guessing must be the result of race conditions because they don't seem to happen very consistently. Anyway, for some reason my diffs look bad on Github, so here are the whitespace-ignoring diffs (below). The change to SerialClassInfo was inadvertent -- I just deleted a blank line after having temporarily inserted a printStackTrace statement.

One comment I would make is that it would be nice if the JDBM maps had the ability to detect when changes are made to a previously inserted object (without having to re-add it), so that changes would be serialized transparently -- in autocommit mode, anyway. This would square its behavior with the in-memory Hashtable class, for instance. This was causing me some grief that took a long time to figure out!

Please let me know if you have any questions or comments.

Best regards,
--David Solin

$ git diff -w 98b794ccc4e2a73a955c62e0601f43f44dd139ca..
diff --git a/src/main/java/org/apache/jdbm/DBAbstract.java b/src/main/java/org/apache/jdbm/DBAbstract.java
index ca5e1ae..140f0b1 100644
--- a/src/main/java/org/apache/jdbm/DBAbstract.java
+++ b/src/main/java/org/apache/jdbm/DBAbstract.java
@@ -398,6 +398,9 @@ abstract class DBAbstract implements DB {
if(nameDirectory_recid==0)
return ret;
HTree m = fetch(nameDirectory_recid);
+ if (m == null) {
+ return null;
+ }

for(Map.Entry e:m.entrySet()){
Object o = fetch(e.getValue());
diff --git a/src/main/java/org/apache/jdbm/HTreeDirectory.java b/src/main/java/org/apache/jdbm/HTreeDirectory.java
index 50cb20e..e882b4d 100644
--- a/src/main/java/org/apache/jdbm/HTreeDirectory.java
+++ b/src/main/java/org/apache/jdbm/HTreeDirectory.java
@@ -154,6 +154,9 @@ final class HTreeDirectory {
HTreeDirectory dir = (HTreeDirectory) node;
dir.setPersistenceContext(child_recid);
return dir.get(key);
+ } else if (node == null) {
+ putRecid(hash, 0L);
+ return null;
} else {
// node is a bucket
HTreeBucket bucket = (HTreeBucket) node;
diff --git a/src/main/java/org/apache/jdbm/SerialClassInfo.java b/src/main/java/org/apache/jdbm/SerialClassInfo.java
index c586412..595576f 100644
--- a/src/main/java/org/apache/jdbm/SerialClassInfo.java
+++ b/src/main/java/org/apache/jdbm/SerialClassInfo.java
@@ -349,7 +349,6 @@ abstract class SerialClassInfo {
return f.get(object);
}
} catch (Exception e) {
-
}

throw new NoSuchFieldError(object.getClass() + "." + fieldInfo.getName());