如何获取 jar 文件中类的名称?

我有一个 JAR 文件,我需要得到这个 JAR 文件中所有类的名称。我该怎么做?

我谷歌了一下,看到了一些关于 JarFile 或 JavaClassLoader的东西,但是我不知道怎么做。

174318 次浏览

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

jar tvf jarfile.jar

- t 存档目录表

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

- f 指定存档文件名

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

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

在这个选项中,我们将使用包含在位于 /path/to/jar/file.jar的 jar 文件中的所有 Java 类的列表填充 classNames

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) : 使用专门的反射库

番石榴

番石榴至少从14.0开始就有 ClassPath了,我用过也很喜欢。ClassPath的一个优点是它不会加载它找到的类,这在扫描大量类时很重要。

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

反光

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

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


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


Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);

你可以试试:

jar tvf jarfile.jar

这只有在 jar 是可执行的时候才有用,也就是说,在清单中,您已经将某个类定义为主类

也许您正在寻找 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 操作就可以看到 .classes 了

$ 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

你可以试试这个:

unzip -v /your/jar.jar

这只有在 jar 是可执行的时候才有用,也就是说,在清单中,您已经将某个类定义为主类

这是我正在使用的黑客技术:

你可以像这样使用 java的自动补全:

java -cp path_to.jar <Tab>

这将为您提供一个可以作为起始类传递的类列表。当然,尝试使用一个没有主文件的文件不会做任何事情,但是您可以看到 java认为 .jar中的类被调用。

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

命令:-unzip -l jarfilename.jar

样品:-

存档: hello-world. jar 长度日期时间名称 --------- ---------- ----- ---- 4316110-18-201715:44 hello-world/com/ami/so/search/So.class 2053110-18-201715:44 hello-world/com/ami/so/util/SoUtil.class --------- ------- 636922个文件

根据 unzip手册

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

你可以使用

jar tf example.jar

Description OF Solution : Eclipse IDE 可以通过创建一个示例 Java 项目并在 Project Build 路径中添加所有 jar 来实现这一点

下面的步骤 :

  1. 创建一个样例 EclipseJava 项目。

  2. 构建路径中的所有 jar

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

  4. 结果将显示在窗口与所有的罐子有该类。见所附图片。 enter image description here

视窗 cmd: 如果将所有 tejar 放在同一个目录中并执行下面的命令,那么这种方法就可以工作

for /r %i in (*) do ( jar tvf %i | find /I "search_string")

使用 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

在窗口中你可以使用 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 "/", ".")
}
}

Mac OS: 终点站:

vim <your jar location>


after jar gets opened, press / and pass your class name and hit enter