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

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

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

30 ответов


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

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


в Unix

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

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

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

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

или использовать find (case sensitively), чтобы найти файл JAR, содержащий данный класс имя:

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

например, чтобы найти имя архива, содержащего IdentityHashingStrategy:

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

если бы банка могла быть в любом месте в системе и locate доступно:

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

окна

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

Web

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


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


grep -l "classname" *.jar

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

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

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


#!/bin/bash

pattern=
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

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

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

}

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

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


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


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

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

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

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

findstr.exe поставляется в стандартной комплектации с Windows и params:

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

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


A bash script решение с помощью unzip (zipinfo). Протестировано на Ubuntu 12.

#!/bin/bash

# ./jarwalker.sh "/a/Starting/Path" "aClassName"

IFS=$'\n'
jars=( $( find -P "" -type f -name "*.jar" ) )

for jar in ${jars[*]}
    do
        classes=( $( zipinfo -1 ${jar} | awk -F '/' '{print $NF}' | grep .class | awk -F '.' '{print }' ) )
        if [ ${#classes[*]} -ge 0 ]; then
            for class in ${classes[*]}
                do
                    if [ ${class} == "" ]; then
                        echo "Found in ${jar}"
                    fi
                done
        fi
    done

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

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


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


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


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

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

для поиска всех файлов jar в данном Каталоге для определенного класса вы можете сделать следующее:

ls *.jar | xargs grep -F MyClass

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

grep -F MyClass *.jar

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

Binary file foo.jar matches

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


скрипт для поиска файла jar: find_jar.sh

IFS=$(echo -en "\n\b") # Set the field separator newline

for f in `find  -iname *.jar`; do
  jar -tf ${f}| grep --color 
  if [ $? == 0 ]; then
    echo -n "Match found: "
    echo -e "${f}\n"
  fi
done
unset IFS

использование:. /find_jar.sh

Это похоже на большинство ответы даны здесь. Но он выводит только имя файла, если grep что-то находит. Если вы хотите подавить вывод grep, вы можете перенаправить его на /dev / null, но я предпочитаю видеть вывод grep, чтобы я мог использовать частичные имена классов и выяснить правильный из списка выходных данных показанный.

имя класса может быть как простым именем класса, как " String "или полным именем, как" java.ленг.Строка"


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

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


вы можете найти класс в каталоге полно банок с скорлупа:

Ищу класс "FooBar":

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

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


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

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


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

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


следующий скрипт поможет вам

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

Это хорошо работает в 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 )" ] ; then
      echo "$i"
    fi
   done 
  IFS=$OLD_IFS
}

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

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

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


проверьте этот плагин для eclipse, который может выполнить работу, которую вы ищете.

https://marketplace.eclipse.org/content/jarchiveexplorer


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

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

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


можно использовать locate и grep:

locate jar | xargs grep 'my.class'

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


использовать это.. можно найти любой файл в 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);
            }
          }
    }

}

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