web-dev-qa-db-fra.com

Trouver une classe quelque part dans des dizaines de fichiers JAR?

Comment trouveriez-vous un nom de classe particulier dans de nombreux fichiers jar?

(Recherche du nom de classe réel, pas des classes qui le référencent.)

231
Kapsh

Eclipse peut le faire, il suffit de créer un projet (temporaire) et de placer vos bibliothèques sur le classpath du projet. Ensuite, vous pouvez facilement trouver les classes.

Un autre outil qui me vient à l’esprit est Java Decompiler. Il peut ouvrir plusieurs bocaux à la fois et aide également à trouver des cours.

54
Andreas_D

Unix

Utilisez les commandes jar (ou unzip -v), grep et find.

Par exemple, ce qui suit va lister tous les fichiers de classe qui correspondent à un nom donné:

for i in *.jar; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done

Si vous connaissez la liste complète des archives Java que vous souhaitez rechercher, vous pouvez toutes les placer dans le même répertoire à l'aide de liens (symboliques).

Ou utilisez find (sensible à la casse) pour trouver le fichier JAR contenant un nom de classe donné:

find path/to/libs -name '*.jar' -exec grep -Hls ClassName {} \;

Par exemple, pour trouver le nom de l’archive contenant IdentityHashingStrategy:

$ find . -name "*.jar" -exec grep -Hsli IdentityHashingStrategy {} \;
./trove-3.0.3.jar

Si le fichier JAR peut être n'importe où dans le système et que la commande locate est disponible:

for i in $(locate "*.jar");
  do echo $i; jar -tvf $i | grep -Hsi ClassName;
done

Les fenêtres

Ouvrez l'invite de commande , accédez au répertoire (ou répertoire des ancêtres) contenant les fichiers JAR, puis:

for /R %G in (*.jar) do @jar -tvf "%G" | find "ClassName" > NUL && echo %G

Voilà comment cela fonctionne:

  1. for /R %G in (*.jar) do - boucle sur tous les fichiers JAR, traversant les répertoires de manière récursive; enregistrer le nom du fichier dans% G.
  2. @jar -tvf "%G" | - exécutez la commande Java Archive pour répertorier tous les noms de fichier de l'archive donnée et écrivez les résultats dans la sortie standard; le symbole @ supprime l’impression de l’appel de la commande.
  3. find "ClassName" > NUL - recherche une entrée standard, issue de la sortie de la commande jar, pour le nom de classe donné; ERRORLEVEL sera défini sur 1 ssi il y a une correspondance (sinon 0).
  4. && echo %G - si et seulement si ERRORLEVEL est différent de zéro, écrivez le nom du fichier d'archive Java sur la sortie standard (la console).

Web

Utilisez un moteur de recherche qui analyse les fichiers JAR .

374
Dave Jarvis

il y a quelque temps, j'ai écrit un programme juste pour ça: https://github.com/javalite/jar-Explorer

58
ipolevoy
grep -l "classname" *.jar

vous donne le nom du pot

find . -name "*.jar" -exec jar -t -f {} \; | grep  "classname"

te donne le paquet de la classe

23
user311174
#!/bin/bash

pattern=$1
shift

for jar in $(find $* -type f -name "*.jar")
do
  match=`jar -tvf $jar | grep $pattern`
  if [ ! -z "$match" ]
  then
    echo "Found in: $jar"
    echo "$match"
  fi
done
11
Pascal Lambert

Je ne connaissais aucun utilitaire pour le résoudre lorsque je suis tombé sur ce problème. J'ai donc écrit ce qui suit:

public class Main {

    /**
     * 
     */
    private static String CLASS_FILE_TO_FIND =
            "class.to.find.Here";
    private static List<String> foundIn = new LinkedList<String>();

    /**
     * @param args the first argument is the path of the file to search in. The second may be the
     *        class file to find.
     */
    public static void main(String[] args) {
        if (!CLASS_FILE_TO_FIND.endsWith(".class")) {
            CLASS_FILE_TO_FIND = CLASS_FILE_TO_FIND.replace('.', '/') + ".class";
        }
        File start = new File(args[0]);
        if (args.length > 1) {
            CLASS_FILE_TO_FIND = args[1];
        }
        search(start);
        System.out.println("------RESULTS------");
        for (String s : foundIn) {
            System.out.println(s);
        }
    }

    private static void search(File start) {
        try {
            final FileFilter filter = new FileFilter() {

                public boolean accept(File pathname) {
                    return pathname.getName().endsWith(".jar") || pathname.isDirectory();
                }
            };
            for (File f : start.listFiles(filter)) {
                if (f.isDirectory()) {
                    search(f);
                } else {
                    searchJar(f);
                }
            }
        } catch (Exception e) {
            System.err.println("Error at: " + start.getPath() + " " + e.getMessage());
        }
    }

    private static void searchJar(File f) {
        try {
            System.out.println("Searching: " + f.getPath());
            JarFile jar = new JarFile(f);
            ZipEntry e = jar.getEntry(CLASS_FILE_TO_FIND);
            if (e == null) {
                e = jar.getJarEntry(CLASS_FILE_TO_FIND);
                if (e != null) {
                    foundIn.add(f.getPath());
                }
            } else {
                foundIn.add(f.getPath());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
7
ILMTitan

Pour localiser les bocaux correspondant à une chaîne donnée:

find . -name \*.jar -exec grep -l YOUR_CLASSNAME {} \;

7
George Armhold

Il existe également deux utilitaires différents appelés "JarScan" qui remplissent exactement ce que vous demandez: JarScan (inetfeedback.com) et JarScan (Java.net)

5
salzo

Je l'ai toujours utilisé sous Windows et cela a fonctionné exceptionnellement bien.

findstr /s /m /c:"package/classname" *.jar, where

findstr.exe est livré en standard avec Windows et les paramètres:

  • / s = récursivement
  • / m = affiche uniquement le nom du fichier s'il y a correspondance
  • / c = chaîne littérale (dans ce cas, le nom de votre package + les noms de classe séparés par un '/')

J'espère que ça aide quelqu'un.

3
Ramesh Rooplahl

le script de user1207523 me convient parfaitement. Voici une variante qui recherche les fichiers jar de manière récurrente en utilisant find au lieu de développement simple;

#!/bin/bash
for i in `find . -name '*.jar'`; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
3
Kurtcebe Eroglu

J'ai trouvé cette nouvelle façon

bash $ ls -1  | xargs -i -t jar -tvf '{}'| grep Abstract
jar -tvf activation-1.1.jar
jar -tvf antisamy-1.4.3.jar
  2263 Thu Jan 13 21:38:10 IST 2011 org/owasp/validator/html/scan/AbstractAntiSamyScanner.class
...

Donc, ceci liste le jar et la classe si trouvé, si vous voulez, vous pouvez donner ls -1 * .jar ou une entrée à xargs avec la commande find HTH Someone.

2
Cleonjoys

Une solution bash script utilisant unzip (zipinfo). Testé sur Ubuntu 12.

#!/bin/bash

# ./jarwalker.sh "/a/Starting/Path" "aClassName"

IFS=$'\n'
jars=( $( find -P "$1" -type f -name "*.jar" ) )

for jar in ${jars[*]}
    do
        classes=( $( zipinfo -1 ${jar} | awk -F '/' '{print $NF}' | grep .class | awk -F '.' '{print $1}' ) )
        if [ ${#classes[*]} -ge 0 ]; then
            for class in ${classes[*]}
                do
                    if [ ${class} == "$2" ]; then
                        echo "Found in ${jar}"
                    fi
                done
        fi
    done
2
Filippo Lauria

Je ne sais pas pourquoi les scripts ici n'ont jamais vraiment fonctionné pour moi. Cela marche:

#!/bin/bash
for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
1
Mikael Lindlöf

Il suffit d’utiliser FindClassInJars util, c’est un programme simple, mais utile. Vous pouvez vérifier le code source ou télécharger le fichier jar à l’adresse http://code.google.com/p/find-class-in-jars/

1
Liubing

Vérifiez JBoss Tattletale ; Bien que je ne l'ait jamais utilisé personnellement, cela semble être l'outil dont vous avez besoin.

1
Wilfred Springer

Pour rechercher une classe particulière dans tous les fichiers jar d'un répertoire donné, vous pouvez procéder comme suit:

ls *.jar | xargs grep -F MyClass

ou, encore plus simple,

grep -F MyClass *.jar

La sortie ressemble à ceci:

Binary file foo.jar matches

C'est très rapide car l'option -F signifie rechercher la chaîne Fixed, de sorte qu'elle ne charge pas le moteur d'expression régulière pour chaque invocation de grep. Si vous en avez besoin, vous pouvez toujours omettre l’option -F et utiliser des expressions rationnelles.

1
Jeff

Pour ajouter encore un autre outil ... c'est un outil très simple et utile pour Windows. Un simple fichier exe sur lequel vous cliquez, donnez-lui un répertoire dans lequel chercher, un nom de classe et il trouvera le fichier jar contenant cette classe. Oui, c'est récursif.

http://sourceforge.net/projects/jarfinder/

1
Ben

Script pour trouver le fichier jar: find_jar.sh

IFS=$(echo -en "\n\b") # Set the field separator newline

for f in `find ${1} -iname *.jar`; do
  jar -tf ${f}| grep --color $2
  if [ $? == 0 ]; then
    echo -n "Match found: "
    echo -e "${f}\n"
  fi
done
unset IFS

Utilisation: ./find_jar.sh <répertoire de niveau supérieur contenant les fichiers JAR> <Nom de la classe à rechercher>

Ceci est similaire à la plupart des réponses données ici. Mais il ne sort que le nom du fichier, si grep trouve quelque chose. Si vous souhaitez supprimer la sortie de grep, vous pouvez le rediriger vers/dev/null, mais je préfère également voir la sortie de grep afin de pouvoir utiliser des noms de classe partiels et trouver le bon dans une liste de sortie affichée.

Le nom de la classe peut être à la fois un nom de classe simple, comme "String" ou un nom complet, tel que "Java.lang.String".

1
Joydip Datta

auto-promotion éhontée, mais vous pouvez essayer un utilitaire que j'ai écrit: http://sourceforge.net/projects/zfind

Il supporte les fichiers d'archive/compressés les plus courants (jar, Zip, tar, tar.gz, etc.) et contrairement à de nombreux autres détecteurs de jar/Zip, prend en charge les fichiers Zip imbriqués (Zip dans Zip, jar dans le bocal, etc.) jusqu'à une profondeur illimitée.

0
Dipankar Datta

Pour rechercher une classe dans un groupe de dossiers (et de sous-dossiers) de fichiers JAR: https://jarscan.com/

Usage: Java -jar jarscan.jar [-help | /?]
                    [-dir directory name]
                    [-Zip]
                    [-showProgress]
                    <-files | -class | -package>
                    <search string 1> [search string 2]
                    [search string n]

Help:
  -help or /?           Displays this message.

  -dir                  The directory to start searching
                        from default is "."

  -Zip                  Also search Zip files

  -showProgress         Show a running count of files read in

  -files or -class      Search for a file or Java class
                        contained in some library.
                        i.e. HttpServlet

  -package              Search for a Java package
                        contained in some library.
                        i.e. javax.servlet.http

  search string         The file or package to
                        search for.
                        i.e. see examples above

Exemple:

Java -jar jarscan.jar -dir C:\Folder\To\Search -showProgress -class GenericServlet
0
KrishPrabakar

Le script suivant vous aidera

for file in *.jar
do
  # do something on "$file"
  echo "$file"
  /usr/local/jdk/bin/jar -tvf "$file" | grep '$CLASSNAME'
done
0
Kartik Jajal

Vous pouvez trouver une classe dans un répertoire plein de jars avec un peu de Shell:

Vous recherchez la classe "FooBar":

LIB_DIR=/some/dir/full/of/jarfiles
for jarfile in $(find $LIBDIR -name "*.jar"); do
   echo "--------$jarfile---------------"
   jar -tvf $jarfile | grep FooBar
done
0
Steve B.

Vérifiez ce plugin pour Eclipse qui peut faire le travail que vous recherchez.

https://marketplace.Eclipse.org/content/jarchiveexplorer

0
kutty

Dans un environnement Linux, vous pouvez effectuer les opérations suivantes:

$ find <base_dir> -name *.jar -print0 | xargs -0 -l jar tf | grep <name>

name est le nom du fichier de classe que vous recherchez dans les fichiers JAR répartis dans la hiérarchie des répertoires situés à l'emplacement racine. base_dir .

0
Victor

Si vous avez une instance de la classe, ou pouvez en obtenir une, vous avez une solution pure Java:

try{
    Class clazz = Class.forName("        try{
        Class clazz = Class.forName("class-name");
        String name = "/"+clazz.getName().replace('.', '/')+".class";
        URL url = clazz.getResource(name);
        String jar = url.toString().substring(10).replaceAll("!.*", "");
        System.out.println( jar );
    }catch(Exception err){
        err.printStackTrace();
    }

Bien sûr, les deux premières lignes doivent être adaptées en fonction de l'endroit où vous avez une instance de la classe ou du nom de la classe.

0
AlainD

Celui-ci fonctionne bien dans MinGW (environnement Windows bash) ~ gitbash

Mettez cette fonction dans votre fichier .bashrc dans votre répertoire HOME:

# this function helps you to find a jar file for the class
function find_jar_of_class() {
  OLD_IFS=$IFS
  IFS=$'\n'
  jars=( $( find -type f -name "*.jar" ) )
  for i in ${jars[*]} ; do 
    if [ ! -z "$(jar -tvf "$i" | grep -Hsi $1)" ] ; then
      echo "$i"
    fi
   done 
  IFS=$OLD_IFS
}
0
kisp

Une chose à ajouter à tout ce qui précède: si vous n'avez pas l'exécutable jar disponible (il est livré avec le JDK mais pas avec le JRE), vous pouvez utiliser unzip (ou WinZip, ou autre) pour accomplir la même chose.

0
Alex

Nom de fichier: searchForFiles.py

import os, zipfile, glob, sys

def main():
    searchFile = sys.argv[1] #class file to search for, sent from batch file below (optional, see second block of code below)
    listOfFilesInJar = []
    for file in glob.glob("*.jar"):
        archive = zipfile.ZipFile(file, 'r')
        for x in archive.namelist():
            if str(searchFile) in str(x):
                listOfFilesInJar.append(file)

    for something in listOfFilesInJar:
        print("location of "+str(searchFile)+": ",something)

if __== "__main__":
    sys.exit(main())

Vous pouvez facilement exécuter cela en créant un fichier .bat avec le texte suivant (remplacez "AddWorkflows.class" par le fichier que vous recherchez):

(Fichier: CallSearchForFiles.bat)

@echo off
python -B -c "import searchForFiles;x=searchForFiles.main();" AddWorkflows.class
pause

Vous pouvez double-cliquer sur CallSearchForFiles.bat pour l'exécuter ou l'appeler à partir de la ligne de commande "CallSearchForFiles.bat SearchFile.class".

Cliquez pour voir un exemple de sortie

0
Collin Fox

Vous pouvez utiliser locate et grep:

locate jar | xargs grep 'my.class'

Assurez-vous d’exécuter updatedb avant d’utiliser locate.

0
mulugu mahesh

Dans Eclipse, vous pouvez utiliser l’ancien mais toujours utilisable plugin jarsearch

0
keiki

Grepj est un utilitaire de ligne de commande permettant de rechercher des classes dans des fichiers jar. Je suis l'auteur de l'utilitaire.

Vous pouvez exécuter l'utilitaire comme grepj package.Class my1.jar my2.war my3.ear

Plusieurs fichiers jar, ear, war peuvent être fournis. Pour une utilisation avancée, utilisez find pour fournir une liste des pots à rechercher.

0
rrevo

Utilisez ceci .. vous pouvez trouver n'importe quel fichier dans classpath .. garanti ..

import Java.net.URL;
import Java.net.URLClassLoader;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipInputStream;

public class FileFinder {

    public static void main(String[] args) throws Exception {

        String file = <your file name>;

        ClassLoader cl = ClassLoader.getSystemClassLoader();

        URL[] urls = ((URLClassLoader)cl).getURLs();

        for(URL url: urls){
            listFiles(file, url);
        }
    }

    private static void listFiles(String file, URL url) throws Exception{
        ZipInputStream Zip = new ZipInputStream(url.openStream());
          while(true) {
            ZipEntry e = Zip.getNextEntry();
            if (e == null)
              break;
            String name = e.getName();
            if (name.endsWith(file)) {
                System.out.println(url.toString() + " -> " + name);
            }
          }
    }

}
0
Apurva Singh

Un peu tard pour la fête, mais quand même ...

J'ai utilisé JarBrowser pour trouver dans quel jar une classe particulière est présente. Il possède une interface graphique facile à utiliser qui vous permet de parcourir le contenu de tous les fichiers jars du chemin sélectionné.

0
maccaroo