6 Replies Latest reply on Nov 14, 2008 4:22 AM by antonio.genghi

    EJB not deployed in EAR file with libraries

    antonio.genghi

      Hi all.

      I have a strage problem with JBoss 4.2.3 running on JDK 1.5.0_16b02 (latest from Sun).

      Here is my case:

      myApp.ear
      |
      |\-lib
      | \-util1.jar
      | |-util2.jar
      |
      |\-META-INF
      | \-application.xml
      | |-MANIFEST.MF
      |
      |-myEjb.jar

      Content of application.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN' 'http://java.sun.com/dtd/application_1_3.dtd'>
      <application>
       <display-name>myApp</display-name>
       <description>Application description</description>
       <module>
       <ejb>myEjb.jar</ejb>
       </module>
       <library-directory>lib</library-directory>
      </application>


      Content of MANIFEST.MF
      Manifest-Version: 1.0
      Ant-Version: Apache Ant 1.7.0
      Created-By: 1.5.0_16-b02 (Sun Microsystems Inc.)


      myEJB.jar
      |
      |\-myPackage
      | \-myBean.class
      |
      |\-META-INF
      | \-ejb-jar.xml
      | |-jboss.xml
      | |-MANIFEST.MF

      Content of ejb-jar.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
      <ejb-jar>
       <display-name>myEJB</display-name>
       <enterprise-beans>
       <message-driven>
       <display-name>myEJB</display-name>
       <ejb-name>myEJB</ejb-name>
       <ejb-class>myPackage.myBean</ejb-class>
       <transaction-type>Container</transaction-type>
       <message-driven-destination>
       <destination-type>javax.jms.Queue</destination-type>
       </message-driven-destination>
       </message-driven>
       </enterprise-beans>
      </ejb-jar>


      Content of jboss.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE jboss PUBLIC
       "-//JBoss//DTD JBOSS 3.2//EN"
       "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">
      <jboss>
       <enterprise-beans>
       <message-driven>
       <ejb-name>myEJB</ejb-name>
       <destination-jndi-name>jms/myQueue</destination-jndi-name>
       </message-driven>
       </enterprise-beans>
      </jboss>
      


      Content of MANIFEST.MF
      Manifest-Version: 1.0
      Ant-Version: Apache Ant 1.7.0
      Created-By: 1.4.2_05-b04 (Sun Microsystems Inc.)
      Class-Path:
       util1.jar
       util2.jar
       Ant-Version: Apache Ant
       1.6.5
      


      (It should be all).

      The problem is that i cannot see th EJB deployed neither bind to JMS queue.
      But if i try to deploy the whole EAR without the util1.jar and util2.jar (also removing from manifest.mf) the EJB deploy correctly and bind to jms quee too.
      Also, the EAR and EJB works correctly if i deploy the archive as an exploded package (also the myEjb.jar).

      The picture was not so clear so i decided to debug the JARDeployer, and i notice that the problem is in those lines:

       // Since a META-INF directory exists within rt.jar, we can't just do a
       // getResource (it will always return rt.jar's version).
       // The method we want is findResource, but it is marked protected in
       // ClassLoader. Fortunately, URLClassLoader exposes it which makes
       // this hack possible. Anybody have a better way to check a URL
       // for the existance of a META-INF??
       URL ddDir;
       try
       {
       ddDir = di.localCl.findResource("META-INF/");
       if (ddDir == null)
       {
       log.debug("No META-INF or WEB-INF resource found, assuming it if for us");
       return true;
       }
       }
       catch (ClassCastException e)
       {
       // assume there is a META-INF...
       ddDir = new URL(di.url, "META-INF/");
       }
      


      The deployer (better, the classloader) cannot access META-INF of myEJB.jar in the temp deploy directory.

      The question is: WHY?

      Where am I wrong?

      Could you help me?

      Thanks a lot in advance.

      Antonio

        • 1. Re: EJB not deployed in EAR file with libraries
          jaikiran

          Post the output of

          jar -tf myApp.ear


          and

          jar -tf myEjb.jar


          • 2. Re: EJB not deployed in EAR file with libraries
            antonio.genghi

            Here there are:

            jar -tf myEar.ear
            META-INF/
            META-INF/MANIFEST.MF
            lib/
            lib/util1.jar
            lib/util2.jar
            myEjb.jar
            META-INF/application.xml


            and

            jar -tf myEjb.jar
            META-INF/
            META-INF/MANIFEST.MF
            myPackage/
            myPackage/myBean
            META-INF/ejb-jar.xml
            META-INF/jboss.xml


            • 3. Re: EJB not deployed in EAR file with libraries
              peterj

              Looks like the class file for your EJB is missing from the jar file.

              • 4. Re: EJB not deployed in EAR file with libraries
                antonio.genghi

                 

                "antonio.genghi" wrote:
                Here there are:

                jar -tf myEar.ear
                META-INF/
                META-INF/MANIFEST.MF
                lib/
                lib/util1.jar
                lib/util2.jar
                myEjb.jar
                META-INF/application.xml


                and

                jar -tf myEjb.jar
                META-INF/
                META-INF/MANIFEST.MF
                myPackage/
                myPackage/myBean.class
                META-INF/ejb-jar.xml
                META-INF/jboss.xml


                Sorry. It's a cut&paste error. The class file is in the jar. Also, the EJB without the util*.jar, works correctly.

                Btw, thanks anyway.

                • 5. Re: EJB not deployed in EAR file with libraries
                  jaikiran

                   

                  <?xml version="1.0" encoding="UTF-8"?>
                  <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN' 'http://java.s
                  un.com/dtd/application_1_3.dtd'>
                  <application>
                   <display-name>myApp</display-name>
                   <description>Application description</description>
                   <module>
                   <ejb>myEjb.jar</ejb>
                   </module>
                   <library-directory>lib</library-directory>
                  </application>


                  Point#1 - The library-directory is not meant to be in the application.xml. Instead it should be in the jboss-app.xml:

                  <jboss-app>
                   <library-directory>lib</library-directory>
                  </jboss-app>


                  Fix the application.xml to remove that element and create a jboss-app.xml file with the above contents in the EAR/META-INF folder.

                  Next, what do the util*.jar contain? And finally, do you see any exceptions in the logs? If yes, then please post the same. Please also post the logs, from the point where your application starts getting deployed.


                  • 6. Re: EJB not deployed in EAR file with libraries
                    antonio.genghi

                     

                    "jaikiran" wrote:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN' 'http://java.s
                    un.com/dtd/application_1_3.dtd'>
                    <application>
                     <display-name>myApp</display-name>
                     <description>Application description</description>
                     <module>
                     <ejb>myEjb.jar</ejb>
                     </module>
                     <library-directory>lib</library-directory>
                    </application>

                    Point#1 - The library-directory is not meant to be in the application.xml. Instead it should be in the jboss-app.xml:

                    <jboss-app>
                     <library-directory>lib</library-directory>
                    </jboss-app>


                    Fix the application.xml to remove that element and create a jboss-app.xml file with the above contents in the EAR/META-INF folder.


                    Really? Why i should put library directory in jboss-app.xml instead of application.xml? J2ee standard say library directory shoul declared in application.xml. Btw, i tried to put in jboss-app, but don't know why, jboss refuses to load the correct schema to read xml, and refuses to parse library directory.
                    But it is that problem, because jboss correctly read lib directory (i'm debugging whole deploy chain and i've seen with my eye jboss read my util*.jar :) )


                    "jaikiran" wrote:

                    Next, what do the util*.jar contain? And finally, do you see any exceptions in the logs? If yes, then please post the same. Please also post the logs, from the point where your application starts getting deployed.


                    Well, util*.jar are two stupid library such as could be log4j, or any other jar containing classes. Nothing more, nothing less.

                    I continued to debug the deployer chain, and i noticed that JBoss "fails" in these:
                    It reads the EAR file
                    Deploy EAR
                    Search in application.xml modules and library.
                    Find 2 libraries and a deployable module
                    Unpack the EAR in the tmp directory
                    Search the correct deployer for the module found.
                    Now comes the problem
                    When EJBDeployer is asked to accepts myEJB.jar (located in the EAR tmp directory), it refuse to accept because it cannot read META-INF/ejb.jar from archive.

                    But obviously, if i open the file and search for ejb-jar, i found it.

                    It seems like an issue with classloading.

                    Here it is the incriminated lines in EJBDeployer:
                     // However the jar must also contain at least one ejb-jar.xml
                     boolean accepts = false;
                     try
                     {
                     URL dd = di.localCl.findResource("META-INF/ejb-jar.xml");
                     if (dd == null)
                     {
                     return false;
                     }
                    


                    di.locaCl is created in the MainDeployer in that way:
                     log.debug("Starting deployment (init step) of package at: " + deployment.url);
                     try
                     {
                     // Create a local copy of that File, the sdi keeps track of the copy directory
                     if (deployment.localUrl == null)
                     {
                     makeLocalCopy(deployment);
                     URL[] localCl = new URL[]{deployment.localUrl};
                     deployment.localCl = new URLClassLoader(localCl);
                     }
                    


                    where localurl is the file in the tmp directory of EAR unpacked.

                    Any idea???

                    Thanks a lot!