156 votes

Comment obtenir les noms des classes dans un fichier jar ?

J'ai un fichier JAR et j'ai besoin d'obtenir le nom de toutes les classes dans ce fichier JAR. Comment puis-je le faire ?

J'ai cherché sur Google et j'ai vu quelque chose à propos de JarFile ou de Java. ClassLoader mais je n'ai aucune idée de la façon de le faire.

0 votes

Utilisez-vous un IDE ? Il s'affichera automatiquement si vous en utilisez un.

0 votes

J'utilise Eclipse, mais j'ai besoin de faire cela avec du code.

0 votes

@LuiggiMendoza - Le duplicata potentiel a des réponses avec des exemples ainsi que des ressources pour la documentation. La recherche d'un de ces noms de classe + exemple donnera plusieurs résultats utiles.

260voto

Sanjeev Gupta Points 201

Vous pouvez utiliser Java jar outil. Lister le contenu du fichier jar dans un fichier txt et vous pouvez voir toutes les classes dans le jar.

jar tvf jarfile.jar

-t liste la table des matières des archives

-v générer une sortie verbeuse sur la sortie standard

-f spécifier le nom du fichier d'archive

5 votes

Merci. Cela répond à la partie du PO qui n'a pas été demandée, à savoir "obtenez simplement une liste des classes".

17 votes

Vous pouvez également utiliser unzip -l jarfile.jar en cas de besoin. Un fichier JAR est simplement un fichier zip avec un manifeste !

4 votes

Le problème est qu'il voulait probablement obtenir les fichiers de classe à l'intérieur d'un jar au moment de l'exécution, étant donné une instance de classloader (probablement pour voir quelles classes sont chargées dans ce jar spécifique).

81voto

sigpwned Points 2166

Malheureusement, Java ne fournit pas un moyen facile de lister les classes dans le JRE "natif". Cela vous laisse deux options : (a) pour un fichier JAR donné, vous pouvez lister les entrées à l'intérieur de ce fichier JAR, trouver le fichier .class et ensuite déterminer quelle classe Java chaque .class représente ; ou (b) vous pouvez utiliser une bibliothèque qui le fait pour vous.

Option (a) : Analyse manuelle des fichiers JAR

Dans cette option, nous allons remplir classNames avec la liste de toutes les classes Java contenues dans un fichier jar à l'adresse suivante /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()));
    }
}

Option (b) : Utilisation de bibliothèques de réflexion spécialisées

Goyave

Goyave a eu ClassPath depuis au moins 14.0, que j'ai utilisé et apprécié. Une bonne chose à propos de ClassPath est qu'il ne charge pas les classes qu'il trouve, ce qui est important lorsque vous recherchez un grand nombre de classes.

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

Réflexions

Je n'ai pas personnellement utilisé la bibliothèque Reflections mais elle semble bien appréciée. De très bons exemples sont fournis sur le site web, comme cette manière rapide de charger toutes les classes d'un paquetage fourni par tout JAR, qui peut également être utile pour votre application.

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

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

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

0 votes

Reflections ne fonctionne pas non plus s'il est exécuté à partir d'un jar exécutable.

0 votes

Une solution Spring fonctionnant à partir de jars exécutables : stackoverflow.com/a/21430849/4265610 .

5 votes

Il suffit d'utiliser. jar tvf jarfile.jar. Pourquoi faites-vous tout ça pour.

21voto

Prayag Upd Points 3347

Vous cherchez peut-être jar pour obtenir la liste des classes dans le terminal,

$ 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

où,

-t  list table of contents for archive
-f  specify archive file name

Ou, juste grep le résultat ci-dessus pour voir .class es seulement

$ 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

Pour voir le nombre de class es,

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

3 votes

C'était exactement ce dont j'avais besoin, même si le propriétaire de la question avait besoin d'une solution basée sur le code. Merci !

13voto

stanm Points 170

C'est une astuce que j'utilise :

Vous pouvez utiliser java L'autocomplétion de l'entreprise comme ceci :

java -cp path_to.jar <Tab>

Vous obtiendrez ainsi une liste de classes disponibles à passer comme classe de départ. Bien sûr, essayer d'en utiliser une qui n'a pas de fichier principal n'aura aucun effet, mais vous pouvez voir ce que la classe java pense que les classes à l'intérieur du .jar sont appelés.

8voto

Pallav Points 1

Vous pouvez essayer :

jar tvf jarfile.jar 

Cela ne sera utile que si votre jar est exécutable, c'est-à-dire que dans le manifeste vous avez défini une classe comme classe principale.

0 votes

Ajoutez à votre réponse un exemple spécifique sur un bocal d'exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X