Trova una classe da qualche parte all'interno di decine di file JAR?


249

Come troveresti un nome di classe particolare in molti file jar?

(Alla ricerca del nome della classe attuale, non delle classi che lo fanno riferimento.)


1
Non conosco nessuna di queste risposte, ma ciò che funziona per me se vedi la classe utilizzata in un progetto di lavoro con numerosi file JAR è posizionare il cursore sul nome della classe, fare clic destro su di essa e fare clic su Apri dichiarazione ( F3); quindi dovrebbe elencare il file JAR nella parte superiore della nuova scheda.
Andrew,

Risposte:


59

Eclipse può farlo, basta creare un progetto (temporaneo) e inserire le tue librerie nel percorso di classe dei progetti. Quindi puoi facilmente trovare le lezioni.

Un altro strumento, che mi viene in mente, è Java Decompiler. Può aprire molti vasetti contemporaneamente e aiuta anche a trovare lezioni.


22
e con l'aiuto di Ctrl + Maiusc + T
KrishPrabakar il

408

Unix

Su Linux, altre varianti di Unix, Git Bash su Windows o Cygwin, usano i comandi jar(o unzip -v) grepe find.

Di seguito sono elencati tutti i file di classe che corrispondono a un determinato nome:

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, è possibile inserirli tutti nella stessa directory utilizzando i collegamenti (simbolici).

Oppure usa find(maiuscole e minuscole) per trovare il file JAR che contiene un determinato nome di classe:

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 potrebbe trovarsi in qualsiasi punto del sistema e il locatecomando è disponibile:

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

Una variazione di sintassi:

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

finestre

Aprire un prompt dei comandi , passare alla directory (o alla directory antenata) 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) do- scorrere su tutti i file JAR, attraversando ricorsivamente le directory; memorizzare il nome del file in %G.
  2. @jar -tvf "%G" |- eseguire il comando Archivio Java per elencare tutti i nomi dei file all'interno dell'archivio dato e scrivere i risultati sullo standard output; il @simbolo elimina la stampa dell'invocazione del comando.
  3. find "ClassName" > NUL- cerca l'input standard, convogliato dall'output del comando jar, per il nome della classe dato; questo sarà impostato ERRORLEVELsu 1 se c'è una corrispondenza (altrimenti 0).
  4. && echo %G- iff ERRORLEVELè diverso da zero, scrivere il nome del file di archivio Java nell'output standard (la console).

ragnatela

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


3
Sì, ti darò questo, ma non molto utile quando riceve il suo input da stdin.
George Armhold,


27
grep -l "classname" *.jar

ti dà il nome del barattolo

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

ti dà il pacchetto della classe


5
Dovrebbe essere 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

Grande ! Ho dovuto usarlo su un sistema che non aveva jar (non nel percorso, cioè), quindi l'ho sostituito jar -tvfcon unzip -l.
ixe013,

9

Per individuare i barattoli che corrispondono a una determinata stringa:

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


Questo trova riferimenti anche alla classe, non solo alla classe stessa.
Trevor Robinson,

8

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

}


4

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

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

4

L'ho sempre usato su Windows e ha funzionato eccezionalmente bene.

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

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

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

Spero che questo aiuti qualcuno.


3

Una bash scriptsoluzione 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
        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

questo script non è compatibile con
mingw

2

Per cercare tutti i file jar in una determinata directory per una particolare classe, puoi fare questo:

ls *.jar | xargs grep -F MyClass

o, ancora più semplice,

grep -F MyClass *.jar

L'output è simile al seguente:

Binary file foo.jar matches

È molto veloce perché l'opzione -F significa cercare la stringa fissa, quindi non carica il motore regex per ogni chiamata grep. Se necessario, puoi sempre omettere l'opzione -F e usare regex.


2

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 classe se trovati, se vuoi puoi dare ls -1 * .jar o input a xargs con il comando find HTH Someone.


Grazie, lo migliora in questo modo: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Abstract
Jérôme B,

2

ClassFinder è un programma progettato per risolvere questo problema. Ti permette di cercare ricorsivamente tra directory e file jar per trovare tutte le istanze di una classe che corrispondono a un modello. È scritto in Java, non in pitone. Ha una bella interfaccia grafica che lo rende facile da usare. E funziona veloce. Questa versione è precompilata in un vaso eseguibile, quindi non è necessario crearla dal sorgente.

Scaricalo qui: ClassFinder 1.0




1

Non so perché gli script qui non abbiano mai funzionato davvero per me. Questo funziona:

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

1

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

Utilizzo: ./find_jar.sh <directory di livello superiore contenente file jar> <Nome classe da trovare>

Questo è simile alla maggior parte delle risposte fornite qui. Ma genera solo il nome del file, se grep trova qualcosa. Se vuoi sopprimere l'output di grep puoi reindirizzarlo a / dev / null ma preferisco vedere anche l'output di grep in modo da poter usare i nomi di classe parziali e capire quello corretto da un elenco di output mostrato.

Il nome della classe può essere sia un semplice nome di classe come "String" o un nome completo come "java.lang.String"


1

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

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


1

Per trovare una classe in un gruppo di cartelle (e sottocartelle) di 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

Esempio:

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

0

Puoi trovare una classe in una directory piena di vasetti con un po 'di shell:

Alla ricerca della 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

Una cosa da aggiungere a tutto quanto sopra: se non hai l'eseguibile jar disponibile (viene fornito con JDK ma non con JRE), puoi usare unzip (o WinZip, o qualsiasi altra cosa) per ottenere lo stesso risultato.


0

autopromozione spudorata, ma puoi provare un'utilità che ho scritto: http://sourceforge.net/projects/zfind

Supporta i file di archivio / compressi più comuni (jar, zip, tar, tar.gz ecc.) E diversamente da molti altri finder jar / zip, supporta i file zip nidificati (zip all'interno di zip, jar all'interno di jar ecc.) Fino a profondità illimitata.


0

Un po 'in ritardo alla festa, ma comunque ...

Sto usando JarBrowser per trovare in quale vaso è presente una particolare classe. Ha una GUI facile da usare che ti permette di navigare tra i contenuti di tutti i barattoli nel percorso selezionato.


0

Il seguente script ti aiuterà

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

0

Questo funziona bene in MinGW (ambiente Windows Bash) ~ gitbash

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

0

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

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

Possono essere forniti più file jar, ear, war. Per un uso avanzato, usare find per fornire un elenco di barattoli da cercare.



0

In un ambiente Linux è possibile effettuare le seguenti operazioni:

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

Dove nome è il nome del file di classe che si sta visualizzando all'interno dei barattoli distribuiti nella gerarchia delle directory radicate in base_dir .


0

Puoi usare locatee grep:

locate jar | xargs grep 'my.class'

Assicurati di correre updatedbprima dell'uso locate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.