在一堆jar文件中找到一个java类,你最喜欢的工具,插件,脚本是什么?
我经常会继承抱怨一个不存在的类的代码,这只是因为jar文件没有包含在类路径中。但是,什么jar文件是类?我可能没有JAR(所以我必须在线搜索),或者在类路径中添加JAR可能会产生重复的类定义问题。
我显然更喜欢使用eclipse插件,但我对任何适用于Windows的软件都是开放的。
我知道...... Windows不是我的选择,但这就是我的工作。
谢谢!
路易斯
P.S。谢谢您的回答。在回顾了一些回复之后,我意识到我应该更好地解释我的情景。我们有一个下载或创建的JAR文件库,但有时候这个类会在某个地方上线。
答案 0 :(得分:36)
(这是对我之前版本的答案中的脚本的改进,因为它以某些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)。通常我不打扰完整的类名,只需输入部分名称。
答案 1 :(得分:11)
与BalusC的答案相同(我无法发表评论,也无法链接2个网址,没有声誉:()),您可以通过这两个jar查找器引擎找到一个jar: - http://www.jarfinder.com/ - findjar
答案 2 :(得分:6)
我无数次遇到同样的问题,所以我写了一个小工具来找到它们。
一个简单的命令行: findclass MyClass -classpath ...
它为您的班级搜索目录,jar,zip,war和ear文件。 几年前我写了它,并一直使用它。 我认为其他人也可能觉得它很有用所以我上传到github。
可免费下载: https://github.com/eurozulu/Findclass/tree/master/dist
如果您想查看来源,它位于同一网站: https://github.com/eurozulu/Findclass/tree/master
如果你喜欢它,请让我知道给我那种温暖舒适的感觉:)
答案 3 :(得分:5)
我通常使用bash:grep -lr "ClassName" .
诀窍是名称不以任何方式编码。你可以在文本编辑器中打开jar文件,你会看到它们。 (您甚至可以在搜索查询中包含包名称。)
我怀疑,也有一些窗户相同。
答案 4 :(得分:5)
更简单的命令。您不必使用'while-do',使用'&amp;&amp;'如果'grep'找到该类,则打印文件名。
find . -name '*.jar' -print0 | xargs -0 -I '{}' sh -c 'jar tf {} | grep Hello.class && echo {}'
答案 5 :(得分:2)
我经常会继承抱怨一个不存在的类的代码,这只是因为jar文件没有包含在类路径中。
如果它不在类路径中,那么您可能根本就没有JAR文件。通过Eclipse的内置Ctrl+Shift+T
函数进行搜索将无济于事。通常,您可以使用包名来“猜测”您可以从互联网上获取JAR文件的位置。例如。 http://commons.apache.org/lang提供org.apache.commons.lang.XXX
课程。
对于不明显的人,我自己使用JAR源代码搜索引擎http://grepcode.com。
答案 6 :(得分:2)
我为此编写了一个程序:https://github.com/javalite/jar-explorer它还将反编译现有的字节代码,以显示接口,方法,超类,将显示其他资源的内容 - 文本,图像,HTML等。
答案 7 :(得分:2)
我使用jarscan。它是一个可执行的jar文件,可以递归搜索整个文件夹结构,以查找包含您正在查找的类的jar。它按类名,包名或正则表达式进行搜索。
答案 8 :(得分:2)
Grepj是一个命令行实用程序,用于搜索jar文件中的类。
您可以像grepj package.Class my1.jar my2.war my3.ear
搜索范围
可以提供多个jar,ear,war文件。
答案 9 :(得分:1)
最好和最简单的方法是使用JAD反编译器。是的,它是 ECLIPSE PLUGIN !
Download并将插件保存在计算机上的任何位置。
该插件包含以下文件:
执行以下步骤:
现在选择任何一个班级并按F3。
.class文件将自动反编译并显示内容!
答案 10 :(得分: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();
}
}
}
答案 11 :(得分:1)
for $ in $(find。-name'* .jar') 做 unzip -l $ x | grep WCCResponseImpl 完成
答案 12 :(得分:0)
我最近创建了一个搜索类,包和库的工具。你可以试试http://javasearch.buggybread.com/。单击框架,它将帮助您找到依赖项信息(jar,pom)。
答案 13 :(得分: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;
}
答案 14 :(得分:0)
@Nikita Rybak:Windows的AstroGrep是我们的朋友:http://astrogrep.sourceforge.net/
答案 15 :(得分:0)
您总是可以在Eclipse中将参考库添加到项目中,然后在Package Browser中,只需展开JAR文件中的包,直到找到您要查找的类。
答案 16 :(得分:-1)
这里只想提一下,可以在jarfinder中搜索第三方的某些特定文件名 虽然它没有直接回答这个问题,但它不会造成伤害:)
希望这有帮助