I have added vaadin-client-compiler dependency as a provided scope dependency in my vaadin application pom.
As I have read, provided dependency is not transitive, so the dependencies of vaadin-client-compiler should become dependencies of my webapp.
But, I found dependencies of vaadin-client-compiler (commons-lang3-3.1.jar) inside my WEB-INF/lib directory.
Also, these dependencies are shown in mvn dependency:tree output as well.
[INFO] | +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] | \- javax.validation:validation-api:jar:sources:1.0.0.GA:compile
[INFO] +- com.vaadin:vaadin-client-compiler:jar:7.6.4:provided
[INFO] | +- com.vaadin:vaadin-sass-compiler:jar:0.9.13:compile
[INFO] | | \- com.yahoo.platform.yui:yuicompressor:jar:2.4.8:compile
[INFO] | | \- rhino:js:jar:1.7R2:compile
[INFO] | +- commons-collections:commons-collections:jar:3.2.2:compile
................................................
.................................................
[INFO] | +- commons-codec:commons-codec:jar:1.8:compile
[INFO] | +- commons-io:commons-io:jar:2.4:compile
[INFO] | +- org.apache.commons:commons-lang3:jar:3.1:compile
Question: Why did dependencies of a provided scope dependency became dependencies of my webapp?
Indeed, according to official Maven Dependency Mediation, the provided scope would bring in its transitive dependencies as following:
Transitive dependencies in compile scope > would be fetched as provided scope
Transitive dependencies in provided scope > ignored
Transitive dependencies in runtime scope > would be fetched as provided scope
Transitive dependencies in test scope > ignored
Hence, transitive dependencies of a provided dependency would either be ignored or be imported as provided as well and as such no part of the final packaged war.
Adding the following dependency to a sample project:
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiler</artifactId>
<version>7.6.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
Would lead to the following, executing:
mvn dependency:tree -Dincludes=com.vaadin
We would have as part of the output:
[INFO] \- com.vaadin:vaadin-client-compiler:jar:7.6.4:provided
[INFO] +- com.vaadin:vaadin-shared:jar:7.6.4:provided
[INFO] +- com.vaadin:vaadin-server:jar:7.6.4:provided
[INFO] +- com.vaadin:vaadin-client:jar:7.6.4:provided
[INFO] +- com.vaadin:vaadin-sass-compiler:jar:0.9.13:provided
[INFO] \- com.vaadin:vaadin-client-compiler-deps:jar:1.2.0:provided
Perfectly consistent with the documentation.
However, if we add to the pom.xml file the following:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-server</artifactId>
<version>7.6.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
Note: we are overriding the scope of one of its transitive dependencies to compile.
Re-executing the previous command we would have:
[INFO] \- com.vaadin:vaadin-client-compiler:jar:7.6.4:provided
[INFO] +- com.vaadin:vaadin-shared:jar:7.6.4:compile
[INFO] +- com.vaadin:vaadin-server:jar:7.6.4:compile
[INFO] +- com.vaadin:vaadin-client:jar:7.6.4:provided
[INFO] +- com.vaadin:vaadin-sass-compiler:jar:0.9.13:compile
[INFO] \- com.vaadin:vaadin-client-compiler-deps:jar:1.2.0:provided
Which means: the transitive dependency vaadin-server is still brought in by vaadin-client-compiler, but its scope is now at compile as per dependency management.
Hence, you should:
Check whether your pom.xml defines any dependencyManagement section
Check whether your parent pom or any pom in the hierarchy would do so, executing mvn help:effective-pom -Doutput=full-pom.xml would definitely help
Check whether any active profile would also influence the build, executing mvn help:active-profiles would also help
The "non-transitivity" of provided dependencies is tricky. It only means that the provided dependencies of your dependencies are not pulled. On the other hand, compile dependencies of provided dependencies are pulled (as you have experienced). The full truth is in the table shown in:
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Related
I am building a Java Maven Project and I have a dependency "net.minidev.json-smart:2.3-SNAPSHOT" imported in my package hbase 2.4.9 with another dependency and this displays a warning and Jenkins takes 1 or 2 minutes to resolve only this dependency.
the dependency tree is the following :
org.apache.hbase:hbase-server:2.4.9 -> org.apache.hadoop:hadoop-auth:2.10 -> com.nimbusds:nimbus-jose-jwt:4.41.1 -> net.minidev:json-smart:2.3-SNAPSHOT)
But when I exclude hadoop-auth 2.10 to use latest ...
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>2.4.9</version>
<exclusions>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
<version>3.3.2</version>
</dependency>
I have this dependency-tree:
[INFO] +- org.apache.hadoop:hadoop-auth:jar:3.3.2:compile
[INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile
[INFO] | | \- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
[INFO] | +- com.nimbusds:nimbus-jose-jwt:jar:9.8.1:compile
[INFO] | | \- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
[INFO] | +- net.minidev:json-smart:jar:2.4.7:compile
[INFO] | | \- net.minidev:accessors-smart:jar:2.4.7:compile
[INFO] | | \- org.ow2.asm:asm:jar:9.1:compile
and when I build with mvn -U clean install I have this message:
[WARNING] The POM for net.minidev:json-smart:jar:2.3-SNAPSHOT is missing, no dependency information available
The debug logs do not say anything more
how can I completely remove it ?
Thanks a lot for your help
In my project, we had to exclude com.nimbusds:nimbus-jose-jwt from hadoop-auth because of an odd transitive dependency. This ticket: https://issues.apache.org/jira/browse/HADOOP-14903 appears to relate to the problem. We are not using this updated version. Based on your error, maybe this "fix" didn't work.
I have a maven project with these dependencies:
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1200-jdbc41</version>
<exclusions>
<exclusion>
<groupId>org.slf4</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
If I run mvn tree it still shows the excluded artifact:
$ mvn dependency:tree
...
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # testArtifact ---
[INFO] testGroup:testArtifact:jar:1.0-SNAPSHOT
[INFO] \- org.postgresql:postgresql:jar:9.4-1200-jdbc41:compile
[INFO] +- com.github.dblock.waffle:waffle-jna:jar:1.7:runtime
[INFO] | +- net.java.dev.jna:jna:jar:4.1.0:runtime
[INFO] | +- net.java.dev.jna:jna-platform:jar:4.1.0:runtime
[INFO] | +- org.slf4j:slf4j-api:jar:1.7.7:runtime
[INFO] | \- com.google.guava:guava:jar:18.0:runtime
[INFO] \- org.slf4j:slf4j-simple:jar:1.7.7:runtime ** <--- BAD ONE
And if I run things like dependency:copy-dependencies or the shaded jar plugin, they all pull in the unwanted jar.
Am I missing something?
Using maven 3.6.0
The groupId is incorrect. Should be org.slf4j instead of org.slf4 (the j is missing).
I have a project that at one point had these lines about jdk.tools
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<scope>system</scope>
<version>1.8.0</version>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
On my Eclipse, removing these lines would gave me an error of
"Missing artifact jdk.tools:jdk.tools:jar:1.8".
But my colleague used the same pom.xml (without those lines) and she did not see
the error.
Also, on a UNIX machine I could maven build without needing
those lines (this is expected, because the scope has been system).
The dependency tree related to this artifact is this:
[INFO] +- org.apache.hadoop:hadoop-common:jar:2.7.3:compile
[INFO] | +- org.apache.hadoop:hadoop-annotations:jar:2.7.3:compile
[INFO] | | \- jdk.tools:jdk.tools:jar:1.8:system
I am trying to convert and old non-maven java NetBeans project to a maven project. The existing project has 36 libraries.
What I did
I outputted the library folder content to a file and got the list of all the jars.
I searched for the jar in maven repo and added the specific version as dependency in pom
The Result
The new maven project now has some new jars which the old one didn't have, probably they are added because they were the dependencies of the ones I added.
My Questions
If the extra jars that are added in the "Dependencies" section are
required by the jars that I added, how was the old project running?
i.e. without those jars included?
Some of the jars in the old project I believe were the dependencies of other jars. This I figured out when I added a jar and it added another jar by itself which I was about to add. So how do I figure out which jar is the
dependency of which one so I don't explicitly specify that one in my
pom? or so I could add them in sequence.
EDIT:
Thanks to #SubOptimal, i was able to check the graph, but here is what I get:
On the left is the old project opened with all the libraries, on the right, is the newly maven converted project's graph opened. Now you can see the library is the same "axis2-kernel-1.6.1.jar". On the left, the old project doesn't have the geronimo-ws-metadata_2.0_spec which is shown as a dependency of the axis2 library.
Now my question is the same, how was the old project working, is this an optional dependency?
The new dependencies might be there because of different library version in the old non-maven project and the new maven project.
Assume the non-maven project would have used JUnit in version 3.8.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sub.optimal</groupId>
<artifactId>foo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
in this example you would have only JUnit as dependency
mvn dependency:tree
output
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # suboptimal ---
[INFO] com.example:suboptimal:jar:0.0.1-SNAPSHOT
[INFO] \- junit:junit:jar:3.8:test
If you now in the maven project would use version 4.12 (instead of the previous 3.8) you would see following dependencies (after changing the version number in the pom.xml)
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
output would be
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # suboptimal ---
[INFO] com.example:suboptimal:jar:0.0.1-SNAPSHOT
[INFO] \- junit:junit:jar:4.12:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test
For the shown dependency junit:junit:jar:4.12:test the test means it's not a runtime dependency. It's need to run the provided tests.
In Netbeans you would see now both as a test dependency
There is another way to show the dependencies directly in Netbeans. When you open the pom.xml click on Graph and only for the first time after you open it on Show Graph.
You get a visual dependency tree
edit: You have not yet said what your old project uses. But find one example for the axis2 kernel below.
When your new project add following dependency
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.6.1</version>
</dependency>
listing the dependencies with mvn dependency:tree reveals following compile time dependencies (needed also for the runtime, see Maven dependency scopes)
[INFO] \- org.apache.axis2:axis2-kernel:jar:1.6.1:compile
[INFO] +- org.apache.ws.commons.axiom:axiom-api:jar:1.2.12:compile
[INFO] | +- org.apache.geronimo.specs:geronimo-activation_1.1_spec:jar:1.0.2:compile
[INFO] | +- org.apache.geronimo.specs:geronimo-javamail_1.4_spec:jar:1.6:compile
[INFO] | +- jaxen:jaxen:jar:1.1.1:compile
[INFO] | \- org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar:1.0.1:compile
[INFO] +- org.apache.ws.commons.axiom:axiom-impl:jar:1.2.12:compile
[INFO] | \- org.codehaus.woodstox:wstx-asl:jar:3.2.9:compile
[INFO] +- org.apache.geronimo.specs:geronimo-ws-metadata_2.0_spec:jar:1.1.2:compile
[INFO] +- org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1:compile
[INFO] +- javax.servlet:servlet-api:jar:2.3:compile
[INFO] +- commons-httpclient:commons-httpclient:jar:3.1:compile
[INFO] | \- commons-codec:commons-codec:jar:1.2:compile
[INFO] +- commons-fileupload:commons-fileupload:jar:1.2:compile
[INFO] +- wsdl4j:wsdl4j:jar:1.6.2:compile
[INFO] +- org.apache.ws.commons.schema:XmlSchema:jar:1.4.7:compile
[INFO] +- org.apache.neethi:neethi:jar:3.0.1:compile
[INFO] +- org.apache.woden:woden-api:jar:1.0M9:compile
[INFO] +- org.apache.woden:woden-impl-dom:jar:1.0M9:compile
[INFO] | \- org.apache.woden:woden-impl-commons:jar:1.0M9:compile
[INFO] +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] \- javax.ws.rs:jsr311-api:jar:1.0:compile
So why it looks now your old project was not needing them? Assuming that your old project uses the axis2.war file (extracted from axis2-1.6.1-war.zip). The dependencies are embedded.
jar -tf axis2.war | grep geronimo-ws-metadata
output
WEB-INF/lib/geronimo-ws-metadata-LICENSE.txt
WEB-INF/lib/geronimo-ws-metadata_2.0_spec-1.1.2.jar
This is a question sounds like bunch of similar questions on SE sites, so I should be quite verbose to make my question clear. So, here is project's minimal pom.xml:
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.gmaven.runtime</groupId>
<artifactId>gmaven-runtime-1.7</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.shabunc.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Here is the dependency tree produced by maven.
mvn dependency:tree -Dverbose -Dincludes=org.slf4j:
[INFO] [dependency:tree {execution: default-cli}]
[INFO] org.shabunc:logdebug:jar:1.0-SNAPSHOT
[INFO] \- ch.qos.logback:logback-classic:jar:1.0.6:compile
[INFO] \- org.slf4j:slf4j-api:jar:1.6.5:compile
Now, let's remove exclusion and check dependencies again. We'll get:
[INFO] org.shabunc:logdebug:jar:1.0-SNAPSHOT
[INFO] +- ch.qos.logback:logback-classic:jar:1.0.6:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.6.5:compile
[INFO] \- org.codehaus.gmaven.runtime:gmaven-runtime-1.7:jar:1.3:compile
[INFO] +- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5)
[INFO] +- org.codehaus.gmaven.feature:gmaven-feature-support:jar:1.3:compile
[INFO] | \- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5)
[INFO] \- org.codehaus.gmaven.runtime:gmaven-runtime-support:jar:1.3:compile
[INFO] +- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5)
[INFO] \- org.sonatype.gshell:gshell-io:jar:2.0:compile
[INFO] \- org.sonatype.gossip:gossip:jar:1.0:compile
[INFO] \- (org.slf4j:slf4j-api:jar:1.5.8:compile - omitted for conflict with 1.6.5)
So, as we can see, everything works as expected, and conflicting dependency is actually get excluded. But the thing is that even with dependency excluded I still get following message while compiling and calling mvn exec:java:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/shabunc/.m2/repository/ch/qos/logback/logback-classic/1.0.6/logback-classic-1.0.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/shabunc/.m2/repository/org/sonatype/gossip/gossip/1.0/gossip-1.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
The question is: Why I still see this warning and what exactly should be done to make only one version of slf4j reachable during execution?
Your problem isn't getting two copies of the SLF4J API, it's getting two different SLF4J implementations. You need to exclude Gossip, not the API. That means something like:
<dependency>
<groupId>org.codehaus.gmaven.runtime</groupId>
<artifactId>gmaven-runtime-1.7</artifactId>
<version>1.3</version>
<exclusions>
<exclusion>
<groupId>org.sonatype.gossip</groupId>
<artifactId>gossip</artifactId>
</exclusion>
</exclusions>
</dependency>
The Gossip dependency is declared by gshell-io; hopefully, it doesn't actually need Gossip, it just needs an SLF4J SLF4J, which you are supplying in the shape of Logback.
All you need to do is add something like this
compile "org.sonatype.gossip:gossip:1.0" {
exclude module:'slf4j-jcl'
exclude module:'slf4j-log4j12'
}
I guess you need to play with scope of dependencies, see: http://www.mojohaus.org/exec-maven-plugin/java-mojo.html
classpathScope -
defines the scope of the classpath passed to the plugin. Set to compile,test,runtime or system depending on your needs.