ค้นหาชั้นเรียนในไฟล์ JAR หลายสิบไฟล์ใช่หรือไม่


249

คุณจะค้นหาชื่อคลาสเฉพาะภายในไฟล์ jar จำนวนมากได้อย่างไร

(ค้นหาชื่อคลาสจริงไม่ใช่คลาสที่อ้างอิง)


1
ฉันไม่รู้เกี่ยวกับคำตอบใด ๆ เหล่านี้ แต่สิ่งที่ใช้ได้ผลสำหรับฉันหากคุณเห็นคลาสที่ใช้ในโครงการที่ทำงานกับไฟล์ JAR จำนวนมากคือการวางเคอร์เซอร์ของคุณในชื่อคลาสคลิกขวาบนและคลิกเปิดการประกาศ ( F3); จากนั้นควรแสดงรายการไฟล์ JAR ที่ด้านบนของแท็บใหม่
แอนดรู

คำตอบ:


59

Eclipse สามารถทำได้เพียงแค่สร้างโครงการ (ชั่วคราว) และวางไลบรารีของคุณบน classpath ของโครงการ จากนั้นคุณสามารถค้นหาชั้นเรียนได้อย่างง่ายดาย

เครื่องมืออีกอย่างที่อยู่ในใจของฉันคือ Java Decompiler มันสามารถเปิดขวดจำนวนมากได้ในครั้งเดียวและช่วยในการค้นหาชั้นเรียนด้วย


22
และด้วยความช่วยเหลือของ Ctrl + Shift + T
KrishPrabakar

408

ยูนิกซ์

บน Linux ตัวแปร Unix อื่น ๆ Git Bash บน Windows หรือ Cygwin ใช้คำสั่งjar(หรือunzip -v) grepและfindคำสั่ง

ต่อไปนี้แสดงรายการไฟล์คลาสทั้งหมดที่ตรงกับชื่อที่กำหนด:

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

หากคุณรู้รายการเก็บถาวร Java ทั้งหมดที่คุณต้องการค้นหาคุณสามารถเก็บไว้ในไดเรกทอรีเดียวกันโดยใช้ลิงก์ (สัญลักษณ์)

หรือใช้find(ตัวพิมพ์เล็กหรือใหญ่) เพื่อค้นหาไฟล์ JAR ที่มีชื่อคลาสที่กำหนด:

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

ตัวอย่างเช่นหากต้องการค้นหาชื่อของไฟล์เก็บถาวรที่มีIdentityHashingStrategy:

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

หาก JAR อาจอยู่ที่ใดก็ได้ในระบบและมีlocateคำสั่งอยู่:

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

รูปแบบไวยากรณ์:

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

ของ windows

เปิดพร้อมต์คำสั่งเปลี่ยนเป็นไดเร็กทอรี (หรือไดเร็กทอรี ancestor) ที่มีไฟล์ JAR จากนั้น:

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

นี่คือวิธีการทำงาน:

  1. for /R %G in (*.jar) do- วนซ้ำไฟล์ JAR ทั้งหมด, วนซ้ำภายในไดเรกทอรี เก็บชื่อไฟล์%Gไว้
  2. @jar -tvf "%G" |- รันคำสั่ง Java Archive เพื่อแสดงรายการชื่อไฟล์ทั้งหมดภายในไฟล์เก็บถาวรที่กำหนดและเขียนผลลัพธ์ไปยังเอาต์พุตมาตรฐาน @ไม่ใส่สัญลักษณ์พิมพ์อุทธรณ์คำสั่งของ
  3. find "ClassName" > NUL- ค้นหาอินพุตมาตรฐาน, ไพพ์จากเอาต์พุตของคำสั่ง jar, สำหรับชื่อคลาสที่กำหนด; สิ่งนี้จะถูกตั้งค่าERRORLEVELเป็น 1 iff มีการแข่งขัน (มิฉะนั้น 0)
  4. && echo %G- iff ERRORLEVELไม่ใช่ศูนย์ให้เขียนชื่อไฟล์เก็บถาวร Java ไปยังเอาต์พุตมาตรฐาน (คอนโซล)

เว็บ

ใช้เครื่องมือค้นหาที่จะสแกนไฟล์ JAR


3
ใช่ -l จะให้สิ่งนั้น แต่ไม่มีประโยชน์มากเมื่อมันได้รับข้อมูลจาก stdin
George Armhold

60

เมื่อไม่นานมานี้ฉันเขียนโปรแกรมเพื่อ: https://github.com/javalite/jar-explorer


4
ค้นหาไฟล์ทุกประเภทไม่ใช่แค่คลาส ดับเบิลคลิกเพื่อดูเนื้อหาไฟล์ Yay, ตอนนี้ฉันสามารถมองเห็น schemas ฤดูใบไม้ผลิของฉันทั้งหมด
Chris Noe

น่ากลัว ขอบคุณ;)
LppEdd

27
grep -l "classname" *.jar

ให้ชื่อขวด

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

ให้แพ็คเกจของคลาส


5
มันควรเป็น 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

เยี่ยมมาก! ผมต้องใช้มันในระบบที่ไม่ได้มีขวด (ไม่อยู่ในเส้นทางที่มี) ดังนั้นฉันถูกแทนที่ด้วยjar -tvf unzip -l
ixe013

9

วิธีค้นหาไหที่ตรงกับสตริงที่กำหนด:

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


นี่เป็นการค้นหาการอ้างอิงไปยังคลาสด้วยไม่ใช่แค่คลาสเอง
Trevor Robinson

8

ฉันไม่ทราบว่าจะมีประโยชน์อะไรเมื่อฉันเจอปัญหานี้ดังนั้นฉันจึงเขียนสิ่งต่อไปนี้:

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

สคริปต์ของ user1207523 ใช้งานได้ดีสำหรับฉัน นี่คือตัวแปรที่ค้นหาไฟล์ jar ซ้ำ ๆ กันโดยใช้ find แทนที่จะเป็นการขยายแบบง่าย

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

4

ฉันเคยใช้สิ่งนี้ใน Windows และมันทำงานได้ดีเป็นพิเศษ

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

findstr.exe มาพร้อมกับมาตรฐาน Windows และ params:

  • / s = วนซ้ำ
  • / m = พิมพ์เฉพาะชื่อไฟล์หากมีการแข่งขัน
  • / c = สตริงตัวอักษร (ในกรณีนี้ชื่อแพ็กเกจของคุณ + ชื่อคลาสคั่นด้วย '/')

หวังว่านี่จะช่วยใครซักคน


3

วิธีการแก้ปัญหาโดยใช้bash script unzip (zipinfo)ทดสอบ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

สคริปต์นี้เข้ากันไม่ได้กับ mingw
kisp

2

ในการค้นหาไฟล์ jar ทั้งหมดในไดเรกทอรีที่กำหนดสำหรับคลาสที่ต้องการคุณสามารถทำได้:

ls *.jar | xargs grep -F MyClass

หรือง่ายกว่า

grep -F MyClass *.jar

ผลลัพธ์มีดังนี้:

Binary file foo.jar matches

มันเร็วมากเพราะอ็อพชัน -F หมายถึงค้นหาสตริงคงที่ดังนั้นจึงไม่โหลดเอ็นจิน regex สำหรับการเรียกใช้ grep แต่ละครั้ง หากคุณต้องการคุณสามารถละเว้นตัวเลือก -F และใช้ regexes


2

ฉันพบวิธีการใหม่นี้

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

ดังนั้นรายการนี้จะแสดงรายการ jar และ class หากพบว่าคุณต้องการให้ ls -1 * .jar หรือ input ไปยัง xargs ด้วยคำสั่ง find HTH


ขอบคุณฉันปรับปรุงด้วยวิธีนี้: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep บทคัดย่อ
Jérôme B

2

ClassFinder เป็นโปรแกรมที่ออกแบบมาเพื่อแก้ปัญหานี้ มันช่วยให้คุณสามารถค้นหาซ้ำผ่านไดเรกทอรีและไฟล์ jar เพื่อค้นหาอินสแตนซ์ทั้งหมดของคลาสที่ตรงกับรูปแบบ มันเขียนใน Java ไม่ใช่หลาม มันมี GUI ที่ดีซึ่งทำให้ใช้งานง่าย และมันก็วิ่งเร็ว รีลีสนี้ได้รับการคอมไพล์ล่วงหน้าในขวดที่รันได้ดังนั้นคุณไม่จำเป็นต้องสร้างมันจากแหล่งที่มา

ดาวน์โหลดได้ที่นี่: ClassFinder 1.0


1

ตรวจสอบ JBoss Tattletale ; แม้ว่าฉันจะไม่เคยใช้มันเป็นการส่วนตัว แต่นี่ก็เป็นเครื่องมือที่คุณต้องการ



1

ไม่แน่ใจว่าทำไมสคริปต์ที่นี่ไม่เคยทำงานให้ฉันจริงๆ งานนี้:

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

1

สคริปต์เพื่อค้นหาไฟล์ 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

การใช้งาน: ./find_jar.sh <ไดเรกทอรีระดับบนสุดที่มีไฟล์ jar> <ชื่อคลาสที่ต้องการค้นหา>

นี่คล้ายกับคำตอบส่วนใหญ่ที่ให้ไว้ที่นี่ แต่จะส่งออกเฉพาะชื่อไฟล์หาก grep พบบางอย่าง หากคุณต้องการระงับเอาต์พุต grep คุณอาจเปลี่ยนเส้นทางไปยัง / dev / null แต่ฉันต้องการเห็นเอาต์พุตของ grep เช่นกันเพื่อที่ฉันจะสามารถใช้ชื่อคลาสบางส่วนและค้นหาชื่อที่ถูกต้องจากรายการผลลัพธ์ที่แสดง

ชื่อคลาสสามารถเป็นได้ทั้งชื่อคลาสแบบง่ายเช่น "String" หรือชื่อแบบเต็มเช่น "java.lang.String"


1

หากต้องการเพิ่มอีกเครื่องมือหนึ่ง ... นี่เป็นเครื่องมือที่ง่ายและมีประโยชน์สำหรับ Windows ไฟล์ exe ง่าย ๆ ที่คุณคลิกให้ไดเรกทอรีเพื่อค้นหาในชื่อชั้นเรียนและจะพบไฟล์ jar ที่มีคลาสนั้น ใช่มันวนซ้ำ

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


1

วิธีค้นหาคลาสในโฟลเดอร์ (และโฟลเดอร์ย่อย) เครือ JARs: 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

ตัวอย่าง:

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

0

คุณสามารถหาคลาสในไดเร็กตอรี่ที่เต็มไปด้วยไหด้วยเปลือกหอย:

กำลังมองหาคลาส "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

สิ่งหนึ่งที่จะเพิ่มให้กับสิ่งที่กล่าวข้างต้นทั้งหมด: หากคุณไม่มี jar ที่ใช้งานได้ (มันมาพร้อมกับ JDK แต่ไม่ใช่กับ JRE) คุณสามารถใช้ unzip (หรือ WinZip หรืออะไรก็ตาม) เพื่อทำสิ่งเดียวกัน


0

การส่งเสริมตนเองที่ไร้ยางอาย แต่คุณสามารถลองใช้โปรแกรมอรรถประโยชน์ที่ฉันเขียนไว้: http://sourceforge.net/projects/zfind

รองรับไฟล์เก็บถาวร / ไฟล์บีบอัดที่พบบ่อยที่สุด (jar, zip, tar, tar.gz ฯลฯ ) และแตกต่างจากตัวค้นหา jar / zip อื่น ๆ รองรับไฟล์ zip หลาย ๆ ไฟล์ (zip ภายใน zip, jar ภายใน jar ฯลฯ ) จนถึงความลึกไม่ จำกัด


0

สายไปงานเลี้ยง แต่อย่างไรก็ตาม ...

ฉันใช้JarBrowserเพื่อค้นหาว่าไหมีคลาสใดอยู่ มี GUI ที่ใช้งานง่ายซึ่งช่วยให้คุณสามารถเรียกดูเนื้อหาของไหทั้งหมดในเส้นทางที่เลือก


0

สคริปต์ต่อไปนี้จะช่วยคุณ

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

0

อันนี้ใช้ได้ดีใน MinGW (windows bash environment) ~ gitbash

ใส่ฟังก์ชั่นนี้ลงในไฟล์. bashrc ในไดเรกทอรี 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เป็นโปรแกรมอรรถประโยชน์บรรทัดคำสั่งเพื่อค้นหาคลาสภายในไฟล์ jar ฉันเป็นผู้เขียนโปรแกรมอรรถประโยชน์

คุณสามารถเรียกใช้โปรแกรมอรรถประโยชน์เช่น grepj package.Class my1.jar my2.war my3.ear

สามารถจัดเตรียมไฟล์ jar, ear, war หลายไฟล์ สำหรับการใช้งานขั้นสูงให้ค้นหาเพื่อระบุรายการขวดที่จะค้นหา



0

ภายใต้สภาพแวดล้อม Linux คุณสามารถทำสิ่งต่อไปนี้:

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

ที่ไหนชื่อเป็นชื่อของไฟล์ชั้นเรียนที่คุณกำลังมองหาที่อยู่ภายในขวดกระจายตามลำดับชั้นของไดเรกทอรีที่หยั่งรากในที่base_dir


0

คุณสามารถใช้locateและgrep:

locate jar | xargs grep 'my.class'

ให้แน่ใจว่าคุณทำงานก่อนที่จะใช้updatedblocate

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.