6 Replies Latest reply on May 27, 2011 9:32 AM by galder.zamarreno

    Need help understanding class loading rules used by JBoss Marshalling in Infinispan

    sellhorn

      This is related to using Infinispan in OSGi.

       

      Basically, after some usage we sometimes see the JBoss Marshalling using the wrong class loaders in an OSGi environment. We have multiple bundles talking to a central bundle that holds all caches (the central bundle exposes itself as an OSGi service an does Dynamic-Import: *). Bundles have their own context and bundle class loaders and everything works fine. But when we run them all at the same time, after some time we start getting class loading exceptions and you can see jboss marshalling using the bundle context classloader from say bundle B, when it's trying to load say class A from bundle A.

       

      It seems like the jboss marshaller keeps references to different classloaders and in a multithreaded environment can get messed up.

       

      Here's an example stack trace of what I'm talking about;

       

      Caused by: java.lang.ClassNotFoundException: com.ge.blah.A.SomeAClass not foundfrom bundle [com.ge.blah.B]

             at org.springframework.osgi.util.BundleDelegatingClassLoader.findClass(BundleDelegatingClassLoader.java:103)

             at org.springframework.osgi.util.BundleDelegatingClassLoader.loadClass(BundleDelegatingClassLoader.java:156)

             at java.lang.ClassLoader.loadClass(ClassLoader.java:248)[:1.6.0_21]

             at java.lang.Class.forName0(Native Method)[:1.6.0_21]

             at java.lang.Class.forName(Class.java:247)[:1.6.0_21]

             at org.jboss.marshalling.AbstractClassResolver.loadClass(AbstractClassResolver.java:135)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.AbstractClassResolver.resolveClass(AbstractClassResolver.java:116)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doResolveClass(RiverUnmarshaller.java:1148)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadClassDescriptor(RiverUnmarshaller.java:862)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1183)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:270)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.exts.ReplicableCommandExternalizer.readObject(ReplicableCommandExternalizer.java:75)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.jboss.ConstantObjectTable$ExternalizerAdapter.readObject(ConstantObjectTable.java:266)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.jboss.ConstantObjectTable.readObject(ConstantObjectTable.java:253)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:357)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.exts.ReplicableCommandExternalizer.readObject(ReplicableCommandExternalizer.java:75)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.jboss.ConstantObjectTable$ExternalizerAdapter.readObject(ConstantObjectTable.java:266)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.jboss.ConstantObjectTable.readObject(ConstantObjectTable.java:253)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:357)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:207)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.jboss.marshalling.AbstractUnmarshaller.readObject(AbstractUnmarshaller.java:85)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.jboss.GenericJBossMarshaller.objectFromObjectStream(GenericJBossMarshaller.java:162)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.marshall.VersionAwareMarshaller.objectFromByteBuffer(VersionAwareMarshaller.java:111)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.remoting.transport.jgroups.MarshallerAdapter.objectFromByteBuffer(MarshallerAdapter.java:26)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.handle(CommandAwareRpcDispatcher.java:146)[198:com.ge.blah.someinfinispanwrapper:1.5.0.SNAPSHOT]

             ... 28 more

       

      Caused by: java.lang.ClassNotFoundException: com.ge.blah.A.SomeAClass

             at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:506)[osgi-3.6.0.v20100517.jar:]

             at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)[osgi-3.6.0.v20100517.jar:]

             at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)[osgi-3.6.0.v20100517.jar:]

             at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)[osgi-3.6.0.v20100517.jar:]

             at java.lang.ClassLoader.loadClass(ClassLoader.java:248)[:1.6.0_21]

             at org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:338)[osgi-3.6.0.v20100517.jar:]

             at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:232)[osgi-3.6.0.v20100517.jar:]

             at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1197)[osgi-3.6.0.v20100517.jar:]

             at org.springframework.osgi.util.BundleDelegatingClassLoader.findClass(BundleDelegatingClassLoader.java:99)

             ... 56 more

       

       

      One work around we've found is that if you turn on lazy deserialization then this seems to fix the problem, but we're seeing degraded performance and issues with running out of memory.

       

      My question is, how does JBoss Marshalling figure out what class loader to use, and how I can make it use the classloader of the bundle that interacts with the class it loads ... OR ... how can I tell it what classloader to use in a more direct way. For example, I believe that if it used the classloader I have with Dynamic-Import: * things would work.

       

      Are these some settings I can try for JBoss marshalling to control what class loader it uses, interceptors I could use?

       

      Thanks