5

I am trying to detect which class inside a jar contains main or a supplied method name (if possible).

At the moment I have the following code

public static void getFromJars(String pathToAppJar) throws IOException{
    FileInputStream jar = new FileInputStream(pathToAppJar);
    ZipInputStream zipSteam = new ZipInputStream(jar);
    ZipEntry ze;
    while ((ze = zipSteam.getNextEntry()) != null) {
        System.out.println(ze.toString());          
    }
    zipSteam.close();
}

This will allow me to get packages and classes under these packages, but I do not know if it is possible to even get methods inside classes. Further, I do not know if this approach is even good for a case of several pkgs inside the jar, since each package can have a class with main in it.

I would appreciate any ideas.

Quantico
  • 2,398
  • 7
  • 35
  • 59
  • you can use a java decompiler and search the decompiled results: http://jd.benow.ca/ – Simulant Oct 26 '15 at 17:26
  • That is true, and I am using it at the moment, but I want something more automatic – Quantico Oct 26 '15 at 17:27
  • Duplicate of http://stackoverflow.com/questions/28776205/java-binary-class-file-format-parser ? – Marged Oct 26 '15 at 17:28
  • 1
    Have you seen http://stackoverflow.com/questions/9314541/analyze-jar-file-programmatically ? Once you got hold of each individual Class calling `getMethods()` should give you the info you need. – fvu Oct 26 '15 at 17:29
  • @fvu, I have not seen this post. This looks like a great solution. – Quantico Oct 26 '15 at 17:31
  • @fvu, looking more closely isn't load class requires the source? – Quantico Oct 26 '15 at 17:41
  • @Quantico no. See the line `if (zipEntry.getName().endsWith(".class")) {` and `Class> clazz = this.loadClass(className);`. It loads the binary class. A Java class file contains enough info to make a pretty decent reproduction of the source code. – fvu Oct 26 '15 at 17:44
  • What is "this" in that code? where is it being defined. In the code that I supplied above say you do ze.getName() ... you cannot just call Class> clazz = this.loadClass(className); – Quantico Oct 26 '15 at 17:46
  • 1
    Note that the proposed method is part of a custom classloader, one that extends `URLClassLoader`. There should be examples floating around but I cannot find a good one except http://examples.javacodegeeks.com/core-java/net/urlclassloader/java-net-urlclassloader-example/ right now. – fvu Oct 26 '15 at 18:02

1 Answers1

3

Thanks to fvu's comments, I ended up with the following code.

public static void getFromJars(String pathToAppJar) throws IOException, ClassNotFoundException
{
    FileInputStream jar = new FileInputStream(pathToAppJar);
    ZipInputStream zipSteam = new ZipInputStream(jar);
    ZipEntry ze;
    URL[] urls = { new URL("jar:file:" + pathToAppJar+"!/") };
    URLClassLoader cl = URLClassLoader.newInstance(urls);

    while ((ze = zipSteam.getNextEntry()) != null) {
        // Is this a class?
        if (ze.getName().endsWith(".class")) {
            // Relative path of file into the jar.
            String className = ze.getName();

            // Complete class name
            className = className.replace(".class", "").replace("/", ".");
            Class<?> klazz = cl.loadClass(className);
            Method[] methodsArray = klazz.getMethods();
        }
    }
    zipSteam.close();
}

I removed the code that uses the methods found, since it is not important for this answer

Gary
  • 13,303
  • 18
  • 49
  • 71
Quantico
  • 2,398
  • 7
  • 35
  • 59