Znajdź klasę gdzieś w dziesiątkach plików JAR?

249

Jak znaleźć konkretną nazwę klasy w wielu plikach jar?

(Szukanie rzeczywistej nazwy klasy, a nie klas, które się do niej odwołują).

Kapsh
źródło
1
Nie znam żadnej z tych odpowiedzi, ale to, co działa dla mnie, jeśli zobaczysz klasę używaną w działającym projekcie z wieloma plikami JAR, to nałożenie kursora na nazwę klasy, kliknięcie prawym przyciskiem myszy i kliknięcie Otwórz deklarację ( F3); następnie powinien wyświetlić plik JAR w górnej części nowej karty.
Andrew

Odpowiedzi:

59

Eclipse może to zrobić, po prostu stwórz (tymczasowy) projekt i umieść swoje biblioteki w ścieżce klas projektów. Następnie możesz łatwo znaleźć zajęcia.

Innym narzędziem, które przychodzi mi do głowy, jest dekompilator Java. Może otwierać wiele słoików naraz i pomaga również znaleźć klasy.

Andreas Dolk
źródło
22
i przy pomocy Ctrl + Shift + T
KrishPrabakar
408

Unix

W systemie Linux inne warianty Uniksa, Git Bash w systemie Windows lub Cygwin, używaj poleceń jar(lub unzip -v) grepi find.

Poniżej wymieniono wszystkie pliki klas pasujące do podanej nazwy:

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

Jeśli znasz całą listę archiwów Java, które chcesz przeszukać, możesz umieścić je wszystkie w tym samym katalogu, używając (symbolicznych) łączy.

Lub użyj find(rozróżniaj wielkość liter), aby znaleźć plik JAR zawierający daną nazwę klasy:

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

Na przykład, aby znaleźć nazwę archiwum zawierającego IdentityHashingStrategy:

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

Jeśli plik JAR może być w dowolnym miejscu w systemie, a locatepolecenie jest dostępne:

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

Wariacja składniowa:

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

Windows

Otwórz wiersz polecenia , przejdź do katalogu (lub katalogu nadrzędnego) zawierającego pliki JAR, a następnie:

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

Oto jak to działa:

  1. for /R %G in (*.jar) do- zapętla wszystkie pliki JAR, rekurencyjnie przeglądając katalogi; zapisz nazwę pliku w %G.
  2. @jar -tvf "%G" |- uruchom polecenie Java Archive, aby wyświetlić wszystkie nazwy plików w danym archiwum i zapisać wyniki na standardowym wyjściu; że @tłumi symbol druku wywołania danego polecenia.
  3. find "ClassName" > NUL- wyszukuje standardowe dane wejściowe, wyprowadzane z danych wyjściowych polecenia jar, dla podanej nazwy klasy; ustawi się ERRORLEVELna 1 i tam jest dopasowanie (w przeciwnym razie 0).
  4. && echo %G- iff ERRORLEVELjest niezerowy, wpisz nazwę pliku archiwum Java na standardowe wyjście (konsolę).

Sieć

Użyj wyszukiwarki, która skanuje pliki JAR .

Dave Jarvis
źródło
3
Tak, -l ci to da, ale niezbyt przydatne, gdy pobiera dane wejściowe ze standardowego wejścia.
George Armhold
60

jakiś czas temu napisałem program tylko do tego: https://github.com/javalite/jar-explorer

ipolevoy
źródło
4
Znajduje dowolny typ pliku, nie tylko klasy. Kliknij dwukrotnie, aby zobaczyć zawartość pliku. Tak, teraz mogę dostrzec wszystkie moje wiosenne schematy.
Chris Noe,
Niesamowite. Dzięki;)
LppEdd
27
grep -l "classname" *.jar

daje nazwę słoika

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

daje ci pakiet klasy

użytkownik311174
źródło
5
Powinien to być grep -lir „nazwa klasy” * .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
Pascal Lambert
źródło
Świetny ! Musiałem użyć go w systemie, który nie miał słoika (to znaczy nie na ścieżce), więc zastąpiłem jar -tvfgo unzip -l.
ixe013
9

Aby zlokalizować słoiki pasujące do podanego ciągu:

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

George Armhold
źródło
Znajduje to również odniesienia do klasy, nie tylko samej klasy.
Trevor Robinson,
8

Kiedy natknąłem się na ten problem, nie wiedziałem o użytecznym narzędziu, dlatego napisałem:

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
źródło
4

Skrypt użytkownika 1207523 działa dla mnie dobrze. Oto wariant, który wyszukuje pliki jar w sposób rekurencyjny, używając find zamiast zwykłego rozszerzenia;

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

Zawsze używałem tego w systemie Windows i działał wyjątkowo dobrze.

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

findstr.exe jest standardowo wyposażony w system Windows i parametry:

  • / s = rekurencyjnie
  • / m = drukuj tylko nazwę pliku, jeśli istnieje zgodność
  • / c = literał (w tym przypadku nazwa pakietu + nazwy klas oddzielone „/”)

Mam nadzieję, że to komuś pomoże.

Ramesh Rooplahl
źródło
3

bash scriptRozwiązanie wykorzystujące unzip (zipinfo). Testowane na 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
źródło
ten skrypt nie jest kompatybilny z
mingw
2

Aby wyszukać wszystkie pliki jar w danym katalogu w poszukiwaniu konkretnej klasy, możesz to zrobić:

ls *.jar | xargs grep -F MyClass

lub nawet prościej

grep -F MyClass *.jar

Dane wyjściowe wyglądają tak:

Binary file foo.jar matches

Jest to bardzo szybkie, ponieważ opcja -F oznacza wyszukiwanie Stałego ciągu, więc nie ładuje silnika regex dla każdego wywołania grep. W razie potrzeby zawsze możesz pominąć opcję -F i użyć wyrażeń regularnych.

Jeff
źródło
2

Znalazłem ten nowy sposób

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

Więc to pokazuje jar i klasę, jeśli zostanie znaleziona, jeśli chcesz, możesz podać ls -1 * .jar lub dane wejściowe do xargs za pomocą komendy find HTH Someone.

Cleonjoys
źródło
Dzięki, poprawiam to w ten sposób: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Streszczenie
Jérôme B
2

ClassFinder to program zaprojektowany w celu rozwiązania tego problemu. Pozwala przeszukiwać rekurencyjnie katalogi i pliki jar, aby znaleźć wszystkie wystąpienia klasy pasujące do wzorca. Jest napisany w Javie, a nie w Pythonie. Ma ładny interfejs graficzny, który ułatwia obsługę. I działa szybko. To wydanie jest wstępnie skompilowane w uruchamialnym słoju, więc nie musisz budować go ze źródła.

Pobierz tutaj: ClassFinder 1.0

Gungwald
źródło
1

Sprawdź JBoss Tattletale ; chociaż nigdy nie korzystałem z niego osobiście, wydaje się, że jest to narzędzie, którego potrzebujesz.

Wilfred Springer
źródło
1

Nie jestem pewien, dlaczego skrypty tutaj nigdy tak naprawdę dla mnie nie działały. To działa:

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

Skrypt do znalezienia pliku 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

Zastosowanie: ./find_jar.sh <katalog najwyższego poziomu zawierający pliki jar> <Nazwa klasy do znalezienia>

Jest to podobne do większości podanych tutaj odpowiedzi. Ale wyświetla tylko nazwę pliku, jeśli grep coś znajdzie. Jeśli chcesz wyłączyć dane wyjściowe grep, możesz przekierować je do / dev / null, ale wolę także zobaczyć dane wyjściowe grep, aby móc użyć częściowych nazw klas i znaleźć właściwą z wyświetlonej listy wyników.

Nazwą klasy może być zarówno prosta nazwa klasy, jak „String” lub pełna nazwa, taka jak „java.lang.String”

Joydip Datta
źródło
1

Aby dodać kolejne narzędzie ... jest to bardzo proste i przydatne narzędzie dla systemu Windows. Prosty plik exe, na który klikniesz, nadaj mu katalog do przeszukania, nazwę klasy, a znajdzie plik jar zawierający tę klasę. Tak, to rekurencyjne.

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

Ben
źródło
1

Aby znaleźć klasę w folderze (i podfolderach) kilka plików 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

Przykład:

java -jar jarscan.jar -dir C:\Folder\To\Search -showProgress -class GenericServlet
KrishPrabakar
źródło
0

Możesz znaleźć klasę w katalogu pełnym słoików z odrobiną powłoki:

Poszukuję klasy „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.
źródło
0

Jedną z rzeczy do dodania do wszystkich powyższych: jeśli nie masz dostępnego pliku wykonywalnego jar (jest dostarczany z JDK, ale nie z JRE), możesz użyć unzip (lub WinZip lub cokolwiek innego), aby osiągnąć to samo.

Alex
źródło
0

bezwstydna autopromocja, ale możesz wypróbować narzędzie, które napisałem: http://sourceforge.net/projects/zfind

Obsługuje większość popularnych plików archiwalnych / skompresowanych (jar, zip, tar, tar.gz itp.) I, w przeciwieństwie do wielu innych wyszukiwarek jar / zip, obsługuje zagnieżdżone pliki zip (zip w zip, jar jar w jar itp.) Do nieograniczonej głębokości.

Dipankar Datta
źródło
0

Trochę późno na imprezę, ale jednak ...

Korzystam z JarBrowser, aby znaleźć, w którym słoju znajduje się dana klasa. Ma łatwy w użyciu interfejs GUI, który pozwala przeglądać zawartość wszystkich słoików na wybranej ścieżce.

maccaroo
źródło
0

Poniższy skrypt pomoże ci

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

Ten działa dobrze w MinGW (środowisko Windows bash) ~ gitbash

Umieść tę funkcję w pliku .bashrc w katalogu 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
}
kisp
źródło
0

Grepj to narzędzie wiersza polecenia do wyszukiwania klas w plikach jar. Jestem autorem narzędzia.

Możesz uruchomić narzędzie jak grepj package.Class my1.jar my2.war my3.ear

Można podać wiele plików jar, ucha i wojennych. Dla zaawansowanego użycia użyj find, aby podać listę słoików do przeszukania.

Rrevo
źródło
0

W środowisku Linux możesz wykonać następujące czynności:

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

Gdzie nazwa jest nazwą pliku klasy, który przeglądasz w słoikach rozmieszczonych w hierarchii katalogów zrootowanych w katalogu katalog_podstawowy .

Zwycięzca
źródło
0

Możesz użyć locatei grep:

locate jar | xargs grep 'my.class'

Upewnij się, że biegniesz updatedbprzed użyciem locate.

Mulugu Mahesh
źródło