2009-08-27 240 views
189

如何在大量的jar文件中找到特定的類名?在幾十個JAR文件中的某處找到一個類?

(尋找實際的類名稱,而不是引用它的類。)

+1

我不知道這些答案中的任何一個,但如果您看到在具有大量JAR文件的工作項目中使用的類,那麼對我而言,適用於將類型名稱放在類名上,右鍵單擊它並單擊公開聲明(F3);那麼它應該在新標籤的頂部列出JAR文件。 – Andrew 2017-02-08 13:27:16

回答

50

Eclipse可以做到這一點,只需要創建一個(臨時)項目,並把你的庫在項目類路徑中。然後您可以輕鬆找到課程。我想到的另一個工具是Java Decompiler。它可以一次打開很多罐子,並有助於找到課程。

+11

並藉助於Ctrl + Shift + T – KrishPrabakar 2015-09-09 04:15:19

7

我不知道一個工具來做到這一點,當我遇到這個問題來了,所以我寫了下面:

public class Main { 

    /** 
    * 
    */ 
    private static String CLASS_FILE_TO_FIND = 
      "class.to.find.Here"; 
    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) { 
     if (!CLASS_FILE_TO_FIND.endsWith(".class")) { 
      CLASS_FILE_TO_FIND = CLASS_FILE_TO_FIND.replace('.', '/') + ".class"; 
     } 
     File start = new File(args[0]); 
     if (args.length > 1) { 
      CLASS_FILE_TO_FIND = args[1]; 
     } 
     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()); 
       } 
      } else { 
       foundIn.add(f.getPath()); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 
302

的Unix

使用jar(或unzip -v),grep,和find命令。

例如,下面將列出匹配給定名稱的所有類文件:

for i in *.jar; do jar -tvf "$i" | grep -Hsi ClassName && echo "$i"; done 

如果你知道你想要搜索的Java歸檔的完整列表,你可以把他們都在同一個目錄使用(符號)鏈接。

或者使用find(案例敏感)來查找包含給定類名的JAR文件:

find path/to/libs -name '*.jar' -exec grep -Hls ClassName {} \; 

例如,要查找包含IdentityHashingStrategy存檔名稱:

$ find . -name "*.jar" -exec grep -Hsli IdentityHashingStrategy {} \; 
./trove-3.0.3.jar 

如果JAR可以是系統中的任何地方並且可以使用locate命令:

for i in $(locate "*.jar"); 
    do echo $i; jar -tvf $i | grep -Hsi ClassName; 
done 

的Windows

打開命令提示符,包含JAR文件,然後切換到該目錄(或上級目錄):

for /R %G in (*.jar) do @jar -tvf "%G" | find "ClassName" > NUL && echo %G 

下面是它如何工作的:

  1. for /R %G in (*.jar) do - 遍歷所有JAR文件,遞歸遍歷目錄;將文件名存儲在%G中。
  2. @jar -tvf "%G" | - 運行Java歸檔命令以列出給定歸檔中的所有文件名,並將結果寫入標準輸出; @符號禁止打印命令的調用。
  3. find "ClassName" > NUL - 對於給定的類名稱,從jar命令的輸出中檢索標準輸入;這會將ERRORLEVEL設置爲1,如果有匹配(否則爲0)。
  4. && echo %G - iff ERRORLEVEL不爲零,請將Java歸檔文件名寫入標準輸出(控制檯)。

網絡

使用search engine,掃描JAR files

+0

找到<目錄樹來搜索.jar文件> -name'*。jar'-print |同時閱讀我;做;完成 – mpez0 2009-08-27 18:50:04

+2

是的-l會給你,但它從stdin獲得它的輸入時不是很有用。 – 2012-04-03 01:27:44

+0

微小的調整,以找到任何位置以減少輸出(對我非常有用btw謝謝!!) - 爲我在$(找到「* .jar」);做jar -tvf $ i | grep -Hsi ClassName && echo $ i;完成 – psf 2016-06-21 09:53:10

0

你可以找到一個完整的罐子有位殼的目錄類:

尋找類 「FooBar的」:

LIB_DIR=/some/dir/full/of/jarfiles 
for jarfile in $(find $LIBDIR -name "*.jar"); do 
    echo "--------$jarfile---------------" 
    jar -tvf $jarfile | grep FooBar 
done 
1

檢查的JBoss Tattletale;儘管我從未親自使用它,但這似乎是您需要的工具。

-1

基本上讓我看看提出的問題的根源。 如果您正在開發一個新項目 - 爲什麼不到技術總監或技術主管詢問他 - 他如何跟蹤依賴關係?

+0

這應該是一個評論,而不是一個解決方案,它不解決也不回答問題,只是一個意見。操作員並沒有要求社會建議,stackoverflow應該是一個技術論壇,而不是心理諮詢。 – vasilevich 2018-01-09 10:06:49

0

有一點需要添加到上述所有內容中:如果您沒有jar可執行文件(它帶有JDK但不包含JRE),則可以使用unzip(或WinZip或其他)來完成一樣的東西。

11
#!/bin/bash 

pattern=$1 
shift 

for jar in $(find $* -type f -name "*.jar") 
do 
    match=`jar -tvf $jar | grep $pattern` 
    if [ ! -z "$match" ] 
    then 
    echo "Found in: $jar" 
    echo "$match" 
    fi 
done 
+0

太棒了!我必須在沒有jar的系統上使用它(不在路徑中),所以我用'unzip -l'替換了'jar -tvf'。 – ixe013 2013-09-30 15:23:50

18
grep -l "classname" *.jar 

給你的jar

find . -name "*.jar" -exec jar -t -f {} \; | grep "classname" 

的名字給你的類

+2

它應該是grep -lir「classname」* .jar – 2013-11-28 19:13:49

53

下載jar文件前一段時間,我寫的只是一個程序:https://github.com/javalite/jar-explorer

+3

查找任何類型的文件,而不僅僅是類。雙擊查看文件內容。耶,現在我可以看到我所有的春天模式。 – 2012-11-08 14:29:11

5

要找到匹配給定的字符串,罐子:

find . -name \*.jar -exec grep -l YOUR_CLASSNAME {} \;

+0

這也可以找到對類的引用,而不僅僅是類本身。 – 2012-07-05 19:05:40

0

無恥的自我推銷,但你可以嘗試一個實用程序,我寫道:http://sourceforge.net/projects/zfind

它支持大多數常見的存檔/壓縮文件(jar,zip,tar,tar.gz等)和不像很多其他的jar/zip finders,支持嵌套的zip文件(拉鍊內的zip,罐子內的jar等),直到無限的深度。

0

有點遲到了,但仍然...

我我一直在使用JarBrowser來查找某個類在哪個jar中。它有一個易於使用的GUI,它允許您瀏覽所選路徑中所有罐子的內容。

1

不知道爲什麼這裏的腳本從來沒有真正爲我工作。這工作:

#!/bin/bash 
for i in *.jar; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done 
0

下面的腳本將幫助你

for file in *.jar 
do 
    # do something on "$file" 
    echo "$file" 
    /usr/local/jdk/bin/jar -tvf "$file" | grep '$CLASSNAME' 
done 
1

要搜索在一個給定的目錄中的所有jar文件的特定類,你可以這樣做:

ls *.jar | xargs grep -F MyClass 

或,更簡單,

grep -F MyClass *.jar 

輸出看起來是這樣的:

Binary file foo.jar matches 

這是非常快,因爲-F選項意味着尋找固定的字符串,所以它不會加載的正則表達式引擎對每個grep的調用。如果需要,您可以隨時省略-F選項並使用正則表達式。

1

A bash script解決方案使用unzip (zipinfo)。經測試Ubuntu 12

#!/bin/bash 

# ./jarwalker.sh "https://stackoverflow.com/a/Starting/Path" "aClassName" 

IFS=$'\n' 
jars=($(find -P "$1" -type f -name "*.jar")) 

for jar in ${jars[*]} 
    do 
     classes=($(zipinfo -1 ${jar} | awk -F '/' '{print $NF}' | grep .class | awk -F '.' '{print $1}')) 
     if [ ${#classes[*]} -ge 0 ]; then 
      for class in ${classes[*]} 
       do 
        if [ ${class} == "$2" ]; then 
         echo "Found in ${jar}" 
        fi 
       done 
     fi 
    done 
+0

此腳本不兼容 – kisp 2013-08-08 09:36:43

3

user1207523的腳本適合我。這是一個使用find而不是簡單擴展來搜索jar文件的變體;

#!/bin/bash 
for i in `find . -name '*.jar'`; do jar -tf "$i" | grep $1 | xargs -I{} echo -e "$i : {}" ; done 
0

要添加另一個太...這是一個非常簡單和有用的Windows工具。點擊一個簡單的exe文件,給它一個搜索目錄,一個類名,它會找到包含該類的jar文件。是的,它是遞歸的。

http://sourceforge.net/projects/jarfinder/

0

在MinGW的(窗戶的bash環境)〜gitbash

將這個功能到你的.bashrc文件在主目錄中這一個效果很好:

# this function helps you to find a jar file for the class 
function find_jar_of_class() { 
    OLD_IFS=$IFS 
    IFS=$'\n' 
    jars=($(find -type f -name "*.jar")) 
    for i in ${jars[*]} ; do 
    if [ ! -z "$(jar -tvf "$i" | grep -Hsi $1)" ] ; then 
     echo "$i" 
    fi 
    done 
    IFS=$OLD_IFS 
} 
0

Grepj是一個命令用於在jar文件中搜索類。我是該實用程序的作者。

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

多個JAR,耳朵,可以提供戰爭文件的工具。對於高級用法,使用find來提供要搜索的罐子列表。

1

腳本找到jar文件:find_jar.sh

IFS=$(echo -en "\n\b") # Set the field separator newline 

for f in `find ${1} -iname *.jar`; do 
    jar -tf ${f}| grep --color $2 
    if [ $? == 0 ]; then 
    echo -n "Match found: " 
    echo -e "${f}\n" 
    fi 
done 
unset IFS 

用法:./find_jar.sh <頂層包含目錄的jar文件> <類名稱查找>

這類似於這裏給出的大多數答案但是它只輸出文件名,如果grep找到了。如果你想抑制grep輸出,你可以將它重定向到/ dev/null,但我更喜歡看到grep的輸出,以便我可以使用部分類名並從顯示的輸出列表中找出正確的名稱。

類名可以是簡單的類名像「String」或完全限定的名稱,如「java.lang。。字符串」

0

在Linux環境中,你可以做到以下幾點:

$ find <base_dir> -name *.jar -print0 | xargs -0 -l jar tf | grep <name> 

名稱是您在分佈在目錄層次結構中的jar內查找的類文件的名稱root編輯於base_dir

0

您可以使用locategrep

locate jar | xargs grep 'my.class' 

確保您使用locate之前運行updatedb

0

使用這個..你可以找到任何文件中的類路徑..保證..

import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 

public class FileFinder { 

    public static void main(String[] args) throws Exception { 

     String file = <your file name>; 

     ClassLoader cl = ClassLoader.getSystemClassLoader(); 

     URL[] urls = ((URLClassLoader)cl).getURLs(); 

     for(URL url: urls){ 
      listFiles(file, url); 
     } 
    } 

    private static void listFiles(String file, URL url) throws Exception{ 
     ZipInputStream zip = new ZipInputStream(url.openStream()); 
      while(true) { 
      ZipEntry e = zip.getNextEntry(); 
      if (e == null) 
       break; 
      String name = e.getName(); 
      if (name.endsWith(file)) { 
       System.out.println(url.toString() + " -> " + name); 
      } 
      } 
    } 

} 
2

我發現這個新的方式

bash $ ls -1 | xargs -i -t jar -tvf '{}'| grep Abstract 
jar -tvf activation-1.1.jar 
jar -tvf antisamy-1.4.3.jar 
    2263 Thu Jan 13 21:38:10 IST 2011 org/owasp/validator/html/scan/AbstractAntiSamyScanner.class 
... 

所以,如果發現此列出的jar和類,如果你想要,你可以給ls -1 * .jar或用find命令HTH Someone輸入到xargs。

+0

謝謝,我通過這種方式進行了改進:ls -1 * .jar | xargs -i -t jar -tvf'{}'| grep摘要 – 2016-09-27 09:18:36

0

在Eclipse中,你可以使用舊的,但仍然可用插件jarsearch

2

我一直用這個在Windows和它的工作非常出色。

findstr /s /m /c:"package/classname" *.jar, where 

的Findstr.exe標配視窗和PARAMS:

  • /S =遞歸
  • /米=打印僅文件名是否存在匹配
  • /C =字面字符串(在這種情況下,您的包名+類名 用'/'分隔)

希望這有助於omeone。

0

如果你有這個類的一個實例,或能得到一個,你有一個純Java解決方案:

try{ 
    Class clazz = Class.forName("  try{ 
     Class clazz = Class.forName("class-name"); 
     String name = "/"+clazz.getName().replace('.', '/')+".class"; 
     URL url = clazz.getResource(name); 
     String jar = url.toString().substring(10).replaceAll("!.*", ""); 
     System.out.println(jar); 
    }catch(Exception err){ 
     err.printStackTrace(); 
    } 

當然,前兩行必須根據,你有實例改編班級或班級名稱。

相關問題