簡體   English   中英

無法在 Spring 引導 web 應用程序中覆蓋 java.util.logging.LogManager:在已加載的 class 上獲取 java.lang.ClassNotFoundException

[英]Can't override java.util.logging.LogManager in a Spring Boot web application: Getting java.lang.ClassNotFoundException on already loaded class

我試圖用我自己的配置覆蓋java.util.logging.LogManager

class CloudwatchHandlerHandler的一個實現,包括這個init()方法:

public static void init() {
    final String julConfigFile = System.getProperty("java.util.logging.config.file");
    if(julConfigFile != null) {
        try (InputStream is = new FileInputStream(julConfigFile)) {
            LogManager logManager = LogManager.getLogManager();
            logManager.reset();
            logManager.readConfiguration(is);
            Logger logger = Logger.getLogger(CloudwatchHandler.class.getName());
            logger.info("LOADED");
        } catch (SecurityException | IOException e) {
            System.err.println(Instant.now() + ": Failed to initialize JUL.");
            e.printStackTrace(System.err);
            throw new RuntimeException(e);
        }
    }
    else {
        System.err.println(Instant.now() + ": java.util.logging.config.file was not specified");
    }

}

申請主 class

public static void main(String[] args) {
    CloudwatchHandler.init();
    SpringApplication.run(MyApp.class, args);
}

錯誤

Can't load log handler "mypackage.CloudwatchHandler"
java.lang.ClassNotFoundException: mypackage.CloudwatchHandler
java.lang.ClassNotFoundException: mypackage.CloudwatchHandler
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        at java.logging/java.util.logging.LogManager.createLoggerHandlers(LogManager.java:1005)
        at java.logging/java.util.logging.LogManager$4.run(LogManager.java:975)
        at java.logging/java.util.logging.LogManager$4.run(LogManager.java:971)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
        at java.logging/java.util.logging.LogManager.loadLoggerHandlers(LogManager.java:971)
        at java.logging/java.util.logging.LogManager.initializeGlobalHandlers(LogManager.java:2424)
        at java.logging/java.util.logging.LogManager$RootLogger.accessCheckedHandlers(LogManager.java:2526)
        at java.logging/java.util.logging.Logger.getHandlers(Logger.java:2090)
        at java.logging/java.util.logging.Logger.log(Logger.java:977)
        at java.logging/java.util.logging.Logger.doLog(Logger.java:1007)
        at java.logging/java.util.logging.Logger.log(Logger.java:1030)
        at java.logging/java.util.logging.Logger.info(Logger.java:1803)
        at mypackage.CloudwatchHandler.init(CloudwatchHandler.java:51)
        ... main ...

這個異常真正瘋狂的地方在於,導致ClassNotFoundException的 class 實際上是當前堆棧幀中的調用者,如堆棧跟蹤中所示。 很明顯它已被發現或無法運行。

是什么原因造成的,我該如何解決? 我只想加載我自己的日志處理程序。

Spring 引導版本為 2.6.3。

如果 Handler 未部署加載到系統 class 加載器中,則可能會發生 ClassNotFoundException,因為 LogManager 使用它來查找處理程序。

更新您的測試用例並重試:

public static void main(String[] args) throws Exception {
    System.out.println(ClassLoader.getSystemClassLoader());
    System.out.println(Thread.currentThread().getContextClassLoader());
    System.out.println(CloudwatchHandler.class.getClassLoader());

    //This is what CloudwatchHandler.init(); triggers
    Class.forName(CloudwatchHandler.class.getName(), true, Thread.currentThread().getContextClassLoader());

   //This is what the LogManager is doing
   Class.forName(CloudwatchHandler.class.getName(), true, ClassLoader.getSystemClassLoader());


   //Force load the root handlers.
   Logger.getLogger("").getHandlers();

   CloudwatchHandler.init();
   SpringApplication.run(MyApp.class, args);
}

如果處理程序部署在上下文 class 加載器中而不是系統類加載器中,那么您需要更改 package 處理程序的方式,以便它對系統類加載器可見。 java.util.logging.config.class選項是 LogManager 的一部分,它將嘗試通過上下文類加載器加載類,這將能夠看到您的類。 對於此選項,您將 init 方法的內容移動到新的 class 並讓構造函數執行操作。 然后在命令行上將值設置為新配置的 FQCN class。

暫無
暫無

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

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