Finden Sie irgendwo in Dutzenden von JAR-Dateien eine Klasse?

249

Wie würden Sie einen bestimmten Klassennamen in vielen JAR-Dateien finden?

(Suchen Sie nach dem tatsächlichen Klassennamen, nicht nach den Klassen, die darauf verweisen.)

Kapsh
quelle
1
Ich kenne keine dieser Antworten, aber was für mich funktioniert, wenn Sie die in einem Arbeitsprojekt mit zahlreichen JAR-Dateien verwendete Klasse sehen, ist, den Cursor auf den Klassennamen zu setzen, mit der rechten Maustaste darauf zu klicken und auf Deklaration öffnen zu klicken ( F3); Dann sollte die JAR-Datei oben auf der neuen Registerkarte aufgelistet werden.
Andrew

Antworten:

59

Eclipse kann dies tun, indem Sie einfach ein (temporäres) Projekt erstellen und Ihre Bibliotheken in den Klassenpfad des Projekts einfügen. Dann können Sie die Klassen leicht finden.

Ein weiteres Tool, das mir in den Sinn kommt, ist Java Decompiler. Es kann viele Gläser gleichzeitig öffnen und hilft auch, Klassen zu finden.

Andreas Dolk
quelle
22
und mit Hilfe von Strg + Umschalt + T
KrishPrabakar
408

Unix

Unter Linux verwenden andere Unix-Varianten, Git Bash unter Windows oder Cygwin die Befehle jar(oder unzip -v) grepund find.

Im Folgenden werden alle Klassendateien aufgelistet, die einem bestimmten Namen entsprechen:

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

Wenn Sie die gesamte Liste der Java-Archive kennen, die Sie durchsuchen möchten, können Sie sie alle mithilfe (symbolischer) Links im selben Verzeichnis ablegen.

Oder verwenden Sie find(Groß- und Kleinschreibung beachten), um die JAR-Datei zu finden, die einen bestimmten Klassennamen enthält:

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

So finden Sie beispielsweise den Namen des Archivs, das Folgendes enthält IdentityHashingStrategy:

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

Wenn sich die JAR an einer beliebigen Stelle im System befinden könnte und der locateBefehl verfügbar ist:

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

Eine Syntaxvariante:

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

Windows

Öffnen Sie eine Eingabeaufforderung , wechseln Sie in das Verzeichnis (oder Vorgängerverzeichnis), das die JAR-Dateien enthält, und gehen Sie dann wie folgt vor:

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

So funktioniert das:

  1. for /R %G in (*.jar) do- Schleife über alle JAR-Dateien und rekursives Durchlaufen von Verzeichnissen; Speichern Sie den Dateinamen in %G.
  2. @jar -tvf "%G" |- Führen Sie den Befehl Java Archive aus, um alle Dateinamen im angegebenen Archiv aufzulisten, und schreiben Sie die Ergebnisse in die Standardausgabe. Das @Symbol unterdrückt das Drucken des Befehlsaufrufs.
  3. find "ClassName" > NUL- Durchsuchen Sie die Standardeingabe, die von der Ausgabe des Befehls jar geleitet wird, nach dem angegebenen Klassennamen. Dies wird ERRORLEVELauf 1 gesetzt , wenn eine Übereinstimmung vorliegt (andernfalls 0).
  4. && echo %G- Wenn ERRORLEVELungleich Null ist, schreiben Sie den Namen der Java-Archivdatei in die Standardausgabe (die Konsole).

Netz

Verwenden Sie eine Suchmaschine , die JAR-Dateien scannt .

Dave Jarvis
quelle
3
Ja -l wird Ihnen das geben, aber nicht sehr nützlich, wenn es seine Eingabe von stdin erhält.
George Armhold
60

Vor einiger Zeit habe ich ein Programm dafür geschrieben: https://github.com/javalite/jar-explorer

ipolevoy
quelle
4
Findet jeden Dateityp, nicht nur Klassen. Doppelklicken Sie, um den Dateiinhalt anzuzeigen. Ja, jetzt kann ich alle meine Frühlingsschemata erkennen.
Chris Noe
Genial. Danke;)
LppEdd
27
grep -l "classname" *.jar

gibt Ihnen den Namen des Glases

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

gibt Ihnen das Paket der Klasse

user311174
quelle
5
Es sollte grep -lir "Klassenname" * .jar sein
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
quelle
Toll ! Ich hatte es auf einem System zu verwenden , die nicht Glas (nicht im Weg, das ist) haben, so dass ich ersetzt jar -tvfmit unzip -l.
ixe013
9

So suchen Sie Gläser, die einer bestimmten Zeichenfolge entsprechen:

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

George Armhold
quelle
Dies findet auch Verweise auf die Klasse, nicht nur auf die Klasse selbst.
Trevor Robinson
8

Ich kannte kein Hilfsprogramm, als ich auf dieses Problem stieß, also schrieb ich Folgendes:

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
quelle
4

Das Skript von user1207523 funktioniert gut für mich. Hier ist eine Variante, die wiederholt nach JAR-Dateien sucht, indem sie find anstelle einer einfachen Erweiterung verwendet.

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

Ich habe dies immer unter Windows verwendet und es hat außergewöhnlich gut funktioniert.

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

findstr.exe wird standardmäßig mit Windows und den folgenden Parametern geliefert:

  • / s = rekursiv
  • / m = druckt nur den Dateinamen, wenn eine Übereinstimmung vorliegt
  • / c = Literalzeichenfolge (in diesem Fall Ihr Paketname + Klassennamen getrennt durch '/')

Hoffe das hilft jemandem.

Ramesh Rooplahl
quelle
3

Eine bash scriptLösung mit unzip (zipinfo). Getestet am 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
quelle
Dieses Skript ist nicht mingw-kompatibel
kisp
2

So durchsuchen Sie alle JAR-Dateien in einem bestimmten Verzeichnis nach einer bestimmten Klasse:

ls *.jar | xargs grep -F MyClass

oder noch einfacher,

grep -F MyClass *.jar

Die Ausgabe sieht folgendermaßen aus:

Binary file foo.jar matches

Es ist sehr schnell, da die Option -F die Suche nach einer festen Zeichenfolge bedeutet, sodass die Regex-Engine nicht für jeden Grep-Aufruf geladen wird. Bei Bedarf können Sie die Option -F jederzeit weglassen und reguläre Ausdrücke verwenden.

Jeff
quelle
2

Ich habe diesen neuen Weg gefunden

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

Dies listet also das JAR und die Klasse auf, wenn sie gefunden werden. Wenn Sie möchten, können Sie ls -1 * .jar geben oder xargs mit dem Befehl find HTH Someone eingeben.

Cleonjoys
quelle
Danke, ich verbessere es so: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Abstract
Jérôme B
2

ClassFinder ist ein Programm, das dieses Problem lösen soll. Sie können rekursiv in Verzeichnissen und JAR-Dateien suchen, um alle Instanzen einer Klasse zu finden, die einem Muster entsprechen. Es ist in Java geschrieben, nicht in Python. Es hat eine schöne GUI, die es einfach zu bedienen macht. Und es läuft schnell. Diese Version ist in einem ausführbaren JAR vorkompiliert, sodass Sie sie nicht aus dem Quellcode erstellen müssen.

Laden Sie es hier herunter: ClassFinder 1.0

Gungwald
quelle
1

Überprüfen Sie JBoss Tattletale ; Obwohl ich es nie persönlich benutzt habe, scheint dies das Werkzeug zu sein, das Sie brauchen.

Wilfred Springer
quelle
1

Verwenden Sie einfach FindClassInJars util, es ist ein einfaches Swing-Programm, aber nützlich. Sie können den Quellcode überprüfen oder die JAR-Datei unter http://code.google.com/p/find-class-in-jars/ herunterladen.

Liubing
quelle
1

Ich bin mir nicht sicher, warum Skripte hier für mich nie wirklich funktioniert haben. Das funktioniert:

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

Skript zum Suchen der JAR-Datei: 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

Verwendung: ./find_jar.sh <Verzeichnis der obersten Ebene mit JAR-Dateien> <Zu suchender Klassenname>

Dies ähnelt den meisten hier gegebenen Antworten. Der Dateiname wird jedoch nur ausgegeben, wenn grep etwas findet. Wenn Sie die grep-Ausgabe unterdrücken möchten, können Sie diese nach / dev / null umleiten, aber ich bevorzuge es, auch die Ausgabe von grep zu sehen, damit ich Teilklassennamen verwenden und die richtige aus einer Liste der angezeigten Ausgaben herausfinden kann.

Der Klassenname kann sowohl ein einfacher Klassenname wie "String" als auch ein vollständig qualifizierter Name wie "java.lang.String" sein.

Joydip Datta
quelle
1

Um noch ein weiteres Tool hinzuzufügen ... dies ist ein sehr einfaches und nützliches Tool für Windows. Eine einfache exe-Datei, auf die Sie klicken, geben Sie ihr ein Verzeichnis zum Suchen, einen Klassennamen und sie findet die JAR-Datei, die diese Klasse enthält. Ja, es ist rekursiv.

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

Ben
quelle
1

So finden Sie eine Klasse in einem Ordner (und in Unterordnern) mit JARs: 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

Beispiel:

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

Sie finden eine Klasse in einem Verzeichnis voller Gläser mit etwas Shell:

Auf der Suche nach Klasse "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.
quelle
0

Eine Sache, die Sie zu all dem hinzufügen sollten: Wenn Sie die ausführbare JAR-Datei nicht zur Verfügung haben (sie wird mit dem JDK, aber nicht mit der JRE geliefert), können Sie Unzip (oder WinZip oder was auch immer) verwenden, um dasselbe zu erreichen.

Alex
quelle
0

Schamlose Eigenwerbung, aber Sie können ein Dienstprogramm ausprobieren, das ich geschrieben habe: http://sourceforge.net/projects/zfind

Es unterstützt die gängigsten archivierten / komprimierten Dateien (jar, zip, tar, tar.gz usw.) und unterstützt im Gegensatz zu vielen anderen jar / zip-Findern verschachtelte zip-Dateien (zip in zip, jar in jar usw.) bis zur unbegrenzten Tiefe.

Dipankar Datta
quelle
0

Ein bisschen spät zur Party, aber trotzdem ...

Ich habe JarBrowser verwendet, um herauszufinden, in welchem ​​Glas eine bestimmte Klasse vorhanden ist. Es verfügt über eine benutzerfreundliche Benutzeroberfläche, mit der Sie den Inhalt aller Gläser im ausgewählten Pfad durchsuchen können.

Maccaroo
quelle
0

Das folgende Skript hilft Ihnen dabei

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

Dieser funktioniert gut in MinGW (Windows Bash-Umgebung) ~ Gitbash

Fügen Sie diese Funktion in Ihre .bashrc-Datei in Ihrem HOME-Verzeichnis ein:

# 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
quelle
0

Grepj ist ein Befehlszeilenprogramm zum Suchen nach Klassen in JAR-Dateien. Ich bin der Autor des Dienstprogramms.

Sie können das Dienstprogramm wie ausführen grepj package.Class my1.jar my2.war my3.ear

Es können mehrere Glas-, Ohr- und Kriegsdateien bereitgestellt werden. Für die erweiterte Verwendung verwenden Sie find, um eine Liste der zu durchsuchenden Gläser bereitzustellen.

rrevo
quelle
0

In einer Linux-Umgebung können Sie Folgendes tun:

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

Dabei ist name der Name der Klassendatei, die Sie in den Jars suchen, die über die Hierarchie der Verzeichnisse verteilt sind, die im base_dir verwurzelt sind .

Sieger
quelle
0

Sie können verwenden locateund grep:

locate jar | xargs grep 'my.class'

Stellen Sie sicher, dass Sie updatedbvor der Verwendung ausführen locate.

Mulugu Mahesh
quelle