Reputation: 47785
Because of transitive dependencies, my wars are getting populated by xml-apis, xerces jars. I tried following the instructions on the reference page for maven-war-plugin but it is not working.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>WEB-INF/lib/xalan-2.6.0.jar,WEB-INF/lib/xercesImpl-2.6.2.jar,WEB-INF/lib/xml-apis-1.0.b2.jar,WEB-INF/lib/xmlParserAPIs-2.6.2.jar</packagingExcludes>
<webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
<warName>project1</warName>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
</configuration>
</plugin>
What am I doing wrong ? If it matters, I discovered that the maven-war-plugin I'm using is at version 2.1-alpha-1
Upvotes: 43
Views: 105441
Reputation: 503
The correct solution is to use the <packagingExcludes>
configuration, as the <scope>provided</scope>
solution is a hack.
Consider the following multi-module project:
A
(war)
/ \
B C
(jar) (jar)
/ /
D /
(jar) /
/ | \ /
e f g
In this multi-module project, module A
requires modules {B
, C
, D
}, but not {e
, f
, g
}. However, modules B
and D
do require {e
, f
g
}, and C
requires {g
}.
First, let's try to solve this problem with the <scope>provided</scope>
approach:
To exclude {e
, f
, g
} from A
, the <scope>provided</scope>
spec must be present in D
's POM. But wait, B
requires {e
, f
, g
}. So to fix that, the dependency declarations for {e
, f
, g
} must be present in B
's POM as well (with <scope>provided</scope>
). This means that the dependency spec complexity from D
must be been pulled into B
. Similarly, since C
depends on {g
}, the dependency declarations for {g
} must be present in C
's POM.
With the the <scope>provided</scope>
solution, modules B
, C
, and D
must all have knowledge of the fact that A
cannot have {e
, f
, g
}.
This approach breaks the encapsulation principle, and is not practical in multi-module projects that have complex dependency graphs.
Second, let's try to solve this problem with the <packagingExcludes>
approach:
To exclude {e
, f
, g
} from A
, one must provide the following in A
's POM:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<packagingExcludes>B*.jar,C*.jar</packagingExcludes>
</configuration>
</plugin>
With this solution, the complexity of "what must be excluded from A
" is contained solely in A
's POM. This frees modules B
, C
and D
from having to care about excluding transitive dependencies for the sake of A
.
This solution upholds the encapsulation principle.
Upvotes: 4
Reputation: 12938
You can do this by specifying inside <packagingExcludes></packagingExcludes>
inside </configuration><configuration>
.
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<packagingExcludes>
WEB-INF/lib/ex1-*.jar,
WEB-INF/lib/ex2-logging-*.jar
</packagingExcludes>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
You can specify by wild cards and regular expressions too. Refer the documentation for more info.
Upvotes: 2
Reputation: 6288
See my answer here. The packaging-excludes
entry only works with maven-war-plugin version 2.1-alpha-1 and above. So, you may need to upgrade the version used or, you may prefer to use dependency-level injection as it's more precise exclusion of specific jars.
Upvotes: 1
Reputation: 6324
To add some clarification, you absolutely can exclude transitive dependencies. For example, if you have a local dependency on A, which has a dependency on M, which in turn has a dependency on X, then you can exclude X where you specify your A dependency.
For example, say you depend on 'myPackageA', which depends on Rampart, which depends on Xerces, then you can exclude Xerces in your myPackageA dependency:
<groupId>myPackageA.dependsOnRampart.whichDependsOnXerces</groupId>
<artifactId>someArtifact</artifactId>
<version>2.1</version>
<exclusions>
<exclusion>
<groupId>org.apache.xerces</groupId>
<artifactId>xmlParserAPIs</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.xerces</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.xerces</groupId>
<artifactId>resolver</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.xerces</groupId>
<artifactId>serializer</artifactId>
</exclusion>
</exclusions>
To check your dependencies afterwards, run 'mvn dependency:tree' and hopefully you won't see any xerces dependencies.
Upvotes: 2
Reputation: 4398
When compiling with maven 3 (I used 3.0.2) with provided scope you have the problem with the transitive dependencies (you have a los of JARs inside the WAR). If you use older versions of maven (I used 2.2.1), the WAR contains what is spected (only dependencies not provided
Upvotes: 0
Reputation: 41
I had no possibility to modify depending war file. I needed to avoid some old jar file from lib. This snippet of POM.xml configuration works well for me. I use Maven 2.2.
<build>
<plugins>
<!-- put aside some unwanted jars from war...-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<overlays>
<overlay>
<groupId>com.company.app</groupId>
<artifactId>web_app</artifactId>
<excludes>
<exclude>WEB-INF/lib/json-lib-2.2.2-jdk13.jar</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
....
Upvotes: 4
Reputation: 161
About exclusion of transitive dependencies, i think don't work with transtive of transitive dependecies, and i think this could be the case.
For example, add dependency of hibernate-core -> dom4j -> xml-apis if add exclude of xml-apis near your hibernate-core, still add xml-apis...
Upvotes: 5
Reputation: 30448
You can mark these dependencies as provided:
<dependency>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
This way the maven will add them to the compilation classpath, but will not package them. It is assumed they exist in your servlet container.
See more about maven scopes here under "scope"
Edit If you want to remove classes added via transitive dependencies you can exclude them from the dependency like this:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
(taken from this answer)
See more here
Upvotes: 71
Reputation: 47785
I fixed it.
Rereading the reference with a bit more care, I discovered that the element packagingExcludes should be warSourceExcludes.
Upvotes: 8