JAR 파일이 있고이 JAR 파일 내의 모든 클래스 이름을 가져와야합니다. 어떻게 할 수 있습니까?
나는 그것을 봤고 JarFile 또는 Java에 대해 뭔가를 보았지만 ClassLoader
어떻게 해야할지 모르겠습니다.
JarInputStream
와 사용 가능한 솔루션을 가리 킵니다 JarEntry
.
JAR 파일이 있고이 JAR 파일 내의 모든 클래스 이름을 가져와야합니다. 어떻게 할 수 있습니까?
나는 그것을 봤고 JarFile 또는 Java에 대해 뭔가를 보았지만 ClassLoader
어떻게 해야할지 모르겠습니다.
JarInputStream
와 사용 가능한 솔루션을 가리 킵니다 JarEntry
.
답변:
불행히도 Java는 "네이티브"JRE에서 클래스를 나열하는 쉬운 방법을 제공하지 않습니다. 그러면 몇 가지 옵션이 남습니다. (a) 주어진 JAR 파일에 대해 해당 JAR 파일 내의 항목을 나열하고 파일을 찾은 .class
다음 각 .class
파일이 나타내는 Java 클래스를 결정할 수 있습니다 . 또는 (b)이 작업을 수행하는 라이브러리를 사용할 수 있습니다.
이 옵션에서는 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()));
}
}
구아바 는 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);
Java jar
도구 를 사용할 수 있습니다 . txt 파일에 jar 파일의 내용을 나열하면 jar의 모든 클래스를 볼 수 있습니다.
jar tvf jarfile.jar
-t 아카이브 목차 목록
-v 표준 출력에 대한 자세한 출력 생성
-f 아카이브 파일 이름 지정
unzip -l jarfile.jar
핀치로 도 사용할 수 있습니다 . JAR 파일은 매니페스트가있는 zip 파일입니다!
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
class
es의 수를 보려면 ,
jar tvf launcher/target/usergrid-launcher-1.0-SNAPSHOT.jar | grep .class | wc -l
61079
당신은 시도 할 수 있습니다:
jar tvf jarfile.jar
이것은 당신의 jar가 실행 가능한 경우에만 도움이 될 것입니다. 즉 매니페스트에서 당신이 어떤 클래스를 메인 클래스로 정의 했습니까?
아래 명령은 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 옵션이 제공된 경우 파일 이름은 소문자로 변환되고 캐럿 (^)이 접두어로 붙습니다.
이 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 "/", ".")
}
}
솔루션 설명 : 샘플 자바 프로젝트를 생성하고 프로젝트 빌드 경로에 모든 jar를 추가하여 Eclipse IDE를 사용할 수 있습니다.
아래 단계 :
샘플 Eclipse Java 프로젝트를 만듭니다.
빌드 경로에있는 모든 항아리
Ctrl + Shift + T를 누르고 전체 클래스 이름을 입력합니다.
결과는 해당 클래스를 가진 모든 항아리와 함께 창에 표시됩니다. 첨부 된 그림을 참조하십시오.