Найти класс где-то внутри десятков JAR-файлов?

249

Как бы вы нашли конкретное имя класса во множестве файлов JAR?

(Ищите фактическое имя класса, а не классы, которые ссылаются на него.)

Kapsh
источник
1
Я не знаю ни одного из этих ответов, но что работает для меня, если вы видите класс, используемый в рабочем проекте с многочисленными JAR-файлами, так это навести курсор на имя класса, щелкнуть по нему правой кнопкой мыши и щелкнуть «Открыть объявление» ( F3); тогда это должно перечислить файл JAR наверху новой вкладки.
Андрей

Ответы:

59

Eclipse может это сделать, просто создайте (временный) проект и поместите свои библиотеки в путь к классам проектов. Тогда вы можете легко найти классы.

Другой инструмент, который приходит мне в голову, это 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

Откройте командную строку , перейдите в каталог (или каталог предков), содержащий файлы 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- если ERRORLEVELне ноль, записать имя файла архива Java в стандартный вывод (консоль).

Web

Используйте поисковую систему, которая сканирует файлы JAR .

Дейв Джарвис
источник
3
Да, я дам вам это, но не очень полезно, когда он получает информацию от stdin.
Джордж Армгольд
60

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

ipolevoy
источник
4
Находит любой тип файла, а не только классы. Дважды щелкните, чтобы увидеть содержимое файла. Да, теперь я могу определить все мои весенние схемы.
Крис Ноу
Потрясающие. Спасибо;)
LppEdd
27
grep -l "classname" *.jar

дает вам имя банки

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

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

user311174
источник
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
9

Чтобы найти банки, которые соответствуют заданной строке:

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

Джордж Армгольд
источник
Это находит ссылки и на класс, а не только на сам класс.
Тревор Робинсон
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();
        }
    }

}
ILMTitan
источник
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 означает поиск строки Fixed, поэтому она не загружает механизм регулярных выражений для каждого вызова 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.

Cleonjoys
источник
Спасибо, я улучшаю это следующим образом: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Abstract
Жером Б
2

ClassFinder - это программа, предназначенная для решения этой проблемы. Он позволяет вам рекурсивно искать в каталогах и jar-файлах, чтобы найти все экземпляры класса, соответствующие шаблону. Он написан на Java, а не на Python. Он имеет приятный графический интерфейс, который делает его простым в использовании. И это работает быстро. Этот выпуск предварительно скомпилирован в работающем фляге, поэтому вам не нужно собирать его из исходного кода.

Загрузите это здесь: ClassFinder 1.0

Gungwald
источник
1

Проверьте JBoss Tattletale ; хотя я никогда не использовал это лично, кажется, это инструмент, который вам нужен.

Уилфред Спрингер
источник
1

Просто используйте утилиту FindClassInJars, это простая программа Swing, но полезная. Вы можете проверить исходный код или загрузить файл jar по адресу http://code.google.com/p/find-class-in-jars/.

Liubing
источник
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

Чтобы добавить еще один инструмент ... это очень простой и полезный инструмент для окон. Простой exe-файл, по которому вы щелкаете, дает ему каталог для поиска, имя класса, и он найдет jar-файл, содержащий этот класс. Да, это рекурсивно.

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

Бен
источник
1

Чтобы найти класс в папке (и подпапках) группы 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

Пример:

java -jar jarscan.jar -dir C:\Folder\To\Search -showProgress -class GenericServlet
KrishPrabakar
источник
0

Вы можете найти класс в директории, полной jar-файлов с небольшой оболочкой:

Ищем класс "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, или что-то еще), чтобы выполнить то же самое.

Alex
источник
0

Самореклама бесстыдная, но вы можете попробовать утилиту, которую я написал: http://sourceforge.net/projects/zfind

Он поддерживает наиболее распространенные архивные / сжатые файлы (jar, zip, tar, tar.gz и т. Д.) И, в отличие от многих других jar / zip-искателей, поддерживает вложенные zip-файлы (zip в zip, jar в jar и т. Д.) До неограниченной глубины.

Дипанкар Датта
источник
0

Немного опоздал на вечеринку, но тем не менее ...

Я использую JarBrowser, чтобы найти, в каком jar присутствует определенный класс. Он имеет простой в использовании графический интерфейс, который позволяет просматривать содержимое всех банок по выбранному пути.

maccaroo
источник
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) ~ Gitbash

Поместите эту функцию в ваш файл .bashrc в вашем домашнем каталоге:

# 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. Для расширенного использования используйте find, чтобы предоставить список банок для поиска.

rrevo
источник
0

В среде Linux вы можете сделать следующее:

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

куда name - это имя файла класса, который вы просматриваете внутри jar- файлов, распределенных по иерархии каталогов с корнем в base_dir .

Виктор
источник
0

Вы можете использовать locateи grep:

locate jar | xargs grep 'my.class'

Убедитесь, что вы запускаете updatedbперед использованием locate.

мулугу махеш
источник