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


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

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

30 210

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 (чувствительно к регистру), чтобы найти файл 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

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

Web

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

некоторое время назад я написал программу именно для этого: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 recusively с помощью найти, а не простое расширение;

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

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

таким образом, это перечисляет банку и класс, если он найден, если вы хотите, вы можете дать ls -1 *.jar или вход в xargs с командой find HTH Someone.

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

просто использовать FindClassInJars утиль, это простая программа для качания, но и полезными. Вы можете проверить исходный код или скачать 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 чтобы найти, в какой банке присутствует определенный класс. Это простой в использовании графический интерфейс, который позволяет просматривать содержимое всех банок в выбранном пути.

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

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

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

установите этот плагин для 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