簡體   English   中英

在 Java 14 運行時將 JarFile 添加到 Classpath

[英]Add JarFile to Classpath at runtime in Java 14

嘿,我如何使用 java 14+ 在運行時將 jar 添加到類路徑中? 正如我在一些示例中看到的那樣,我嘗試將 SystemClassLoader 轉換為 URLClassLoader,但它會引發 ClassCastException。 有誰知道我如何將 jar 放到較新的 java 版本的類路徑中?

“在運行時添加到系統類路徑”作為一個概念,通常不受支持。 可能有各種不支持的(因為它依賴於例如一些公共的東西是某物的子類,即使規范沒有做出這樣的保證)黑客來使其工作,但那里的關鍵字是unsupported 維護負擔非常高,因此只能作為最后的手段使用。 在這種情況下,沒有理由這樣做; 有更好的選擇。

即你在問一個 X/Y 問題。 你有一些未說明的問題,你想:我知道。 我將在運行時將 jar 添加到類路徑中! 現在你問的是如何做到這一點。

但錯誤出現在“我知道。我將在運行時將 jar 添加到類路徑中”部分。 那是錯誤的。

好的,那什么是對的?

只需創建一個新的類加載器,它將系統類加載器作為父類。 您顯然是在此處動態加載內容,因此請確保在正確的上下文中執行此操作。 (也就是說,不要運行例如Class.forName("foo.bar") ,而是運行thatClassLoaderYouMadeForThis.loadClass() )。

一個棘手的事情是以下過程:

  • 默認情況下(您可以使用自定義實現覆蓋此默認值,但這會使事情變得相當復雜),ClassLoader 將首先要求其父加載器加載一個事物,並且只有在父級找不到它時才會實際加載 class 本身。

  • class 將使用其自己的類加載器加載其任何依賴項(其中使用的任何類型)。 如果該類加載器找不到它,則會出現錯誤。

換句話說,如果你有這個 class:

class MyClassA {
   MyClassB b;
}

以及class MyClassB extends MyClassA {} ,並且MyClassA在您的系統類路徑中可用(因此,可以加載),而MyClassB不是,因此您正在使用子類加載器加載它,那么這不起作用- 行為加載MyClassB將導致MyClassA被加載,但由於父類加載器(作為系統類加載器)確實知道在哪里可以找到MyClassA ,它成為 MyClassA 的加載器,因此它將被要求加載MyClassB以了解該字段它有,這將失敗,因為系統加載程序不知道如何做到這一點。 But this is quite a bizarre scenario - how did you end up in a scenario where you have a class file ( MyClassA.class ) that was compiled with access to MyClassB , but MyClassB is no longer part of either the same jar file myClassA is in ,還是一般相同的類路徑條件?

所以,通常,這不是問題,但最好了解它是如何工作的。

順便說一句:

URLClassLoader myLoader = new URLCLassLoader(new URL[] {
  new URL(Paths.get("/path/to/my/custom/lib.jar").toUri().toURL()});

myLoader.loadClass("com.foo.whateverYouWantedToLoad");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM