Знайти клас десь у десятках файлів JAR?


249

Як би ви знайшли назву конкретного класу у великій кількості файлів jar?

(Шукаєш власне ім’я класу, а не класи, на які посилається.)


1
Я не знаю про жодну з цих відповідей, але те, що працює для мене, якщо ви бачите клас, який використовується у робочому проекті з численними файлами JAR, - це навести курсор на ім’я класу, клацнути правою кнопкою миші та натиснути Відкрити декларацію ( F3); тоді він повинен перелічити файл JAR у верхній частині нової вкладки.
Андрій

Відповіді:


59

Eclipse може це зробити, просто створити (тимчасовий) проект і поставити свої бібліотеки на клас проектів проектів. Тоді ви можете легко знайти заняття.

Ще один інструмент, який мені спадає на думку, - це Java Decompiler. Це може відкрити відразу багато банок і допоможе знайти заняття.


22
і за допомогою Ctrl + Shift + T
KrishPrabakar

408

Unix

В 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

Відкрийте командний рядок , перейдіть до каталогу (або каталогу предків), що містить файли 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, якщо є відповідність (інакше 0).
  4. && echo %G- якщо iff ERRORLEVELне дорівнює нулю, запишіть ім'я файлу архіву Java на стандартний вихід (консоль).

Веб

Використовуйте пошукову систему, яка сканує файли JAR .


3
Так, я дам вам це, але не дуже корисно, коли він отримує свій внесок від stdin.
Джордж Армхолд

60

деякий час тому я написав програму саме для цього: https://github.com/javalite/jar-explorer


4
Знаходить будь-який тип файлу, а не лише класи. Двічі клацніть, щоб переглянути вміст файлу. Так, тепер я можу помітити всі свої весняні схеми.
Кріс Ное

Дивовижно. Спасибі;)
LppEdd

27
grep -l "classname" *.jar

дає назву банку

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

дає вам пакет класу


5
Це має бути grep -lir "classname" * .jar
Леонард Саєр

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 (не на шляху, тобто), тому я замінив jar -tvfна unzip -l.
ixe013


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 та параметрами:

  • / 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 означає пошук виправленої рядка, тому вона не завантажує механізм регулярних виразів для кожного виклику grep. Якщо вам потрібно, ви завжди можете опустити параметр -F і використовувати регулярні вирази.


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 та клас, якщо ви хочете, ви можете дати ls -1 * .jar або ввести xargs за допомогою команди find HTH Someone.


Дякую, я вдосконалюю це так: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Анотація
Jérôme B

2

ClassFinder - програма, призначена для вирішення цієї проблеми. Це дозволяє рекурсивно шукати через каталоги та файли jar, щоб знайти всі екземпляри класу, що відповідають шаблону. Він написаний на Java, а не python. Він має приємний графічний інтерфейс, що робить його простим у використанні. І швидко пробігає. Цей випуск попередньо компілюється в баночку для запуску, тому вам не доведеться створювати його з джерела.

Завантажте його тут: ClassFinder 1.0




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), ви можете скористатися розпакуванням (або WinZip, або будь-яким іншим), щоб виконати те саме.


0

безсоромне самореклама, але ви можете спробувати утиліту, яку я написав: http://sourceforge.net/projects/zfind

Він підтримує найпоширеніші архіви / стислі файли (jar, zip, tar, tar.gz тощо) і на відміну від багатьох інших шукачів jar / zip, підтримує вкладені поштові файли (zip у zip, jar у jar тощо) до необмеженої глибини.


0

Трохи запізнюємось на вечірку, але все-таки ...

Я використовую JarBrowser, щоб знайти, в якій банці присутній певний клас. У ньому є простий у користуванні графічний інтерфейс, який дозволяє переглядати вміст усіх банок у вибраному шляху.


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

Можна надати кілька банок, вух, файли війни. Для розширеного використання використовуйте пошук, щоб надати список банок, які слід шукати.



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'

Переконайтеся, що ви працюєте updatedbперед використанням locate.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.