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

时间:2013-03-30 16:30:16

标签: java file class jar classloader

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

我用Google搜索并看到了有关JarFile或Java ClassLoader的内容,但我不知道该怎么做。

12 个答案:

答案 0 :(得分:155)

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

jar tvf jarfile.jar

答案 1 :(得分:62)

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

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

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

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

番石榴

Guava已经有ClassPath至少14.0,我已经使用过并喜欢过。关于ClassPath的一个好处是,它不会加载它找到的类,这对于您扫描大量类时非常重要。

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

思考

我还没有亲自使用the Reflections library,但似乎很受欢迎。网站上提供了一些很好的例子,就像在这个快速的方法中加载任何 JAR文件提供的包中的所有类一样,这对你的应用程序也很有用。

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

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

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

答案 2 :(得分:18)

也许您正在寻找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

$ 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

查看class es的数量,

jar tvf launcher/target/usergrid-launcher-1.0-SNAPSHOT.jar | grep .class | wc -l
61079

答案 3 :(得分:9)

这是我正在使用的黑客:

您可以使用java自动完成功能,如下所示:

java -cp path_to.jar <Tab>

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

答案 4 :(得分:6)

您可以使用

jar tf example.jar

答案 5 :(得分:5)

下面的命令将列出 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 list archive files(短格式)。名称,未压缩文件大小以及指定文件的修改日期和时间   打印,以及所有人的总计                 指定的文件。如果在定义了OS2_EAS的情况下编译了UnZip,则-l选项还会列出存储的OS / 2大小的列   扩展属性(EA)和OS / 2访问                 控制列表(ACL)。此外,还会显示zipfile注释和单个文件注释(如果有)。如果是文件   从单个案例文件系统归档                 (例如,旧的MS-DOS FAT文件系统)和-L选项,文件名转换为小写,是   以脱字符(^)为前缀。

答案 6 :(得分:4)

您可以尝试:

jar tvf jarfile.jar 

这只有在你的jar可执行时才有用,即在清单中你已经将某些类定义为主类

答案 7 :(得分:2)

你可以试试这个:

unzip -v /your/jar.jar

这只有在你的jar可执行时才有用,即在清单中你已经将某些类定义为主类

答案 8 :(得分: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 "/", ".")
    }
}

答案 9 :(得分:2)

Mac OS: 在终端上:

vim <your jar location>

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

答案 10 :(得分:0)

解决方案描述:Eclipse IDE可以通过创建示例java项目并在项目构建路径中添加所有jar来实现此目的

以下步骤

  1. 创建示例Eclipse Java项目。

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

  3. CTRL + SHIFT + T并输入完整的班级名称。

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

答案 11 :(得分:0)

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

,则此方法将起作用
for /r %i in (*) do ( jar tvf %i | find /I "search_string")