In case you are not on the jboss as dev list here is an explanation AND
workaround for the weird classloader and seam errors
we have had when we package with *standard* manifest.mf.
Basically JBoss will create multiple temp .jar's for one unique jar in
an deployment if they are not deployed in sequence.
Resulting in the applications seeing multiple URL's even though there
only are one.
/max
-------- Original Message --------
From: Jaikiran Pai <jpai(a)redhat.com>
Subject: Re: [jboss-dev] Classloader changes from AS 4.2.2 to AS 4.2.3
affecting launch of Tool built Seam apps
To: Max Rydahl Andersen <max.andersen(a)redhat.com>
CC:
JBoss.org development list <jboss-development(a)lists.jboss.org>
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/mai...
[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