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

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

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

210
demandé sur Vadim Kotov 2009-08-27 22:23:46

30 réponses

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

Un autre outil, qui me vient à l'esprit, est Java Decompiler. Il peut ouvrir beaucoup de pots à la fois et aide à trouver des classes aussi bien.

52
répondu Andreas_D 2009-08-27 18:32:00

Unix

Utiliser le jar (ou unzip -v), grep, et find commandes.

Par exemple, ce qui suit liste 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 les placer toutes dans le même répertoire en utilisant des liens (symboliques).

Ou utilisez find (en tenant compte de 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 POT peut être n'importe où dans le système et la locate commande est disponible:

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

Fenêtres

Ouvrez une invite de commande , passez au répertoire (ou au 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 cela fonctionne:

  1. for /R %G in (*.jar) do - parcourez tous les fichiers JAR en parcourant récursivement les répertoires; stockez le nom du fichier dans %G.
  2. @jar -tvf "%G" | - exécutez Java Commande Archive pour lister tous les noms de fichiers dans l'archive donnée et écrire les résultats dans la sortie standard; le symbole @ supprime l'impression de l'invocation de la commande.
  3. find "ClassName" > NUL - recherche d'entrée standard, canalisée à partir de la sortie de la commande jar, pour le nom de classe donné; cela définira ERRORLEVEL à 1 s'il y a une correspondance (sinon 0).
  4. && echo %G - iff ERRORLEVEL est différent de zéro, écrivez le nom du fichier d'archive Java dans la sortie standard (la console).

Web

Utilisation un moteur de recherche qui analyse les fichiers JAR .

337
répondu Dave Jarvis 2018-05-24 21:44:35

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

53
répondu ipolevoy 2015-03-19 05:27:48
grep -l "classname" *.jar

Vous donne le nom du pot

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

Vous donne le paquet de la classe

21
répondu user311174 2011-03-22 14:43:24
#!/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
répondu Pascal Lambert 2011-02-11 16:31:34

Je ne connaissais pas d'utilitaire pour le faire quand je suis tombé sur ce problème, alors j'ai é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
répondu ILMTitan 2009-08-27 18:34:35

Pour localiser les jars qui correspondent à une chaîne donnée:

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

6
répondu George Armhold 2012-04-03 01:46:54

Il y a aussi deux utilitaires différents appelés "JarScan" qui font exactement ce que vous demandez: JarScan (inetfeedback.com) et JarScan (java.net)

5
répondu salzo 2012-08-08 02:57:53

Le script de

User1207523 fonctionne très bien pour moi. Voici une variante qui recherche les fichiers JAR de manière recusive 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
3
répondu Kurtcebe Eroglu 2013-07-19 11:22:22

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 s'il y a une correspondance
  • / C = chaîne littérale (dans ce cas, votre nom de paquet + noms de classe séparé par'/')

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

3
répondu Ramesh Rooplahl 2016-10-21 14:42:28

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
répondu Filippo Lauria 2013-07-21 09:54:12

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 jar et la classe si elle est trouvée, si vous le souhaitez, vous pouvez donner ls -1 *.jar ou entrée à xargs avec la commande find HTH Quelqu'un.

2
répondu Cleonjoys 2016-07-04 12:24:31

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

1
répondu Wilfred Springer 2009-08-27 18:42:52

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

1
répondu Liubing 2011-03-31 13:36:10

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

#!/bin/bash
for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done
1
répondu Mikael Lindlöf 2013-03-04 12:38:30

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 regex pour chaque appel grep. Si vous en avez besoin, vous pouvez toujours omettre l'option-F et utiliser des expressions rationnelles.

1
répondu Jeff 2013-07-19 18:00:59

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

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

Le le nom de classe peut être à la fois un nom de classe simple comme "String" ou un nom complet comme " java.lang.Chaîne "

1
répondu Joydip Datta 2015-01-31 07:34:34

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

Http://sourceforge.net/projects/jarfinder/

1
répondu Ben 2018-04-08 16:05:58

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

Recherche de 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
répondu Steve B. 2009-08-27 18:41:21

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
répondu Alex 2009-09-14 16:53:10

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 à beaucoup d'autres trouveurs jar/zip, prend en charge les fichiers zip imbriqués (zip dans zip, jar dans jar etc) jusqu'à une profondeur illimitée.

0
répondu Dipankar Datta 2012-05-23 11:09:34

Un peu en retard à la fête, mais quand même...

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

0
répondu maccaroo 2013-02-15 00:41:20

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
répondu Kartik Jajal 2013-05-08 10:05:53

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

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

# 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
répondu kisp 2013-08-08 09:48:39

Grepj est un utilitaire de ligne de commande pour rechercher des classes dans les 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 de jars à rechercher.

0
répondu rrevo 2013-08-19 04:12:49

Vérifiez ce Plugin pour eclipse qui peut faire le travail que vous recherchez.

Https://marketplace.eclipse.org/content/jarchiveexplorer

0
répondu kutty 2014-06-06 11:26:14

Sous un environnement Linux, vous pouvez faire ce qui suit :

$ 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 distribués dans la hiérarchie des répertoires enracinés _dir de base.

0
répondu Victor 2015-04-17 16:18:43

, Vous pouvez utiliser locate et grep:

locate jar | xargs grep 'my.class'

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

0
répondu mulugu mahesh 2016-04-11 13:22:56

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

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
répondu Apurva Singh 2016-04-28 17:13:10

Dans eclipse, vous pouvez utiliser la vieille mais encore utilisable plugin jarsearch

0
répondu keiki 2016-08-22 13:27:30