Hi David,

On 6.11.2025 19:51, KARR, DAVID wrote:
> We support a large number of SpringBoot applications using tomcat-
> embed-core (currently at 10.1.41).  There are some configuration issues
> that result in the service startup failing with a "Tomcat startup"
> exception, which provides no information about the actual root cause.


Could you clarify what you mean by “root cause”?
Do you see no stack trace at all in the logs, or do you see a stack
trace that doesn’t include the original exception cause?


> I also note that in the service that shows the root cause, I see this in my 
> log:
> 
> 08:43:14,376 |-INFO in 
> ch.qos.logback.classic.jul.LevelChangePropagator@4eba373c - Propagating DEBUG 
> level on Logger[org.apache.catalina] onto the JUL framework
> 
> I do NOT see that in the service that is not showing the root cause. 


This message appears when Spring Boot installs SLF4JBridgeHandler [1] as
the `java.util.logging` (JUL) handler for all log events.
It’s worth noting that:

- The bridge is not installed at JVM startup, but later during Spring
  Boot initialization (specifically, when the `Environment` becomes
  available), so some early JUL events may not be captured.
- The installation is conditional: if JUL has exactly one
  `ConsoleHandler`, Spring Boot replaces it with the bridge.
  Therefore, behavior depends on the active `logging.properties` file.
- Before the bridge is active, JUL log levels and handlers are still
  governed by `logging.properties`, which may differ from Logback’s
  configuration or Spring Boot’s backend-independent `logging.level.*`
  [2] settings.

These factors can explain why you’re missing some log output during startup.

To make Tomcat’s logging more consistent and deterministic, you could
consider one or both of the following approaches:

### 1. Use an alternative Tomcat JULI backend

By default, Tomcat JULI uses the standard JUL backend, which is not very
friendly to replace. Spring Boot mitigates this by redirecting JUL
output as soon as possible, but there’s still a window where messages
can be lost.

Fortunately, you can replace Tomcat’s JULI backend entirely by adding a
different implementation to the classpath. Two good options are:

- Direct “Tomcat JULI → SLF4J” bridge [3]
- Indirect “Tomcat JULI → Log4j API” bridge [4] (maintained by ASF
  Logging Services)

Either works out of the box, since Spring Boot already includes the
”Log4j API → SLF4J” bridge (`log4j-to-slf4j` [5]).

With these bridges, all Tomcat log events will flow through Logback from
the very beginning of the JVM lifecycle.

### 2. Use an alternative JUL implementation

There are two ways to “replace” JUL itself:

- Use the standard `java.util.logging.LogManager` but forward its
  messages to another backend.
  This is what Spring Boot currently does, though it can cause double
  filtering: once in JUL and again in the target backend. If
  configurations are not aligned, some messages may be dropped. Aligning
  the configuration is the job of the LevelChangePropagator.
- Use an alternative `LogManager` implementation such as
  `org.apache.logging.log4j.jul.LogManager` [6], which forwards all JUL
  calls directly to the Log4j API.
  Replacing JUL completely is tricky: it must be done via the launcher
  script or a static initializer in your main class.
  Since JDK-8262741 [7] (which would allow ServiceLoader-based
  replacement) is unlikely to be implemented, we are considering writing
  a lightweight, Log4j-agnostic replacement `LogManager`. However,
  that’s currently low on our priority list.

Best regards,
Piotr

References:
[1] https://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
[2]
https://docs.spring.io/spring-boot/appendix/application-properties/index.html#application-properties.core.logging.level

[3] https://github.com/tomcat-slf4j-logback/tomcat-slf4j-logback
[4] https://logging.apache.org/log4j/2.x/jakarta.html#replace-tomcat
[5] https://logging.apache.org/log4j/2.x/components.html#log4j-to-slf4j
[6] https://logging.apache.org/log4j/2.x/log4j-jul.html#bridge-logmanager
[7] https://bugs.openjdk.org/browse/JDK-8262741


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to