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.)

Kapsh
la source
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.

Andreas Dolk
la source
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 .

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

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

ipolevoy
la source
4
Recherche tout type de fichier, pas seulement les classes. Double-cliquez pour voir le contenu du fichier. Oui, maintenant je peux repérer tous mes schémas de printemps.
Chris Noe
Impressionnant. Merci;)
LppEdd
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

user311174
la source
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
Pascal Lambert
la source
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 {} \;

George Armhold
la source
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();
        }
    }

}
ILMTitan
la source
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
Kurtcebe Eroglu
la source
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.

Ramesh Rooplahl
la source
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
Filippo Lauria
la source
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.

Jeff
la source
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.

Cleonjoys
la source
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

Gungwald
la source
1

Vérifiez JBoss Tattletale ; même si je ne l'ai jamais utilisé personnellement, cela semble être l'outil dont vous avez besoin.

Wilfred Springer
la source
1

Utilisez simplement FindClassInJars, c'est un programme swing simple, mais utile. Vous pouvez vérifier le code source ou télécharger le fichier jar sur http://code.google.com/p/find-class-in-jars/

Liubing
la source
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
Mikael Lindlöf
la source
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"

Joydip Datta
la source
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/

Ben
la source
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
KrishPrabakar
la source
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
Steve B.
la source
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.

Alex
la source
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.

Dipankar Datta
la source
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é.

maccara
la source
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
Kartik Jajal
la source
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
}
kisp
la source
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.

rrevo
la source
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 .

Victor
la source
0

Vous pouvez utiliser locateet grep:

locate jar | xargs grep 'my.class'

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

mulugu mahesh
la source