从外部Java .jar文件

时间:2017-02-27 08:03:38

标签: java jar

我正在尝试检索外部java .jar文件中的方法列表。这个外部jar不会包含在我的构建路径中,我需要完全通过在外部代码中引用它来获取信息。用例是搜索.jars中已弃用的方法,这些方法已加载到我使用的应用程序上。

我已经在网上找到了几个解决方案并应用了它们,但是它们都希望有一些原生的java或构建路径。我只能提供一个文件/文件路径作为参数,并基于此推导出所有内容。

我现在的代码如下,我正在寻找如何以我需要的方式使用它的解决方案。任何帮助将不胜感激!

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);
}

1 个答案:

答案 0 :(得分:1)

您可以使用外部jar文件构建URLClassLoader,并使用它来加载您在jar中发现的类。当您有一个类对象时,可以调用getMethods()getDeclaredMethods()来获取类的私有,受保护和公共方法。

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));
    }