This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/release-2.x by this push:
new 17c6ae5 [LOG4J2-2612] NullPointerException at
org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:803).
17c6ae5 is described below
commit 17c6ae50d2ad98035537016bee7296f3ca612e95
Author: Gary Gregory <[email protected]>
AuthorDate: Wed May 29 20:27:33 2019 -0400
[LOG4J2-2612] NullPointerException at
org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:803).
---
.../core/appender/db/jdbc/JdbcDatabaseManager.java | 53 ++++++++++++++++------
src/changes/changes.xml | 3 ++
2 files changed, 42 insertions(+), 14 deletions(-)
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
index f919966..da92a10 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
@@ -25,6 +25,7 @@ import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
+import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
@@ -480,13 +481,13 @@ public final class JdbcDatabaseManager extends
AbstractDatabaseManager {
private void checkConnection() {
boolean connClosed = true;
try {
- connClosed = this.connection == null || this.connection.isClosed();
+ connClosed = isClosed(this.connection);
} catch (final SQLException e) {
// Be quiet
}
boolean stmtClosed = true;
try {
- stmtClosed = this.statement == null || this.statement.isClosed();
+ stmtClosed = isClosed(this.statement);
} catch (final SQLException e) {
// Be quiet
}
@@ -509,28 +510,28 @@ public final class JdbcDatabaseManager extends
AbstractDatabaseManager {
}
protected void closeResources(final boolean logExceptions) {
+ final PreparedStatement tempPreparedStatement = this.statement;
+ this.statement = null;
try {
// Closing a statement returns it to the pool when using Apache
Commons DBCP.
// Closing an already closed statement has no effect.
- Closer.close(this.statement);
+ Closer.close(tempPreparedStatement);
} catch (final Exception e) {
if (logExceptions) {
logWarn("Failed to close SQL statement logging event or
flushing buffer", e);
}
- } finally {
- this.statement = null;
}
+ final Connection tempConnection = this.connection;
+ this.connection = null;
try {
// Closing a connection returns it to the pool when using Apache
Commons DBCP.
// Closing an already closed connection has no effect.
- Closer.close(this.connection);
+ Closer.close(tempConnection);
} catch (final Exception e) {
if (logExceptions) {
logWarn("Failed to close database connection logging event or
flushing buffer", e);
}
- } finally {
- this.connection = null;
}
}
@@ -656,6 +657,28 @@ public final class JdbcDatabaseManager extends
AbstractDatabaseManager {
}
}
+ /**
+ * Checks if a statement is closed. A null statement is considered
closed.
+ *
+ * @param statement The statement to check.
+ * @return true if a statement is closed, false if null.
+ * @throws SQLException if a database access error occurs
+ */
+ private boolean isClosed(final Statement statement) throws SQLException
{
+ return statement == null || statement.isClosed();
+ }
+
+ /**
+ * Checks if a connection is closed. A null connection is considered
closed.
+ *
+ * @param connection The connection to check.
+ * @return true if a connection is closed, false if null.
+ * @throws SQLException if a database access error occurs
+ */
+ private boolean isClosed(final Connection connection) throws
SQLException {
+ return connection == null || connection.isClosed();
+ }
+
private void reconnectOn(final Exception exception) {
if (!factoryData.retry) {
throw new AppenderLoggingException("Cannot connect and prepare",
exception);
@@ -743,11 +766,10 @@ public final class JdbcDatabaseManager extends
AbstractDatabaseManager {
protected void writeInternal(final LogEvent event, final Serializable
serializable) {
StringReader reader = null;
try {
- if (!this.isRunning() || this.connection == null ||
this.connection.isClosed() || this.statement == null
- || this.statement.isClosed()) {
- throw new AppenderLoggingException(
- "Cannot write logging event; JDBC manager not
connected to the database.");
- }
+ if (!this.isRunning() || isClosed(this.connection) ||
isClosed(this.statement)) {
+ throw new AppenderLoggingException(
+ "Cannot write logging event;
JDBC manager not connected to the database.");
+ }
// Clear in case there are leftovers.
statement.clearParameters();
if (serializable instanceof MapMessage) {
@@ -817,7 +839,10 @@ public final class JdbcDatabaseManager extends
AbstractDatabaseManager {
} finally {
// Release ASAP
try {
- statement.clearParameters();
+ // statement can be null when a AppenderLoggingException is
thrown at the start of this method
+ if (statement != null) {
+ statement.clearParameters();
+ }
} catch (final SQLException e) {
// Ignore
}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 909eae2..a3f3fe2 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -79,6 +79,9 @@
<action issue="LOG4J2-2611" dev="ckozak" type="add">
AsyncQueueFullPolicy configuration short values "Default" and
"Discard" are case insensitive to avoid confusion.
</action>
+ <action issue="LOG4J2-2612" dev="ggregory" type="fix">
+ NullPointerException at
org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager.writeInternal(JdbcDatabaseManager.java:803).
+ </action>
</release>
<release version="2.11.2" date="2019-02-04" description="GA Release
2.11.2">
<action issue="LOG4J2-2500" dev="rgoers" type="fix">