views:

55

answers:

4

How do I use maven or another tool to find which dependency of a dependency which provides a particular jar? Sometimes they're three or four dependencies deep.

A: 

Even for direct dependencies in Java it is at least a challenge. Not all dependencies are static and could be reflected from the class file. And even for those classes there's no way to get the correct library that is needed to meet that dependancy.

We have for example the Class.forName(String className) way of adding dynamic dependencies and the class name could be written in a resource or properties file or constructed at runtime. And the named class then could introduce a dependenciy to a different library.

I doubt that any tool is capable of resolving all those dependencies.

Andreas_D
+2  A: 

I suppose you are looking for:

mvn dependency:tree

Edit: There are more options available to analyze dependencies. Have a look at the documentation

Hardcoded
@Hardcoded - Just beat me to it. Some example output is here http://docs.codehaus.org/display/MAVENUSER/Dependency+Mechanism
JoseK
A: 

This isn't a direct answer but it might help if you are using Eclipse with a Maven plugin.

If I want to find where a class comes from, I do the following:

  1. Select the class name and use the F3 shortcut to load the source code into the Editor window.
  2. Use "Show In > Package Explorer" to locate the file in (typically) the Maven Dependencies section of the build path.
  3. Look at the JAR filename of the enclosing dependency "folder", and read off the group id, artifact id and version.

(This might not be 100% reliable in a multi-module project if you use Eclipse Maven's nested module support. But I've not encountered problems in practice.)

Stephen C
+1  A: 

If you want to find out from where a transitive dependency is coming from for a given project, then the Maven Dependency Plugin is indeed your friend. Use it with the includes parameter that allows to specify a comma-separated list of artifacts to filter the serialized dependency tree by, or null not to filter the dependency tree. The artifact syntax is defined by StrictPatternIncludesArtifactFilter.

About the syntax, the javadoc writes:

The artifact pattern syntax is of the form

[groupId]:[artifactId]:[type]:[version]

Where each pattern segment is optional and supports full and partial * wildcards. An empty pattern segment is treated as an implicit wildcard.

For example, org.apache.* would match all artifacts whose group id started with org.apache., and :::*-SNAPSHOT would match all snapshot artifacts.

Here is an example (I want to find from where the activation artifact is coming from on a project):

$ mvn dependency:tree -Dincludes=:activation::
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Java EE 6 Demo - Petstore - Domain
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] name.thivent.samples.javaee6.domain:domain:jar:1.0-SNAPSHOT
[INFO] \- org.hibernate:hibernate-validator:jar:4.0.2.GA:runtime
[INFO]    \- javax.xml.bind:jaxb-api:jar:2.1:runtime
[INFO]       \- javax.activation:activation:jar:1.1:runtime
[INFO] ------------------------------------------------------------------------
...

M2Eclipse provides a nice front-end to the dependency:tree if you are using it.

For something "closer" to rpm --whatprovides (i.e. without searching for a particular project), you would have to use a repository search engine. Here is an example for activation-1.1.jar (see the This artifact is used by ... section).

Pascal Thivent