1 2 Previous Next 20 Replies Latest reply on Nov 22, 2006 10:46 AM by weston.price

    Classloading and sharing classes between .ear and .rar

    rupertlssmith

      I have a resource adapter that I have written and succesfully called from an application. Both were deployed seperately using the default server on JBoss 4.0.4 (as supplied in the distribution with its flat class loading).

      Recently, I've had to start using isolated class loading for my application because I'm using JAXB 2.0 which conflicts with the JAXB libraries integrated into JBoss (in the default/lib directory). Now, I'm having problems sharing classes between my .ear and my .rar. I've taken the steps described in the WIKI to make JBoss J2EE compliant by turning on call-by-value. The trouble is that I have to share some classes between the application and resource adapter (the ones that implement cci.ConnectionSpec) so these classes are duplicatied between the .rar and .ear files.

      With flat class loading this wasn't a problem, presumably the class loader just took whichever it found first and ignored the other. With isolated class loaders I get class cast exceptions. I'm surprised by this having taken steps to ensure call-by-value is turned on because I thought this would serialize the objects passed to the resource adapter (like a call between ejb's in different .ears would be) but this doesn't seem to be happening.

      One solution I tried is to deploy the .rar inside my .ear instead; the idea being to put all shared .jars at the top level of the .ear. However, I can't get this working, despite adding a connector module statement to my application.xml and a service module statement to my jboss-app.xml. It tries to deploy the -ds.xml service descriptor but just seems to ignore the connector module statement concerning the .rar file?

      The other solution I may turn to, is simply to put the ConnectionSpecImpl (and whatever other shared classses are needed) into a /lib directory and not include them in either the .rar or the .ear so I know there is only one instance of them. Its a little less modular and clean and J2EE compliant but on the upside I can probably turn off call-by-value semantics doing it that way.

      Does anyone have a working example of deploying a .rar inside an .ear and could shed some light on how to get this working?

      Should .rar files be deployed with isolated class loaders and call-by-value semantics? Does anyone know if there is a way to do this? I didn't see a statement inside the rar deployer config xml like in the ear deployer xml to do this.

      Thanks for reading and for any help you are able to give.

      Rupert Smith

        • 1. Re: Classloading and sharing classes between .ear and .rar
          weston.price

          Are you including a reference to the shared classes in the MANIFEST.MF file of the RAR? This is usually the issue when someone runs into something like this.

          • 2. Re: Classloading and sharing classes between .ear and .rar
            rupertlssmith

            Presumably you mean in the scenario where the .rar is put inside the .ear file? I wasn't but I have now changed my MANIFEST to include references to them. It is stil not working.

            To give a clearer picture, the relevant parts of my .ear file now looks like:

            index-ra-test-0.1.ear:
            |
            |-index-ra-ds.xml (the JBoss service descriptor for the ra)
            |-index-ra-client-0.1.jar (the client interface for the resource adapter)
            |-index-ra-0.1.rar (a resource adapter for the search engine)
            |-META-INF/application.xml
            |-META-INF/jboss-app.xml
            |-common-0.1.jar (my common lib)
            |-index-0.1.jar (the index - a text search engine)
            |...(more stuff, including EJB module that calls index-ra-0.1.rar using client interface in index-ra-client.jar).

            The index-ra-0.1.rar file contains META-INF/MANIFEST.MF with class path:

            Class-Path: index-0.1.jar common-0.1.jar index-ra-client-0.1.jar

            refering to the shared jars.

            The application.xml contains:


            index-ra-0.1.rar


            and the jboss-app.xml contains:


            index-ra-ds.xml


            The index-ra-ds.xml contains:

            <!-- Non-transactional Index resource adaptor service configuration. -->
            <connection-factories>
            <tx-connection-factory>
            <adapter-display-name>IndexResourceAdapter</adapter-display-name>
            <jndi-name>index_connection_factory</jndi-name>
            <local-transaction/>
            <rar-name>index-ra-0.1.rar</rar-name>
            <connection-definition>
            uk.co.thebadgerset.index.ra.IndexConnectionFactory
            </connection-definition>
            </tx-connection-factory>
            </connection-factories>

            Some highlights from the debug trace are:

            DEBUG org.jboss.deployment.EARDeployer Extracted deployable content: index-ra-ds.xml
            DEBUG org.jboss.deployment.EARDeployer Extracted deployable content: index-ra-0.1.rar

            DEBUG org.jboss.deployment.MainDeployer Starting deployment (init step) of package at: file:/C:/projects/index-ra-test/target/jboss/myjboss/tmp/deploy/tmp50591index-ra-test-0.1.ear-contents/index-ra-0.1.rar
            DEBUG org.jboss.deployment.MainDeployer using deployer org.jboss.resource.deployment.RARDeployer@1649a55

            DEBUG org.jboss.deployment.MainDeployer Starting deployment (init step) of package at: file:/C:/projects/index-ra-test/target/jboss/myjboss/tmp/deploy/tmp50591index-ra-test-0.1.ear-contents/index-ra-ds.xml
            DEBUG org.jboss.deployment.MainDeployer using deployer org.jboss.deployment.XSLSubDeployer@367013

            DEBUG uk.co.thebadgerset.index.ra.ResourceAdapterImpl public void start(BootstrapContext context): called

            So I can see my resource adapters start method being called. It doesn't seem to bind the service to its JNDI name, as when I look it up from the session bean:

            Context nc = new InitialContext();
            IndexConnectionFactory cf =
            (IndexConnectionFactory)nc.lookup("java:comp/env/ra/index/index_connection_factory");

            I get a naming exception. Bear in mind that I have set up a resource reference (XDoclet tag from the source):

            @jboss:resource-ref res-ref-name="ra/index/index_connection_factory"
            jndi-name="java:/index_connection_factory"

            So I would expect the connection factory to be at java:/index_connection_factory.

            I'm wondering if there is something wrong with my -ds.xml file? Does the rar-name need to be:

            <rar-name>index-ra-test-0.1.ear#index-ra-0.1.rar</rar-name>

            as described in the Wiki? Or this only when the -ds.xml file is not in the .ear? I tried that too but it didn't work.

            • 3. Re: Classloading and sharing classes between .ear and .rar
              weston.price

              Any particular reason you want to include the *-ds.xml file in the EAR? Typically this isn't done because it limits your ability to change settings and have them hot deployed.

              • 4. Re: Classloading and sharing classes between .ear and .rar
                rupertlssmith

                The application.xml contains:

                <module>
                <connector>index-ra-0.1.rar</connector>
                </module>


                and the jboss-app.xml contains:

                <module>
                <service>index-ra-ds.xml</service>
                </module>


                • 5. Re: Classloading and sharing classes between .ear and .rar
                  weston.price

                  If you remove the *-ds.xml file from the EAR, then you should be able to do:

                  <rar-name>index-ra-0.1.rar</rar-name>

                  • 6. Re: Classloading and sharing classes between .ear and .rar
                    weston.price

                    Note, in using this scheme, your ejb-jar file will also have to include a MANIFEST.MF entry to reference the client jar.

                    • 7. Re: Classloading and sharing classes between .ear and .rar
                      rupertlssmith

                      No particular reason for putting the -dm.xml in the .ear. Right now I'd be happy to get it working any old way. Regardless of neatness of the solution, it should still work when its in the .ear? I've now moved it out of the .ear and into the /deploy directory but I get an error:

                      Do I need to be carefull to deploy the .ear first and then the -ds.xml file? Trying again....

                      ERROR org.jboss.deployment.scanner.URLDeploymentScanner Incomplete Deployment listing:

                      --- MBeans waiting for other MBeans ---
                      ObjectName: jboss.jca:service=ManagedConnectionFactory,name=index_connection_factory
                      State: FAILED
                      Reason: org.jboss.deployment.DeploymentException: Could not find ManagedConnectionFactory class: uk.co.thebadgerset.index.ra.ManagedConnectionFactoryImpl
                      I Depend On:
                      jboss.jca:service=RARDeployment,name='index-ra-test-0.1.ear#index-ra-0.1.rar'
                      Depends On Me:
                      jboss.jca:service=ManagedConnectionPool,name=index_connection_factory

                      --- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
                      ObjectName: jboss.jca:service=ManagedConnectionFactory,name=index_connection_factory
                      State: FAILED
                      Reason: org.jboss.deployment.DeploymentException: Could not find ManagedConnectionFactory class: uk.co.thebadgerset.index.ra.ManagedConnectionFactoryImpl
                      I Depend On:
                      jboss.jca:service=RARDeployment,name='index-ra-test-0.1.ear#index-ra-0.1.rar'
                      Depends On Me:
                      jboss.jca:service=ManagedConnectionPool,name=index_connection_factory

                      Thu Aug 03 20:21:07 BST 2006 main 3882 localhost localhost:1535

                      • 8. Re: Classloading and sharing classes between .ear and .rar
                        rupertlssmith

                        Yes, the ejb jar file has its MANIFEST class path set up for the shared .jars.

                        • 9. Re: Classloading and sharing classes between .ear and .rar
                          weston.price

                          Hmmm...interesting...

                          Let me cook up a test case.

                          • 10. Re: Classloading and sharing classes between .ear and .rar
                            weston.price

                            Out of curiosity, could you try remove the ear# syntax?

                            Then

                            Deploy the RAR
                            Deploy the *-ds.xml file

                            Thanks.

                            • 11. Re: Classloading and sharing classes between .ear and .rar
                              rupertlssmith

                               

                              "weston.price@jboss.com" wrote:
                              If you remove the *-ds.xml file from the EAR, then you should be able to do:

                              <rar-name>index-ra-0.1.rar</rar-name>



                              Are you sure about that? I tried that but it responded with:

                              --- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
                              ObjectName: jboss.jca:service=RARDeployment,name='index-ra-0.1.rar'
                              State: NOTYETINSTALLED
                              Depends On Me:
                              jboss.jca:service=ManagedConnectionFactory,name=index_connection_factory

                              I think when the -ds.xml is outside the ear it should be:

                              <rar-name>index-ra-test-0.1.ear#index-ra-0.1.rar</rar-name>

                              and when inside it should be:

                              <rar-name>index-ra-0.1.rar</rar-name>

                              • 12. Re: Classloading and sharing classes between .ear and .rar
                                rupertlssmith

                                 

                                "weston.price@jboss.com" wrote:
                                Out of curiosity, could you try remove the ear# syntax?

                                Then

                                Deploy the RAR
                                Deploy the *-ds.xml file

                                Thanks.


                                Ok. I did that and it seems to be working. Bear in mind I've had to change the RAR a little to do this because it is no longer in the .ear but now being deployed seperately. So I put the shared .jars that it needs into the .rar instead of in the .ear.

                                Interestingly, I got this message in the debug trace, which I wasn't getting when I tried to deploy it in the .ear:

                                INFO org.jboss.resource.connectionmanager.ConnectionFactoryBindingService Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=index_connection_factory' to JNDI name 'java:index_connection_factory'

                                For some reason it doesn't seem to get as far as binding the connection factory to its JNDI name when deployed in the .ear


                                • 13. Re: Classloading and sharing classes between .ear and .rar
                                  rupertlssmith

                                  I've also tried deploying the EAR with the RAR inside it and shared libs in the root of the EAR. I deployed that first and then deployed the -ds.xml seperately with the ear# syntax. I got a class not found exception:

                                  java.lang.ClassNotFoundException: No ClassLoaders found for: uk.co.thebadgerset.index.ra.ManagedConnectionFactoryImpl

                                  Presumably because the .ear is being deployed in an isolated class loader?

                                  I'll try deploying it with that way with the flat class loader and see what happens... (won't be able to run it though, as in the original post i said that i'm using the isolated class loader because of JAXB library conflicts).

                                  • 14. Re: Classloading and sharing classes between .ear and .rar
                                    rupertlssmith

                                    Yes, without the isolated class loader I was able to deploy the RAR in the EAR, then seperately deploy the -ds.xml using the ear# syntax.

                                    INFO org.jboss.resource.connectionmanager.ConnectionFactoryBindingService Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=index_connection_factory' to JNDI name 'java:index_connection_factory'

                                    So, does that give me a legitimate reason for putting the -ds.xml in the EAR too? So that it can see the EARs classes. This brings me back to my original question, is it possible to deploy the EAR and RAR (and -ds.xml) seperately using isolated class loaders and call-by-value semantics (to avoid the class cast exceptions)?

                                    1 2 Previous Next