I have a Jersey servlet project, where I organize the depencies with maven. It runs in Tomcat.
Update of slf4j-api
Now I am trying to use <artifactId>slf4j-api</artifactId><version>2.0.17</version>
.
But I am not able to figure the right implementation yet. The documentation states:
Most notably, slf4j-api now relies on the ServiceLoader mechanism to find its logging backend. SLF4J 1.7.x and earlier versions relied on the static binder mechanism which is no longer honored by slf4j-api version 2.0.x. More specifically, during its initialization, the LoggerFactory class will no longer search for the org.slf4j.impl.StaticLoggerBinder class on the class path.
Instead of "bindings" now org.slf4j.LoggerFactory searches for "providers". These ship for example with slf4j-nop-2.0.x.jar, slf4j-simple-2.0.x.jar or slf4j-jdk14-2.0.x.jar.
If I am right, I need the following dependencies (works with slf4j-api v1.7):
- log4j-core
- log4j-weg
- log4j-slf4j-impl
Provider
When I use <artifactId>log4j-slf4j2-impl</artifactId><version>2.25.1</version>
I am getting the following information:
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
So no logging happens.
When I use <artifactId>log4j-slf4j-impl</artifactId><version>2.25.1</version>
I am getting this:
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
SLF4J(W): Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier.
SLF4J(W): Ignoring binding found at [jar:file:/path/to/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/quality-check/WEB-INF/lib/log4j-slf4j-impl-2.25.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
I especially don't get the line Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier
.
Usage
I am using a logger factory in my classes, where I need to log something. Like org.slf4j.LoggerFactory.getLogger(MyClass.class);
Solution?
Did anybody see a similar problem and how can I solve this? I am going back to slf4j-api 1.7 for now, but I am pretty sure that there is a way for using the fresher version.
-
version? jersey version? Tomcat version?life888888– life88888809/01/2025 10:25:26Commented 10 hours ago
-
Provide a minimal reproducible example in the question including the versions and if you are building with Maven/Gradle the build file.aled– aled09/01/2025 11:50:23Commented 9 hours ago
1 Answer 1
Create a Jersey 3.1.11 web application
https://eclipse-ee4j.github.io/jersey/download.html
If you want to create a Servlet container deployable Jersey 3.1.11 web application instead, use
Linux:
mvn archetype:generate \
-DarchetypeGroupId=org.glassfish.jersey.archetypes \
-DarchetypeArtifactId=jersey-quickstart-webapp \
-DarchetypeVersion=3.1.11
Windows:
mvn archetype:generate ^
-DarchetypeGroupId=org.glassfish.jersey.archetypes ^
-DarchetypeArtifactId=jersey-quickstart-webapp ^
-DarchetypeVersion=3.1.11
input groupId and artifactId:
- Define value for property 'groupId': com.example
- Define value for property 'artifactId': hello-jersey
Confirm properties configuration:
groupId: com.example
artifactId: hello-jersey
version: 1.0-SNAPSHOT
package: com.example
- Y: y
Output
hello-jersey
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── MyResource.java
│ └── webapp
│ ├── index.jsp
│ └── WEB-INF
│ └── web.xml
└── test
└── java
└── com
└── example
- delete directory
test
Modify Example
hello-jersey
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── MyResource.java
├── resources
│ └── log4j2.xml
└── webapp
├── index.jsp
└── WEB-INF
└── web.xml
pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>hello-jersey</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>hello-jersey</name>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jakarta.servlet.version>6.0.0</jakarta.servlet.version>
<slf4j.version>2.0.13</slf4j.version>
<log4j2.version>2.23.1</log4j2.version>
<jersey.version>3.1.11</jersey.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
</dependencies>
<build>
<finalName>hello-jersey</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://jakarta.ee/xml/ns/jakartaee" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" id="WebApp_ID" version="6.0">
<display-name>hello-jersey</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
log4j2.xml
ADD >>>>
at PatternLayout pattern=
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern=">>>> [%d{yyyy-MM-dd HH:mm:ss}] [%-5level] %c{1} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
MyResource.java
ADD:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(MyResource.class);
logger.info("Got it!");
package com.example;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Root resource (exposed at "myresource" path)
*/
@Path("myresource")
public class MyResource {
private static final Logger logger = LoggerFactory.getLogger(MyResource.class);
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
logger.info("Got it!");
return "Got it!";
}
}
Build
in hello-jersey directory:
mvn clean package
install into Tomcat
JDK 17
Tomcat 10.1
copy
target/hello-jersey.war
into tomcat webapps
cd tomcat/bin
./startup.sh
Test
Firefox open :
- http://localhost:8080/hello-jersey/
then click link : Jersey resource
- http://localhost:8080/hello-jersey/webapi/myresource
get return: Got it!
Open log
tomcat/logs/catalina.out
>>>> [2025年09月01日 20:21:04] [INFO ] MyResource - Got it!
>>>> [2025年09月01日 20:35:53] [INFO ] MyResource - Got it!
My Process
Problem breakdown, your requirements:
- SLF4J 2
- LOG4J2
- WAR running on Tomcat
Forget about Jersey for now.
Reorganized requirements:
- Maven
- JDK 17
- Tomcat 10.1
- Jakarta EE 10
- Web WAR
- SLF4J 2
- LOG4J2
Create the first POC WAR
So the first POC WAR requirement can be organized.
Then you can create a hello.war
using (1) SLF4J 2 and (2) LOG4J2, deployed to the Tomcat Server. It has nothing to do with Jersey.
After you successfully test it, you will know which (1) SLF4J 2 and (2) LOG4J2 dependency jars and corresponding versions are needed.
Create the second POC WAR(this answer)
After that, the next step (the second POC WAR) will be to build a Jersey WAR example based on the official documentation.
This example will simply integrate the SLF4J 2 and LOG4J2 dependencies and versions you discovered from the first POC WEB.
-
That works! This is probably one of the 'I have no clue how this ever worked' cases, I did not use
log4j-api
yet.BairDev– BairDev09/01/2025 13:19:30Commented 7 hours ago -
@BairDev At the end of my answer, I add: My Process; Problem breakdown to explain how I arrived at this answer.life888888– life88888809/01/2025 13:38:39Commented 7 hours ago