簡體   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