users@glassfish.java.net

Re: Proxy classes + resource adapters = classloader problems

From: Jagadish Prasath Ramu <jagadish.ramu_at_oracle.com>
Date: Fri, 01 Apr 2011 20:19:38 +0530

Hi Laird,

By any chance, is the class Responses bundled/made available twice to
the application ?
If it is made available via GF_HOME/lib or GF_HOME/domains/<domain>/lib,
then connector container will have the visibility and the RAR will be
able to see it.

If you think that two different classloaders are involved, you can try
to log :
"responses.getClass().getClassLoader()"/"Responses.class.getClassLoader()" in both the cases which might give some clues.

Thanks,
-Jagadish

On Thu, 2011-03-31 at 15:01 -0400, Laird Nelson wrote:
> 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