127

我有一个 JAR 文件,我需要获取此 JAR 文件中所有类的名称。我怎样才能做到这一点?

我在谷歌上搜索了一下,看到了一些关于 JarFile 或 Java 的东西,ClassLoader但我不知道该怎么做。

4

12 回答 12

220

您可以使用 Javajar工具。将 jar 文件的内容以 txt 文件形式列出,您可以看到 jar 中的所有类。

jar tvf jarfile.jar

-t 列出归档目录

-v 在标准输出上生成详细输出

-f 指定归档文件名

于 2013-03-30T16:39:04.593 回答
68

不幸的是,Java 没有提供一种简单的方法来列出“本机”JRE 中的类。这给您留下了两个选择: (a) 对于任何给定的 JAR 文件,您可以列出该 JAR 文件中的条目,找到这些.class文件,然后确定每个.class文件代表哪个 Java 类;或(b)您可以使用为您执行此操作的库。

选项 (a):手动扫描 JAR 文件

在此选项中,我们将填写classNames包含在 .jar 文件中的所有 Java 类的列表/path/to/jar/file.jar

List<String> classNames = new ArrayList<String>();
ZipInputStream zip = new ZipInputStream(new FileInputStream("/path/to/jar/file.jar"));
for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip.getNextEntry()) {
    if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
        // This ZipEntry represents a class. Now, what class does it represent?
        String className = entry.getName().replace('/', '.'); // including ".class"
        classNames.add(className.substring(0, className.length() - ".class".length()));
    }
}

选项 (b):使用专门的反射库

番石榴

GuavaClassPath至少从 14.0 开始就有,我一直使用并喜欢它。一件好事ClassPath是它不会加载它找到的类,这在您扫描大量类时很重要。

ClassPath cp=ClassPath.from(Thread.currentThread().getContextClassLoader());
for(ClassPath.ClassInfo info : cp.getTopLevelClassesRecurusive("my.package.name")) {
    // Do stuff with classes here...
}

思考

我没有亲自使用过 Reflections 库,但它似乎很受欢迎。网站上提供了一些很好的示例,例如这种快速加载任何JAR 文件提供的包中的所有类的方法,这也可能对您的应用程序有用。

Reflections reflections = new Reflections("my.project.prefix");

Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);

Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
于 2013-03-30T16:46:31.387 回答
21

也许您正在寻找jar命令来获取终端中的类列表,

$ jar tf ~/.m2/repository/org/apache/spark/spark-assembly/1.2.0-SNAPSHOT/spark-assembly-1.2.0-SNAPSHOT-hadoop1.0.4.jar 
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/spark/
org/apache/spark/unused/
org/apache/spark/unused/UnusedStubClass.class
META-INF/maven/
META-INF/maven/org.spark-project.spark/
META-INF/maven/org.spark-project.spark/unused/
META-INF/maven/org.spark-project.spark/unused/pom.xml
META-INF/maven/org.spark-project.spark/unused/pom.properties
META-INF/NOTICE

在哪里,

-t  list table of contents for archive
-f  specify archive file name

或者,只需在结果上方 grep 即可.class仅查看 es

$ jar tf ~/.m2/repository/org/apache/spark/spark-assembly/1.2.0-SNAPSHOT/spark-assembly-1.2.0-SNAPSHOT-hadoop1.0.4.jar | grep .class
org/apache/spark/unused/UnusedStubClass.class

要查看classes 的数量,

jar tvf launcher/target/usergrid-launcher-1.0-SNAPSHOT.jar | grep .class | wc -l
61079
于 2014-10-24T18:17:59.433 回答
12

这是我正在使用的黑客:

您可以java像这样使用 's 自动完成功能:

java -cp path_to.jar <Tab>

这将为您提供可作为起始课程通过的课程列表。当然,尝试使用没有主文件的文件不会做任何事情,但是您可以看到java认为里面的类.jar被调用了什么。

于 2016-07-22T22:02:08.203 回答
8

你可以试试:

jar tvf jarfile.jar 

仅当您的 jar 是可执行的,即在清单中您已将某个类定义为主类时,这才会有帮助

于 2014-10-08T06:10:58.247 回答
7

您可以使用

jar tf example.jar
于 2017-10-16T16:44:40.193 回答
4

下面的命令将列出jar文件的内容。

命令:- unzip -l jarfilename.jar

样品 o/p :-

Archive: hello-world.jar Length Date Time Name --------- ---------- ----- ---- 43161 10-18-2017 15:44 hello-world/com/ami/so/search/So.class 20531 10-18-2017 15:44 hello-world/com/ami/so/util/SoUtil.class --------- ------- 63692 2 files

根据说明书unzip

-l 列出归档文件(短格式)。打印指定文件的名称、未压缩文件大小和修改日期和时间,以及所有指定文件的总数。如果 UnZip 是在定义 OS2_EAS 的情况下编译的,则 -l 选项还会列出存储的 OS/2 扩展属性 (EA) 和 OS/2 访问控制列表 (ACL) 的大小列。此外,还会显示 zipfile 注释和单个文件注释(如果有)。如果文件是从单一大小写文件系统(例如,旧的 MS-DOS FAT 文件系统)归档的,并且给出了 -L 选项,则文件名将转换为小写字母并以插入符号 (^) 为前缀。

于 2017-02-21T11:05:00.663 回答
4

Mac OS:在终端上:

vim <your jar location>

after jar gets opened, press / and pass your class name and hit enter
于 2020-07-09T02:59:10.090 回答
2

你可以试试这个:

unzip -v /your/jar.jar

仅当您的 jar 是可执行的,即在清单中您已将某个类定义为主类时,这才会有帮助

于 2016-02-24T09:44:36.387 回答
2

使用这个 bash 脚本:

#!/bin/bash

for VARIABLE in *.jar
do
   jar -tf $VARIABLE |grep "\.class"|awk -v arch=$VARIABLE '{print arch ":" $4}'|sed 's/\//./g'|sed 's/\.\.//g'|sed 's/\.class//g'
done

这将以以下形式列出目录中 jar 中的类:

file1.jar:fullyqualifiedclassName
file1.jar:fullyqualifiedclassName
file1.jar:fullyqualifiedclassName
file1.jar:fullyqualifiedclassName
file2.jar:fullyqualifiedclassName
file2.jar:fullyqualifiedclassName
file2.jar:fullyqualifiedclassName

样本输出:

commons-io.jar:org.apache.commons.io.ByteOrderMark
commons-io.jar:org.apache.commons.io.Charsets
commons-io.jar:org.apache.commons.io.comparator.AbstractFileComparator
commons-io.jar:org.apache.commons.io.comparator.CompositeFileComparator
commons-io.jar:org.apache.commons.io.comparator.DefaultFileComparator
commons-io.jar:org.apache.commons.io.comparator.DirectoryFileComparator
commons-io.jar:org.apache.commons.io.comparator.ExtensionFileComparator
commons-io.jar:org.apache.commons.io.comparator.LastModifiedFileComparator

在 Windows 中,您可以使用 powershell:

Get-ChildItem -File -Filter *.jar |
ForEach-Object{
    $filename = $_.Name
    Write-Host $filename
    $classes = jar -tf $_.Name |Select-String -Pattern '.class' -CaseSensitive -SimpleMatch
    ForEach($line in $classes) {
       write-host $filename":"(($line -replace "\.class", "") -replace "/", ".")
    }
}
于 2020-06-05T23:44:02.383 回答
0

解决方案描述:Eclipse IDE 可以通过创建一个示例 java 项目并在项目构建路径中添加所有 jars 来使用

以下步骤

  1. 创建一个示例 Eclipse Java 项目。

  2. 您在其构建路径中拥有的所有 jar

  3. CTRL+SHIFT+T 并键入完整的类名。

  4. 结果将显示在窗口中,所有 jar 都具有该类。见附图。 在此处输入图像描述

于 2018-03-09T00:38:35.210 回答
0

windows cmd:如果您将所有 te jar 放在同一目录中并执行以下命令,这将起作用

for /r %i in (*) do ( jar tvf %i | find /I "search_string")
于 2019-11-20T05:48:36.837 回答