jarファイル内のクラスの名前を取得するにはどうすればよいですか?


112

JARファイルがあり、このJARファイル内のすべてのクラスの名前を取得する必要があります。どうやってやるの?

私はそれをググって、JarFileかJavaについて何かを見ましたClassLoader、しかし、私はそれをする方法がわかりません。


IDEを使用していますか?IDEを使用している場合は自動的に表示されます。
joey rohan

私はEclipseを使用していますが、コードでこれを行う必要があります。
sticksu 2013年

@LuiggiMendoza-潜在的な重複には、例とドキュメントのリソースに関する回答があります。これらのクラス名の1つを検索すると、いくつかの有用な結果が得られます。
Aiias 2013年

@Alias可能性のある重複は、jarからファイルを見つけて取得する方法を示していますが、問題は、jar内のクラス名(おそらくその中のすべてのパッケージのクラス)を取得することです。ErikKajuの回答のリンクは、参照されたリンクの回答で私が見つけることができない、使用可能なクラスJarInputStreamJarEntryクラスを示しています。
Luiggi Mendoza 2013

回答:


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):特殊なリフレクションライブラリを使用する

グアバ

グアバClassPath、少なくとも14.0から使用しています。良い点の1つ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);

リフレクションは、実行可能なjarから実行しても機能しません。
ルーク、

実行可能なjarから機能するSpringソリューション:stackoverflow.com/a/21430849/4265610
ルーク、

1
使うだけ。jar tvf jarfile.jar。なんでそんなことをするの?
Philip Rego

183

Java jarツールを使用できます。jarファイルの内容をtxtファイルにリストすると、jar内のすべてのクラスを確認できます。

jar tvf jarfile.jar

-tアーカイブの目次をリスト

-v標準出力に詳細出力を生成します

-fアーカイブファイル名を指定


1
ありがとう。これは、尋ねられなかったOPの「クラスのリストを取得する」部分に答えます。
タコグラブバス2013年

9
ひとつまみにも使えますunzip -l jarfile.jar。JARファイルは、マニフェストを含む単なるzipファイルです。
2015年

3
問題は、クラスローダーインスタンスが指定されている場合(おそらく、特定のjar内にロードされているクラスを確認するため)、実行時にjar内にクラスファイルを取得したかったことです。
Richard Duerr 2016

19

たぶんあなたは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

または、.classesのみを表示するには、上記の結果をgrepします

$ 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

2
質問の所有者がコードベースのソリューションを必要としていたとしても、これはまさに私が必要とするものでした。ありがとう!
プロビデンスマック

10

これは私が使っているハックです:

次のjavaようなオートコンプリートを使用できます。

java -cp path_to.jar <Tab>

これにより、開始クラスとして渡すことができるクラスのリストが表示されます。もちろん、メインファイルのないものを使用しようとしても何も起こりませんが、java内部のクラス.jarが呼び出されていると考えるものを確認できます。



5

あなたが試すことができます:

jar tvf jarfile.jar 

これは、jarが実行可能な場合、つまりマニフェストでいくつかのクラスをメインクラスとして定義した場合にのみ役立ちます。


サンプルjarの具体的な例を回答に追加します。
ジュール、2014年

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オプションが指定された場合、ファイル名は小文字に変換され、先頭にキャレット(^)が付きます。


このコードスニペットは歓迎されており、多少の助けになるかもしれませんが、これが問題を解決する方法理由の説明含めると、大幅に改善されます。あなたが今尋ねている人だけでなく、将来の読者のための質問に答えていることを忘れないでください!回答を編集して説明を追加し、適用される制限と前提を示してください。
Toby Speight 2017

2

あなたはこれを試すことができます:

unzip -v /your/jar.jar

これは、jarが実行可能な場合、つまりマニフェストでいくつかのクラスをメインクラスとして定義した場合にのみ役立ちます。


1

次の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 "/", ".")
    }
}

0

ソリューションの説明:サンプルJavaプロジェクトを作成し、プロジェクトビルドパスにすべてのjarを追加することで、Eclipse IDEを使用できます。

以下の手順

  1. サンプルのEclipse Javaプロジェクトを作成します。

  2. ビルドパスにあるすべてのjar

  3. Ctrl + Shift + Tおよびクラスの完全な名前を入力します。

  4. 結果は、そのクラスを持つすべてのjarとともにウィンドウに表示されます。添付画像を参照してください。 ここに画像の説明を入力してください


0

windows cmd:これは、すべてのte jarが同じディレクトリにあり、以下のコマンドを実行する場合に機能します

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

0

Mac OS:ターミナル:

vim <your jar location>

after jar gets opened, press / and pass your class name and hit enter
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.