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

Как бы вы нашли определенное имя класса внутри большого количества файлов jar?

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

Ответ 1

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

Другим инструментом, который приходит мне на ум, является Java Decompiler. Он может открывать сразу множество банок и помогает находить классы.

Ответ 2

Юникс

Используйте команды jar (или unzip -v), grep и find.

Например, следующее перечисляет все файлы классов, которые соответствуют заданному имени:

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

Если вам известен весь список архивов Java, которые вы хотите найти, вы можете разместить их в одном каталоге, используя (символические) ссылки.

Или используйте find (case sensitive), чтобы найти 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

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 на стандартный вывод (консоль).

Web

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

Ответ 4

grep -l "classname" *.jar

дает имя флага

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

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

Ответ 5

#!/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

Ответ 6

Я не знал об утилите, когда я сталкивался с этой проблемой, поэтому написал следующее:

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();
        }
    }

}

Ответ 7

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

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

Ответ 8

Существуют также две разные утилиты, называемые "JarScan", которые выполняют именно то, что вы просите: JarScan (inetfeedback.com) и JarScan (java.net)

Ответ 9

user1207523 script отлично работает для меня. Вот вариант, который ищет файлы jar с помощью утилиты find вместо простого расширения;

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

Ответ 10

Я всегда использовал это в Windows, и он работал исключительно хорошо.

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

findstr.exe поставляется с Windows и параметрами:

  • /s = рекурсивно
  • /m = печатать только имя файла, если есть соответствие
  • /c = буквальная строка (в этом случае имя вашего пакета + имена классов разделенных символом '/')

Надеюсь, это поможет кому-то.

Ответ 11

A 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

Ответ 12

Я нашел этот новый способ

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 Кто-то.

Ответ 13

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

Ответ 14

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

Ответ 15

Не знаю, почему сценарии здесь никогда не работали для меня. Это работает:

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

Ответ 16

Для поиска всех файлов jar в заданном каталоге для определенного класса вы можете сделать это:

ls *.jar | xargs grep -F MyClass

или, что еще проще,

grep -F MyClass *.jar

Результат выглядит следующим образом:

Binary file foo.jar matches

Это очень быстро, потому что опция -F означает поиск фиксированной строки, поэтому она не загружает механизм регулярных выражений для каждого вызова grep. Если вам нужно, вы всегда можете опустить параметр -F и использовать регулярные выражения.

Ответ 17

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

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

Ответ 18

Script, чтобы найти файл 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"

Ответ 19

Вы можете найти класс в каталоге, заполненном банками с небольшим количеством оболочки:

Ищете класс "FooBar":

LIB_DIR=/some/dir/full/of/jarfiles
for jarfile in $(find $LIBDIR -name "*.jar"); do
   echo "--------$jarfile---------------"
   jar -tvf $jarfile | grep FooBar
done

Ответ 20

Одна вещь, которую нужно добавить ко всему вышесказанному: если у вас нет исполняемого файла jar (он поставляется с JDK, но не с JRE), вы можете использовать unzip (или WinZip или что-то еще) для выполнения такой же предмет.

Ответ 21

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

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

Ответ 22

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

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

Ответ 23

После script вам поможет

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

Ответ 24

Это хорошо работает в среде MinGW (windows bash) ~ 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
}

Ответ 25

Grepj - это утилита командной строки для поиска классов в файлах jar. Я автор полезности.

Вы можете запустить утилиту как grepj package.Class my1.jar my2.war my3.ear

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

Ответ 27

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

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

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

Ответ 28

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

locate jar | xargs grep 'my.class'

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

Ответ 29

Используйте это.. вы можете найти любой файл в classpath.. гарантированный..

import java.net.URL;
import java.net.URLClassLoader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class FileFinder {

    public static void main(String[] args) throws Exception {

        String file = <your file name>;

        ClassLoader cl = ClassLoader.getSystemClassLoader();

        URL[] urls = ((URLClassLoader)cl).getURLs();

        for(URL url: urls){
            listFiles(file, url);
        }
    }

    private static void listFiles(String file, URL url) throws Exception{
        ZipInputStream zip = new ZipInputStream(url.openStream());
          while(true) {
            ZipEntry e = zip.getNextEntry();
            if (e == null)
              break;
            String name = e.getName();
            if (name.endsWith(file)) {
                System.out.println(url.toString() + " -> " + name);
            }
          }
    }

}

Ответ 30

В eclipse вы можете использовать старый, но все еще используемый плагин jarsearch