Maven ignoring provided scope - maven-2

I have a EAR with a number of EJB dependencies. 2 of these have a provided scope dependency to the glassfish-embedded-all jar. However when I do a mvn install on my local machine or when the application is build through maven on hudson the ear always contains the glassfish-embedded-all jar.
e.g. DataAccess-ejb with provided dependency
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.0</version>
<scope>provided</scope>
</dependency>
Application-ear with ejb dependency
<dependency>
<groupId>com.xxx.yyy</groupId>
<artifactId>DataAccess-ejb</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
Any ideas what I am doing wrong or possible suggestions?
Cheers,
James

Try using mvn dependency:tree in order to analyze what artifact is including the glassfish-embedded-all.jar, chances are that you're overlooking something. Maven won't include an artifact that is not declared as as direct dependency and/or inherited through transitive dependency.
You can also issue and mvn dependency:analyze-only command to further clean up those dependencies that you don't really need.

Dependencies with a provided scope are not transitive so you're not getting it transitively, there must be something else. Run mvn dependency:tree from the ear module.
But actually, I really wonder why you're using a provided scope, I think a test scope might be more appropriate. And by the way, I suggest using GF 3.0.1:
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.0.1</version>
<scope>test</scope>
</dependency>

Related

SLF4J: Class path contains multiple SLF4J bindings

I'm getting the following error. It seems there are multiple logging frameworks bound to slf4j. Not sure how to resolve this. Any help is greatly appreciated.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/admin/.m2/repository/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/admin/.m2/repository/org/slf4j/slf4j-log4j12/1.6.1/slf4j-log4j12-1.6.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
Resolved by adding the following exclusion in the dependencies (of pom.xml) that caused conflict.
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
Gradle version;
configurations.all {
exclude module: 'slf4j-log4j12'
}
The error probably gives more information like this (although your jar names could be different)
SLF4J: Found binding in
[jar:file:/D:/Java/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in
[jar:file:/D:/Java/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.8.2/log4j-slf4j-impl-2.8.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
Noticed that the conflict comes from two jars, named logback-classic-1.2.3 and log4j-slf4j-impl-2.8.2.jar.
Run mvn dependency:tree in this project pom.xml parent folder, giving:
Now choose the one you want to ignore (could consume a delicate endeavor I need more help on this)
I decided not to use the one imported from spring-boot-starter-data-jpa (the top dependency) through spring-boot-starter and through spring-boot-starter-logging, pom becomes:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
in above pom spring-boot-starter-data-jpa would use the spring-boot-starter configured in the same file, which excludes logging (it contains logback)
Sbt version:
Append exclude("org.slf4j", "slf4j-log4j12") to the dependency that transitively includes slf4j-log4j12. For example, when using Spark with Log4j 2.6:
libraryDependencies ++= Seq(
// One SLF4J implementation (log4j-slf4j-impl) is here:
"org.apache.logging.log4j" % "log4j-api" % "2.6.1",
"org.apache.logging.log4j" % "log4j-core" % "2.6.1",
"org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.6.1",
// The other implementation (slf4j-log4j12) would be transitively
// included by Spark. Prevent that with exclude().
"org.apache.spark" %% "spark-core" % "1.5.1" exclude("org.slf4j", "slf4j-log4j12")
)
1.Finding the conflicting jar
If it's not possible to identify the dependency from the warning, then you can use the following command to identify the conflicting jar
mvn dependency: tree
This will display the dependency tree for the project and dependencies who have pulled in another binding with the slf4j-log4j12 JAR.
Resolution
Now that we know the offending dependency, all that we need to do is exclude the slf4j-log4j12 JAR from that dependency.
Ex - if spring-security dependency has also pulled in another binding with the slf4j-log4j12 JAR, Then we need to exclude the slf4j-log4j12 JAR from the spring-security dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Note - In some cases multiple dependencies have pulled in binding with the slf4j-log4j12 JAR and you don't need to add exclude for each and every dependency that has pulled in.
You just have to do that add exclude dependency with the dependency which has been placed at first.
Ex -
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
If you work with gradle then add following code to your build.gradle file to exclude SLF4J binding from all the modules
configurations.all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
I just ignored/removed that jar file.
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-log4j2</artifactId>-->
<!--</dependency>-->
I solved by delete this:spring-boot-starter-log4j2
Just use only required dependency, not all :))). For me, for normal work of logging process you need this dependency exclude others from pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.8</version>
</dependency>
This is issue because of StaticLoggerBinder.class class belongs to two different jars. this class references from logback-classic-1.2.3.jar and same class also referenced from log4j-slf4j-impl-2.10.0.jar. both of jar in classpath. Hence there is conflict between them.
This is reason of log file is not generation even though log4j2.xml file in classpath [src/main/resource].
We have so select one of jar, I recommend use log4j-slf4j-impl-2.10.0.jar file and exclude logback-classic-1.2.3.jar file.
Solution: open pom file and view the dependency Hierarchy [eclipse] or run
mvn dependency:tree command to find out the dependency tree and source of dependency that download the dependency. find the conflicting dependency and exclude them. For Springboot application try this.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
This is working fine for me after struggling a lots.
...
org.codehaus.mojo
cobertura-maven-plugin
2.7
test
ch.qos.logback
logback-classic
tools
com.sun
...
## I fixed with this
...
org.codehaus.mojo
cobertura-maven-plugin
2.7
test
ch.qos.logback
logback-classic
tools
com.sun
...
For me, it turned out to be an Eclipse/Maven issue after switch from log4j to logback. Take a look into your .classpath file and search for the string "log4j".
In my case I had the following there:
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-log4j12/1.7.1/slf4j-log4j12-1.7.1.jar"/>
<classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.17/log4j-1.2.17.jar" />
Removing those entries from the file (or you could regenerate it) fixed the issue.
For me the answer was to force a Maven rebuild. In Eclipse:
Right click on project-> Maven -> Disable Maven nature
Right click on project-> Spring Tools > Update Maven Dependencies
Right click on project-> Configure > Convert Maven Project
I solved this by going to Project Structure from my Intellij project.
I deleted the file named: Maven: org.apache.logging.log4j:log4j-to-slf4j-impl:2.14.1
This file is not shown in this picture. You may see two libraries mentioned as log4j-to-slf4j. Delete one and you are good to go.
For all those looking for the solution for spring-boot-type dependencies, the magic incantation for Gradle is this:
configurations.all {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
in your build.gradle at the top level (not inside the dependencies block).
All other solutions found in the interwebs (including the one here suggesting to exclude the slf4j module) did not work for me.
This is what I have in my build.gradle (snippet):
// Removes the annoying warning about the multiple SLF4J implementations:
// SLF4J: Class path contains multiple SLF4J bindings.
configurations.all {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation ('org.springframework.boot:spring-boot-starter-actuator')
implementation ('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')
implementation ('org.springframework.boot:spring-boot-starter-webflux')
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
compileOnly "org.projectlombok:lombok:${lombokVersion}"
// Removes the annoying warning:
// warning: unknown enum constant When.MAYBE
// reason: class file for javax.annotation.meta.When not found
// See: https://stackoverflow.com/questions/29805622/could-not-find-or-load-main-class-org-gradle-wrapper-gradlewrappermain/31622432
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2'
// other stuff...
YMMV
I had the same problem. In my pom.xml i had both
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.28</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
When i deleted the spring-boot-starter-web dependency, problem was solved.
I got this issue in a non-maven project, two depended jar each contained a slf4j. I solved
by remove one depended jar, compile the project(which of course getting failure) then add the removed one back.
In case these logs are the result of this fix:
https://stackoverflow.com/a/9919375/2894819
When one of your libraries actually use it. And your application doesn't need SL4J just replace implementation to runtimeOnly.
// contains dependency to sl4j-api
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.2.0")
// add this to remove both warnings
runtimeOnly("org.slf4j:slf4j-nop:1.7.36")
In that case when you run your app the actual dependency will be included once by the library and won't be included to the bundle of your application.jar itself.
In my case I had 2 sources of dependencies for log4 one in C:\Program Files\smcf.ear directory and the second from maven which caused the multiple binding for sl4j.
Deleting the smcf.ear directory solved the issue for me.
The combination of <scope>provided</scope> and <exclusions> didn't work for me.
I had to use this:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/empty.jar</systemPath>
</dependency>
Where empty.jar is a jar file with literally nothing in it.
Seems removing .m2 directory and :
mvn install -DskipTests -T 4 resolved this issue for me.

Specifying an ejb client as dependency in Maven

I have 2 EJBs A and B (in different jar files), EJB A calls one method of EJB B.
From the following Maven's documents, I use generateClient to create a ejb-client and use ejb-client dependency to get the jar.
http://maven.apache.org/plugins/maven-ejb-plugin/examples/generating-ejb-client.html
http://people.apache.org/~aramirez/maven-ejb-plugin/examples/ejb-client-dependency.html
It's ok to use Maven to build, deploy and run. The problem is, although project A only needs the interface class of EJB B, but Maven includes all EJB B's dependency libraries into EJB A's dependency. The result is EJB A will have lots of non-necessary jar files. Is there any solution to fix it?
I found another solution, Maven's dependency has exclude function and I use it to remove some jar files.
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>ejb-project</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb-client</type>
<exclusions>
<exclusion>
<groupId>sample.ProjectD</groupId>
<artifactId>Project-D</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
The only way is to move interface of EJB B to a separate jar. Then use it as dependency in EJBs A and B project/modules.

where is the correct and recent ehcache maven repository

I've been struggling to get ehcache 2.1.0 in my environment. Anytime I thought I got it right, it's just not downloading it. Here is where I set the repository:
<repository>
<!--<url>https://oss.sonatype.org/content/repositories/releases/</url>-->
<url>http://oss.sonatype.org/content/repositories/sourceforge-releases</url>
<id>sonatype-mirror</id>
<layout>default</layout>
<name>Repository for library including ehcache recent ones</name>
</repository>
And I add the dependency this way :
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.1.0</version>
</dependency>
Is there anything that's i'm doing wrong or not properly?
Ehcache is available in the maven central repository, there is no need to add a particular repository.
However, the ehcache artifact is special, it's an "aggregating" artifact which is of type pom. So the dependency should be declared like this:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.1.0</version>
<type>pom</type>
</dependency>
Of course, you can also declare dependencies on individual modules if you want (e.g. ehcache-core) in which case you don't need to specify the type.
References
Ehcache Documentation
Java Requirements and Dependencies
net.sf.ehcache:ehcache:2.1.0 is a dependency of type pom therefore you need to specify it:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.1.0</version>
<type>pom</type>
</dependency>
See also:
3.6. POM Best Practices

Using Maven, how can I assemble several modules into one artifact?

We have a mother-ship project with several modules:
foo
+ foo-core
+ foo-resource
+ foo-util
+ foo-whatever
I want to allow developers to include the core, resource, and util modules as dependencies (excluding the -whatever module). I know that I can specify that they include each dependency, but it would be nice to allow for them to just specify something like
<artifactId>foo-sdk</artifactId>
And get everything that they need to develop a foo. This has the added advantage that it gives us the power to add (or remove) what goes into the sdk.
It would be best if foo-sdk was not just a jar with the other jars jammed in it. I'd rather it be a pom that simply points to the other artifacts.
I feel like I've seen this done before but can't find instructions to do it. I checked out Maven Assembly Plugin but it doesn't look like this is its intended use.
You can group dependencies in a project with a packaging of type pom. From the Maven book:
3.6.1. Grouping Dependencies
If you have a set of dependencies
which are logically grouped together.
You can create a project with pom
packaging that groups dependencies
together. For example, let's assume
that your application uses Hibernate,
a popular Object-Relational mapping
framework. Every project which uses
Hibernate might also have a dependency
on the Spring Framework and a MySQL
JDBC driver. Instead of having to
include these dependencies in every
project that uses Hibernate, Spring,
and MySQL you could create a special
POM that does nothing more than
declare a set of common dependencies.
You could create a project called
persistence-deps (short for
Persistence Dependencies), and have
every project that needs to do
persistence depend on this convenience
project:
Example 3.11. Consolidating Dependencies in a Single POM Project
<project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernateVersion}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernateAnnotationsVersion}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-hibernate3</artifactId>
<version>${springVersion}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysqlVersion}</version>
</dependency>
</dependencies>
<properties>
<mysqlVersion>(5.1,)</mysqlVersion>
<springVersion>(2.0.6,)</springVersion>
<hibernateVersion>3.2.5.ga</hibernateVersion>
<hibernateAnnotationsVersion>3.3.0.ga</hibernateAnnotationsVersion>
</properties>
</project>
If you create this project in a
directory named persistence-deps, all
you need to do is create this
pom.xml and run mvn install. Since
the packaging type is pom, this POM
is installed in your local repository.
You can now add this project as a
dependency and all of its dependencies
will be added as transitive
dependencies to your project. When you
declare a dependency on this
persistence-deps project, don't
forget to specify the dependency type
as pom.
Example 3.12. Declaring a Dependency on a POM
<project>
<description>This is a project requiring JDBC</description>
...
<dependencies>
...
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
If you later decide to switch to a
different JDBC driver (for example,
JTDS), just replace the dependencies
in the persistence-deps project to use
net.sourceforge.jtds:jtds instead of
mysql:mysql-java-connector and update
the version number. All projects
depending on persistence-deps will use
JTDS if they decide to update to the
newer version. Consolidating related
dependencies is a good way to cut down
on the length of pom.xml files that
start having to depend on a large
number of dependencies. If you need to
share a large number of dependencies
between projects, you could also just
establish parent-child relationships
between projects and refactor all
common dependencies to the parent
project, but the disadvantage of the
parent-child approach is that a
project can have only one parent.
Sometimes it makes more sense to group
similar dependencies together and
reference a pom dependency. This way,
your project can reference as many of
these consolidated dependency POMs as
it needs. Note
Maven uses the depth of a dependency
in the tree when resolving conflicts
using a nearest-wins approach. Using
the dependency grouping technique
above pushes those dependencies one
level down in the tree. Keep this in
mind when choosing between grouping in
a pom or using dependencyManagement
in a parent POM
Wouldn't this just be another sub-module foo-sdk with packaging pom and dependencies on foo-{core,resource,util}?

Exclude all transitive dependencies of a single dependency

In Maven2, to exclude a single transitive dependency, I have to do something like this:
<dependency>
<groupId>sample.group</groupId>
<artifactId>sample-artifactB</artifactId>
<version>1</version>
<exclusions>
<exclusion>
<groupId>sample.group</groupId>
<artifactId>sample-artifactAB</artifactId>
</exclusion>
</exclusions>
</dependency>
The problem with this approach is that I have to do this for every transitive dependency contributed by sample-artifactB.
Is there a way to use some sort of wildcard to exclude all transitive dependencies at once instead of one-by-one?
What has worked for me (may be a newer feature of Maven) is merely doing wildcards in the exclusion element.
I have a multi-module project that contains an "app" module that is referenced in two WAR-packaged modules. One of those WAR-packaged modules really only needs the domain classes (and I haven't separated them out of the app module yet). I found this to work:
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>app</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
The wildcard on both groupId and artifactId exclude all dependencies that normally would propagate through to the module using this dependency.
For maven2 there isn't a way to do what you describe. For maven 3, there is. If you are using maven 3 please see another answer for this question
For maven 2 I'd recommend creating your own custom pom for the dependency that has your <exclusions>. For projects that need to use that dependency, set the dependency to your custom pom instead of the typical artifact. While that does not necessarily allow you exclude all transitive dependencies with a single <exclusion>, it does allow you only have to write your dependency once and all of your projects don't need to maintain unnecessary and long exclusion lists.
One thing I have found useful:
If you put the dependency with the exclusions in the dependencyManagement section of either the parent POM for your project, or in an importable dependency management POM, then you don't need to repeat the exclusion (or the version).
For example, if your parent POM has:
<dependencyManagement>
<dependencies>
...
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
....
</dependencies>
</dependencyManagement>
Then the modules in your project can simply declare the dependency as:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
The in the parent POM will specify both the version and the exclusions. I use this technique for nearly all of our projects and it eliminates a lot of repetition.
Three years ago I recommended using Version 99 Does Not Exist, but now I've figured out a better way, especially since Version 99 is offline:
In your project's parent POM, use maven-enforcer-plugin to fail the build if the unwanted dependency creeps into the build. This can be done using the plugin's banned dependencies rule:
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>only-junit-dep-is-used</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>junit:junit</exclude>
</excludes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
Then when that alerts you about an unwanted dependency, exclude it in the parent POM's <dependencyManagement> section:
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<version>2.1.8.RELEASE</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
This way the unwanted dependency won't show up accidentally (unlike just an <exclusion> which is easy to forget), it won't be available even during compile time (unlike provided scope), there are no bogus dependencies (unlike Version 99) and it'll work without a custom repository (unlike Version 99). This approach will even work based on the artifact's version, classifiers, scope or a whole groupId - see the documentation for details.
I use the following workaround : instead of trying to exclude the artifact in all appropriate dependencies, I draw the dependency as "provided" at top level.
For example, to avoid shipping xml-apis "whatever version" :
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>[1.0,]</version>
<scope>provided</scope>
</dependency>
Currently, there's no way to exclude more than one transitive dependency at a time, but there is a feature request for this on the Maven JIRA site:
https://issues.apache.org/jira/browse/MNG-2315
if you need to exclude all transitive dependencies from a dependency artifact that you are going to include in an assembly, you can specify this in the descriptor for the assembly-plugin:
<assembly>
<id>myApp</id>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<useTransitiveDependencies>false</useTransitiveDependencies>
<includes><include>*:struts2-spring-plugin:jar:2.1.6</include></includes>
</dependencySet>
</dependencySets>
</assembly>
There is a workaround for this, if you set the scope of a dependency to runtime, transitive dependencies will be excluded. Though be aware this means you need to add in additional processing if you want to package the runtime dependency.
To include the runtime dependency in any packaging, you can use the maven-dependency-plugin's copy goal for a specific artifact.
If you develop under Eclipse, you can in the POM Editor (advanced tabs enabled) dependency graph look for the dependency you want to exclude of your project and then:
right click on it -> "Exclude Maven Artifact ..." and Eclipse will make the exclusion for you without the need to find out on which dependency the lib is linked.
What is your reason for excluding all transitive dependencies?
If there is a particular artifact (such as commons-logging) which you need to exclude from every dependency, the Version 99 Does Not Exist approach might help.
Update 2012: Don't use this approach. Use maven-enforcer-plugin and exclusions. Version 99 produces bogus dependencies and the Version 99 repository is offline (there are similar mirrors but you can't rely on them to stay online forever either; it's best to use only Maven Central).
In a simular issue I had the desired dependency declared with scope provided.
With this approach the transitive dependencies are fetched but are NOT included in the package phase, which is what you want.
I also like this solution in terms of maintenance, because there is no pom, or custom pom as in whaley's solution, needed to maintain; you only need to provide the specific dependency in the container and be done
Use the latest maven in your classpath.. It will remove the duplicate artifacts and keep the latest maven artifact..