[jboss-dev] Classloader changes from AS 4.2.2 to AS 4.2.3 affecting launch of Tool built Seam apps

Jaikiran Pai jpai at redhat.com
Thu Apr 30 05:47:56 EDT 2009


Max Rydahl Andersen wrote:
>> 1) Should (EJB) *deployments* be listed in the MANIFEST.MF files of 
>> other deployments. In this example the jboss-seam.jar which is a EJB 
>> deployment (marked as a "module" in application.xml) is listed in 
>> MANIFEST.MF of an xxx-ejb.jar deployment.
>
> We list these in manifest.mf since that is the only way Eclipse can 
> know what is on the classpath; application.xml afaik does not 
> attribute to the classpath - at least I never seen an IDE does that 
> (they might be wrong ;)
> In any case, listing it in manifest.mf and in application.xml should 
> not hurt anything since they should just resolve to the *same* jar.
I agree, adding it to the MANIFEST.MF should not be breaking the deployment.
>
>> 2) Is the duplicate temp files for the same jar file (jboss-seam.jar) 
>> intentional? It's created once during the MANIFEST.MF parsing of 
>> xxx-ejb.jar deployment and once during deploying jboss-seam.jar 
>> deployment (which is listed as a module in application.xml).
> This is *the* bug I believe ? This will keep causing problems...
Someone who knows better about JBoss-4.x deployers would probably know 
how to fix this.
>
> Any suggestion for a workaround that still allow me to use *standard* 
> manifest.mf classpath entries ?
Luckily yes :) I looked at what the MainDeployer[1] does. The important 
piece of code is :

private void parseManifestLibraries(DeploymentInfo sdi)
{
...//blah blah blah
if (classPath != null)
      {
         StringTokenizer st = new StringTokenizer(classPath);
         log.debug("resolveLibraries: "+classPath);

         while (st.hasMoreTokens())
         {
...//blah blah blah
              
        // Only deploy this if it is not already being deployed
               if ( deploymentMap.containsKey(lib) == false )
               {
                  /* Test that the only deployer for this is the 
JARDeployer.
                   Any other type of deployment cannot be initiated through
                   a manifest reference.
                  */
                  DeploymentInfo mfRef = new DeploymentInfo(lib, null, 
getServer());
                  makeLocalCopy(mfRef);
                  URL[] localURL = {mfRef.localUrl};
                  mfRef.localCl = new java.net.URLClassLoader(localURL);
                  findDeployer(mfRef);
                  SubDeployer deployer = mfRef.deployer;
                  if(deployer != null && (deployer instanceof 
JARDeployer) == false)
                  {
                     // Its a non-jar deployment that must be deployed 
seperately
                     log.warn("Found non-jar deployer for " + tk + ": " 
+ deployer);
                  }

                  // add the library
                  sdi.addLibraryJar(lib);
               }
            }

So, if the classpath entry contains a reference to a jar which is 
*already being deployed*, then it will *not* create a (duplicate) temp 
copy while parsing the manifest entry. The (single) temp copy will be 
created when the deployment jar (marked as module in application.xml) is 
being processed for deployment.

So the *workaround* is to ensure that deployments which are referenced 
in Classpath attribute of other deployments are deployed first. For ex: 
in the application attached to the JIRA, the xxx-ejb.jar refers to 
jboss-seam.jar (EJB deployment) in the MANIFEST.MF. So the trick is to 
ensure that jboss-seam is picked up for deployment before xxx-ejb.jar is 
picked for deployment (and the subsequent MANIFEST.MF processing). This 
can be done by specifying the correct order of modules in the 
application.xml and *also* specifying the module-order as "strict" in 
jboss-app.xml (by default the module-order is "implicit" which follows 
filename based deployment ordering [2]). So here's what i did:

application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/application_5.xsd"
    version="5">

    <display-name>xxx-ear</display-name>

    <!-- JBIDE-4166 Workaround - Make sure we deploy this first, since 
this is referenced in xxx-ejb.jar-->
     <module>
        <ejb>jboss-seam.jar</ejb>
    </module>

    <module>
        <ejb>xxx-ejb.jar</ejb>
    </module>
    <module>
        <web>
            <web-uri>xxx.war</web-uri>
            <context-root>/xxx</context-root>
        </web>
    </module>
</application>

jboss-app.xml:

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE jboss-app
    PUBLIC "-//JBoss//DTD J2EE Application 4.2//EN"
    "http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd">

<jboss-app>
   <!-- JBIDE-4166 : We need strict ordering to follow the order mentioned
    in application.xml -->   
   <module-order>strict</module-order>

   <loader-repository>
      seam.jboss.org:loader=xxx-ear.ear
   </loader-repository>
</jboss-app>

So all that JBoss Tools needs to do is add a intelligent ordering of the 
modules in the application.xml and mark the application for strict 
module ordering in the jboss-app.xml. 

[1] 
http://anonsvn.jboss.org/repos/jbossas/tags/JBoss_4_2_3_GA/system/src/main/org/jboss/deployment/MainDeployer.java
[2] This also explains why the deployment behaves differently when the 
name of the deployment is changed.
>
>> --------------------
>> Archived deployment :
>> --------------------
>> When the application is deployed as an archive, the deployment 
>> framework creates a exploded temp of the EAR in the tmp folder. It 
>> however does *not* create temps for the sub-deployments or the 
>> libraries within the ear. So there is only one jboss-seam.jar in 
>> tmp/sometmpName.ear-contents. Because of this the logic explained 
>> above, registers the SeamPhaseListener only once and hence no issues.
> Why the difference in behavior ? Legacy ? Intentional ?
Not sure. Someone who has more experience on the 4.x deployers might know.
>>> Why does it matter which letters we use in the deployment, i.e. 
>>> fseam.ear behaves different that seam.ear ? 
>> Though the JIRA mentions this, i don't see a reason why the name 
>> should matter. I did not see any other explanation in the JIRA as to 
>> how this fixed the issue.  Is there some app which shows this behaviour?
> The problem is that it only shows up sometimes - I have seen it 
> several times with capital letters (another bug) and even went so far 
> to add a warning in the ui that using capital letters as the first 
> character were not recommended.
> I'll try and see if I can find a way to reproduce the situation with 
> different lett
When i read the JIRA, i thought the user was noting that changing the 
name of the EAR fixed the issue. That's why i commented that naming of 
the files should not matter (atleast for this specific issue). However 
after what i explained above, related to implicit ordering of 
deployments *within* an EAR, i think the user was talking about renaming 
the deployments *within* the EAR. That makes sense now and it definitely 
affects (= is expected) the deployment ordering.

-Jaikiran



More information about the jboss-development mailing list