Skip to content

Starting executable war with -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager produces a ClassNotFoundException #12659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
electricsam opened this issue Mar 28, 2018 · 7 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@electricsam
Copy link

electricsam commented Mar 28, 2018

I would like to use Log4j2 as the logging implementation. As per the documentation here: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html#howto-configure-log4j-for-logging, I have set the following system property: -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager.

The following error is printed at startup:

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:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.util.logging.LogManager$1.run(LogManager.java:195)
	at java.util.logging.LogManager$1.run(LogManager.java:181)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.util.logging.LogManager.<clinit>(LogManager.java:181)
	at java.util.logging.Logger.demandLogger(Logger.java:448)
	at java.util.logging.Logger.getLogger(Logger.java:502)
	at com.sun.jmx.remote.util.ClassLogger.<init>(ClassLogger.java:55)
	at javax.management.NotificationBroadcasterSupport.<clinit>(NotificationBroadcasterSupport.java:365)
	at javax.management.MBeanServerDelegate.<init>(MBeanServerDelegate.java:72)
	at com.sun.jmx.mbeanserver.MBeanServerDelegateImpl.<init>(MBeanServerDelegateImpl.java:100)
	at com.sun.jmx.mbeanserver.JmxMBeanServer.newMBeanServerDelegate(JmxMBeanServer.java:1374)
	at javax.management.MBeanServerBuilder.newMBeanServerDelegate(MBeanServerBuilder.java:66)
	at javax.management.MBeanServerFactory.newMBeanServer(MBeanServerFactory.java:321)
	at javax.management.MBeanServerFactory.createMBeanServer(MBeanServerFactory.java:231)
	at javax.management.MBeanServerFactory.createMBeanServer(MBeanServerFactory.java:192)
	at java.lang.management.ManagementFactory.getPlatformMBeanServer(ManagementFactory.java:469)
	at org.apache.logging.log4j.core.jmx.Server.reregisterMBeansAfterReconfigure(Server.java:139)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:556)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.commons.logging.LogFactory$Log4jLog.<clinit>(LogFactory.java:199)
	at org.apache.commons.logging.LogFactory$Log4jDelegate.createLog(LogFactory.java:166)
	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:109)
	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:99)
	at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:198)
	at com.example.Application.main(Application.java:10)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
	at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:58)

Attached is a sample project that demonstrates the problem. Build it with "mvn package", unzip the log4j-war-example-1.0.0-SNAPSHOT.zip and run bin/run.sh.

I am using Spring Boot 2.0.0.

log4j-war-example.zip

@philwebb
Copy link
Member

philwebb commented Mar 28, 2018

Looks like we're either missing a dependency or our documentation needs updating. Try adding the following to your POM:

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-jul</artifactId>
</dependency>

@philwebb
Copy link
Member

See #11660 which added that documentation. I wonder if there's any problem adding the dependency to the starter?

@philwebb philwebb added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 28, 2018
@philwebb philwebb added this to the 2.0.x milestone Mar 28, 2018
@electricsam
Copy link
Author

electricsam commented Mar 29, 2018

@philwebb Adding that dependency to my pom worked.

@wilkinsona
Copy link
Member

I can't recall if we considered adding log4j-jul to the starter when we looked at #11660. The jar's only 24KB and I don't think it has any effect without the system property. There aren't any problems with adding it to the starter that I can see.

@philwebb
Copy link
Member

I think we should add it since it's only 24kb.

@wilkinsona wilkinsona self-assigned this Jun 4, 2018
@wilkinsona wilkinsona modified the milestones: 2.0.x, 2.0.3 Jun 4, 2018
@mkrawetko
Copy link

still getting exception with spring boot 2.0.3.RELEASE:

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:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.util.logging.LogManager$1.run(LogManager.java:195)
        at java.util.logging.LogManager$1.run(LogManager.java:181)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.util.logging.LogManager.<clinit>(LogManager.java:181)
        at java.util.logging.Logger.demandLogger(Logger.java:448)
        at java.util.logging.Logger.getLogger(Logger.java:502)
        at com.sun.jmx.remote.util.ClassLogger.<init>(ClassLogger.java:55)
        at sun.management.jmxremote.ConnectorBootstrap.<clinit>(ConnectorBootstrap.java:814)
        at sun.management.Agent.startAgent(Agent.java:257)
        at sun.management.Agent.startAgent(Agent.java:447)

adding dependency doesn't help :(

<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jul</artifactId>
        </dependency>

@wilkinsona
Copy link
Member

wilkinsona commented Jun 15, 2018

As shown by the stack trace, that's a different problem to the one reported in this issue.

In your case, Log4j needs to be available to the system class loader rather than the launcher class loader that Boot creates from the contents of BOOT-INF/lib. One way to achieve that would be to package Log4j's classes in the root of the jar. That's currently not as easy as we'd like it to be when using Maven (#6626). It's quite a bit easier with Gradle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants