Vous trouvez une classe quelque part dans des dizaines de fichiers JAR?


249

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

(Vous recherchez le nom de classe réel, pas les classes qui le référencent.)


1
Je ne connais aucune de ces réponses, mais ce qui fonctionne pour moi si vous voyez la classe utilisée dans un projet de travail avec de nombreux fichiers JAR est de placer votre curseur sur le nom de la classe, de faire un clic droit dessus et de cliquer sur Ouvrir la déclaration ( F3); il doit alors répertorier le fichier JAR en haut du nouvel onglet.
Andrew

Réponses:


59

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

Un autre outil qui me vient à l'esprit est Java Decompiler. Il peut ouvrir de nombreux bocaux à la fois et permet également de trouver des cours.


22
et avec l'aide de Ctrl + Shift + T
KrishPrabakar

408

Unix

Sous Linux, d'autres variantes Unix, Git Bash sous Windows ou Cygwin, utilisent les commandes jar(ou unzip -v) grep, et find.

La liste suivante répertorie tous les fichiers de classe correspondant à 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 les placer toutes dans le même répertoire à l'aide de liens (symboliques).

Ou utilisez find(en respectant la casse) pour trouver le fichier JAR qui contient 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 se trouver n'importe où dans le système et que la locatecommande est disponible:

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

Une variation de syntaxe:

find path/to/libs -name '*.jar' -print | \
  while read i; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done 

les fenêtres

Ouvrez une invite de commande , accédez au répertoire (ou répertoire ancêtre) contenant les fichiers JAR, puis:

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

Voici comment ça fonctionne:

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

la toile

Utilisez un moteur de recherche qui analyse les fichiers JAR .


3
Oui -l vous donnera cela, mais pas très utile quand il obtient son entrée de stdin.
George Armhold


27
grep -l "classname" *.jar

vous donne le nom du pot

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

vous donne le package de la classe


5
Ce devrait être grep -lir "classname" * .jar
Leonard Saers

12
#!/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

Génial ! Je devais l'utiliser sur un système qui n'avait pas de pot (pas dans le chemin, c'est-à-dire), donc je l'ai remplacé jar -tvfpar unzip -l.
ixe013

9

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

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


Cela trouve également des références à la classe, pas seulement à la classe elle-même.
Trevor Robinson

8

Je ne connaissais pas d'utilitaire pour le faire lorsque j'ai rencontré 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();
        }
    }

}


4

Le script de user1207523 fonctionne bien pour moi. Voici une variante qui recherche les fichiers jar de manière récursive en utilisant find au lieu d'une simple expansion;

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

4

J'ai toujours utilisé cela sur Windows et cela a exceptionnellement bien fonctionné.

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 en cas de correspondance
  • / c = chaîne littérale (dans ce cas, votre nom de package + noms de classe séparés par '/')

J'espère que cela aide quelqu'un.


3

Une bash scriptsolution 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

ce script n'est pas compatible avec
mingw

2

Pour rechercher tous les fichiers jar dans un répertoire donné pour une classe particulière, vous pouvez faire ceci:

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 une chaîne fixe, donc elle ne charge pas le moteur d'expression régulière pour chaque appel grep. Si vous en avez besoin, vous pouvez toujours omettre l'option -F et utiliser des expressions régulières.


2

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, cela répertorie le pot et la classe s'il est trouvé, si vous le souhaitez, vous pouvez donner ls -1 * .jar ou saisir xargs avec la commande find HTH Someone.


Merci, je l'améliore de cette façon: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Résumé
Jérôme B

2

ClassFinder est un programme conçu pour résoudre ce problème. Il vous permet de rechercher récursivement dans les répertoires et les fichiers JAR pour trouver toutes les instances d'une classe correspondant à un modèle. Il est écrit en Java, pas en python. Il a une belle interface graphique qui le rend facile à utiliser. Et ça tourne vite. Cette version est précompilée dans un pot exécutable afin que vous n'ayez pas à la construire à partir des sources.

Téléchargez-le ici: ClassFinder 1.0




1

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

Script pour rechercher 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 classe à rechercher>

Ceci est similaire à la plupart des réponses données ici. Mais il ne produit 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 celui correct à partir d'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 comme "java.lang.String"


1

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 de recherche, un nom de classe et il trouvera le fichier jar qui contient cette classe. Oui, c'est récursif.

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


1

Pour rechercher une classe dans un dossier (et des 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

Vous pouvez trouver une classe dans un répertoire plein de pots avec un peu de shell:

Vous cherchez 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

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

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

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


0

Un peu tard pour la fête, mais néanmoins ...

J'ai utilisé JarBrowser pour trouver dans quel pot 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 pots du chemin sélectionné.


0

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

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

Grepj est un utilitaire de ligne de commande pour 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 de bocal, d'oreille et de guerre peuvent être fournis. Pour une utilisation avancée, utilisez find pour fournir une liste des pots à rechercher.



0

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

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

nom est le nom du fichier de classe que vous recherchez à l'intérieur des fichiers JAR répartis dans la hiérarchie des répertoires enracinés dans rép_base .


0

Vous pouvez utiliser locateet grep:

locate jar | xargs grep 'my.class'

Assurez-vous de courir updatedbavant de l'utiliser locate.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.