Temukan kelas di suatu tempat di dalam puluhan file JAR?

249

Bagaimana Anda menemukan nama kelas tertentu di dalam banyak file jar?

(Mencari nama kelas yang sebenarnya, bukan kelas yang merujuknya.)

Kapsh
sumber
1
Saya tidak tahu tentang jawaban ini, tetapi apa yang berfungsi untuk saya jika Anda melihat kelas yang digunakan dalam proyek yang bekerja dengan banyak file JAR adalah untuk meletakkan kursor Anda pada nama kelas, klik kanan padanya, dan klik Buka Deklarasi ( F3); maka itu harus mencantumkan file JAR di bagian atas tab baru.
Andrew

Jawaban:

59

Eclipse dapat melakukannya, cukup buat proyek (sementara) dan letakkan perpustakaan Anda di classpath proyek. Maka Anda dapat dengan mudah menemukan kelas.

Alat lain, yang muncul di benak saya, adalah Java Decompiler. Ini dapat membuka banyak stoples sekaligus dan membantu untuk menemukan kelas juga.

Andreas Dolk
sumber
22
dan dengan bantuan Ctrl + Shift + T
KrishPrabakar
408

Unix

Di Linux, varian Unix lainnya, Git Bash di Windows, atau Cygwin, gunakan jar (atau unzip -v) grep,, dan findperintah.

Berikut ini daftar semua file kelas yang cocok dengan nama yang diberikan:

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

Jika Anda tahu seluruh daftar arsip Java yang ingin Anda cari, Anda bisa menempatkan semuanya di direktori yang sama menggunakan tautan (simbolis).

Atau gunakan find(case sensitif) untuk menemukan file JAR yang berisi nama kelas yang diberikan:

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

Misalnya, untuk menemukan nama arsip yang mengandung IdentityHashingStrategy:

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

Jika JAR bisa berada di mana saja dalam sistem dan locateperintah tersedia:

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

Variasi sintaks:

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

Windows

Buka prompt perintah , ubah ke direktori (atau direktori leluhur) yang berisi file JAR, lalu:

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

Begini cara kerjanya:

  1. for /R %G in (*.jar) do- loop di atas semua file JAR, direktori traversing rekursif; simpan nama file di %G.
  2. @jar -tvf "%G" |- Jalankan perintah Java Archive untuk mendaftar semua nama file dalam arsip yang diberikan, dan tulis hasilnya ke output standar; yang @Menekan simbol mencetak doa perintah ini.
  3. find "ClassName" > NUL- cari input standar, disalurkan dari output perintah jar, untuk nama kelas yang diberikan; ini akan ERRORLEVELmenjadi 1 jika ada kecocokan (jika tidak 0).
  4. && echo %G- iff ERRORLEVELbukan nol, tulis nama file arsip Java ke output standar (konsol).

Web

Gunakan mesin pencari yang memindai file JAR .

Dave Jarvis
sumber
3
Ya -l akan memberi Anda itu, tetapi tidak terlalu berguna ketika mendapat input dari stdin.
George Armhold
60

beberapa waktu lalu, saya menulis sebuah program hanya untuk itu: https://github.com/javalite/jar-explorer

ipolevoy
sumber
4
Menemukan semua jenis file, bukan hanya kelas. Klik dua kali untuk melihat konten file. Yay, sekarang saya bisa melihat semua skema musim semi saya.
Chris Noe 8-12
Luar biasa. Terima kasih;)
LppEdd
27
grep -l "classname" *.jar

memberi Anda nama toples

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

memberi Anda paket kelas

pengguna311174
sumber
5
Seharusnya 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
Pascal Lambert
sumber
Bagus ! Aku harus menggunakannya pada sistem yang tidak memiliki jar (tidak di jalan, yaitu), jadi saya diganti jar -tvfdengan unzip -l.
ixe013
9

Untuk menemukan stoples yang cocok dengan string yang diberikan:

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

George Armhold
sumber
Ini menemukan referensi ke kelas juga, bukan hanya kelas itu sendiri.
Trevor Robinson
8

Saya tidak tahu utilitas untuk melakukannya ketika saya menemukan masalah ini, jadi saya menulis yang berikut:

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

skrip user1207523 berfungsi dengan baik untuk saya. Berikut ini adalah varian yang mencari file jar secara rekursif menggunakan find alih-alih ekspansi sederhana;

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

Saya selalu menggunakan ini pada Windows dan ini bekerja dengan sangat baik.

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

findstr.exe datang standar dengan Windows dan params:

  • / s = secara rekursif
  • / m = cetak hanya nama file jika ada kecocokan
  • / c = string literal (dalam hal ini nama paket Anda + nama kelas dipisahkan oleh '/')

Semoga ini bisa membantu seseorang.

Ramesh Rooplahl
sumber
3

Sebuah bash scriptsolusi menggunakan unzip (zipinfo). Diuji pada 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
sumber
skrip ini tidak kompatibel dengan mingw
kisp
2

Untuk mencari semua file jar di direktori tertentu untuk kelas tertentu, Anda bisa melakukan ini:

ls *.jar | xargs grep -F MyClass

atau, bahkan lebih sederhana,

grep -F MyClass *.jar

Output terlihat seperti ini:

Binary file foo.jar matches

Ini sangat cepat karena opsi -F berarti mencari string tetap, sehingga tidak memuat mesin regex untuk setiap permintaan grep. Jika perlu, Anda selalu dapat menghilangkan opsi -F dan menggunakan regex.

Jeff
sumber
2

Saya menemukan cara baru ini

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

Jadi ini mencantumkan jar dan kelas jika ditemukan, jika mau, Anda dapat memberikan ls -1 * .jar atau input ke xargs dengan perintah find HTH Someone.

Cleonjoys
sumber
Terima kasih, saya memperbaikinya dengan cara ini: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Abstract
Jérôme B
2

ClassFinder adalah program yang dirancang untuk mengatasi masalah ini. Ini memungkinkan Anda untuk mencari secara rekursif melalui direktori dan file jar untuk menemukan semua instance kelas yang cocok dengan suatu pola. Itu ditulis dalam Java, bukan python. Ini memiliki GUI yang bagus yang membuatnya mudah digunakan. Dan itu berjalan cepat. Rilis ini dikompilasi dalam jar yang bisa dijalankan sehingga Anda tidak harus membuatnya dari sumber.

Unduh di sini: ClassFinder 1.0

Gungwald
sumber
1

Periksa JBoss Tattletale ; Meskipun saya tidak pernah menggunakannya secara pribadi, ini tampaknya menjadi alat yang Anda butuhkan.

Wilfred Springer
sumber
1

Cukup gunakan util FindClassInJars, ini adalah program ayunan sederhana, tetapi bermanfaat. Anda dapat memeriksa kode sumber atau mengunduh file jar di http://code.google.com/p/find-class-in-jars/

Liubing
sumber
1

Tidak yakin mengapa skrip di sini tidak pernah benar-benar bekerja untuk saya. Ini bekerja:

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

Script untuk menemukan 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

Penggunaan: ./find_jar.sh <direktori tingkat atas yang berisi file jar> <Nama kelas untuk ditemukan>

Ini mirip dengan sebagian besar jawaban yang diberikan di sini. Tapi itu hanya menampilkan nama file, jika grep menemukan sesuatu. Jika Anda ingin menekan output grep Anda dapat mengarahkan ulang ke / dev / null tapi saya lebih suka melihat output grep juga sehingga saya dapat menggunakan nama kelas parsial dan mencari tahu yang benar dari daftar output yang ditampilkan.

Nama kelas dapat berupa nama kelas sederhana Seperti "String" atau nama yang sepenuhnya memenuhi syarat seperti "java.lang.String"

Joydip Datta
sumber
1

Untuk menambah alat lain ... ini adalah alat yang sangat sederhana dan berguna untuk windows. File exe sederhana yang Anda klik, berikan direktori untuk mencari, nama kelas dan itu akan menemukan file jar yang berisi kelas itu. Ya, ini bersifat rekursif.

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

Ben
sumber
1

Untuk menemukan kelas di folder (dan subfolder) sekelompok 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

Contoh:

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

Anda dapat menemukan kelas di direktori yang penuh dengan stoples dengan sedikit shell:

Mencari kelas "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.
sumber
0

Satu hal untuk ditambahkan ke semua di atas: jika Anda tidak memiliki jar yang dapat dieksekusi tersedia (itu datang dengan JDK tetapi tidak dengan JRE), Anda dapat menggunakan unzip (atau WinZip, atau apa pun) untuk mencapai hal yang sama.

Alex
sumber
0

promosi diri yang tidak tahu malu, tetapi Anda dapat mencoba utilitas yang saya tulis: http://sourceforge.net/projects/zfind

Ini mendukung arsip / file terkompresi paling umum (jar, zip, tar, tar.gz dll) dan tidak seperti banyak finder jar / zip lainnya, mendukung file zip bersarang (zip dalam zip, jar dalam jar dll) hingga kedalaman tak terbatas.

Dipankar Datta
sumber
0

Agak terlambat ke pesta, tapi tetap saja ...

Saya telah menggunakan JarBrowser untuk menemukan di mana jar kelas tertentu hadir. Itu punya GUI mudah digunakan yang memungkinkan Anda untuk menelusuri isi semua guci di jalur yang dipilih.

maccaroo
sumber
0

Script berikut akan membantu Anda

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

Yang ini berfungsi dengan baik di MinGW (lingkungan windows bash) ~ gitbash

Masukkan fungsi ini ke file .bashrc Anda di direktori HOME Anda:

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

Grepj adalah utilitas baris perintah untuk mencari kelas dalam file jar. Saya adalah penulis utilitas.

Anda dapat menjalankan utilitas seperti grepj package.Class my1.jar my2.war my3.ear

Beragam file jar, telinga, perang dapat disediakan. Untuk penggunaan lanjutan, gunakan untuk menyediakan daftar toples yang akan dicari.

rrevo
sumber
0

Di bawah lingkungan Linux Anda dapat melakukan hal berikut:

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

Di mana nama adalah nama file kelas yang Anda cari di dalam guci yang didistribusikan di hierarki direktori yang di-root di base_dir .

Pemenang
sumber
0

Anda dapat menggunakan locatedan grep:

locate jar | xargs grep 'my.class'

Pastikan Anda menjalankan updatedbsebelum menggunakan locate.

mulesh mahesh
sumber