14 Replies Latest reply on Jan 15, 2007 3:01 PM by andber

    packaging and deployment of ear-files (classcastexception, n

    andber

      Hi,

      I have this:

      app1.ear
      app1-ejb.jar


      app2.ear
      app2.war
      web-inf
      lib


      app2 contains a servlet which connects through a remote ejb interface included in app1-ejb.jar, so app2.ear needs to have app1-ejb.jar (or really a subset of it but let's say it is the same jar) in its classpath.

      Both applications use the isolation in jboss-app.xml

      <loader-repository>
      myapp1:loader=myapp1.ear <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
      </loader-repository>


      I have tried to put app1-ejb.jar directly under the ear (noclassdeffounderror) and in the war/web-inf/lib (classcastexception).

      If I check in jmx-console (displayClassInfo) for the "repository myapp1 I can see all the jars and I can search for a classname and get which jar it is in.

      But here is the strange part, if I check in jmx-console for myapp2 the jars that are included in the ear are not listed and if I search for the remote interface class it is not found in the repository.


      What decides if a jar is listed in the jmx-console?

      Thanks

        • 1. Re: packaging and deployment of ear-files (classcastexceptio
          andber

          To clarify:

          app2.ear contains a war-file which calls a remote session bean interface in app1.ear, therefore app2 needs app1-ejb.jar in its classpath.

          When app1-ejb.jar is included in app2.ear it is not found in the list when viewing the loader-repositories in jmx-console. I think this is why it doesn't work but why isn't it shown in the loader-repositories list for app2.ear?

          • 2. Re: packaging and deployment of ear-files (classcastexceptio
            andber

            I now see that all other jars than the app1-ejb.jar is shown in the loader-repository for app2.ear.. Why is this?

            • 3. Re: packaging and deployment of ear-files (classcastexceptio
              asack

               

              "andber" wrote:
              I now see that all other jars than the app1-ejb.jar is shown in the loader-repository for app2.ear.. Why is this?


              Is EAR isolation turned on or off via the EAR deployer?

              java2Parent delegation effects if a JAR is first seen (cached) in the UCL, not whether EARs are isolated - that's part of your ear-service.xml in the deploy directory.

              If its turned on then everything in app1 will not be seen via app2. If you are trying to share some interface across EARs, you should package those specific interfaces as a JAR, drop it in the deploy directory so now it has global scope across EARs.

              If EAR isolation is turned off, than app1-ejb.jar should be visible to app2 (at least my understanding of JBoss classloading).

              Please take a look at the following WIKIs if you haven't already:

              http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossClassLoadingUseCases
              http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassLoadingOverview

              And Chapter 8 of the J2EE spec.

              • 4. Re: packaging and deployment of ear-files (classcastexceptio
                andber

                 

                "asack" wrote:
                "andber" wrote:
                I now see that all other jars than the app1-ejb.jar is shown in the loader-repository for app2.ear.. Why is this?


                Is EAR isolation turned on or off via the EAR deployer?

                java2Parent delegation effects if a JAR is first seen (cached) in the UCL, not whether EARs are isolated - that's part of your ear-service.xml in the deploy directory.

                If its turned on then everything in app1 will not be seen via app2. If you are trying to share some interface across EARs, you should package those specific interfaces as a JAR, drop it in the deploy directory so now it has global scope across EARs.

                If EAR isolation is turned off, than app1-ejb.jar should be visible to app2 (at least my understanding of JBoss classloading).

                Please take a look at the following WIKIs if you haven't already:

                http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossClassLoadingUseCases
                http://wiki.jboss.org/wiki/Wiki.jsp?page=ClassLoadingOverview

                And Chapter 8 of the J2EE spec.


                Hi, ear isolation is turned off (as default) in the ear-deployer.xml.

                I am not trying to "use" the jar file in app1 from app2, the ejb-jar-file in app1 is included in both app1.ear (as an ejb-module) and in app2.ear (as a simple jar to get the remote interfaces from app1 in the app2 classpath.

                Should work, shouldn't it? I have checked the pages you linked to.

                Thanks.

                • 5. Re: packaging and deployment of ear-files (classcastexceptio
                  andber

                  In this thread:

                  http://www.jboss.com/index.html?module=bb&op=viewtopic&t=66651

                  I see why I get the classcastexception if I put the remote interface in app2.ear/webapp/WEB-INF/lib.

                  But I still can't understand why it doesn't work if I put the jar with the remote interface of app1 in the root of app2.ear..

                  • 6. Re: packaging and deployment of ear-files (classcastexceptio
                    asack

                    Absolutely not. With EAR isolation turned off, that means that the first verison of ejb-jar-file will be used for ALL EARs. I'm not sure why you've turned off java2Parent delegation exactly either since you have EAR isolation turned off (as per WIKI, java2Parent delegation is to prevent an EAR from grabbing a cached version of library first before checking if its packaged with it - dom4j.jar is a good example where you could run into problems if you need XPath as well as incompatibilities with cglib which is packaged in several places depending on JBoss build!).

                    If you are including this jar file in both EARs then why not do the following to prevent incorrect classloading issues:

                    - turned EAR isolation on (IMO should be the default, more than likely its not for historical/compatibility issues)
                    - include the jar file in both EARs or have a singular library deployed outside of both EARs
                    - any modules within an EAR that are using this client side jar file have a reference to it in their MANIFEST.MF file via the Class-Path entry

                    For example this is what I have in my current project:

                    EAR isolation turned on (java2Parent delegation is on as well)

                    deploy:
                    my-lib.jar (has global scope across deployments)
                    my-module-1.ear
                    my1.jar (MANIFEST.MF has Class-Path: lib/optional-lib.jar)
                    lib/optional-lib.jar
                    my-module-2.ear
                    my2.jar (MANIFEST.MF has Class-Path: lib/optional-lib1.jar)
                    my3.war (libraries are picked up from WEB-INF/lib according to Servlet spec, I could put a MANIFEST.MF entry here as well if optional-lib1.jar was needed by the WAR and was NOT in WEB-INF/lib)
                    lib/optional-lib1.jar

                    Works like a champ for me. I'm using local interfaces since remoting seems like overkill to me within the same VM (not to mention dirt slow).

                    Remember, a classloader uses both the classloader repository (uri. etc) and classname to determine the right class. If you are packaing the same class all over the place and are unscoped you ARE ASKING for ClassCastExceptions as per all the WIKIs on this site!

                    Hope some of this helps and makes sense...

                    • 7. Re: packaging and deployment of ear-files (classcastexceptio
                      andber

                      Hi, and many thanks for your reply!

                      I have tried to turn on ear isolation in ear-deployer.xml but according to my experience this has the same effect as specifying the loader-repository in jboss-app.xml as per above. And I agree, isolated class-loading between the apps should be default.

                      Why I have turned off java2parentDelegation is because I have had problems with dom4j and jaxen libraries in my app as they collided with jboss shipped jars.

                      Please check http://www.jboss.com/index.html?module=bb&op=viewtopic&t=81514 where I managed to give a better description of my current findings and problems.

                      My current question is why I can't get the ejb-jar.jar (from app1.ear) to be loaded in app2.ear, I put it in the root of app2.ear but it is not loaded unless I put it in the manifest.mf of the war in app2.ear. But then I get a ClassCastException instead.. Don't know if that is related to what I read about not being allowed to put interfaces in web-inf/lib since jboss 4.0.2..? Maybe loading the ejb-jar.jar from the war-file manifest has the same effect as putting the ejb-jar.jar in web-inf/lib == bad..?

                      Thanks again! :)

                      • 8. Re: packaging and deployment of ear-files (classcastexceptio
                        andber

                        Just to clarify; turning on ear-isolation in ear-deployer.xml didn't help me, I have tried it. It made exactly the same to me as putting loader-repository in jboss-app.xml.

                        I use remote interfaces because in some situations these ears are deployed on separate servers.

                        And I use jboss 4.0.4.

                        • 9. Re: packaging and deployment of ear-files (classcastexceptio
                          andber

                           

                          "asack" wrote:

                          For example this is what I have in my current project:

                          EAR isolation turned on (java2Parent delegation is on as well)

                          deploy:
                          my-lib.jar (has global scope across deployments)
                          my-module-1.ear
                          my1.jar (MANIFEST.MF has Class-Path: lib/optional-lib.jar)
                          lib/optional-lib.jar
                          my-module-2.ear
                          my2.jar (MANIFEST.MF has Class-Path: lib/optional-lib1.jar)
                          my3.war (libraries are picked up from WEB-INF/lib according to Servlet spec, I could put a MANIFEST.MF entry here as well if optional-lib1.jar was needed by the WAR and was NOT in WEB-INF/lib)
                          lib/optional-lib1.jar

                          Works like a champ for me. I'm using local interfaces since remoting seems like overkill to me within the same VM (not to mention dirt slow).


                          I would prefer not having to deploy separate jar-files since that is not a standard J2EE option.

                          When you are referring to lib/optional-lib.jar are you then referring to the lib of the jboss server? I guess so since my-module-2.ear doesn't have a lib/ but the my2.jar is referring to lib/ in the class-path..?


                          If you have to deploy separate jar-files to make the case with two ears (where one of the ears is calling the other ears session beans) work then I am beginning to consider this to be a BUG in JBOSS.
                          Note that it seems to be related to using the isolated classpath for ears, when not using isolation it works but I can't run without isolation (and can't think of why anyone would like to..).


                          (Another note not related to this problem but more a note on what I think is a bug in JBOSS; even if you use isolation you are not allowed to have your own instance of commons-logging in the application..!!)

                          • 10. Re: packaging and deployment of ear-files (classcastexceptio
                            asack

                             

                            "andber" wrote:
                            "asack" wrote:

                            For example this is what I have in my current project:

                            EAR isolation turned on (java2Parent delegation is on as well)

                            deploy:
                            my-lib.jar (has global scope across deployments)
                            my-module-1.ear
                            my1.jar (MANIFEST.MF has Class-Path: lib/optional-lib.jar)
                            lib/optional-lib.jar
                            my-module-2.ear
                            my2.jar (MANIFEST.MF has Class-Path: lib/optional-lib1.jar)
                            my3.war (libraries are picked up from WEB-INF/lib according to Servlet spec, I could put a MANIFEST.MF entry here as well if optional-lib1.jar was needed by the WAR and was NOT in WEB-INF/lib)
                            lib/optional-lib1.jar

                            Works like a champ for me. I'm using local interfaces since remoting seems like overkill to me within the same VM (not to mention dirt slow).


                            I would prefer not having to deploy separate jar-files since that is not a standard J2EE option.

                            When you are referring to lib/optional-lib.jar are you then referring to the lib of the jboss server? I guess so since my-module-2.ear doesn't have a lib/ but the my2.jar is referring to lib/ in the class-path..?


                            If you have to deploy separate jar-files to make the case with two ears (where one of the ears is calling the other ears session beans) work then I am beginning to consider this to be a BUG in JBOSS.
                            Note that it seems to be related to using the isolated classpath for ears, when not using isolation it works but I can't run without isolation (and can't think of why anyone would like to..).


                            (Another note not related to this problem but more a note on what I think is a bug in JBOSS; even if you use isolation you are not allowed to have your own instance of commons-logging in the application..!!)


                            Since commons-logging is part of the platform (like dom4j) it is certainly not a bug according to J2EE 1.4 Seciton 8.2.

                            HAving a separate jar-file is better since you don't have dupliate classes all over the place. Moreover, it has nothing to do with J2EE per say.

                            If you want to include the same jar file and remote that's fine. Make sure your objects are serializable when you pass them back and forth. I believe you can't have one jar file packaged in an EAR with isolation on and expect the other EAR to pick it up. Either share them by yanking them out like so:

                            http://wiki.jboss.org/wiki/Wiki.jsp?page=HotDeployClassCastExceptions

                            or including them with both EARs and remoting between them (slower but can avoid some of the classloading issues).

                            I may not be understanding your use case exactly but I believe the Class-Path strategy, remoting, or the library jar shared globally by sticking in deploy will just work (it does for me).

                            • 11. Re: packaging and deployment of ear-files (classcastexceptio
                              andber

                               

                              "asack" wrote:
                              "andber" wrote:
                              "asack" wrote:

                              For example this is what I have in my current project:

                              EAR isolation turned on (java2Parent delegation is on as well)

                              deploy:
                              my-lib.jar (has global scope across deployments)
                              my-module-1.ear
                              my1.jar (MANIFEST.MF has Class-Path: lib/optional-lib.jar)
                              lib/optional-lib.jar
                              my-module-2.ear
                              my2.jar (MANIFEST.MF has Class-Path: lib/optional-lib1.jar)
                              my3.war (libraries are picked up from WEB-INF/lib according to Servlet spec, I could put a MANIFEST.MF entry here as well if optional-lib1.jar was needed by the WAR and was NOT in WEB-INF/lib)
                              lib/optional-lib1.jar

                              Works like a champ for me. I'm using local interfaces since remoting seems like overkill to me within the same VM (not to mention dirt slow).


                              I would prefer not having to deploy separate jar-files since that is not a standard J2EE option.

                              When you are referring to lib/optional-lib.jar are you then referring to the lib of the jboss server? I guess so since my-module-2.ear doesn't have a lib/ but the my2.jar is referring to lib/ in the class-path..?


                              If you have to deploy separate jar-files to make the case with two ears (where one of the ears is calling the other ears session beans) work then I am beginning to consider this to be a BUG in JBOSS.
                              Note that it seems to be related to using the isolated classpath for ears, when not using isolation it works but I can't run without isolation (and can't think of why anyone would like to..).


                              (Another note not related to this problem but more a note on what I think is a bug in JBOSS; even if you use isolation you are not allowed to have your own instance of commons-logging in the application..!!)


                              Since commons-logging is part of the platform (like dom4j) it is certainly not a bug according to J2EE 1.4 Seciton 8.2.

                              HAving a separate jar-file is better since you don't have dupliate classes all over the place. Moreover, it has nothing to do with J2EE per say.

                              If you want to include the same jar file and remote that's fine. Make sure your objects are serializable when you pass them back and forth. I believe you can't have one jar file packaged in an EAR with isolation on and expect the other EAR to pick it up. Either share them by yanking them out like so:

                              http://wiki.jboss.org/wiki/Wiki.jsp?page=HotDeployClassCastExceptions

                              or including them with both EARs and remoting between them (slower but can avoid some of the classloading issues).

                              I may not be understanding your use case exactly but I believe the Class-Path strategy, remoting, or the library jar shared globally by sticking in deploy will just work (it does for me).


                              Hi, it is possible that the global jar in deploy could work but I don't want that solution because it is not supported by any other application server and is not the standard way to package j2ee-applications.

                              My problem is that app2 which has a webapp that calls a sessionbean in app1 gets a classcastexception when doing the call. Both ears have the jar-file with app1 interfaces included..



                              • 12. Re: packaging and deployment of ear-files (classcastexceptio
                                anbukarasi

                                Hi,
                                I'm also facing similar problem with classloader scoping. I have a sar with all the portal libraries (like portal-security-lib) in sar's lib folder. I have clasloader isolation configured in META-INF/jboss-service.xml

                                <loader-repository>dot.com:loader=xxx.sar
                                <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
                                </loader-repository>

                                Now I get a ClassNotFoundExceptions for the portal classes as below:
                                26.04.2006_14:54:05|I|000000|10.3.3.220|cae_admin-server 8111|org.jboss.system.ServiceConfigurator|[Problem configuring service portal:service=PolicyService]
                                java.lang.ClassNotFoundException: No ClassLoaders found for: org.jboss.portal.security.jacc.JBossSecurityProvider
                                at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:198)
                                at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:475)
                                at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:377)
                                at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                                at org.jboss.system.ServiceConfigurator.configure(ServiceConfigurator.java:356)
                                at org.jboss.system.ServiceConfigurator.internalInstall(ServiceConfigurator.java:442)
                                at org.jboss.system.ServiceConfigurator.install(ServiceConfigurator.java:153)
                                at org.jboss.system.ServiceController.install(ServiceController.java:215)
                                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                                at java.lang.reflect.Method.invoke(Method.java:585)
                                at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
                                at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
                                at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
                                at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:245)
                                at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
                                at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:176)
                                at $Proxy4.install(Unknown Source)

                                Any ideas what could be the problem?

                                Thanks

                                • 13. Re: packaging and deployment of ear-files (classcastexceptio
                                  j2ee_junkie

                                  Hey gang,

                                  I have this exact problem too. I have two ear's that are isolated with by unique loader-repository elements in thier respective jboss-app.xmls. If a class of ear 1 want's to call a ejb bean of ear 2, I get NoClassDefFoundException. So I created a jar file with ear1's bean interfaces. Put the interfaces jar in ear2 root. Add an appropriate manifest entry. Now I get ClassCastExceptions. Is there a solution to this exact situation?

                                  thanks for your time, cgriffith

                                  • 14. Re: packaging and deployment of ear-files (classcastexceptio
                                    andber

                                     

                                    "j2ee_junkie" wrote:
                                    Hey gang,

                                    I have this exact problem too. I have two ear's that are isolated with by unique loader-repository elements in thier respective jboss-app.xmls. If a class of ear 1 want's to call a ejb bean of ear 2, I get NoClassDefFoundException. So I created a jar file with ear1's bean interfaces. Put the interfaces jar in ear2 root. Add an appropriate manifest entry. Now I get ClassCastExceptions. Is there a solution to this exact situation?

                                    thanks for your time, cgriffith


                                    So is there anyone that has solved this standard J2EE issue for JBOSS yet? Seems like a major bug..