![](/img/trans.png)
[英]Hazelcast Spring Boot 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 CloudwatchHandler是Handler
的一個實現,包括這個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.