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.)
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.)
Antworten:
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.
Unter Linux verwenden andere Unix-Varianten, Git Bash unter Windows oder Cygwin die Befehle jar
(oder unzip -v
) grep
und 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 locate
Befehl 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
Ö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:
for /R %G in (*.jar) do
- Schleife über alle JAR-Dateien und rekursives Durchlaufen von Verzeichnissen; Speichern Sie den Dateinamen in %G
.@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.find "ClassName" > NUL
- Durchsuchen Sie die Standardeingabe, die von der Ausgabe des Befehls jar geleitet wird, nach dem angegebenen Klassennamen. Dies wird ERRORLEVEL
auf 1 gesetzt , wenn eine Übereinstimmung vorliegt (andernfalls 0).&& echo %G
- Wenn ERRORLEVEL
ungleich Null ist, schreiben Sie den Namen der Java-Archivdatei in die Standardausgabe (die Konsole).Verwenden Sie eine Suchmaschine , die JAR-Dateien scannt .
Vor einiger Zeit habe ich ein Programm dafür geschrieben: https://github.com/javalite/jar-explorer
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
#!/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
jar -tvf
mit unzip -l
.
So suchen Sie Gläser, die einer bestimmten Zeichenfolge entsprechen:
find . -name \*.jar -exec grep -l YOUR_CLASSNAME {} \;
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();
}
}
}
Es gibt auch zwei verschiedene Dienstprogramme namens "JarScan", die genau das tun, wonach Sie fragen: JarScan (inetfeedback.com) und JarScan (java.net)
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
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:
Hoffe das hilft jemandem.
Eine bash script
Lö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
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.
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.
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
Überprüfen Sie JBoss Tattletale ; Obwohl ich es nie persönlich benutzt habe, scheint dies das Werkzeug zu sein, das Sie brauchen.
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.
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
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.
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.
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
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.
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.
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
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
}
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.
Überprüfen Sie dieses Plugin auf Eclipse, das die Arbeit erledigen kann, die Sie suchen.
Sie können verwenden locate
und grep
:
locate jar | xargs grep 'my.class'
Stellen Sie sicher, dass Sie updatedb
vor der Verwendung ausführen locate
.