如何找到包含类定义的jar文件? [关闭]
Posted
技术标签:
【中文标题】如何找到包含类定义的jar文件? [关闭]【英文标题】:how to find the jar file containing a class definition? [closed] 【发布时间】:2011-03-30 16:28:14 【问题描述】:是否有工具、插件或脚本可以用来在一堆 jar 文件中查找 java 类?
我经常继承抱怨不存在的类的代码,这只是因为 jar 文件未包含在类路径中。但是,类在什么 jar 文件中?我可能没有 JAR(所以我必须在线搜索),或者将 JAR 添加到类路径可能会产生重复的类定义问题。
我显然更喜欢 Eclipse 插件,但我愿意接受任何适用于 Windows 的软件。
我知道...Windows 不是我的选择,但这就是我必须使用的。
谢谢!
路易斯
附:谢谢您的回答。在查看了一些回复后,我意识到我应该更好地解释我的场景。我们有一个下载或创建的 JAR 文件库,但有时课程会在某个地方在线。
【问题讨论】:
好问题。我一直遇到这个。不知道为什么它被关闭为题外话。奇怪 这就是你的 ***。 【参考方案1】:我通常为此使用 bash:grep -lr "ClassName" .
诀窍是名称不会以任何方式编码。您可以在文本编辑器中打开 jar 文件,您会看到它们。 (您甚至可以在搜索查询中包含包名称。)
我怀疑,也有一些 Windows 等价物。
【讨论】:
是的,但问题是很难判断文件是否包含类的定义或使用。而且,是的,有一个可以下载的 grep 实用程序。谢谢! @luiscolorado 以前从来没有给我误报过。我不知道,可能大部分内容(包括引用的类)都以某种方式编码。 Mmmmmhh... 不幸的是我得到了一堆误报。或者可能是因为该类在多个包中具有相同的名称。无论如何,我会再试一次。谢谢,尼基塔!【参考方案2】:您总是可以在 Eclipse 中将参考库添加到您的项目中,然后在包浏览器中,只需展开 JAR 文件中的包,直到找到您要查找的类。
【讨论】:
当然!虽然我在寻找更快的东西:) 我必须在这个项目中列出 20 个 jar 文件,谁知道有多少类。 对于构建路径上的 jars,只需使用 Ctrl-Shift-T 来定位一个类。 仍然不是我的那杯茶,但我们拭目以待。【参考方案3】:@Nikita Rybak:AstroGrep for Windows 是我们的朋友:http://astrogrep.sourceforge.net/
【讨论】:
我喜欢 AstroGrep!与命令行版本相比,我发现它很友好。但是,它与任何 grep 都有相同的问题(请参阅我对 Nikita Rybak 的评论)。 True... 但是 使用 AstroGrep 您可以将其设置为返回 +/- N 行数。所以这当然不是最好的选择,但它可能会奏效。【参考方案4】:我经常继承抱怨一个不存在的类的代码,这只是因为 jar 文件未包含在类路径中。
如果它不在类路径中,那么您可能根本没有 JAR 文件本身。通过 Eclipse 的内置 Ctrl+Shift+T
函数搜索不会有太大帮助。通常你可以利用包名来“猜测”你可以从互联网上从哪里得到 JAR 文件。例如。 org.apache.commons.lang.XXX
课程可在 http://commons.apache.org/lang 获得。
对于不明显的,我自己使用http://grepcode.com,JAR 源代码搜索引擎。
【讨论】:
如果它不在类路径中,那么您可能根本没有 JAR 文件本身 嗯,我经常遇到 jboss。数百个内部库,您通常只需要很少的库来编译您的代码。不过,感谢您的链接,这很有趣。 @Nikita:在这种特定情况下,您希望将动态 Web 项目的目标服务器更新为 JBoss。 嘘...... 8 年后仍然无法使用!我认为 Maven Repo 应该提供这个......它拥有所有的东西......它所要做的“所有”就是保持一个最新的 Lucene 索引,是的,它的所有 .jar 中的每个类!跨度> 【参考方案5】:使用这个:
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();
【讨论】:
【参考方案6】:在与 BalusC 的答案相同的行中(我还不能发表评论,也不能链接 2 个 url,没有声誉 :(),由于这 2 个 jar finder 引擎,你可以找到一个 jar: - http://www.jarfinder.com/ - 查找罐
【讨论】:
网站已移至:findjar.com【参考方案7】:我为此编写了一个程序:https://github.com/javalite/jar-explorer 它还会反编译现有的字节码以显示接口、方法、超类,将显示其他资源的内容 - 文本、图像、html 等。
【讨论】:
谢谢!!好工具!!! 我正在使用你的工具,但我遇到了一些错误:OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000ebcff000, 196608, 0) failed; error='Cannot allocate memory' (errno=12) # # 内存不足,Java 运行时环境无法继续。 # 本机内存分配 (mmap) 未能映射 196608 字节以提交保留内存。 # 包含更多信息的错误报告文件保存为: # /host/tools/jar-explorer/target/hs_err_pid6786.log 它不打算与 OpenJDK 一起使用吗?是否有建议分配给此 JAR 的内存量? 不知道为什么。我刚刚在 OpenJDK 版本 8 上运行它,它按预期工作。您可以下载源代码并使用 JDK 在本地构建。它没有依赖关系,因此构建很容易【参考方案8】:我无数次遇到同样的问题,所以我写了一个小工具来找到它们。
一个简单的命令行: findclass MyClass -classpath ...
它会为您的班级搜索目录、jar、zip、war 和 ear 文件。 几年前我写了它并一直使用它。 我想其他人可能也会觉得它有用,所以我上传到了 github。
它可以免费下载: https://github.com/eurozulu/Findclass/tree/master/dist
如果您想查看源代码,它位于同一个站点中: https://github.com/eurozulu/Findclass/tree/master
如果你喜欢它,请告诉我,给我那种温暖舒适的感觉 :)
【讨论】:
我发现你的工具很有用。谢谢!【参考方案9】:我使用jarscan。它是一个可执行的 jar 文件,可以递归地在整个文件夹结构中搜索包含您要查找的类的 jar。它按类名、包名或正则表达式搜索。
【讨论】:
【参考方案10】:(这是对我在以前版本的答案中的脚本的改进,因为它以一些 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]
完全限定类名中的点字符将被解释为“任何字符”的正则表达式,但这没什么大不了的,因为这是一个启发式实用程序(这就是为什么它也不区分大小写 BTW)。通常我不关心完整的类名,只输入其中的一部分。
【讨论】:
【参考方案11】:Grepj 是一个命令行实用程序,用于在 jar 文件中搜索类。
您可以像grepj package.Class my1.jar my2.war my3.ear
一样运行该实用程序
搜索范围是
jar 文件中的类 嵌套工件中的类,例如 ear 和 war 文件中的 jars WEB-INF/classes 也会被搜索。可以提供多个jar、ear、war文件。
【讨论】:
【参考方案12】:这里只想提一下,第三方可以在jarfinder中搜索一些特定的文件名 虽然它没有直接回答问题,但它不会伤害:)
希望对你有帮助
【讨论】:
这本质上是一个链接的答案。此外,已经提供了它的链接,实际上是投票最多的答案。你忍了三年【参考方案13】:一个更简单的命令。您不必使用 'while-do',如果 'grep' 找到类,则使用 '&&' 打印文件名。
find . -name '*.jar' -print0 | xargs -0 -I '' sh -c 'jar tf | grep Hello.class && echo '
【讨论】:
【参考方案14】:for x in $(find .-name '*.jar') 做 解压-l $x | grep WCCResponseImpl 完成
【讨论】:
【参考方案15】:我尝试了其中一些 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;
$optionswanted = \&processFoundFile;
$optionsno_chdir = 1;
$optionsfollow = 1; # So that $File::Find::fullname will be populated.
$optionsfollow_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 $optionsfollow == 1
# Windowize filename:
$fullFileName = qxcygpath --windows $fullFileName 2>&1;
chomp $fullFileName;
$fullFileName = '"' . $fullFileName . '"';
my @results = qxjar -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】:最好和最简单的方法是使用 JAD 反编译器。是的,它是一个 ECLIPSE 插件!
Download 并将插件保存在您机器上的任何位置。
插件包含以下文件:
-
temp 文件夹
一个 jad.exe 文件
*net.sf.jadclipse_3.3.0.jar* JAR 插件
自述文件
执行以下步骤:
-
将JAR插件复制到eclipse文件夹的plugins文件夹中
打开日食。转到窗口 >> 首选项 >> Java >> JADClipse >> 反编译器路径。
给出jad.exe的路径
重启 Eclipse
现在选择任意班级并按 F3。
.class 文件会自动反编译并显示内容!
【讨论】:
【参考方案17】:我最近创建了一个搜索类、包和库的工具。你可以试试http://javasearch.buggybread.com/。点击框架,它会帮你定位依赖信息(jar,pom)。
【讨论】:
链接似乎已失效 现在可以使用了。以上是关于如何找到包含类定义的jar文件? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章