jar 파일 내에서 클래스 이름을 얻는 방법은 무엇입니까?


112

JAR 파일이 있고이 JAR 파일 내의 모든 클래스 이름을 가져와야합니다. 어떻게 할 수 있습니까?

나는 그것을 봤고 JarFile 또는 Java에 대해 뭔가를 보았지만 ClassLoader어떻게 해야할지 모르겠습니다.


IDE를 사용하고 있습니까? IDE를 사용하는 경우 자동으로 표시되므로
joey rohan 2013 년

Eclipse를 사용하고 있지만 코드로이 작업을 수행해야합니다.
sticksu 2013 년

@LuiggiMendoza-잠재적 중복 항목에는 문서에 대한 리소스와 예제가 포함 된 답변이 있습니다. 이러한 클래스 이름 + 예제 중 하나를 검색하면 몇 가지 유용한 결과가 생성됩니다.
Aiias

@Alias ​​가능한 중복은 항아리에서 파일을 찾고 가져 오는 방법을 나타내며 질문은 항아리 내부의 클래스 이름을 가져 오는 것에 관한 것입니다 (아마도 내부의 모든 패키지에있는 클래스). ErikKaju의 답변에있는 링크는 추천 링크의 어떤 답변에서도 찾을 수없는 클래스 JarInputStream와 사용 가능한 솔루션을 가리 킵니다 JarEntry.
Luiggi Mendoza 2013 년

답변:


68

불행히도 Java는 "네이티브"JRE에서 클래스를 나열하는 쉬운 방법을 제공하지 않습니다. 그러면 몇 가지 옵션이 남습니다. (a) 주어진 JAR 파일에 대해 해당 JAR 파일 내의 항목을 나열하고 파일을 찾은 .class다음 각 .class파일이 나타내는 Java 클래스를 결정할 수 있습니다 . 또는 (b)이 작업을 수행하는 라이브러리를 사용할 수 있습니다.

옵션 (a) : 수동으로 JAR 파일 스캔

이 옵션에서는 classNamesjar 파일에 포함 된 모든 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 이후로 사용하고 좋아했습니다. 한 가지 좋은 점은 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에서 실행되는 경우에도 리플렉션이 작동하지 않습니다.
Luke

실행 가능한 jar에서 작동하는 Spring 솔루션 : stackoverflow.com/a/21430849/4265610 .
Luke

1
그냥 사용하십시오. jar tvf jarfile.jar. 왜이 모든 일을하는 거죠?
Philip Rego

184

Java jar도구 를 사용할 수 있습니다 . txt 파일에 jar 파일의 내용을 나열하면 jar의 모든 클래스를 볼 수 있습니다.

jar tvf jarfile.jar

-t 아카이브 목차 목록

-v 표준 출력에 대한 자세한 출력 생성

-f 아카이브 파일 이름 지정


1
감사. 이것은 요청되지 않은 OP의 "just get a class Listing"부분에 대한 답변입니다.
octopusgrabbus

9
unzip -l jarfile.jar핀치로 도 사용할 수 있습니다 . JAR 파일은 매니페스트가있는 zip 파일입니다!
sigpwned

3
문제는 클래스 로더 인스턴스가 주어 졌을 때 런타임에 jar에 클래스 파일을 가져오고 싶었을 가능성이 있다는 것입니다 (특정 jar 내부에 어떤 클래스가로드되는지 확인할 가능성이 있음).
리처드 Duerr

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

또는 결과 위의 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

2
이것은 질문 소유자가 코드 기반 솔루션을 필요로하더라도 정확히 제가 필요로하는 것입니다. 감사!
Providencemac 2014

10

이것은 내가 사용하는 해킹입니다.

다음 java과 같이의 자동 완성을 사용할 수 있습니다 .

java -cp path_to.jar <Tab>

그러면 시작 클래스로 통과 할 수있는 클래스 목록이 제공됩니다. 물론 주 파일이없는 파일을 사용하려고하면 아무 작업도 수행되지 않지만 java내부의 클래스 .jar가 호출 되었다고 생각하는 것을 볼 수 있습니다 .



5

당신은 시도 할 수 있습니다:

jar tvf jarfile.jar 

이것은 당신의 jar가 실행 가능한 경우에만 도움이 될 것입니다. 즉 매니페스트에서 당신이 어떤 클래스를 메인 클래스로 정의 했습니까?


답변에 예제 jar에 대한 특정 예제를 추가하십시오.
Juru 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

솔루션 설명 : 샘플 자바 프로젝트를 생성하고 프로젝트 빌드 경로에 모든 jar를 추가하여 Eclipse IDE를 사용할 수 있습니다.

아래 단계 :

  1. 샘플 Eclipse Java 프로젝트를 만듭니다.

  2. 빌드 경로에있는 모든 항아리

  3. Ctrl + Shift + T를 누르고 전체 클래스 이름을 입력합니다.

  4. 결과는 해당 클래스를 가진 모든 항아리와 함께 창에 표시됩니다. 첨부 된 그림을 참조하십시오. 여기에 이미지 설명 입력


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.