ramanathan1504 opened a new issue, #4242:
URL: https://github.com/apache/logging-log4j2/issues/4242
## Description
When `CassandraManager.startupInternal()` fails, the `Cluster` it created is
never closed, and because the DataStax 3.x driver's threads are **non-daemon**,
the JVM never exits. An application that logs to Cassandra and fails to start
the appender hangs on shutdown forever, having reported nothing worse than a
status-logger line.
Two things combine:
**1. The `Cluster` is built in the factory, but only closed from
`shutdownInternal()`.**
```java
@Override
protected void startupInternal() throws Exception {
session = cluster.connect(keyspace); // throws -> session stays
null
preparedStatement = session.prepare(insertQueryTemplate);
}
@Override
protected boolean shutdownInternal() throws Exception {
session.close(); // would NPE anyway if
reached
cluster.close(); // the only close() for
the Cluster
return true;
}
```
**2. `AbstractDatabaseManager.shutdown()` is guarded by `if
(this.isRunning())`**, and a failed startup leaves `running = false` — so
`shutdownInternal()` is never called and `cluster.close()` never runs.
`LogManager.shutdown()` reports success:
```
main DEBUG Shutting down CassandraManager Cassandra
main DEBUG Shut down CassandraManager Cassandra, all resources released: true
```
while five non-daemon driver threads remain alive, each carrying the
appender's configured `clusterName`:
```
"log4j-bench-nio-worker-0" non-daemon
"log4j-bench-nio-worker-1" non-daemon
"log4j-bench-connection-reaper-0" non-daemon
"log4j-bench-scheduled-task-worker-0" non-daemon
"log4j-bench-timeouter-0" non-daemon
```
The general guard asymmetry is #4241, since it affects every
`AbstractDatabaseManager`; this issue is the concrete case where the
consequence is a hung JVM rather than noisy logs.
### Why startup fails in the first place is worth recording too
The appender cannot bootstrap the keyspace it needs from the same JVM,
because its own driver initialises Log4j. The DataStax driver depends on Netty,
and Netty's `InternalLoggerFactory` acquires a Log4j logger *during driver
initialisation*. That first `LogManager.getLogger` call triggers configuration,
which starts the Cassandra appender, which calls `cluster.connect(keyspace)` —
for a keyspace that any in-JVM bootstrap code has not created yet, because it
is the very code initialising the driver:
```
at
org.apache.logging.log4j.cassandra.CassandraManager.startupInternal(CassandraManager.java:78)
at
org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager.startup(AbstractDatabaseManager.java:259)
at
org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender.start(AbstractDatabaseAppender.java:183)
at
org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:344)
at
org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:697)
...
at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:624)
at
io.netty.util.internal.logging.Log4J2LoggerFactory.newInstance(Log4J2LoggerFactory.java:33)
at
io.netty.util.internal.logging.InternalLoggerFactory.useLog4J2LoggerFactory(InternalLoggerFactory.java:76)
```
`startupInternal()` runs once, so the appender is dead for the rest of the
run. Creating the schema outside the JVM, before anything touches the driver,
is the only thing that works — and with the keyspace pre-created the appender
starts, writes and reads back correctly, which is what confirms the diagnosis
rather than working around it. This may be unavoidable given the driver, but it
is worth a line in the `log4j-cassandra` documentation, since the failure is
silent and the natural fix (create the keyspace at startup) cannot work.
## Configuration
**Version:** 2.x @ `04c93c1d33` (`log4j-cassandra` is not present on `main`,
so this is 2.x-only)
**Operating system:** macOS 15 (Darwin 25.5.0)
**JDK:** Temurin 21
**Cassandra:** 4.1.11 (driver
`com.datastax.cassandra:cassandra-driver-core:3.11.x` as shipped)
## Logs
```
main ERROR CassandraManager Cassandra Could not perform database startup
operations:
com.datastax.driver.core.exceptions.InvalidQueryException: Keyspace
'log4j' does not exist
main ERROR Unable to write to database [Cassandra] for appender [Cassandra].
java.lang.NullPointerException: Cannot invoke
"com.datastax.driver.core.PreparedStatement.bind(Object[])"
because "this.preparedStatement" is null
(repeated once per logged event)
main DEBUG Shut down CassandraManager Cassandra, all resources released: true
(JVM then does not exit)
```
## Reproduction
1. Start Cassandra 4.1 and do **not** create the keyspace.
2. Configure a `Cassandra` appender against it:
```xml
<Cassandra name="Cassandra" clusterName="log4j-bench" keyspace="log4j"
table="log_events" bufferSize="0" batched="false">
<SocketAddress host="localhost" port="9042"/>
<ColumnMapping name="id" pattern="%uuid{TIME}" type="java.util.UUID"/>
<ColumnMapping name="message" pattern="%message"/>
<ColumnMapping name="level" pattern="%level"/>
</Cassandra>
```
3. Log one event, call `LogManager.shutdown()`, and return from `main`.
Expected: the JVM exits. Actual: it hangs; `jstack` shows the non-daemon
driver threads above. Run with `-Dlog4j2.debug=true` to see the startup failure
that the per-event NPEs otherwise bury.
## Suggested fix
- Close the `Cluster` when `startupInternal()` fails — either by wrapping
the body in a `try`/`catch` that calls `cluster.close()` and rethrows, or by
making `shutdownInternal()` null-tolerant (`if (session != null)
session.close(); if (cluster != null) cluster.close();`) and letting it run
irrespective of `running`, per #4241.
- Optionally note in the `log4j-cassandra` docs that the keyspace and table
must exist before the JVM starts, and why in-JVM creation cannot work.
Happy to put a PR together if the approach looks right.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]