Подтвердить что ты не робот

Как найти файл jar, содержащий определение класса?

Каков ваш любимый инструмент, плагин, script, чтобы найти java-класс в кучке файлов jar?

Очень часто я наследую код, который жалуется на класс, который не существует, и это только потому, что файл jar не включен в путь к классам. Но, в каком файле jar есть класс? У меня может не быть JAR (так что я должен искать в Интернете), или добавление JAR в путь к классам может создать проблему с дублированным определением класса.

Я бы предпочел плагин eclipse, но я открыт для любого программного обеспечения, которое работает с Windows.

Я знаю... Windows не мой выбор, но это то, с чем мне нужно работать.

Спасибо!

Луис

P.S. Спасибо за ответ. Изучив некоторые ответы, я понял, что должен лучше объяснить свой сценарий. У нас была библиотека загруженных или созданных JAR файлов, но иногда класс был где-то в сети.

4b9b3361

Ответ 1

(Это улучшение по сравнению с script, которое у меня было в предыдущих версиях ответа, поскольку оно дает намного более чистый результат по цене некоторого awk специального/уродливого цитирования.)

Я построил script (findinjars), который делает именно это.

#!/usr/bin/env bash
if [[ ($# -ne 1) && ($# -ne 2) ]]
then
    echo "usage is $0 <grep pattern to look for in 'jar tvf' output> [<top-of-dir-tree> or, if missing, current dir]"
else
    THING_TO_LOOKFOR="$1"
    DIR=${2:-.}
    if [ ! -d $DIR ]; then
        echo "directory [$DIR] does not exist";
        exit 1;
    fi
    find "$DIR" -iname \*.jar | while read f ; do (jar tf $f | awk '{print "'"$f"'" "  " $0}' | grep -i "$THING_TO_LOOKFOR") ; done
fi

вы можете вызвать его с помощью:

$findinjars a.b.c.d.Class [directoryTreeRoot or, if missing, current dir]

или просто

$findinjars partOfClassName [directoryTreeRoot or, if missing, current dir]

Точечные символы в имени полного класса будут интерпретироваться в смысле регулярного выражения "любой символ", но это не очень важно, так как это утилита эвристики (почему и нечувствительность к регистру тоже BTW). Обычно я не беспокоюсь о полном имени класса и просто набираю его часть.

Ответ 2

В тех же строках, что и ответ BalusC (я не могу оставлять комментарии еще и ссылку 2 urls, нет репутации:(), вы можете найти банку благодаря этим двум механизмам поиска jar: - http://www.jarfinder.com/ - findjar

Ответ 3

Я обычно использую bash для этого: grep -lr "ClassName" . Фокус в том, что имена никак не закодированы. Вы можете открыть файл jar в текстовом редакторе, и вы увидите их. (Вы даже можете включить имя пакета в поисковый запрос.)

Я подозреваю, что некоторые эквиваленты окон тоже.

Ответ 4

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

Простая командная строка: findclass MyClass -classpath...

Он ищет каталоги, jar, zip, war и ear файлы для вашего класса. Я написал это несколько лет назад и использую его все время. Я думал, что другие могут оказаться полезными, поэтому я загрузил github.

Он свободно доступен для загрузки: https://github.com/eurozulu/Findclass/tree/master/dist

Если вы хотите посмотреть источник, он находится на том же сайте: https://github.com/eurozulu/Findclass/tree/master

Если вам это нравится, просто дай мне знать, чтобы дать мне это теплое комфортное чувство:)

Ответ 5

Простая команда. Вам не нужно использовать "while-do", используйте "& &" для печати имени файла, если 'grep' находит класс.

find . -name '*.jar' -print0 |  xargs -0 -I '{}' sh -c 'jar tf {} | grep Hello.class &&  echo {}'

Ответ 6

Очень часто я наследую код, который жалуется на класс, который не существует, и это просто потому, что файл jar не включен в путь к классам.

Если это не в пути к классам, то у вас, вероятно, вообще нет самого файла JAR. Поиск через встроенную функцию Eclipse Ctrl+Shift+T не поможет. Обычно вы можете использовать имя пакета для "угадывания", где вы можете получить JAR файл из Интернета. Например. Класс org.apache.commons.lang.XXX доступен в http://commons.apache.org/lang.

Для неочевидных я сам использую http://www.jarhoo.com, механизм поиска JAR (который, к сожалению, недоступен в этот момент!).

Ответ 7

используйте это:

public class Main {

    private static final String SEARCH_PATH = "C:\\workspace\\RPLaunch";
    private static String CLASS_FILE_TO_FIND =
            "javax.ejb.SessionBean";
    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) {
        File start;
        new Scanner(args[0]);
        if (args.length > 0) {
            start = new File(args[0]);
            if (args.length > 1) {
                CLASS_FILE_TO_FIND = args[1];
            }
        } else {
            start = new File(SEARCH_PATH);
        }
        if (!CLASS_FILE_TO_FIND.endsWith(".class")) {
            CLASS_FILE_TO_FIND = CLASS_FILE_TO_FIND.replace('.', '/') + ".class";
        }
        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());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Ответ 8

Я написал программу для этого: https://github.com/javalite/jar-explorer Он также декомпилирует существующий байтовый код, чтобы показать вам интерфейсы, методы, суперклассы, покажет содержимое других ресурсов - текст, изображения, html и т.д.

Ответ 9

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

Ответ 10

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

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

Область поиска

  • Классы в файле jar
  • Классы внутри вложенных артефактов, таких как банки в ушных и военных файлах
  • Также просматриваются WEB-INF/классы.

Можно предоставить несколько файлов jar, ear, war.

Ответ 11

для x в $(find. -name '*.jar') делать unzip -l $x | grep WCCResponseImpl сделано

Ответ 12

Самый лучший и простой способ - использовать Decompiler JAD. И да, его ECLIPSE PLUGIN!

Загрузить и сохранить плагин в любом месте на вашем компьютере.

Плагин содержит следующие файлы:

  • Временная папка
  • Файл jad.exe
  • A * net.sf.jadclipse_3.3.0.jar * Плагин JAR
  • Readme

Выполните следующие шаги:

  • Скопируйте плагин JAR в папку плагинов папки eclipse
  • Открыть затмение. Перейти к окну → Предпочтения → Java → JADClipse → Путь к декомпилятору.
  • Укажите путь к jad.exe
  • Перезапуск Eclipse

Теперь выберите любой класс и нажмите F3.

Файл .class автоматически декомпилирует и отображает содержимое!

Ответ 13

Вы всегда можете добавить библиотеку Reference в свой проект в Eclipse, а затем в Package Browser, просто расширьте пакеты в JAR файле, пока не найдете нужный класс.

Ответ 15

Я пробовал некоторые из этих команд Unix, но они по ошибке вызывали ошибки. Здесь Perl script я написал. Он специально разработан для работы на Cygwin с использованием версии Perl для Cygwin.

#!/bin/perl

# This program searches recursively for a given class in .jar files contained in or below
# directories given as command-line arguments. See subroutine printUsageAndExit for details,
# or just run it with -h command-line argument.
#
# It is specfically designed to run on Windows via Cygwin, with Cygwin version of Perl,
# though it could easily be modified to run elsewhere.

use strict;
use File::Find;
use Getopt::Std;

sub processCommandLineArguments (\$\@);
sub checkCommandLineArguments;

my $className;
my @startingDirectories;

&checkCommandLineArguments;
&processCommandLineArguments (\$className, \@startingDirectories );

my %options;
$options{wanted} = \&processFoundFile;
$options{no_chdir} = 1;
$options{follow} = 1; # So that $File::Find::fullname will be populated.
$options{follow_skip} = 2; # So it won't die if it encounters the same thing twice.

&find ( \%options, @startingDirectories );  # find comes from "use File::Find".

sub processFoundFile{
    # This routine is called by File::Find.
    #
    #  $File::Find::dir is the current directory name,
    #  $_ is the current filename within that directory
    #  $File::Find::name is the complete pathname to the file.

    my $jarFileName = $_;

    return unless /\.jar$/;

    my $fullFileName = $File::Find::fullname; # set by File::Find only when $options{follow} == 1

    # Windowize filename:
    $fullFileName = qx{cygpath --windows $fullFileName 2>&1};
    chomp $fullFileName;
    $fullFileName = '"' . $fullFileName . '"';

    my @results = qx{jar -tf $fullFileName 2>&1};

    local $/ = "\r\n";  # So that this Unix-based Perl can read output from Windows based jar command.

    for my $result ( @results )
    {
        chomp $result;

        if ( $result =~ /\b(\w+)\.((java)|(class))$/ )
        {
            my $classNameFound = $1;

            if ($classNameFound eq $className)
            {
                print $jarFileName, "\n";
                return;
            }
        }
    }
}

sub processCommandLineArguments (\$\@){

    my $refClassName = shift;
    my $refStartingDirectories = shift;

    $$refClassName = '';

    # parse @ARGV
    while (@ARGV){
        my $arg = shift @ARGV;

        if ($arg =~ /\Q-c/){
            $$refClassName = shift @ARGV;
        }elsif ($arg =~ /\Q-directories/){

            while ($ARGV[0] =~ m{^/(\w+/?)+\b}){
                my $directory = shift @ARGV;
                die "Can't find $directory $!" if ! -e $directory;
                push @$refStartingDirectories, $directory;
            }
        }
    }

    die "Must give -c class_name argument $!" if $$refClassName eq "";

    push @$refStartingDirectories, '.' if scalar (@$refStartingDirectories ) == 0;
}

sub checkCommandLineArguments
{
    {
        # getopts butchers @ARGV, so have to use it on a local version.
        local @ARGV = @ARGV;

        our $opt_h;
        &getopts('hc'); # Have to specify all options given or getopts will die.

        &printUsageAndExit if $opt_h;
    }

    my $className;

    {
        # getopts butchers @ARGV, so have to use it on a local version.
        local @ARGV = @ARGV;

        while (@ARGV){
            my $arg = shift @ARGV;

            if ($arg =~ /\Q-c/){
                $className = shift @ARGV;

                &printUsageAndExit if $className =~ /^\s*$/ ;

                return;
            }
        }
    }

    &printUsageAndExit;
}

sub printUsageAndExit
{
    print "Usage:\n\n";
    print "$0 -c class_name_to_search_for [ -directories startingDirectory1 startingDirectory2 ...]\n\n";
    print "Example:\n\n";
    print "findJarContainingClass.pl -c ApplicationMaster -directories /home/lylez/Hadoop/hadoop-2.x/hadoop-2.2.0/share/hadoop/yarn/sources /home/lylez/Hadoop/hadoop-2.x/hadoop-2.2.0/share/hadoop/yarn\n\n";

    exit;
}

Ответ 16

Недавно я создал инструмент для поиска классов, пакетов и библиотек. Вы можете попробовать http://javasearch.buggybread.com/. Нажмите на фреймворк, и он поможет вам найти информацию о зависимостях (jar, pom).

Ответ 17

Просто хотел упомянуть здесь, что сторонние партнеры могут искать какое-то определенное имя файла в jarfinder Хотя он напрямую не отвечает на вопрос, но это не повредит:)

Надеюсь, что это поможет