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条回答
The star\"
2楼-- · 2019-01-21 23:12

Grepj is a command line utility to search for classes within jar files.

You can run the utility like grepj package.Class my1.jar my2.war my3.ear

Search scope is

  • Classes in the jar file
  • Classes within nested artifacts like jars within ear and war files
  • WEB-INF/classes is also searched.

Multiple jar, ear, war files can be provided.

查看更多
淡お忘
3楼-- · 2019-01-21 23:12

use this:

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();
        }
    }
}
查看更多
放荡不羁爱自由
4楼-- · 2019-01-21 23:17

for x in $(find . -name '*.jar') do unzip -l $x | grep WCCResponseImpl done

查看更多
我命由我不由天
5楼-- · 2019-01-21 23:18

(This is an improvement over the script I had in previous versions of the answer as it produces much cleaner output at the price of some awk special/ugly quoting.)

I've built a script (findinjars) which does just that.

#!/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

you can then invoke it with:

$findinjars a.b.c.d.Class [directoryTreeRoot or, if missing, current dir]

or just

$findinjars partOfClassName [directoryTreeRoot or, if missing, current dir]

Dot characters in the fully qualified class name will be interpreted in the regexp sense of 'any character' but that's not a big deal since this is a heuristics utility (that's why it's case-insensitive too BTW). Usually I don't bother with the full class name and just type part of it.

查看更多
叛逆
6楼-- · 2019-01-21 23:20

The best and easiest way is to use the JAD Decompiler. And yes, its an ECLIPSE PLUGIN !

Download and save the plugin in any location on your machine.

The plugin contains the following files:

  1. A temp folder
  2. A jad.exe file
  3. A *net.sf.jadclipse_3.3.0.jar* JAR plugin
  4. A Readme

Perform the following steps:

  1. Copy the JAR plugin to the plugins folder of eclipse folder
  2. Open eclipse. Goto Window >> Preferences >> Java >> JADClipse >> Path to Decompiler.
  3. Give the path of jad.exe
  4. Restart Eclipse

Now select any class and press F3.

The .class file will automatically decompile and display the contents !

查看更多
戒情不戒烟
7楼-- · 2019-01-21 23:20

You could always add the Reference library to your project in Eclipse and then in Package Browser, just expand the packages in the JAR file until you find the class that you are looking for.

查看更多
登录 后发表回答