繁体   English   中英

在运行时动态加载 jar?

[英]Load jar dynamically at runtime?

我当前的 java 项目正在使用另一个项目(同一个包)中的方法和变量。 现在另一个项目的 jar 必须在类路径中才能正常工作。 我的问题是 jar 的名称会随着版本的增加而改变,并且因为你不能在清单类路径中使用通配符,所以不可能将它添加到类路径中。 因此,目前启动我的应用程序的唯一选项是使用命令行中的-cp参数,手动添加我的项目所依赖的另一个 jar。

为了改进这一点,我想动态加载 jar 并阅读有关使用 ClassLoader 的信息。 我阅读了很多例子,但是我仍然不明白如何在我的情况下使用它。

我想要的是加载一个 jar 文件,比如说myDependency-2.4.1-SNAPSHOT.jar ,但它应该能够只搜索以myDependency-开头的 jar 文件 - 因为正如我已经说过的,版本号可以改变在任何时候。 然后我应该能够像现在一样在我的代码中使用它的方法和变量(比如ClassInMyDependency.exampleMethod() )。

任何人都可以帮我解决这个问题,因为我已经在网上搜索了几个小时,但仍然不知道如何使用 ClassLoader 来完成我刚刚解释的事情。

提前谢谢了

事实上,这有时是必要的。 这就是我在生产中这样做的方式。 它使用反射来规避系统类加载器中addURL的封装。

/*
     * Adds the supplied Java Archive library to java.class.path. This is benign
     * if the library is already loaded.
     */
    public static synchronized void loadLibrary(java.io.File jar) throws MyException
    {
        try {
            /*We are using reflection here to circumvent encapsulation; addURL is not public*/
            java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
            java.net.URL url = jar.toURI().toURL();
            /*Disallow if already loaded*/
            for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
                if (it.equals(url)){
                    return;
                }
            }
            java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
            method.setAccessible(true); /*promote the method to public access*/
            method.invoke(loader, new Object[]{url});
        } catch (final java.lang.NoSuchMethodException | 
            java.lang.IllegalAccessException | 
            java.net.MalformedURLException | 
            java.lang.reflect.InvocationTargetException e){
            throw new MyException(e);
        }
    }

我需要在运行时为 java 8 和 java 9+ 加载一个 jar 文件。 这是执行此操作的方法(如果可能相关,请使用 Spring Boot 1.5.2)。

public static synchronized void loadLibrary(java.io.File jar) {
    try {            
        java.net.URL url = jar.toURI().toURL();
        java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
        method.setAccessible(true); /*promote the method to public access*/
        method.invoke(Thread.currentThread().getContextClassLoader(), new Object[]{url});
    } catch (Exception ex) {
        throw new RuntimeException("Cannot load library from jar file '" + jar.getAbsolutePath() + "'. Reason: " + ex.getMessage());
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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