Hello,
I'm already running log4j3 with java24 / tomcat 10.1.34. Just some questions:
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?
1. You told me to set up "log4j-core" with scope = 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 = (LoggerContext) LogManager.getContext(false);
context.setConfigLocation(Paths.get(servletRealPath +
"WEB-INF/log4j.xml).toUri());
Is this the correct way to do this? Or is there any other way that does
not need to directly use log4j-core?
2. My config is finally this:
On the parent pom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>${log4j2.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
On the module (child) pom:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<scope>runtime</scope>
</dependency>
a) Imported "log4j-core" because of what I said in point 1.
b) Imported "log4j-api" (that adds the "log4j-api-2.24.1.jar" to our
war file)
c) Imported "log4j-slf4j2-impl", otherwise when our app starts I get
the following warning:
INFO: SLF4J: Failed to load class
"org.slf4j.impl.StaticLoggerBinder".
INFO: SLF4J: Defaulting to no-operation (NOP) logger
implementation
INFO: SLF4J: See
http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Question: is it possible this warning is coming from any of our
external libraries that we are using?
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?
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.
System.setProperty("log.buffer", 4096);
--> This system property is used in the log4j.xml:
<RollingRandomAccessFile name="ACCESS_LOG"
fileName="${sys:log.dir}vproxy_access"
filePattern="${sys:log.dir}vproxy_access.%d{yyyy-MM-dd}" append="true" ********
bufferSize="${sys:log.buffer}" ******* immediateFlush="false">
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}?
5. Finally, if I enable the log4j debug, how should I look at to check I'm
really using synchronous loggers?
Thanks!
Joan.
-----Original Message-----
From: Piotr P. Karwasz <[email protected]>
Sent: Monday, January 27, 2025 10:44 AM
To: [email protected]
Subject: Re: Trying log4j3 with java24 (virtual threads)
Hi Joan,
We did prepare a migration guide from Log4j 2 to Log4j Core 3:
https://logging.apache.org/log4j/3.x/migrate-from-log4j2.html
As Volkan mentioned, some features migrated to new modules, others were
deprecated.
On 25.01.2025 13:37, [email protected] wrote:
> 2. My current maven looks like below now, where log4j2.version is '2.24.2'
>
> <!-- disruptor -->
> <dependency>
> <groupId>com.lmax</groupId>
> <artifactId>disruptor</artifactId>
> <version>4.0.0</version>
> </dependency>
>
> <!-- log4j -->
> <dependency>
> <groupId>org.apache.logging.log4j</groupId>
> <artifactId>log4j-core</artifactId>
> <version>${log4j2.version}</version>
> </dependency>
We strongly recommend the usage of the Bill-of-Materials (BOM):
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>3.0.0-beta3</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
There are multiple reasons behind that:
* If you don't use the BOM an unrelated direct dependency (e.g. Apache
POI) can pull a version of `log4j-api`, which is incompatible with `log4j-core`
version `3.0.0-beta3`.
* The `log4j-core` artifact version `3.0.0-beta3` requires `log4j-api` version
`2.24.x`. You don't have to remember that if you use the BOM.
We also recommend to put `log4j-core` in the `runtime` scope, since you will
not be referring to it from your code.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>runtime</scope>
</dependency>
Regarding `com.lmax:disruptor`, you need to replace it with:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-async-logger</artifactId>
<scope>runtime</scope>
</dependency>
LMAX Disruptor will still be a transitive dependency of your project, but you
don't need to upgrade it manually any more.
> <dependency>
> <groupId>org.apache.logging.log4j</groupId>
> <artifactId>log4j-api</artifactId>
> <version>${log4j2.version}</version>
> </dependency>
As mentioned above, `log4j-core` 3.x will depend on `log4j-api` 2.x, so you
should use the BOM.
Also, if you don't use the Log4j API[1] in your code (because you use another
logging API like SLF4J for example), you can remove this dependency. Don't get
me wrong: we are happy if you use Log4j API and there are a lot of advantages
to use Log4j API over SLF4J[2], but we understand if you use a different
logging API. After all, logging APIs are there to give you the freedom to
choose whatever implementation you want.
[1] https://logging.apache.org/log4j/3.x/manual/api.html
[2]
https://stackoverflow.com/questions/41498021/is-it-worth-to-use-slf4j-with-log4j2
> <dependency>
> <groupId>org.apache.logging.log4j</groupId>
> <artifactId>log4j-jakarta-web</artifactId>
> <version>${log4j2.version}</version>
> </dependency>
As Volkan mentioned, `log4j-jakarta-web` will have its own lifecycle and we
didn't have the time to release a Beta version yet, sorry. It is on our TODO
list.
> <dependency>
> <groupId>org.apache.logging.log4j</groupId>
> <artifactId>log4j-slf4j-impl</artifactId>
> <version>${log4j2.version}</version>
> </dependency>
The choice of the SLF4J-to-Log4j API bridge to use depends on the version of
SLF4J you use. For SLF4J 2.x you need to use `log4j-slf4j2-impl` instead.
> <dependency>
> <groupId>org.apache.logging.log4j</groupId>
> <artifactId>log4j-1.2-api</artifactId>
> <version>${log4j2.version}</version>
> </dependency>
This is a temporary artifact to help users upgrade from Log4j 1 to Log4j 2. In
2025 you probably don't want it. It is only required if:
* If you have dependencies that use Log4j 1 as logging API. Most libraries
migrated to Commons Logging or SLF4J by 2010, so no modern library should
require it.
* If you have an extensive user base that has custom `log4j.properties`
configuration files and you wish to allow them to keep using that format.
Piotr
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]