Encontre uma classe em algum lugar dentro de dezenas de arquivos JAR?


249

Como você encontraria um nome de classe específico em muitos arquivos jar?

(Procurando o nome da classe real, não as classes que a referenciam.)


1
Não conheço nenhuma dessas respostas, mas o que funciona para mim se você vir a classe usada em um projeto de trabalho com vários arquivos JAR é colocar o cursor no nome da classe, clicar com o botão direito do mouse e clicar em Abrir Declaração ( F3); então ele deve listar o arquivo JAR na parte superior da nova guia.
8303 Andrew

Respostas:


59

O Eclipse pode fazer isso, basta criar um projeto (temporário) e colocar suas bibliotecas no caminho de classe do projeto. Então você pode encontrar facilmente as aulas.

Outra ferramenta, que me vem à cabeça, é o Java Decompiler. Ele pode abrir muitos frascos de uma só vez e ajuda a encontrar aulas também.


22
e com a ajuda de Ctrl + Shift + T
KrishPrabakar

408

Unix

No Linux, outras variantes do Unix, Git Bash no Windows ou Cygwin, usam os botões jar(ou unzip -v) grepefind comandos .

A seguir, lista todos os arquivos de classe que correspondem a um determinado nome:

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

Se você souber toda a lista de arquivos Java que deseja pesquisar, poderá colocá-los todos no mesmo diretório usando links (simbólicos).

Ou use find(com distinção entre maiúsculas e minúsculas) para encontrar o arquivo JAR que contém um determinado nome de classe:

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

Por exemplo, para encontrar o nome do arquivo que contém IdentityHashingStrategy:

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

Se o JAR puder estar em qualquer lugar do sistema e o locatecomando estiver disponível:

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

Uma variação de sintaxe:

find path/to/libs -name '*.jar' -print | \
  while read i; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done 

janelas

Abra um prompt de comandos , vá para o diretório (ou diretório ancestral) que contém os arquivos JAR e:

for /R %G in (*.jar) do @jar -tvf "%G" | find "ClassName" > NUL && echo %G

Veja como funciona:

  1. for /R %G in (*.jar) do- loop sobre todos os arquivos JAR, atravessando recursivamente os diretórios; armazene o nome do arquivo em%G .
  2. @jar -tvf "%G" |- execute o comando Java Archive para listar todos os nomes de arquivos dentro do arquivo especificado e grave os resultados na saída padrão; o @símbolo suprime a impressão da chamada do comando.
  3. find "ClassName" > NUL- pesquise entrada padrão, canalizada a partir da saída do comando jar, para o nome de classe especificado; isso será definido ERRORLEVELcomo 1 se houver uma correspondência (caso contrário, 0).
  4. && echo %G- se ERRORLEVELfor diferente de zero, escreva o nome do arquivo Java na saída padrão (o console).

Rede

Use um mecanismo de pesquisa que varre arquivos JAR .


3
Sim -l lhe dará isso, mas não será muito útil quando estiver recebendo a entrada de stdin.
George Armhold


27
grep -l "classname" *.jar

dá-lhe o nome do frasco

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

dá-lhe o pacote da classe


5
Deve ser grep -lir "classname" * .jar
Leonard Saers

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

Ótimo ! Eu tive que usá-lo em um sistema que não tinha jar (não no caminho, ou seja), então substituí jar -tvfpor unzip -l.
precisa saber é o seguinte

9

Para localizar os frascos que correspondem a uma determinada sequência:

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


Também encontra referências à classe, não apenas à própria classe.
Trevor Robinson

8

Eu não sabia de um utilitário para fazer isso quando me deparei com esse problema, então escrevi o seguinte:

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

O script de user1207523 funciona bem para mim. Aqui está uma variante que procura por arquivos jar de forma recusativa, usando find em vez de simples expansão;

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

4

Eu sempre usei isso no Windows e funcionou excepcionalmente bem.

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

O findstr.exe é padrão no Windows e nos parâmetros:

  • / s = recursivamente
  • / m = imprime apenas o nome do arquivo se houver uma correspondência
  • / c = string literal (nesse caso, o nome do seu pacote + os nomes da classe separados por '/')

Espero que isso ajude alguém.


3

Uma bash scriptsolução usando unzip (zipinfo). Testado em 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

este script não é mingw compatível
kisp

2

Para pesquisar todos os arquivos jar em um determinado diretório para uma classe específica, você pode fazer o seguinte:

ls *.jar | xargs grep -F MyClass

ou, ainda mais simples,

grep -F MyClass *.jar

A saída é assim:

Binary file foo.jar matches

É muito rápido, porque a opção -F significa procurar por String fixa, portanto, não carrega o mecanismo de expressão regular para cada chamada grep. Se necessário, você sempre pode omitir a opção -F e usar expressões regulares.


2

Eu encontrei esse novo jeito

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

Portanto, isso lista o jar e a classe, se encontrados, se você quiser, pode fornecer ls -1 * .jar ou inserir xargs com o comando find HTH Someone.


Obrigado, eu o aprimoro desta maneira: ls -1 * .jar | xargs -i -t jar -tvf '{}' | grep Resumo
Jérôme B

2

O ClassFinder é um programa desenvolvido para solucionar esse problema. Ele permite pesquisar recursivamente por diretórios e arquivos jar para encontrar todas as instâncias de uma classe que corresponda a um padrão. Está escrito em Java, não em python. Possui uma interface gráfica agradável, que facilita o uso. E corre rápido. Esta versão é pré-compilada em um frasco executável para que você não precise construí-la a partir do código-fonte.

Faça o download aqui: ClassFinder 1.0




1

Não sei por que os scripts aqui nunca funcionaram realmente para mim. Isso funciona:

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

1

Script para localizar o arquivo 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

Uso: ./find_jar.sh <diretório de nível superior que contém arquivos jar> <Nome da classe a ser encontrado>

Isso é semelhante à maioria das respostas dadas aqui. Mas ele apenas gera o nome do arquivo, se o grep encontrar alguma coisa. Se você deseja suprimir a saída do grep, você pode redirecioná-lo para / dev / null, mas eu prefiro ver a saída do grep também, para que eu possa usar nomes de classes parciais e descobrir o correto da lista de resultados mostrada.

O nome da classe pode ser um nome de classe simples, como "String" ou um nome completo, como "java.lang.String"


1

Para adicionar mais uma ferramenta ... esta é uma ferramenta muito simples e útil para Windows. Um arquivo exe simples no qual você clica, fornece um diretório para pesquisar, um nome de classe e ele encontrará o arquivo jar que contém essa classe. Sim, é recursivo.

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


1

Para encontrar uma classe em um grupo de pastas (e subpastas) de 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

Exemplo:

java -jar jarscan.jar -dir C:\Folder\To\Search -showProgress -class GenericServlet

0

Você pode encontrar uma classe em um diretório cheio de jars com um pouco de shell:

Procurando pela classe "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

Uma coisa a acrescentar a todos os itens acima: se você não tiver o executável jar disponível (ele vem com o JDK, mas não com o JRE), você pode usar o descompactação (ou WinZip, ou o que for) para realizar a mesma coisa.


0

autopromoção desavergonhada, mas você pode tentar um utilitário que escrevi: http://sourceforge.net/projects/zfind

Ele suporta arquivos compactados / de arquivo mais comuns (jar, zip, tar, tar.gz etc) e, diferentemente de muitos outros localizadores de jar / zip, suporta arquivos zip aninhados (zip dentro de zip, jar dentro de jar etc) até uma profundidade ilimitada.


0

Um pouco tarde para a festa, mas mesmo assim ...

Eu tenho usado o JarBrowser para descobrir em qual jar uma determinada classe está presente. Possui uma interface gráfica fácil de usar, que permite navegar pelo conteúdo de todos os jars no caminho selecionado.


0

O script a seguir o ajudará

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

0

Este funciona bem no MinGW (ambiente Windows Bash) ~ gitbash

Coloque esta função no seu arquivo .bashrc no diretório 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 é um utilitário de linha de comando para procurar classes em arquivos jar. Eu sou o autor do utilitário.

Você pode executar o utilitário como grepj package.Class my1.jar my2.war my3.ear

Podem ser fornecidos vários arquivos de jar, ouvido e guerra. Para uso avançado, use find para fornecer uma lista de frascos a serem pesquisados.



0

Em um ambiente Linux, você pode fazer o seguinte:

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

Onde name é o nome do arquivo de classe que você está procurando dentro dos jars distribuídos pela hierarquia de diretórios enraizados no base_dir .


0

Você pode usar locatee grep:

locate jar | xargs grep 'my.class'

Certifique-se de executar updatedbantes de usar locate.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.