Trova una class da qualche parte all’interno di dozzine di file JAR?

Come troveresti un particolare nome di class all’interno di molti file jar?

(Cercando il nome effettivo della class, non le classi che lo fanno riferimento).

Eclipse può farlo, basta creare un progetto (temporaneo) e mettere le tue librerie sul classpath dei progetti. Quindi puoi facilmente trovare le classi.

Un altro strumento, mi viene in mente, è Java Decompiler. Può aprire molti vasi contemporaneamente e aiuta a trovare anche le classi.

Unix

Usa i comandi jar (o unzip -v ), grep e find .

Ad esempio, il seguente elenco elencherà tutti i file di class che corrispondono a un nome dato:

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

Se si conosce l’intero elenco di archivi Java che si desidera cercare, è ansible inserirli tutti nella stessa directory utilizzando collegamenti (simbolici).

Oppure usa find (case sensitive) per trovare il file JAR che contiene un nome di class dato:

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

Ad esempio, per trovare il nome dell’archivio contenente IdentityHashingStrategy :

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

Se il JAR può essere ovunque nel sistema e il comando locate è disponibile:

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

windows

Aprire un prompt dei comandi , passare alla directory (o alla directory degli antenati) contenente i file JAR, quindi:

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

Ecco come funziona:

  1. for /R %G in (*.jar) dofor /R %G in (*.jar) do loop su tutti i file JAR, attraversando ricorsivamente le directory; memorizzare il nome del file in% G.
  2. @jar -tvf "%G" | – eseguire il comando Java Archive per elencare tutti i nomi di file all’interno dell’archivio specificato e scrivere i risultati sullo standard output; il simbolo @ sopprime la stampa della chiamata del comando.
  3. find "ClassName" > NUL – cerca input standard, inviato dall’output del comando jar, per il nome della class data; questo imposterà ERRORLEVEL a 1 se è presente una corrispondenza (altrimenti 0).
  4. && echo %G – iff ERRORLEVEL è diverso da zero, scrivere il nome del file di archivio Java sullo standard output (la console).

web

Utilizzare un motore di ricerca che esegue la scansione dei file JAR .

qualche tempo fa, ho scritto un programma solo per questo: https://github.com/javalite/jar-explorer

 grep -l "classname" *.jar 

ti dà il nome del barattolo

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

ti dà il pacchetto della class

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

Non sapevo di un’utilità per farlo quando mi sono imbattuto in questo problema, quindi ho scritto quanto segue:

 public class Main { /** * */ private static String CLASS_FILE_TO_FIND = "class.to.find.Here"; private static List foundIn = new LinkedList(); /** * @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(); } } } 

Per individuare i jar che corrispondono a una determinata stringa:

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

Ci sono anche due diverse utility chiamate sia “JarScan” che fanno esattamente quello che stai chiedendo: JarScan (inetfeedback.com) e JarScan (java.net)

Lo script di user1207523 funziona bene per me. Ecco una variante che cerca in modo ricusivo i file jar usando find invece di una semplice espansione;

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

L’ho sempre usato su Windows e ha funzionato molto bene.

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

findstr.exe è fornito di serie con Windows e i parametri:

  • / s = ricorsivamente
  • / m = stampa solo il nome del file se c’è una corrispondenza
  • / c = stringa letterale (in questo caso il nome del pacchetto + i nomi delle classi separati da ‘/’)

Spero che questo aiuti qualcuno.

Una soluzione di bash script che utilizza unzip (zipinfo) . Testato su 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 classs=( $( zipinfo -1 ${jar} | awk -F '/' '{print $NF}' | grep .class | awk -F '.' '{print $1}' ) ) if [ ${#classs[*]} -ge 0 ]; then for class in ${classs[*]} do if [ ${class} == "$2" ]; then echo "Found in ${jar}" fi done fi done 

Ho trovato questo nuovo modo

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

Quindi questo elenca il jar e la class se trovato, se vuoi puoi dare ls -1 * .jar o input a xargs con il comando find HTH Someone.

Controlla JBoss Tattletale ; anche se non l’ho mai usato personalmente, questo sembra essere lo strumento di cui hai bisogno.

Basta usare FindClassInJars util, è un semplice programma di swing, ma utile. Puoi controllare il codice sorgente o scaricare il file jar all’indirizzo http://code.google.com/p/find-class-in-jars/

Non sono sicuro del motivo per cui gli script qui non hanno mai veramente funzionato per me. Questo funziona:

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

Per cercare tutti i file jar in una determinata directory per una particolare class, puoi fare ciò:

 ls *.jar | xargs grep -F MyClass 

o, ancora più semplice,

 grep -F MyClass *.jar 

L’output è simile a questo:

 Binary file foo.jar matches 

È molto veloce perché l’opzione -F indica la ricerca di una stringa fissa, quindi non carica il motore regex per ogni chiamata di grep. Se è necessario, puoi sempre omettere l’opzione -F e usare espressioni regolari.

Script per trovare il file 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 

Uso: ./find_jar.sh

Questo è simile alla maggior parte delle risposte fornite qui. Ma emette solo il nome del file, se grep trova qualcosa. Se vuoi sopprimere l’output di grep puoi redirect quello a / dev / null ma preferisco vedere anche l’output di grep in modo che io possa usare nomi di classi parziali e capire quello corretto da un elenco di output mostrato.

Il nome della class può essere sia un nome di class semplice come “String” o un nome completo come “java.lang.String”

Per aggiungere ancora un altro strumento … questo è uno strumento molto semplice e utile per Windows. Un semplice file exe su cui fai clic, dargli una directory in cui cercare, un nome class e troverà il file jar che contiene quella class. Sì, è ricorsivo.

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

Puoi trovare una class in una directory piena di vasi con un po ‘di shell:

Alla ricerca di class “FooBar”:

 LIB_DIR=/some/dir/full/of/jarfiles for jarfile in $(find $LIBDIR -name "*.jar"); do echo "--------$jarfile---------------" jar -tvf $jarfile | grep FooBar done 

Una cosa da aggiungere a tutto quanto sopra: se non si dispone dell’eseguibile jar disponibile (viene fornito con JDK ma non con JRE), è ansible utilizzare unzip (o WinZip o altro) per ottenere la stessa operazione.

auto promozione spudorata, ma puoi provare un’utilità che ho scritto: http://sourceforge.net/projects/zfind

Supporta la maggior parte degli archivi comuni / file compressi (jar, zip, tar, tar.gz ecc.) E, a differenza di molti altri cercatori jar / zip, supporta i file zip annidati (zip dentro zip, jar all’interno jar ecc.) Fino alla profondità illimitata.

Un po ‘tardi per la festa, ma comunque …

Ho usato JarBrowser per trovare in quale jar è presente una particolare class. Ha una GUI facile da usare che ti permette di sfogliare i contenuti di tutti i barattoli nel percorso selezionato.

Lo script seguente ti aiuterà

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

Questo funziona bene in MinGW (windows bash environment) ~ gitbash

Inserisci questa funzione nel tuo file .bashrc nella tua cartella 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 } 

Grepj è un’utilità della riga di comando per cercare le classi all’interno dei file jar. Sono l’autore dell’utilità.

È ansible eseguire l’utilità come grepj package.Class my1.jar my2.war my3.ear

Possono essere forniti più file jar, ear, war. Per l’utilizzo avanzato, trovare find per fornire un elenco di vasi da cercare.

Controlla questo plugin per Eclipse che può fare il lavoro che stai cercando.

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

Sotto un ambiente Linux puoi fare quanto segue:

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

Dove nome è il nome del file di class che si sta guardando all’interno dei vasi distribuiti attraverso la gerarchia delle directory rootate su base_dir .

Puoi usare locate e grep :

 locate jar | xargs grep 'my.class' 

Assicurati di eseguire updatedb prima di utilizzare locate .

Usa questo .. puoi trovare qualsiasi file in classpath .. garantito ..

 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 = ; 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); } } } } 

In eclipse puoi usare il vecchio ma ancora utilizzabile plugin jarsearch