how to find the jar file containing a class defini

2019-01-21 22:22发布

What is your favorite tool, plugin, script, to find a java class in a bunch of jar files?

Very often I inherit code that complains about a class that doesn't exist, and it is just because the jar file is not included in the classpath. But, in what jar file(s) is the class? I may not have the JAR (so I have to search online), or adding a JAR to the classpath could create a duplicated class definition problem.

I obviously would prefer an eclipse plugin, but I'm open to any piece of software that works with Windows.

I know... Windows is not my choice, but that's what I got to work with.

Thanks!

Luis

P.S. Thank you for your answers. After reviewing some responses, I became aware that I should have explained better my scenario. We had a library of downloaded or created JAR files, but sometimes the class would be online somewhere.

17条回答
女痞
2楼-- · 2019-01-21 23:00

@Nikita Rybak: AstroGrep for Windows is our friend: http://astrogrep.sourceforge.net/

查看更多
该账号已被封号
3楼-- · 2019-01-21 23:01

I recently created a tool to search class , packages and libraries. You can try it http://javasearch.buggybread.com/. Click on the framework and it will help you locate dependency information ( jar , pom).

查看更多
ら.Afraid
4楼-- · 2019-01-21 23:02

I usually employ bash for that: grep -lr "ClassName" . The trick is that names aren't encoded in any way. You can open jar file in text editor and you'll see them. (You can even include package name in search query.)

I suspect, there's some windows equivalent too.

查看更多
Ridiculous、
5楼-- · 2019-01-21 23:03

I tried some of those Unix commands, but they errored out for various reasons. Here's a Perl script I wrote. It's specifically designed to run on Cygwin using the Cygwin version of Perl.

#!/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's 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;
}
查看更多
Juvenile、少年°
6楼-- · 2019-01-21 23:10

I ran into the same problem countless times, so I wrote a little tool to find them.

A simple command line: findclass MyClass -classpath ...

It searches directories, jar, zip, war and ear files for your class. I wrote it a few years back and use it all the time. I thought others might find it useful too so I uploaded onto github.

It's freely available to download: https://github.com/eurozulu/Findclass/tree/master/dist

If you want to look at the source, it's in the same site: https://github.com/eurozulu/Findclass/tree/master

If you like it, just let me know to give me that warm comfy feeling :)

查看更多
Animai°情兽
7楼-- · 2019-01-21 23:10

Just wanted to mention here that thirdparties can be searched for some specific file name in jarfinder Although it doesn't directly answer the question, but it won't harm :)

Hope this helps

查看更多
登录 后发表回答