8 Replies Latest reply on Dec 14, 2011 5:29 AM by dan.berindei

    hotrod client classloader

    henners

      Dear infinispanners

       

      I am getting started with a hotrod client ... I want to use it from an application container where each application has its own classloader.

       

      I want the hotrod client to be available to all applications deployed on my container...  The problem is that the RmeoteCacheMamanger will not use the the classloader of the application when deserialising objects it will use the class loader that loaded the marshaller....which will be the parent of the application class loader..so I'll get class not found exceptions. 

       

      See what I mean ?  any suggestions ?

       

      Thanks

      Henners

        • 1. Re: hotrod client classloader
          galder.zamarreno

          Well, seems like the solution would be for each app to ship the hotrod client. What would be the problem with that?

           

          What container are you deploying to?

          • 2. Re: hotrod client classloader
            henners

            Thanks , as  the question was framed its the correct answer .. an additional requirement though is that the hot rod client is wrapped by a Resource adaptor API so that reponses can be fired as events ... its to be compliant with the JAIN SLEE spec (jsr240) ..so to answer your question its a JAIN SLEE container.. So I was wondering why doesn't the hotrod client use the classloader I provided to it ?

            • 3. Re: hotrod client classloader
              henners

              To close this issue..

               

              setting the context class loader of the current thread before calling the cacheAPI does the trick.

              • 4. Re: hotrod client classloader
                galder.zamarreno

                Btw, if you look at the RemoteCacheManager constructors, you'll see that there're some options that allow you to pass in the ClassLoader, i.e. http://docs.jboss.org/infinispan/5.1/apidocs/org/infinispan/client/hotrod/RemoteCacheManager.html#RemoteCacheManager(java.lang.String, boolean, java.lang.ClassLoader)

                • 5. Re: hotrod client classloader
                  henners

                  True , but  setting the classloader there didn't work as I expected.. I mean it used that classloader to load the Marshaller, but that class loader delegated loading the marhaller to its parent.. then to deserialize it tried to use the same classloader which loaded the Marshaller.. which was the parent of the one that I wanted it to use.

                  • 6. Re: hotrod client classloader
                    galder.zamarreno

                    henners wrote:

                     

                    ...I mean it used that classloader to load the Marshaller, but that class loader delegated loading the marhaller to its parent...

                     

                    Hmmm, so it appears that the problem is with the classloader that did the wrong delegation?

                    • 7. Re: hotrod client classloader
                      henners

                      Depends on your point of view, For me the delegation was expected but the behaviour of the hotrod client was not expected , only when I looked in the code I realized what it does with the classloader passed to it. So maybe just clearer javadoc is needed, but my case is probably unusual and I have a work around.

                      • 8. Re: hotrod client classloader
                        dan.berindei

                        I agree 100%  that the RemoteCacheManager constructors should clearly state what the ClassLoader argument is used for: to load the classes configured in the Properties argument.

                         

                        The default marshaller always uses the thread context class loader for deserialization, it never considers the ClassLoader that was passed to the RemoteCacheManager constructor. The Marshaller class' ClassLoader is intended as a fallback mechanism for internal classes, in case not all the Infinispan classes are accessible from the application's classloader. That's why we're using the ClassLoader of the Marshaller interface and not the RemoteCacheManager argument.

                         

                        If you don't want to set the thread context class loader around each RemoteCache invocation, you could write your own Marshaller implementation that extends GenericJBossMarshaller and calls baseCfg.setClassResolver() with your own ClassResolver implementation.

                         

                        I think it would be a good idea to make this scenario easier: setting the thread context class loader in non-webapp environments can be a PITA, so there are probably others who would use a fixed ClassLoader instead.