简体   繁体   中英

Get Methods From External Java .jar File

I am trying to retrieve a list of the methods within an external java .jar file. This external jar will not be included in my build path, I need to source the info entirely by referencing it in the code externally. The use case is to search for deprecated methods inside of .jars which have been loaded on an app I work with.

I have found a couple of solutions online and applied them, however they all expect something to either be native to java or on the buildpath. I will only be able to provide a file/filepath as an argument, and derive everything based on this.

My code for now is as below, I'm looking for solutions on how to use this the way I need to. Any help would be greatly appreciated!

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

    Collection<Class<?>> classes = new ArrayList<Class<?>>();

    JarFile jar = new JarFile("C:\\app\\folder\\jar\\file.jar");

    for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); )
    {
        JarEntry entry = entries.nextElement();
        String file = entry.getName();

        if (file.endsWith(".class"))
        {

            String classname = file.replace('/','.').substring(0, file.length()-6);
        System.out.println(classname);

            try {
                Class<?> c = Class.forName(classname);
                classes.add(c);
            } catch (Throwable e) {
                System.out.println("WARNING: failed to instantiate " + classname + " from " + file);
            }
        }
    }
    for (Class<?> c: classes) 
        System.out.println(c);
}

You can construct a URLClassLoader with your external jar file and that use it to load classed you discovered in the jar. When you have a class object you can call getMethods() and getDeclaredMethods() to get private, protected and public methods of a class.

public static void main(String[] args) throws Exception {
        Set<Class<?>> classes = new HashSet<>();

        URL jarUrl = new URL("file:///C:/app/folder/jar/file.jar");
        URLClassLoader loader = new URLClassLoader(new URL[]{jarUrl});
        JarFile jar = new JarFile("C:\\app\\folder\\jar\\file.jar");

        for (Enumeration<JarEntry> entries = jar.entries(); entries.hasMoreElements(); )
        {
            JarEntry entry = entries.nextElement();
            String file = entry.getName();

            if (file.endsWith(".class"))
            {

                String classname =
                        file.replace('/', '.').substring(0, file.length() - 6).split("\\$")[0];
//                System.out.println(classname);

                try {
                    Class<?> c = loader.loadClass(classname);
                    classes.add(c);
                } catch (Throwable e) {
                    System.out.println("WARNING: failed to instantiate " + classname + " from " + file);
                }
            }
        }
        Map<String, List<Method>> collected =
                classes.stream().collect(Collectors.toMap(Class::getName, clz -> {
                    List<Method> methods = new ArrayList<>(Arrays.asList(clz.getDeclaredMethods()));
                    methods.addAll(Arrays.asList(clz.getMethods()));
                    return methods;
                }));

        collected.forEach((clz, methods) -> System.out.println("\n" + clz + "\n\n" + methods));
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM