I have the following dependency specified in my project's POM:
<dependency>
<groupId>org.jboss.client</groupId>
<artifactId>jbossall-client</artifactId>
<scope>compile</scope>
</dependency>
My project itself has to be the child of another POM. And in that one, the following is defined:
<dependency>
<groupId>org.jboss.client</groupId>
<artifactId>jbossall-client</artifactId>
<version>4.2.3.GA</version>
<scope>provided</scope>
<type>jar</type>
</dependency>
When I now assembly my program, it seems that the "provided" scope of the parent POM overrides the scope of my project, since the jbossall-client.jar is not included in my assembly. Although it seems illogical to me, maybe it's this feature taking effect here.
Do you know a way to include the dependency in my assembly without touching the parent POM?
Edit:
Output of mvn dependency-tree (Updated!):
[dependency:tree]
com.myproject:myproject:jar:0.0.1-SNAPSHOT
+- com.myproject-commons:jar:1.0-SNAPSHOT:compile
| +- commons-logging:commons-logging:jar:1.0.4:compile
| +- log4j:log4j:jar:1.2.14:compile
| +- sv.seucc:seucc-unicode:jar:1.0.1.5:compile
| +- commons-lang:commons-lang:jar:2.2:compile
| +- com.thoughtworks.xstream:xstream:jar:1.2.1:compile
| \- xpp3:xpp3_min:jar:1.1.3.4.O:compile
+- com.myproject-interfaces2:jar:1.0-SNAPSHOT:compile
| \- com.myproject-service-commons:jar:1.0-SNAPSHOT:compile
+- org.springframework:spring:jar:2.5.6:compile
+- commons-io:commons-io:jar:1.3.1:compile
+- com.myproject-modules:ejb:1.0-SNAPSHOT:compile
\- org.jboss.client:jbossall-client:jar:4.2.3.GA:compile
Edit 2: Here the dependency part of my assembly XML.
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
Edit 3: Here are the files in the lib folder of my obtained assembly.
commons-io-1.3.1.jar
commons-lang-2.2.jar
commons-logging-1.0.4.jar
log4j-1.2.14.jar
seucc-unicode-1.0.1.5.jar
spring-2.5.6.jar
xpp3_min-1.1.3.4.O.jar
xstream-1.2.1.jar
myproject-commons-1.0-SNAPSHOT.jar
myproject-modules-1.0-SNAPSHOT.jar
myproject-service-commons-1.0-SNAPSHOT.jar
myproject-interfaces2-1.0-SNAPSHOT.jar
myproject-0.0.1-SNAPSHOT.jar
Edit 4: For the answer to this question see the final comments of the correct answer.
Both dependencies don't have the same groupId so nothing get overridden here, they are treated as distinct artifacts. But I wonder how things work in your child pom (since the jbossall-client doesn't have any version). Do you have a dependencyManagement section?
Anyway, to "debug" this kind of problem, use mvn dependency:tree in your child project (and post the output if you need more help).
Update: The above was my answer to the initial question and does not reflect the current state of the question.
For the sake of clarity, the key of the final solution was to declare a <scope>compile</scope> (which defaults to runtime) in the dependencySet element of the assembly descriptor. See the comments for all details.
See also
8.5.4.3. Including and Excluding Dependencies by Scope
We had the same issue and solved it by adding a 2nd dependencySet of scope provided, BUT this only worked once we upgraded to version 2.2.1 of the assembly plugin.
Related
I am well aware of the fact that this is not good idea, but I need to define a dependency with multiple versions. I would also like to know if it is possible to resolve all transitive dependencies of such diamond dependencies. For example, if two dependencies of the project each have a dependency on commons-lang (2.1 and 3.0) and the project itself defines version 2.5, I would like to be able to download all three versions along with their transitive dependencies. Is this at all possible and how can I do it?
To answer my own question, "yes", as shown below:
<ivy-module version="2.0">
<info organisation="com.foo"
module="diamond-dependency"
revision="1.0-SNAPSHOT"/>
<dependencies>
<dependency org="javax.activation" name="activation" rev="1.1-rev-1"/>
<dependency org="org.apache.commons" name="commons-email" rev="1.3.1"/>
<conflict manager="all"/>
</dependencies>
</ivy-module>
The key bit is in the conflict manager section which, in this case, is being told to resolve all conflicting dependencies.
The above will have a dependency tree looking like this (containing three different versions of javax.activation:activation:
+- javax.activation:activation:jar:1.1-rev-1:compile
\- org.apache.commons:commons-email:jar:1.3.1:compile
+- javax.mail:mail:jar:1.4.5:compile
| \- (javax.activation:activation:jar:1.1:compile - omitted for conflict with 1.1-rev-1)
\- (javax.activation:activation:jar:1.1.1:compile - omitted for conflict with 1.1-rev-1)
Here's my generic problem:
My project P depends on A which depends on B which depends on C which depends on version 1.0.1 of D.
There's a problem with version 1.0.1 of D and I want to force the use of another module. I don't know how to declare this in my project's POMs since I haven't added a dependency on D directly. It's C which declared the dependency on D.
Important: In this case, not only the version is changed, but the group & artifact as well. So it's not just a matter of overriding the version of the dependency, but rather, of excluding a module and including another one.
In the concrete case, D is StAX whose 1.0.1 has a bug. According to the notes in the bug, "the problems were solved by replacing the stax-api-1.0.1 (maven GroupId = stax) by stax-api-1.0-2 (maven GroupId = javax.xml.stream)" so I'm trying just that.
Thus, D = stax:stax-api:jar:1.0.1 and C = org.apache.xmlbeans:xmlbeans:jar:2.3.0
I'm using maven 2.0.9 in case it matters.
Output of mvn dependency:tree"
mvn dependency:tree
[..snip..]
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile
[INFO] | +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile
[INFO] | | +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] | | | \- stax:stax-api:jar:1.0.1:compile
In my project's POM I have the following dependency on "A":
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.6</version>
</dependency>
Simply specify the version in your current pom. The version specified here will override other.
Forcing a version
A version will always be honoured if it is declared in the current POM with a particular version - however, it should be noted that this will also affect other poms downstream if it is itself depended on using transitive dependencies.
Resources :
Dependency Mediation and Conflict Resolution
Introduction to the Dependency Mechanism
Alternatively, you can just exclude the dependency that you don't want. STAX is included in JDK 1.6, so if you're using 1.6 you can just exclude it entirely.
My example below is slightly wrong for you - you only need one of the two exclusions but I'm not quite sure which one. There are other versions of Stax floating about, in my example below I was importing A which imported B which imported C & D which each (through yet more transitive dependencies) imported different versions of Stax. So in my dependency on 'A', I excluded both versions of Stax.
<dependency>
<groupId>a.group</groupId>
<artifactId>a.artifact</artifactId>
<version>a.version</version>
<exclusions>
<!-- STAX comes with Java 1.6 -->
<exclusion>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
<exclusion>
<groupId>stax</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
</exclusions>
<dependency>
What you put inside the </dependencies> tag of the root pom will be included by all child modules of the root pom. If all your modules use that dependency, this is the way to go.
However, if only 3 out of 10 of your child modules use some dependency, you do not want this dependency to be included in all your child modules. In that case, you can just put the dependency inside the </dependencyManagement>. This will make sure that any child module that needs the dependency must declare it in their own pom file, but they will use the same version of that dependency as specified in your </dependencyManagement> tag.
You can also use the </dependencyManagement> to modify the version used in transitive dependencies, because the version declared in the upper most pom file is the one that will be used. This can be useful if your project A includes an external project B v1.0 that includes another external project C v1.0. Sometimes it happens that a security breach is found in project C v1.0 which is corrected in v1.1, but the developers of B are slow to update their project to use v1.1 of C. In that case, you can simply declare a dependency on C v1.1 in your project's root pom inside `, and everything will be good (assuming that B v1.0 will still be able to compile with C v1.1).
I also had trouble overruling a dependency in a third party library. I used scot's approach with the exclusion but I also added the dependency with the newer version in the pom. (I used Maven 3.3.3)
So for the stAX example it would look like this:
<dependency>
<groupId>a.group</groupId>
<artifactId>a.artifact</artifactId>
<version>a.version</version>
<exclusions>
<!-- STAX comes with Java 1.6 -->
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>javax.xml.stream</groupId>
</exclusion>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
<dependency>
<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency>
The accepted answer is correct but I'd like to add my two cents. I've run into a problem where I had a project A that had a project B as a dependency. Both projects use slf4j but project B uses log4j while project A uses logback.
Project B uses slf4j 1.6.1, while project A uses slf4j 1.7.5 (due to the already included logback 1.2.3 dependency).
The problem: Project A couldn't find a function that exists on slf4j 1.7.5, after checking eclipe's dependency hierarchy tab I found out that during build it was using slf4j 1.6.1 from project B, instead of using logback's slf4j 1.7.5.
I solved the issue by changing the order of the dependencies on project A pom, when I moved project B entry below the logback entry then maven started to build the project using slf4j 1.7.5.
Edit:
Adding the slf4j 1.7.5 dependency before Project B dependency worked too.
I have two independent gwt based projects using pom aggregation , so four projects(or modules) in total. Tree looks like this .
Reactor1(just pom.xml)
|-- war1 (gwt related stuff)
`-- jar1 (Spring , hibernate etc)
and an other project but structure is exactly the same
Reactor2(just pom.xml)
|-- war2 (gwt related stuff)
`-- jar2 (Spring , hibernate etc)
While being independent they are part of same business project . One is say reporting project and other one is CMS .I want to centralize all the major dependencies say just for example GWT , Spring , Hibernate (as obviously the core ones) . So I am thinking of a tree like this .
Parent(GWT ,SPring,Hibernate)
|-- Reactor1 (just pom.xml)
| |-- war1 (gwt stuff from parent)
| `-- jar1 (Spring , hibernate etc from parent)
`-- Reactor2 (just pom.xml)
|-- war2 (gwt related stuff from parent)
`-- jar2 (Spring , hibernate etc from parent)
Can some one please advice me if I am on the right path . I am just thinking that war file this is also getting the dependencies that it did not need (like spring and hibernate etc) like wise jars are getting dependencies like gwt which they do not need . Does it matter or not ? or am I on a tangent here :) . Any advice would be really appreciated . (I know my formatting is looking horrible but I hope it makes sense)
Can some one please advice me if I am on the right path.
I think that you are definitely on the right path. Just create this Parent aggregating pom and declare the GWT, Spring, and Hibernate dependencies under the dependencyManagement element.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.acme.business</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.5.5-Final</version>
</dependency>
...
<dependencies>
</dependencyManagement>
...
</project>
Then, in a child project, you can add a dependency on Hibernate Core using the following declaration:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.acme.business</groupId>
<artifactId>reactor-1</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>jar1</artifactId>
...
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>
</project>
References
Introduction to the Dependency Mechanism
Dependency Management
Maven: The Definitive Guide
9.4.6. Dependency Management
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}?
I run a simple CXF maven project http://cxf.apache.org/docs/using-cxf-with-maven.html, and get error below
[INFO] [cxf-codegen:wsdl2java {execution: generate-sources}]
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] org/springframework/core/io/support/ResourcePatternResolver
org.springframework.core.io.support.ResourcePatternResolver
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: org/springframework/core/io/support/ResourcePatternResolver
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:719)
I don't know how to put the springframework-core dependance ?
I tried below like most of answers
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.6</version>
</dependency>
</dependencies>
but it didn't help, I also don't know why it depends on springframework
It works if I put the jar file under $M2_HOME/lib, but is it correct way ? since when I solve this, it requires to add more lib there, can I put it into pom.xml somewhere ?
I tried to put <dependencies/> inside <build> tag, it doesn't work
my maven is 2.2.1 on windows
It works if I put the jar file under $M2_HOME/lib, but is it correct way ?
No, definitely not. To add a dependency, you need to declare it in your pom.xml, something like this:
<project>
...
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>???</version>
</dependency>
...
</dependencies>
</project>
But I don't understand why you would have to add this dependency, spring-core is a dependency of cxf, you should get it transitively. You're not providing enough context information for a more precise answer though.
You have to define it in the pom.xml
Read the docs at http://maven.apache.org/pom.html#Dependencies
You'll need to add this to your Maven pom.xml file in the <dependencies> section:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>???</version>
</dependency>
The version number will depend on which version of spring you're using. (I'm using 2.0 as the version #, along with spring 2.0.8).
Finally I found it by myself, it is due to the error of my springframework-2.5.5 package from local repository. The jar file is not correct. I notice this later in eclipse
Pascal's answer is also correct.
The springframework-2.5.5 is automatically download by maven, unfortunately it is broken, so it still complain the class, and if I put springframework-2.5.6 inside, even it will be downloaded, it will not be used, maven still think it loaded the springframework-2.5.5 into its classpath.
And if I put into %M2_HOME%/lib, surely it will be maven's classpath, and it is wrong to use it.
Since I met this kind of problem before, now I know what it is.
Summary: checking your dependance files to see whether the package is correct
BTW: Thanks for all especially pascal