波多野结衣 蜜桃视频,国产在线精品露脸ponn,a v麻豆成人,AV在线免费小电影

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了Spring Boot Runnable JAR無法找到通過java.system.class.loader JVM參數設置的類加載器的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

在如下的模塊結構中:

項目

|-公共模塊
|-app模塊

在app模塊將公共模塊作為依賴項的情況下,我有一個在公共模塊中定義的定制類加載器類。應用程序模塊-Djava.system.class.loader=org.project.common.CustomClassLoaderJVM參數設置為使用公共模塊中定義自定義類加載器。

在IDEA中運行一個Spring Boot項目,這可以完美地工作。找到自定義類加載器,將其設置為系統類加載器,一切正常。

編譯一個可運行的JAR(使用沒有任何定制屬性的默認Spring-Boot-maven-plugin),JAR本身擁有所有類,并且在它的lib目錄中是具有定制類加載器的公共JAR。但是,使用-Djava.system.class.loader=org.project.common.CustomClassLoader運行JAR會導致以下異常

java.lang.Error: org.project.common.CustomClassLoader
    at java.lang.ClassLoader.initSystemClassLoader(java.base@12.0.2/ClassLoader.java:1989)
    at java.lang.System.initPhase3(java.base@12.0.2/System.java:2132)
Caused by: java.lang.ClassNotFoundException: org.project.common.CustomClassLoader
    at jdk.internal.loader.BuiltinClassLoader.loadClass(java.base@12.0.2/BuiltinClassLoader.java:583)
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(java.base@12.0.2/ClassLoaders.java:178)
    at java.lang.ClassLoader.loadClass(java.base@12.0.2/ClassLoader.java:521)
    at java.lang.Class.forName0(java.base@12.0.2/Native Method)
    at java.lang.Class.forName(java.base@12.0.2/Class.java:415)
    at java.lang.ClassLoader.initSystemClassLoader(java.base@12.0.2/ClassLoader.java:1975)
    at java.lang.System.initPhase3(java.base@12.0.2/System.java:2132)

為什么會發生這種情況?是否因為在Runnable JAR中,類加載器類位于lib目錄中的jar中,所以類加載器試圖在將lib類添加到類路徑之前進行設置?除了將類加載器從公共模塊移動到所有其他需要它的模塊之外,我還能做什么嗎?

編輯:我嘗試將自定義類加載器類從公共模塊移動到應用程序,但仍然收到相同的錯誤。這是怎么回事?

推薦答案

在IDEA中運行一個Spring Boot項目,這可以完美地工作。找到自定義類加載器,將其設置為系統類加載器,一切正常。

因為IDEA將模塊放在類路徑上,并且其中一個模塊包含自定義類加載器。

是否因為在可運行的JAR中,類加載器類位于lib目錄中的jar中,因此在將lib類添加到類路徑之前嘗試設置類加載器?

差不多吧。庫類沒有添加到類路徑中,但可運行的Spring Boot應用程序自己的自定義類加載器知道在哪里找到它們以及如何加載它們。

要更深入地了解java.system.class.loader,請閱讀ClassLoader.getSystemClassLoader()的Javadoc(添加了枚舉后略微重新格式化):

    如果第一次調用此方法時定義了系統屬性java.system.class.loader,則該屬性的值將被視為將作為系統類加載器返回的類的名稱。
    該類是使用默認系統類加載器加載的,并且必須定義一個公共構造函數,該構造函數接受用作委托父級的類型ClassLoader的單個參數。
    然后使用此構造函數以默認系統類加載器作為參數創建實例。
    結果類加載器被定義為系統類加載器。
    在構造過程中,類加載器要特別注意避免調用getSystemClassLoader()。如果檢測到系統類加載器的循環初始化,則引發IllegalStateException

這里的決定性因素是#3:用戶定義的系統類加載器由默認的系統類加載器加載。當然,后者不知道如何從嵌套JAR中加載內容。只有在JVM完全初始化并啟動了Spring Boot的特殊應用程序類加載器之后,才能讀取這些嵌套的JAR。

即您遇到了雞和蛋的問題:為了在JVM初始化期間找到您的自定義類加載器,您需要使用尚未初始化的Spring Boot Runnable JAR類加載器。

如果您想知道上面所描述的Javadoc在實踐中是如何實現的,請查看OpenJDKsource code of ClassLoader.initSystemClassLoader()

除了將類加載器從公共模塊移動到所有其他需要它的模塊之外,我還能做什么嗎?

如果您堅持使用Runnable JAR,即使這樣也無濟于事。您可以執行以下任一操作:

運行您的應用程序,而不是將其壓縮到可運行的JAR中,而是將其作為一個普通的Java應用程序運行,所有應用程序模塊(尤其是包含自定義類加載器的模塊)都位于類路徑上。
將您的自定義類加載器提取到可運行JAR外部的單獨模塊中,并在運行可運行JAR時將其放在類路徑上。
通過Thread.setContextClassLoader()左右設置您的自定義類加載器,而不是嘗試將其用作系統類加載器(如果這是一個可行的選項)。


更新2020-10-28:在可執行Jar格式文檔中,我在"Executable Jar Restrictions"下找到了:

系統類加載器:啟動的應用程序在加載類時應該使用Thread.getContextClassLoader()(大多數庫和框架默認這樣做)。嘗試使用ClassLoader.getSystemClassLoader()加載嵌套的JAR類失敗。java.util.Logging始終使用系統類加載器。因此,您應該考慮不同的日志記錄實現。

這證實了我在上面所寫的內容,特別是我關于使用線程上下文類加載器的最后一個要點。

這篇關于Spring Boot Runnable JAR無法找到通過java.system.class.loader JVM參數設置的類加載器的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標簽:Boot JAR Runnable Spring 加載 參數設置 找到
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定