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">

Reply via email to