10 Replies Latest reply on Sep 13, 2012 12:13 PM by pugsherpa

    How Do You Make Deployment Classes Available to Server Modules?

    pugsherpa

      I have come across two situations where the Jboss server-specific modules were trying to find classes from within our deployments (EAR, JAR, WAR, whatever) but they couldn't find classes.

       

      If this was reversed, it seems easy - if one of the classes in my deployment archive was missing a class that a jboss server-specific module had, I would just add a Dependencies: to the artifact or add the module dependency to the jboss-deployment-structure.xml. 

       

      I'm not sure how to expose the server modules to the code they need to find in our deployments?

       

      For instance, one of our custom LoginModule classes needs to be accessed from Module "org.picketbox:main"

      Am I supposed to edit the module.xml file for picketbox and create a dependency on our ear?  That seems wrong. 

       

      Then we saw it again, the server-packaged hibernate module needs to access our DAO classes, but it can't see them.  How am I supposed to expose our classes to the  Module "org.hibernate:main" ?

        • 1. Re: How Do You Make Deployment Classes Available to Server Modules?
          jameslivingston

          Generally speaking, if a server module is in a situation where it may need to access deployment classes it should be using the Thread Context ClassLoader (TCCL) to do so. In most cases the code should obviously be accessing a class visible from the deployment or obviously accessing an internal class, so it may be a bug. Could you post the exceptions you are seeing (with stack traces), so that we can see where the access is coming from?

          • 2. Re: How Do You Make Deployment Classes Available to Server Modules?
            pugsherpa

            James,

            I think the hibernate problem is related to how our hibernate archive is packaged.  I noticed that it's not the DTO object that it can't find, it's the proxy class.

             

            fishstore.hbm.xml  (no we aren't moving to annotations yet, we still have mapping files, this is a huge migration effort)

            {code}

            <class name="com.fishstore.dto.impl.FishTypeDTO" table="FISHTYPE" lazy="false" polymorphism="explicit" proxy="com.fishstore.dto.FishType">

            .....

            </class>

            {code}

             

            The stack trace is complaining about not being able to find the proxy class (com.fishstore.dto.FishType).

             

            The ear is packaged like this:

             

            {code}

            fishstore.ear

                 |

                 ---  fishstore-ejb.jar

                 |

                 ---  fishstore-rest-webapp.jar

                 |

                 ---  fishstore-webapp.war

                 |

                 ---  APP-INF

                          |

                          --- lib

                                |

                                ---  fishstore-classes.jar

                                |

                                ---  fishstore-hibernate-archive.jar

                                                   |

                                                   --- *.hbm.xml   hibernate.properties  (no java classes at all in this jar)

                                                   |

                                                   --- META-INF

                                                            |

                                                            ---  persistence.xml

            {code}

             

            Both classes com.fishstore.FishTypeDTO and com.fishstore.dto.FishType are in fishstore-classes.jar

             

            I would copy and paste the server log into here if I could to show you, but we're air-gapped and it's a really long stack trace, I'd have to type it in by hand.  I think this might be a packaging problem.  This ear we're trying to port it from Hibernate 3.1.3, Jboss 4.0.4 to Hibernate 4.1, Jboss 7.  I've had to tweak our artifact packaging, I'm betting this is another case where the proper classes aren't visible the way they are supposed to be.  How do I make the classes in the fishstore-classes.jar file available to hibernate module?

            • 3. Re: How Do You Make Deployment Classes Available to Server Modules?
              pugsherpa

              I tried building the hibernate jar with the appropriate classes and I still am getting this error (not consistently though - so odd).  I'll try to make time on Monday to type in the entire stack trace.

              • 4. Re: How Do You Make Deployment Classes Available to Server Modules?
                pugsherpa

                Here's the stacktrace.  Please forgive typos.  I tried really hard to make sure I had the right line number in the classes.

                 

                {code}

                ERROR [or.hibernate.proxy.pojo.javassist.JavassistLazyInitializer] HHH000142 Javassist Enhancement failed: com.fishstore.dto.impl.FishTypeDTO: java.lang.RuntimeException: by java.lang.NoClassDeFoundError: com.fishstore.dto.FishType

                    at javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:510) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    at javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:487) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    at javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:423) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    at javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:395) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.getProxyFactory(JavassistLazyInitializer.java:163)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.proxy.pojo.javassist.JavassistProxyFactory.postInstantiate(JavassistProxyFactory.java:66)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.tuple.entity.PojoEntityTuplizer.buildProxyFactory(PojoEntityTuplizer.java:221) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:212)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:82) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at sun.relect.GeneratedConstructorAccessor30.newInstance(Unknown Source) [:1.6.0_27]

                     at sun.reflect.DelegatingConstructorAccessorImpl.netInstance(DelegatingConstructorAccessorImpl.java:27) [rt.jar:1.6.0_27]

                    at java.lang.relfect.Constructor.newInstance(Constructor.java:513) [rt.jar:1.6.0_27]

                    at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:135)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:188)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java: 341) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.persister.entity.AbstractentityPersister.<init>(AbstractEntityPersister.java:503)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:144) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at sun.reflect.GeneratedConstructorAccessor29.newInstance(Unknown Source) [:1.6.0_27]

                    at sun.reflect.DelegatingConstructorAcessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)[rt.jar:1.6.0_27]

                    at java.lang.relfect.Constructor.newInstance(Constructor.java:513) [rt.jar:1.6.0_27]

                    at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java: 163) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:384) [hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java: 1740)[hibernate-core-4.1.1.Final.jar:4.1.1.Final]

                    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java: 84) [hibernate-entitymanager-4.0.1.Final]

                    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904) [hibernate-entitymanager-4.0.1.Final]

                    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889) [hibernate-entitymanager-4.0.1.Final]

                    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)  [hibernate-entitymanager-4.0.1.Final]

                    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:162) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]

                    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.start(PersistenceUnitServiceImpl.java:85) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]

                    at org.jboss.msc.service.ServiceconrollerImpl$StartTask.startService(ServiceControllerImpl.java:1811)

                    at org.jboss.msc.service.ServiceconrollerImpl$StartTask.run(ServiceControllerImpl.java:1746)

                    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)[rt.jar:1.6.0_27]

                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)[rt.jar:1.6.0_27]

                    at java.lang.Thread.run(Thread.java:662)[rt.jar:1.6.0_27]

                Caused by: javassist.CannotCompileException: by java.lang.NoClassDefFoundError: com/fishstore/dto/FishType

                    at javassit.util.proxy.FactoryHelper.toClass(FactoryHelper.java:170) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    at javassit.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:502) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    .... 36 more

                Caused by: java.lang.NoClassDefFoundError: com/fishstore/dto/FishType

                    at java.lang.ClassLoader.defineClass1(Native Method)[rt.jar:1.6.0_27]

                    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)[rt.jar:1.6.0_27]

                    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)[rt.jar:1.6.0_27]

                    at sun.reflect.GeneratedMethodAccesor3.invoke(Unknown source) [rt.jar:1.6.0_27]

                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)[rt.jar:1.6.0_27]

                    at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_27]

                    at javassit.util.proxy.FactoryHelper.toClass2(FactoryHelper.java:182) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    at javassit.util.proxy.FactoryHelper.toClass(FactoryHelper.java:164) [javassist-3.15.0-GA.jar:3.15.0.GA]

                    .... 37 more

                Caused by: java.lang.ClassNotFoundException: com.fishstore.dto.FishType from [Module "org.hibernate:main" from local module loader @7f5e2075 (roots:/apps/jboss/modules)]

                    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java: 190)

                    at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)

                    at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)

                    at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:423)

                    at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:423)

                    at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)

                    at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)

                    .... 45 more

                 

                {code}

                • 5. Re: How Do You Make Deployment Classes Available to Server Modules?
                  jameslivingston

                  That looks like Hibernate or Javassist is using the wrong classloader - Hibernate's rather than the one FishType belongs to.

                   

                  It looks vaguely similar to https://hibernate.onjira.com/browse/HHH-3826, but I don't know enough about Hibernate to be sure. Hopefully someone else who knows it better than me can comment.

                  • 6. Re: How Do You Make Deployment Classes Available to Server Modules?
                    ajay.deshwal

                    You are right James. Its the way we initialize session factory that decides what classloaders will be used by hibernate to load classes.

                    If session factory is build without passing an appropriate ServiceRegistry, all class loaders are set to ClassLoaderServiceImpl.class.getClassLoader() which will fail to load application classes.

                    As you pointed, if a module needs to access deployment classpath resources, it must use thread context class loader.

                    I was facing a similar issue which i fixed by setiing all classloaders to null in my service registry initialization. Hibernate's ClassLoaderServiceImpl will initialize them appropriately.

                    Pugsherpa- Please see following post to fix the issue. Hope it helps.

                    1 of 1 people found this helpful
                    • 7. Re: How Do You Make Deployment Classes Available to Server Modules?
                      pugsherpa

                      Ajay,

                      Your solution would probably work, but I'm not sure how to use it in our code.  We aren't using spring to inject the sessionfactory into the DAO layer - we were retrieving it from JNDI(entitymanager->Sessionfactory) as it was created by the persistence unit specified in our hibernate archive's persistence.xml.  I don't know how to force the persistence unit to bind a custom class to JNDI.  Any ideas?

                       

                      Thank you for sharing your solution.  At least I'm not the only one.  I'm seeing it with the picketbox module trying to find our custom login modules too.  This new classloader model needs a lot of help. 

                      • 8. Re: How Do You Make Deployment Classes Available to Server Modules?
                        pugsherpa

                        Here's my write-up on the similar issue I was having with the login modules: https://community.jboss.org/thread/204595

                        • 9. Re: How Do You Make Deployment Classes Available to Server Modules?
                          ajay.deshwal

                          Hi Pugsherpa,

                           

                          Sorry if you were waiting on my response. I was off the grid for sometime.

                          I'll set up a similar config as you mentioned and will try to figure out a fix. Please let me know the hibernate version you're using. Are you injecting entity manager via @PersistentContext annotation?

                           

                          Cheers!

                          • 10. Re: How Do You Make Deployment Classes Available to Server Modules?
                            pugsherpa

                            No, we are not using annotations at all.  Very old legacy project.  We are letting the hibernate archive create the entity manager and bind it to JNDI which we do a lookup in the code when it's needed.