users@glassfish.java.net

Proxy classes + resource adapters = classloader problems

From: Laird Nelson <ljnelson_at_gmail.com>
Date: Thu, 31 Mar 2011 15:01:56 -0400

I think this is a bug in Glassfish 3.1 final, but I'm not sure. Please bear
with the rather lengthy explanation that follows.

I have a resource adapter (http://code.google.com/p/drools-jca/). It
supplies instances of the Drools KnowledgeBase class (
http://downloads.jboss.com/drools/docs/5.1.1.34858.FINAL/apidocs/org/drools/KnowledgeBase.html
).

Next, I have a stateless session bean that uses it. The KnowledgeBase is
injected via a @Resource annotation:

  @Resource
  private KnowledgeBase kb;

This stateless session bean also contains a reference to another stateless
session bean like this:

  @EJB
  private Responses responses;

All fine and good.

Now, one of the things a KnowledgeBase does is vend
StatefulKnowledgeSessions (
http://downloads.jboss.com/drools/docs/5.1.1.34858.FINAL/apidocs/org/drools/runtime/StatefulKnowledgeSession.html).
And one of the things you can do with a StatefulKnowledgeSession is set a
global variable on it (
http://downloads.jboss.com/drools/docs/5.1.1.34858.FINAL/apidocs/org/drools/runtime/KnowledgeRuntime.html#setGlobal%28java.lang.String,%20java.lang.Object%29).
It's kind of like a HashMap.

Finally, Drools lets you write rules files (the main purpose of the
project). In those rules files, you can specify global variables (that will
be supplied as I've mentioned above). Here are the details:
http://downloads.jboss.com/drools/docs/5.1.1.34858.FINAL/drools-expert/html_single/index.html#d0e3157
Rules files are compiled at resource adapter startup time.

If you're still with me, congratulations and thank you. That's all the
background.

Here's the problem. If I setGlobal() with my Responses reference above,
Drools complains that the global is not an instance of Responses. That is:

  this.kb.newStatefulKnowledgeSession().setGlobal("responses", responses);

...fails. It says that my Responses reference is not an instance of
Responses. The responses object of course is a java.lang.reflect.Proxy
generated by Glassfish. It most certainly IS a Responses instance, or my
SLSB wouldn't have started up.

For completeness, the global part of my rules file looks like this:

  global com.foobar.Responses responses;

It is the same class--i.e. I would expect that this is a perfectly legal
assignment.

Now, I have all of this stuff packed up in an .ear file. The .jar file
containing the Responses interface is in the lib directory.

This looks to me like a classloading issue. It looks like perhaps the
Drools resource adapter is loading "Responses.class" with a different
classloader than that used by the proxy generation mechanism--or, almost
equivalently, that the classloader used to generate the Proxy class does not
have the proper parent set or something like that. In any event,
Responses.class seems to be being loaded twice.

The first thing anyone will ask me for is a test case, of course, and I'm
working on one. However given the intricacies of the systems involved it
might be easier if I give you an .ear file so you can see for yourself.

Should I file a bug here?

Thanks,
Laird