java version "1.5.0_14" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03) Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode)
I'm trying to debug a NullPointerException I'm getting for passing a reference to statically defined field. To be more specific, I'm setting a global on a Drools3 working memory instance.
workingMemory.setGlobal("log", workingMemorieslog);
My assumption is that the Class where the field is statically defined is being garbage collected. (The receiving class must be using WeakReference or something like that, I don't really know)
How would you suggest to debug this? I think that if I could know exactly when JVM's GC unloads a class / instance of a class then I could narrow down on the cause of the buggy behavior. (If not the exact time of the event at least getting an indication that something did happened).
Thank you, Maxim.
The typical CUI GC monitoring method involves using a separate CUI application called "jstat", or selecting a JVM option called "verbosegc" when running JVM. GUI GC monitoring is done by using a separate GUI application, and three most commonly used applications would be "jconsole", "jvisualvm" and "Visual GC".
To trace GC activity add this to java command:
-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
NPE that you are getting is probably you passing null value.
Why not keep the class in memory then see if it still happens, if it does then your problem lies elsewhere. If not then you know the issue lies in garbage collection.
It turns out that eclipse is the main issue here.
I'll explain:
I have wrapped our webapp in a main() method in order to test performance. We use a lot of 3rd party code, namely Apache commons-pool.
It turns out we had several versions of the jar spread across the projects (eclipse projects). My app which uses these projects had commons-pool-1.3, a different project had commons-pool-1.2.
When loaded using the servlet container (Tomcat6) the webapp class loader had first priority so it always loaded the webapp version. When I started the application using main() eclipse in it's not very wise behavior exported the depended projects jars in in the -classpath BEFORE the ones in the current project.
The conflict was between 2 versions of commons-pool, which caused a non defined behavior - On a object borrow is SOMETIMES decided to create a new object. I haven't looked inside the implementation code, I assume that this is something to do with a static map hold by the GenericKeyedObjectPool (the problematic class). Because a new instance was created it indeed contains a null reference to the mentioned global.
The solution to my luck was rather simple, commons-pool is being used only by my webapp so I could delete it from all referenced projects, otherwise I think i would just try to upgrade them all to a single version. If I couldn't do either I really don't know what would I've done. This is a very strange default of eclipse.
Thank you for reading and helping.
// ps. 3 days. That's the time I've spend on understanding what the hell I did wrong in my servlet replacement code. Turns out I'm not even the problem. :P
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With