The Maven archiver, used by the Maven WAR plugin, provides a means to generate Class-Path entries in the WAR's manifest but unfortunately the archiver takes an all-or-nothing approach. Once you pass addClassPath=true
to the archive configuration, the archiver puts Class-Path entries for all of the WAR's required- and optional dependencies into the manifest.
However, some entries simply do not belong in there. Class-Path entries are used to denote "Download Extensions," or references to JARs external to the WAR. JARs located in WEB-INF/lib
should not, therefore, have Class-Path entries in the WAR's manifest. Maven's War plugin breaks this rule when you set addClassPath=true
in the archiver.
Moreover, when you pass addClassPath=true
to Maven's archiver, it gives all of the Class-Path entries the same directory prefix -- no matter where the dependencies are located within the EAR. This causes problems when optional- and required dependencies are located in separate locations such as the EAR root directory, EAR lib
and WAR WEB-INF/lib
.
Naturally, when one deploys an EAR whose WAR manifest contains the above errors JBoss throws warnings if the WAR class loader can ultimately find a dependency (JARs located in WEB-INF/lib
) or errors if the class path prefix is wrong (e.g. on an EJB JAR or a dependency in the EAR lib
directory).
Therefore, if your WAR, like mine, depends on an EJB module, located at the root of the EAR, and any number of dependencies that are located inWEB-INF/lib
, Maven archiver will generate Class-Path entries for all of the dependencies and they will all have the same prefix regardless of their location within the EAR.
Not good.
The problem would be ameliorated somewhat if the archiver would provide a means to exclude Class-Path entries of the JARs located in WEB-INF. But it does not.
Here's a summary of the outcome for each dependency setting when one uses addClassPath=true
:
Setting Generate Copy JAR into
Class-Path WEB-INF/lib
Entry
1. <scope>provided</scope> NO NO
2. <optional>true</optional> YES NO
3. (no option -- default) YES YES
4. ????? NO YES
What is needed is coverage for situation #4, above: do not create a Class-Path entry and, yes, do copy the JAR into WEB-INF/lib
. Maven archiver should implement this behavior by default.
The best solution I can think of is to use brute force and turn off the Maven archiver's automatic Class-Path entry generation. Instead, I explicitly create a Class-Path entry for the EJB module in the WAR's manifest using the archiver's manifestEntries
option. The way to do this is to remove the following from Patrac-web/pom.xml
:
<manifest>
<addClasspath>true</addClasspath>
</manifest>
and replace it with this:
<manifestEntries>
<Class-Path>Patrac-ejb-${project.version}.jar</Class-Path>
</manifestEntries>
Using this configuration only one Class-Path entry, for the EJB module, is created explicitly.