2010-08-16 61 views
25

什么是你最喜欢的工具,插件,脚本,在一堆jar文件中找到一个java类?如何找到包含类定义的jar文件?

很多时候我会继续抱怨一个不存在的类的代码,这只是因为jar文件没有包含在类路径中。但是,在什么jar文件是类?我可能没有JAR(所以我必须在线搜索),或者将JAR添加到类路径中可能会导致重复的类定义问题。

我明显会更喜欢一个Eclipse插件,但我可以使用任何可以与Windows一起工作的软件。

我知道...... Windows并不是我的选择,但那就是我一起工作的。

谢谢!

Luis

P.S.谢谢您的回答。在回顾了一些回复之后,我意识到我应该更好地解释我的情况。我们有一个下载或创建的JAR文件库,但有时候这个类会在某个地方联机。

+0

很好的问题。我一直遇到这个问题。不确定为什么它被关闭作为题外话。很奇怪 – Tagar 2017-07-03 20:24:41

回答

5

我通常使用bash:grep -lr "ClassName" .诀窍是名称不以任何方式编码。你可以在文本编辑器中打开jar文件,你会看到它们。 (你甚至可以在搜索查询中包括包名。)

我怀疑,这里也有一些窗口。

+0

是的,但问题是,很难判断文件是否包含定义或类的用法。 而且,是的,有一个可以下载的grep工具。 谢谢! – luiscolorado 2010-08-16 21:56:18

+0

@luiscolorado它从来没有给我以前的假阳性。我不知道,可能大部分内容(包括引用的类)都以某种方式编码。 – 2010-08-16 22:02:35

+0

嗯......不幸的是我得到了一堆误报。或者,也许是因为这个班级在多个软件包中有相同的名字。 无论如何,我会再试一次。谢谢,尼基塔! – luiscolorado 2010-08-16 22:12:16

0

您可以随时在Eclipse中添加引用库到您的项目中,然后在包浏览器中,只需展开JAR文件中的包直到找到您正在寻找的类。

+0

当然可以!尽管我在寻找更快的东西:)我必须在这个项目中列出20个jar文件,并且谁知道有多少类。 – luiscolorado 2010-08-16 21:53:43

+1

对于构建路径上的罐子,只需使用Ctrl-Shift-T来定位一个类。 – 2010-08-16 21:55:05

+0

仍然不是我的一杯茶,但我们会看到。 – luiscolorado 2010-08-16 22:05:32

0

@Nikita Rybak的:AstroGrep的Windows是我们的朋友:http://astrogrep.sourceforge.net/

+0

我喜欢AstroGrep!与命令行版本相比,我发现它很友好。但是,它具有与grep相同的问题(请参阅我对Nikita Rybak的评论)。 – luiscolorado 2010-08-16 22:08:46

+0

真的......但是使用AstroGrep,您可以将其设置为返回+/- N行数。所以它不是最好的选择,但它可能工作。 – NinjaCat 2010-08-16 22:11:44

1

很多时候我继承抱怨不存在的一类代码,它只是因为jar文件中不包括类路径。

如果它不在类路径中,那么您可能根本没有JAR文件本身。通过Eclipse的内置搜索功能Ctrl+Shift+T搜索功能没有多大帮助。通常你可以利用包名称来“猜测”你可以从互联网上获取JAR文件的位置。例如。一个org.apache.commons.lang.XXX类可在http://commons.apache.org/lang

对于不明显的,我自己使用的是JAR源代码搜索引擎http://grepcode.com

+1

_如果它不在类路径中,那么你可能根本没有JAR文件_好吧,它经常发生在我用jboss。数百个内部库,你经常需要它们中的几个来编译你的代码。感谢您的链接,但这很有趣。 – 2010-08-16 22:00:21

+0

@Nikita:在这种特殊情况下,您更愿意将动态Web项目的目标服务器更新为JBoss。 – BalusC 2010-08-16 22:17:02

+0

Boo ... 8年后仍然无法使用!我认为Maven Repo应该提供这个......它拥有所有的东西......“所有”必须做的是保持一个最新的Lucene索引,是的,它的所有.jars中的每个类都是最新的! – 2018-02-25 14:45:22

1

使用本:

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(); 
     } 
    } 
} 
10

在同一行作为BalusC的答案(我不能发表评论,也没有还链接2个网址,没有信誉:(),你可以找到一个罐子感谢这些罐子2取景器引擎: - http://www.jarfinder.com/ - findjar

+1

jarfinder * IS *你的朋友。 – Tom 2010-08-16 22:11:08

+0

该网站已移至:http://www.findjar.com/ – 2011-02-01 20:24:36

2

我写了一个程序是:https://github.com/javalite/jar-explorer它还将反编译现有的字节代码向你展示接口,方法,超类,将显示其他资源的内容 - 文字,图片, html等。

+0

谢谢!伟大的工具! – DBQ 2018-01-29 02:33:16

6

我遇到了无数次相同的问题,所以我写了一个小工具来找到它们。

一个简单的命令行: findClass的MyClass的-classpath ...

它搜索目录,JAR,ZIP,战争和EAR文件为你的类。 我几年前写下来并一直使用它。 我以为其他人可能会觉得它很有用,所以我上传到github上。

它是免费提供下载: https://github.com/eurozulu/Findclass/tree/master/dist

如果你想看看源,它是在同一个站点: https://github.com/eurozulu/Findclass/tree/master

如果你喜欢它,只是让我知道给我说,温暖舒适的感觉:)

+0

我发现你的工具很有用。谢谢! – ObviousChild 2017-09-21 19:30:18

2

我使用jarscan。它是一个可执行的jar文件,可以递归搜索包含您正在查找的类的jar的整个文件夹结构。它按类名,包名或正则表达式进行搜索。

33

(这是在剧本我在回答以前版本的改进,因为它在一些特殊awk /丑报价的价格生产更清洁的输出。)

我已经建立了一个脚本(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] 
的完全限定类名

点的字符将在“任何字符”的正则表达式的含义来解释但这不是什么大问题,因为这是一个启发式实用程序(这就是为什么它也不区分大小写)。通常我不打扰完整的类名,只输入它的一部分。

2

Grepj是一个命令行工具,用于搜索jar文件中的类。

您可以运行像grepj package.Class my1.jar my2.war my3.ear

搜索范围的效用是在JAR文件

  • 类嵌套的工件,如内EAR和WAR文件罐中
  • WEB-INF /类也被搜索。

可以提供多个jar,ear,war文件。

-1

只是想在这里指出,thirdparties可以搜索一些特定的文件名中jarfinder 虽然没有直接回答这个问题,但它不会伤害:)

希望这有助于

+0

这实质上是单链接的答案。此外,它所提供的链接已经提供,实际上是最高票数的答案。你被*三年* – 2014-01-02 21:40:40

3

一个更简单的命令。如果'grep'找到类,则不必使用'while-do',使用'& &'打印文件名。

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

在$ X(找到-name '的* .jar'。) 做 解压缩-l $ X | grep WCCResponseImpl done

0

我尝试了一些Unix命令,但由于各种原因而出错。这是我写的Perl脚本。它专门设计用于使用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'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; 
} 
1

最好的和最简单的方法是使用JAD反编译器。是的,它的一个ECLIPSE PLUGIN

Download并将插件保存在您的机器上的任何位置。

插件包含以下文件:

  1. 一个临时文件夹
  2. 一个的jad.exe文件
  3. A * net.sf.jadclipse_3.3.0.jar * JAR插件
  4. A Readme

执行以下步骤:

  1. 复制JAR插件eclipse文件夹
  2. 开放的Eclipse的插件文件夹中。转到窗口>>首选项>> Java >> JADClipse >>反编译器的路径。
  3. 重启Eclipse

现在选择任何类,并按F3的jad.exe的路径。

.class文件将自动反编译并显示内容!

0

我最近创建了一个工具来搜索类,包和库。你可以试试http://javasearch.buggybread.com/。点击框架,它会帮助你找到依赖信息(jar,pom)。