Tìm một lớp ở đâu đó bên trong hàng tá tệp JAR?


249

Làm thế nào bạn sẽ tìm thấy một tên lớp cụ thể trong rất nhiều tệp jar?

(Tìm kiếm tên lớp thực tế, không phải các lớp tham chiếu nó.)


1
Tôi không biết về bất kỳ câu trả lời nào trong số những câu trả lời này, nhưng điều gì hiệu quả với tôi nếu bạn thấy lớp được sử dụng trong một dự án làm việc với nhiều tệp JAR là đặt con trỏ của bạn vào tên lớp, nhấp chuột phải vào nó và nhấp vào Khai báo mở ( F3); sau đó nó sẽ liệt kê tệp JAR ở đầu tab mới.
Andrew

Câu trả lời:


59

Eclipse có thể làm điều đó, chỉ cần tạo một dự án (tạm thời) và đặt các thư viện của bạn trên đường dẫn dự án. Sau đó, bạn có thể dễ dàng tìm thấy các lớp.

Một công cụ khác, theo ý tôi, là Trình dịch ngược Java. Nó có thể mở rất nhiều lọ cùng một lúc và cũng giúp tìm các lớp.


22
và với sự trợ giúp của Ctrl + Shift + T
KrishPrabakar

408

Unix

Trên Linux, các biến thể Unix khác, Git Bash trên Windows hoặc Cygwin, sử dụng jar(hoặc unzip -v) grepfindcác lệnh.

Sau đây liệt kê tất cả các tệp lớp khớp với một tên đã cho:

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

Nếu bạn biết toàn bộ danh sách các tài liệu lưu trữ Java mà bạn muốn tìm kiếm, bạn có thể đặt tất cả chúng trong cùng một thư mục bằng các liên kết (tượng trưng).

Hoặc sử dụng find(trường hợp nhạy cảm) để tìm tệp JAR chứa tên lớp đã cho:

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

Ví dụ: để tìm tên của kho lưu trữ chứa IdentityHashingStrategy:

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

Nếu JAR có thể ở bất cứ đâu trong hệ thống và locatelệnh có sẵn:

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

Một biến thể cú pháp:

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

các cửa sổ

Mở một dấu nhắc lệnh , thay đổi thư mục (hoặc thư mục tổ tiên) có chứa các tệp JAR, sau đó:

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

Đây là cách nó hoạt động:

  1. for /R %G in (*.jar) do- lặp trên tất cả các tệp JAR, các thư mục duyệt qua đệ quy; lưu trữ tên tập tin trong %G.
  2. @jar -tvf "%G" |- chạy lệnh Lưu trữ Java để liệt kê tất cả các tên tệp trong kho lưu trữ đã cho và ghi kết quả vào đầu ra tiêu chuẩn; các @ngăn chặn biểu tượng in gọi của lệnh.
  3. find "ClassName" > NUL- tìm kiếm đầu vào tiêu chuẩn, được lấy từ đầu ra của lệnh jar, cho tên lớp đã cho; cái này sẽ được đặt ERRORLEVELthành 1 nếu có một trận đấu (nếu không là 0).
  4. && echo %G- iff ERRORLEVELkhác không, ghi tên tệp lưu trữ Java vào đầu ra tiêu chuẩn (bàn điều khiển).

Web

Sử dụng một công cụ tìm kiếm quét các tệp JAR .


3
Có -l sẽ cung cấp cho bạn điều đó, nhưng không hữu ích lắm khi nó nhận được đầu vào từ stdin.
George Armkeep

60

Cách đây một thời gian, tôi đã viết một chương trình chỉ dành cho điều đó: https://github.com/javalite/jar-explorer


4
Tìm bất kỳ loại tập tin, không chỉ các lớp. Nhấp đúp để xem nội dung tập tin. Yay, bây giờ tôi có thể phát hiện ra tất cả các lược đồ mùa xuân của tôi.
Chris Noe

Tuyệt vời. Cảm ơn;)
LppEdd

27
grep -l "classname" *.jar

cho bạn tên của bình

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

cung cấp cho bạn gói của lớp


5
Nó phải là 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

Tuyệt quá ! Tôi đã phải sử dụng nó trên một hệ thống không có jar (không phải trong đường dẫn), vì vậy tôi đã thay thế jar -tvfbằng unzip -l.
ixe013

9

Để xác định vị trí các lọ khớp với một chuỗi đã cho:

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


Điều này tìm thấy các tài liệu tham khảo cho lớp là tốt, không chỉ bản thân lớp.
Trevor Robinson

8

Tôi không biết một tiện ích để làm điều đó khi tôi gặp phải vấn đề này, vì vậy tôi đã viết như sau:

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

kịch bản của user1207523 hoạt động tốt với tôi. Đây là một biến thể tìm kiếm các tệp jar theo cách sử dụng find thay vì mở rộng đơn giản;

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

4

Tôi đã luôn sử dụng nó trên Windows và nó hoạt động rất tốt.

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

findstr.exe có tiêu chuẩn với Windows và các thông số:

  • / s = đệ quy
  • / m = chỉ in tên tệp nếu có kết quả khớp
  • / c = chuỗi ký tự (trong trường hợp này là tên gói + tên lớp được phân tách bằng '/')

Hy vọng điều này sẽ giúp được ai đó.


3

Một bash scriptgiải pháp sử dụng unzip (zipinfo). Đã thử nghiệm trên 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

tập lệnh này không tương thích với mingw
kisp

2

Để tìm kiếm tất cả các tệp jar trong một thư mục nhất định cho một lớp cụ thể, bạn có thể làm điều này:

ls *.jar | xargs grep -F MyClass

hoặc, thậm chí đơn giản hơn,

grep -F MyClass *.jar

Đầu ra trông như thế này:

Binary file foo.jar matches

Nó rất nhanh vì tùy chọn -F có nghĩa là tìm kiếm chuỗi Cố định, do đó, nó không tải công cụ regex cho mỗi lần gọi grep. Nếu bạn cần, bạn luôn có thể bỏ qua tùy chọn -F và sử dụng biểu thức chính quy.


2

Tôi tìm thấy cách mới này

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

Vì vậy, điều này liệt kê jar và lớp nếu tìm thấy, nếu bạn muốn, bạn có thể cung cấp ls -1 * .jar hoặc nhập vào xargs bằng lệnh find HTH someoneone.


Cảm ơn, tôi cải thiện nó theo cách này: ls -1 * .jar | xargs -i -t jar -tvf '{}' | Tóm tắt grep
Jérôme B

2

Class Downloader là một chương trình được thiết kế để giải quyết vấn đề này. Nó cho phép bạn tìm kiếm đệ quy thông qua các thư mục và tệp jar để tìm tất cả các phiên bản của một lớp khớp với một mẫu. Nó được viết bằng Java, không phải python. Nó có một GUI đẹp giúp dễ sử dụng. Và nó chạy nhanh. Bản phát hành này được biên dịch sẵn trong một cái lọ có thể chạy được để bạn không phải xây dựng nó từ nguồn.

Tải xuống tại đây: Class Downloader 1.0




1

Không chắc chắn tại sao các kịch bản ở đây chưa bao giờ thực sự làm việc cho tôi. Những công việc này:

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

1

Tập lệnh tìm tập tin 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

Cách sử dụng: ./find_jar.sh <thư mục cấp cao nhất chứa tệp jar> <Tên lớp cần tìm>

Điều này tương tự với hầu hết các câu trả lời được đưa ra ở đây. Nhưng nó chỉ xuất ra tên tệp, nếu grep tìm thấy thứ gì đó. Nếu bạn muốn triệt tiêu đầu ra grep, bạn có thể chuyển hướng đó sang / dev / null nhưng tôi thích xem đầu ra của grep hơn để tôi có thể sử dụng tên lớp một phần và tìm ra tên chính xác từ danh sách đầu ra được hiển thị.

Tên lớp có thể là cả tên lớp đơn giản như "Chuỗi" hoặc tên đủ điều kiện như "java.lang.String"


1

Để thêm một công cụ khác ... đây là một công cụ rất đơn giản và hữu ích cho các cửa sổ. Một tệp exe đơn giản mà bạn nhấp vào, cung cấp cho nó một thư mục để tìm kiếm, một tên lớp và nó sẽ tìm thấy tệp jar chứa lớp đó. Vâng, đó là đệ quy.

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


1

Để tìm một lớp trong một thư mục (và các thư mục con), các tệp 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

Thí dụ:

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

0

Bạn có thể tìm thấy một lớp trong một thư mục chứa đầy các lọ có một chút vỏ:

Tìm kiếm lớp "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

Một điều cần thêm vào tất cả những điều trên: nếu bạn không có sẵn tệp thực thi jar (nó đi kèm với JDK nhưng không phải với JRE), bạn có thể sử dụng giải nén (hoặc WinZip hoặc bất cứ thứ gì) để thực hiện điều tương tự.


0

tự quảng cáo không biết xấu hổ, nhưng bạn có thể thử một tiện ích tôi đã viết: http://sourceforge.net/projects/zfind

Nó hỗ trợ hầu hết các tệp lưu trữ / nén phổ biến (jar, zip, tar, tar.gz, v.v.) và không giống như nhiều công cụ tìm jar / zip khác, hỗ trợ các tệp zip lồng nhau (zip trong zip, jar trong jar, v.v.) cho đến độ sâu không giới hạn.


0

Đến bữa tiệc muộn một chút, tuy nhiên ...

Tôi đã sử dụng JarBrowser để tìm trong đó một lớp cụ thể có mặt. Nó có một GUI dễ sử dụng cho phép bạn duyệt qua nội dung của tất cả các lọ trong đường dẫn đã chọn.


0

Kịch bản sau đây sẽ giúp bạn ra ngoài

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

0

Cái này hoạt động tốt trong MinGW (môi trường bash windows) ~ gitbash

Đặt chức năng này vào tệp .bashrc trong thư mục HOME của bạn:

# 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 là một tiện ích dòng lệnh để tìm kiếm các lớp trong các tệp jar. Tôi là tác giả của tiện ích.

Bạn có thể chạy các tiện ích như grepj package.Class my1.jar my2.war my3.ear

Nhiều tập tin jar, tai, chiến tranh có thể được cung cấp. Để sử dụng nâng cao, sử dụng find để cung cấp danh sách các lọ cần tìm kiếm.



0

Trong môi trường Linux, bạn có thể làm như sau:

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

Nơi tên là tên của tập tin lớp học mà bạn đang tìm bên trong lọ phân phối trên hệ thống các thư mục gốc rễ tại base_dir .


0

Bạn có thể sử dụng locategrep:

locate jar | xargs grep 'my.class'

Hãy chắc chắn rằng bạn chạy updatedbtrước khi sử dụng locate.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.