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

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

Andreas Dolk
fonte
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 .

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

há algum tempo, escrevi um programa exatamente para isso: https://github.com/javalite/jar-explorer

ipolevoy
fonte
4
Localiza qualquer tipo de arquivo, não apenas classes. Clique duas vezes para ver o conteúdo do arquivo. Agora posso ver todos os meus esquemas de primavera.
Chris Noe
Impressionante. Obrigado;)
LppEdd 1/11/18
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

user311174
fonte
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
Pascal Lambert
fonte
Ó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 {} \;

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

}
ILMTitan
fonte
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
Kurtcebe Eroglu
fonte
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.

Ramesh Rooplahl
fonte
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
Filippo Lauria
fonte
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.

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

Cleonjoys
fonte
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

Gungwald
fonte
1

Verifique o JBoss Tattletale ; embora eu nunca o tenha usado pessoalmente, essa parece ser a ferramenta que você precisa.

Wilfred Springer
fonte
1

Basta usar o utilitário FindClassInJars, é um programa simples, mas útil. Você pode verificar o código-fonte ou fazer o download do arquivo jar em http://code.google.com/p/find-class-in-jars/

Liubing
fonte
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
Mikael Lindlöf
fonte
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"

Joydip Datta
fonte
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/

Ben
fonte
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
KrishPrabakar
fonte
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
Steve B.
fonte
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.

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

Dipankar Datta
fonte
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.

maccaroo
fonte
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
Kartik Jajal
fonte
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
}
kisp
fonte
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.

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

Vencedor
fonte
0

Você pode usar locatee grep:

locate jar | xargs grep 'my.class'

Certifique-se de executar updatedbantes de usar locate.

mulugu mahesh
fonte