如何列出 JAR 的依赖项

是否有一个工具可以列出包含在 JAR 中引用的(第三方)类的第三方“包”?假设它从 JAR 文件定义中识别出什么是“ home”包,并打印出在 JAR 中引用的第三方类的完全限定名列表。

org.apache.commons
org.apache.maven
javax.servlet.jsp
org.eclipse.persistence
org.apache.jackrabbit

目的是我需要找到该 JAR 文件的 maven 依赖项,并将其部署为 maven 构件。

129312 次浏览

This might be an alternative for this tool. But it doesn't list referenced classes. The last number determines "package level".

jar tvf yourjar.jar | perl -nle'BEGIN{$depth=(shift)-1}print join(".", (split(/\//, (split)[-1]))[0..$depth])' 3

Problem is, that this way it is impossible to get referenced classes out of class definitions. So the only way possible seems to be do it in JAVA.

So the question is: Is there any Java tool that can do it ?

EDIT:

I found what I needed : M2eclipse has a feature called Class search

In the maven repositories view, right click a repository and enable full index

Then Navigate > Open type from maven - there you can look through all artifacts available based on java package convention

If yours is a maven based project

mvn dependency:build-classpath -Dmdep.pathSeparator=":" -Dmdep.prefix='' -Dmdep.fileSeparator=":" -Dmdep.outputFile=classpath

Look at the below link http://maven.apache.org/plugins/maven-dependency-plugin/build-classpath-mojo.html

May be in your case

mvn dependency:build-classpath -Dmdep.pathSeparator=":" -Dmdep.prefix='' -Dmdep.fileSeparator=":" -Dmdep.outputFile=classpath -f pathtopom.xml of third party

JarAnalyzer:

a dependency management utility for jar files. It's primary purpose is to traverse through a directory, parse each of the jar files in that directory, and identify the dependencies between the jar files. The output is an xml file representing the PhysicalDependencies between the jar files.

For more information on PhysicalDependencies, including a variety of design patterns, check out Extensible Java...

My first thought was that you could do this by using a class loader to iterate over all the class files in the jar and use reflection to analyse each one for their dependences. However the Class class does not have a method which tells you this information. So the next thought would be to use some sort of bytecode analyser (asm for example) to pull out all the referenced classes from a compile class.

Presuming that you could get this information the next issue would be to back trace the classes to jars. In a sense this would be the easy part because all you would need to do is create a classloader for each jar in your maven repo, or directory or wherever the jars are, and then ask each one in turn if it contained the specific class.

The flaw in that thinking is that a java class (raw source or compiled) does not detail where to get the imported class from. So if you have two classes with the same package and name (happens more often than you might think), then you would be unable to tell which to use.

Even java just assumes that the first one it finds in the class path is the correct one and throws an exception if it turns out to be incorrect (MethodNotFoundException). So unless you are going to further analyse the bytecode to figure out what methods on each class are called and then compare those with the classes in your class path, you still won't be able to be correct.

IN short, it's probably possible to do what you want, but likely to be very difficult and time consuming.

The way I normally deal with this is to simply fire up the class in test code and keep adding dependencies until I can get it to execute every method I'm interested in.

If you use maven (as I understood), you can simply use Maven Dependency plugin.

First you need to write a basic pom.xml with all your jars, you can copy this example (i use hibernate as example), and substitute your jars :

    <?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>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.5.0-Final</version>
</dependency>
<!-- add here other dependencies -->
</dependencies>
</project>

then open terminal, go into the containing folder of the pom.xml above and run this command :

mvn dependency:tree

this will print a list of dependencies...

or if you want download and copy in a folder all dependencies run the following command :

mvn dependency:copy-dependencies

you'll find all your dependencies in folder ./target/dependencies

Tattleltale is a tool from JBoss which does this

tattletale.jboss.org/

You can do the following (if its a maven project):

mvn dependency:tree

It shows transitive dependencies as well, making it very useful to debug dependency conflicts.

There is a new tool since JDK 8: jdeps

https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

jdeps is a new command-line tool added since JDK 8 for developers to use to understand the static dependencies of their applications and libraries. jdeps is a static analysis tool on the given class files