RE: Trying log4j3 with java24 (virtual threads)
<[email protected]> Tue, 28 Jan 2025 17:31:51 +0100
| Newsgroups | gmane.comp.jakarta.log4j.user |
|---|---|
| Message-ID | <[email protected]> |
Hi, Same error with 3.0.0-alpha1 Joan. -----Original Message----- From: [email protected] <[email protected]>=20 Sent: Tuesday, January 28, 2025 5:24 PM To: 'Log4J Users List' <[email protected]> Subject: RE: Trying log4j3 with java24 (virtual threads) Hi Piotr, Thanks for the quick response. I'm trying to remove my initialization of = log4j and delegate it to the log4j-jakarta-web. When I add the = dependency, maven requires me to add a version tag, so I set: <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jakarta-web</artifactId> <version>2.24.3</version> <scope>runtime</scope> </dependency> But when I start my application, this error occurs: Caused by: java.lang.NoSuchMethodError: 'boolean = org.apache.logging.log4j.core.util.Loader.isClassAvailable(java.lang.Stri= ng)' at = org.apache.logging.log4j.web.Log4jWebInitializerImpl.<clinit>(Log4jWebIni= tializerImpl.java:57) at = org.apache.logging.log4j.web.WebLoggerContextUtils.getWebLifeCycle(WebLog= gerContextUtils.java:84) at = org.apache.logging.log4j.web.Log4jServletContainerInitializer.onStartup(L= og4jServletContainerInitializer.java:56) at = org.apache.catalina.core.StandardContext.startInternal(StandardContext.ja= va:4426) at = org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) Should I use another version? The 3.0.0 is in alpha1 yet. Thanks, Joan. -----Original Message----- From: Piotr P. Karwasz <[email protected]> Sent: Tuesday, January 28, 2025 3:49 PM To: [email protected] Subject: Re: Trying log4j3 with java24 (virtual threads) Hi Joan, On 28.01.2025 14:58, [email protected] wrote: > 0. Using these java version and log4j3, and taking into account that = 3.0.0-beta1 already includes support for virtual threads, will the fact = of pinning a thread for log output no longer happen? If you are referring to the usage of `synchronized` blocks, not all such = blocks were removed in 3.x, although it should be a rather easy PR. Note = that Java 24 removed thread pinning if `synchronized` blocks are used. > 1. You told me to set up "log4j-core" with scope =3D runtime, but I'm = using it on my code to load the log4j xml config file: > > import org.apache.logging.log4j.core.LoggerContext; > ( . . . ) > LoggerContext context =3D (LoggerContext) = LogManager.getContext(false); > context.setConfigLocation(Paths.get(servletRealPath +=20 > "WEB-INF/log4j.xml).toUri()); > =09 > Is this the correct way to do this? Or is there any other way that = does not need to directly use log4j-core? Loading the appropriate configuration file from the WAR archive is the = job of `log4j-jakarta-web`. See the description of the = `log4jConfiguration` servlet init parameter[1]. If you don't set the = parameter, `/WEB-INF/log4j2.xml` will be loaded (not = `/WEB-INF/log4j.xml`). I haven't checked, but version `3.0.0-alpha1` or = even `2.24.3` of `log4j-jakarta-web` should be compatible with beta 3 of = `log4j-core`. [1] https://logging.apache.org/log4j/2.x/jakarta.html#log4jConfiguration > b) Imported "log4j-api" (that adds the "log4j-api-2.24.1.jar" to our=20 > war file) As a transitional measure, you could bump the version of `log4j-api` to = `2.24.3`. We had a critical bug that sometimes returns `null` loggers, = so we do not recommend `2.24.1` of the Log4j API (see release notes = [2]). Obviously we'll fix the dependency version in beta 4. [2] https://logging.apache.org/log4j/2.x/release-notes.html#release-notes-2-2= 4-1 > c) Imported "log4j-slf4j2-impl", otherwise when our app starts I get = the following warning: > =09 > INFO: SLF4J: Failed to load class = "org.slf4j.impl.StaticLoggerBinder". > INFO: SLF4J: Defaulting to no-operation (NOP) logger implementation > INFO: SLF4J: Seehttp://www.slf4j.org/codes.html#StaticLoggerBinder = for further details. > =09 > Question: is it possible this warning is coming from any of our = external libraries that we are using? This is a side-effect of Maven's breadth-first conflict resolution algorithm: `log4j-slf4j2-impl` requires `slf4j-api` version 2.x or = higher, while other dependencies might requires SLF4J 1.x. Those = dependencies probably come first in your dependency tree. > 3. We have not included "log4j-jakarta-web", everything seems to be = working fine without it. Is it really necessary to include it in when = using app webs like ours executing in a tomcat container? The purpose of `log4j-jakarta-web` is to synchronize Log4j's lifecycle = with the lifecycle of the container. Basically it pick the right = configuration file at startup and shuts down the appenders, when the = application shuts down. See the documentation[3] for more info. [3] https://logging.apache.org/log4j/2.x/jakarta.html#log4j-jakarta-web-insta= llation > 4. We have programatically added: > System.setProperty("log4j.loggerContext.selector", = "org.apache.logging.log4j.core.selector.BasicContextSelector"); > --> This is to use synchronous loggers, I understand it is correct. Yes, `BasicContextSelector` creates a single logger context and = synchronous loggers. However, since you bundle Log4j Core with your = application and web application libraries are not shared between = applications, you would have the same effect with the default value = `ClassLoaderContextSelector` (theoretically it gives one logger context = per classloader, but since it can not be accessed from other = classloaders=E2=80=A6 you effectively have one logger context) [4] https://logging.apache.org/log4j/2.x/manual/systemproperties.html#log4j2.= contextSelector > Question: if the config is reloaded due to some change and, at the = same time, there was a change in the ${sys:log.buffer} env. variable, = will log4j be able to get the new value of ${sys:log.buffer}? Yes, variables are interpolated again at each reconfiguration. > 5. Finally, if I enable the log4j debug, how should I look at to check = I'm really using synchronous loggers? In Log4j Core 3 the asynchronous logger implementation is in the = `log4j-async-logger` artifact. You can be pretty sure your loggers are = synchronous. Piotr --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]