问题
I have an WebSphere Application Server which runs an WebApp. I start the Server from Eclipse. The main logging framework in that application is log4j2, but there are some third party libraries which use java.util.logging. I want to redirect those logs to log4j2 so it uses my filters, log format etc.
Therefore I tried to add the Log4j JDK Logging Adapter. I added the necessary JAR (I lacked only log4j-jul
as I already had the other log4j-jars for other purposes) to the Build Path and to the Deployment Assembly and added the line -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
to my jvm.options
.
Immediatly after startup I get the following exception:
Could not load Logmanager "org.apache.logging.log4j.jul.LogManager"
java.lang.ClassNotFoundException: org.apache.logging.log4j.jul.LogManager
at java.net.URLClassLoader.findClass(URLClassLoader.java:609)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:850)
at java.lang.ClassLoader.loadClass(ClassLoader.java:829)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:329)
at java.lang.ClassLoader.loadClass(ClassLoader.java:809)
at java.util.logging.LogManager$1.run(LogManager.java:206)
at java.util.logging.LogManager$1.run(LogManager.java:192)
at java.security.AccessController.doPrivileged(AccessController.java:594)
at java.util.logging.LogManager.<clinit>(LogManager.java:192)
at java.util.logging.Logger.demandLogger(Logger.java:459)
at java.util.logging.Logger.getLogger(Logger.java:513)
at com.sun.jmx.remote.util.ClassLogger.<init>(ClassLogger.java:67)
at javax.management.NotificationBroadcasterSupport.<clinit>(NotificationBroadcasterSupport.java:376)
at com.ibm.lang.management.OperatingSystemMXBeanImpl.<init>(OperatingSystemMXBeanImpl.java:38)
at com.ibm.lang.management.ExtendedOperatingSystem.<clinit>(ExtendedOperatingSystem.java:23)
at com.ibm.lang.management.RuntimeMXBeanImpl.<clinit>(RuntimeMXBeanImpl.java:29)
at com.ibm.lang.management.ManagementUtils.getRuntimeBean(ManagementUtils.java:402)
at java.lang.management.ManagementFactory.getRuntimeMXBean(ManagementFactory.java:393)
at com.ibm.ws.logging.internal.impl.LogProviderConfigImpl.getLogHeader(LogProviderConfigImpl.java:259)
at com.ibm.ws.logging.internal.impl.LogProviderConfigImpl.<init>(LogProviderConfigImpl.java:177)
at com.ibm.ws.logging.internal.impl.LogProviderImpl.configure(LogProviderImpl.java:31)
at com.ibm.ws.kernel.launch.internal.LauncherDelegateImpl.getLogProviderImpl(LauncherDelegateImpl.java:185)
at com.ibm.ws.kernel.launch.internal.LauncherDelegateImpl.launchFramework(LauncherDelegateImpl.java:91)
at com.ibm.ws.kernel.boot.internal.KernelBootstrap.go(KernelBootstrap.java:212)
at com.ibm.ws.kernel.boot.Launcher.handleActions(Launcher.java:246)
at com.ibm.ws.kernel.boot.Launcher.createPlatform(Launcher.java:121)
at com.ibm.ws.kernel.boot.cmdline.EnvCheck.main(EnvCheck.java:59)
at com.ibm.ws.kernel.boot.cmdline.EnvCheck.main(EnvCheck.java:35)
I don't know most of the classes in this stack trace but to me it looks like the exception is thrown very early, maybe while setting up the JVM, and that the jars packed in my .war file are not yet known.
The problem is that according to the log4j documentation linked above, I need to set the System Property for the LogManager
before the first call of the LogManager
, which indeed seems to happen in the NotificationBroadcasterSupport
from the stack trace.
Is there a way to make the jar known at this stage of startup?
Edit I asked a follow up question here and followed the suggestion there to use the Log4jBridgeHandler
instead of swapping out the LogManager
.
回答1:
The problem here is that it's not just your app that uses java.util.logging (JUL) - so does the core of the server, and by attempting to redirect JUL to Log4J and enforcing it with a system property (which applies to the entire JVM), you're essentially attempting to redirect all logging in the server through your Log4J setup. Anything that would be in the server's messages.log is going to show up in your logging instead.
If you still REALLY want to do this, the simplest solution is probably to put the log4j-jul jar into the JVM launch class path, so it's visible to the Java system loader (you may have to do the same with any dependencies and configuration files). Again, you're overriding all of the server-level logging, so I wouldn't expect that this would be a supported configuration (if you open a support case, they're not gonna want to review your custom Log4J-formatted logs for server details), but it should theoretically be functional.
来源:https://stackoverflow.com/questions/55827925/websphere-could-not-load-logmanager-org-apache-logging-log4j-jul-logmanager