Repository: logging-log4j2
Updated Branches:
  refs/heads/master 639f093b8 -> 83f24c091


[LOG4J2-2186] Add a JDBC ConnectionSource that provides pooling through
Apache Commons DBCP 2. Avoid generics compiler differences between
Eclipse and Oracle Java.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/83f24c09
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/83f24c09
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/83f24c09

Branch: refs/heads/master
Commit: 83f24c091ed08b0eae6bde9b3edf6644a3306a86
Parents: 639f093
Author: Gary Gregory <[email protected]>
Authored: Thu Jan 18 22:12:33 2018 -0700
Committer: Gary Gregory <[email protected]>
Committed: Thu Jan 18 22:12:33 2018 -0700

----------------------------------------------------------------------
 .../db/jdbc/AbstractConnectionSource.java       |  26 +++
 .../AbstractDriverManagerConnectionSource.java  | 219 +++++++++++++++++++
 .../core/appender/db/jdbc/ConnectionSource.java |   4 +-
 .../db/jdbc/DataSourceConnectionSource.java     |   2 +-
 .../db/jdbc/DriverManagerConnectionSource.java  | 192 +---------------
 .../db/jdbc/FactoryMethodConnectionSource.java  |   2 +-
 .../appender/db/jdbc/JdbcDatabaseManager.java   |   3 +
 .../jdbc/JdbcAppenderHsqldbDataSourceTest.java  |   2 +-
 .../JdbcAppenderHsqldbFactoryMethodTest.java    |   2 +-
 .../core/appender/db/jdbc/JdbcH2TestHelper.java |   2 +-
 .../db/jdbc/PoolingDriverConnectionSource.java  |  30 ++-
 .../jdbc/PoolingDriverConnectionSourceTest.java |   2 +-
 .../log4j-samples-flume-embedded/pom.xml        |   2 +-
 src/changes/changes.xml                         |   3 +
 14 files changed, 290 insertions(+), 201 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractConnectionSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractConnectionSource.java
new file mode 100644
index 0000000..bd04eac
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractConnectionSource.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.db.jdbc;
+
+import org.apache.logging.log4j.core.AbstractLifeCycle;
+
+public abstract class AbstractConnectionSource extends AbstractLifeCycle 
implements ConnectionSource {
+    
+    // nothing yet
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractDriverManagerConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractDriverManagerConnectionSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractDriverManagerConnectionSource.java
new file mode 100644
index 0000000..717ce65
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractDriverManagerConnectionSource.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender.db.jdbc;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.Property;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * A {@link ConnectionSource} that uses a JDBC connection string, a user name, 
and a password to call
+ * {@link DriverManager#getConnection(String, String, String)}.
+ * <p>
+ * This plugin does not provide any connection pooling unless it is available 
through the connection string and driver
+ * itself. This handy to get you off the ground without having to deal with 
JNDI.
+ * </p>
+ */
+public class AbstractDriverManagerConnectionSource extends 
AbstractConnectionSource {
+
+    /**
+     * Builds DriverManagerConnectionSource instances.
+     *
+     * @param <B>
+     *            This builder type or a subclass.
+     */
+    public static class Builder<B extends Builder<B>> {
+
+        @PluginBuilderAttribute
+        @Required
+        private String connectionString;
+
+        @PluginBuilderAttribute
+        private String driverClassName;
+
+        @PluginBuilderAttribute
+        private char[] password;
+
+        @PluginElement("Properties")
+        private Property[] properties;
+
+        @PluginBuilderAttribute
+        private char[] userName;
+
+        @SuppressWarnings("unchecked")
+        protected B asBuilder() {
+            return (B) this;
+        }
+
+        public String getConnectionString() {
+            return connectionString;
+        }
+
+        public String getDriverClassName() {
+            return driverClassName;
+        }
+
+        public char[] getPassword() {
+            return password;
+        }
+
+        public Property[] getProperties() {
+            return properties;
+        }
+
+        public char[] getUserName() {
+            return userName;
+        }
+
+        public B setConnectionString(final String connectionString) {
+            this.connectionString = connectionString;
+            return asBuilder();
+        }
+
+        public B setDriverClassName(final String driverClassName) {
+            this.driverClassName = driverClassName;
+            return asBuilder();
+        }
+
+        public B setPassword(final char[] password) {
+            this.password = password;
+            return asBuilder();
+        }
+
+        public B setProperties(final Property[] properties) {
+            this.properties = properties;
+            return asBuilder();
+        }
+
+        public B setUserName(final char[] userName) {
+            this.userName = userName;
+            return asBuilder();
+        }
+    }
+
+    private static final Logger LOGGER = StatusLogger.getLogger();
+
+    public static Logger getLogger() {
+        return LOGGER;
+    }
+
+    private final String actualConnectionString;
+    private final String connectionString;
+    private final String driverClassName;
+    private final char[] password;
+    private final Property[] properties;
+    private final char[] userName;
+
+    public AbstractDriverManagerConnectionSource(final String driverClassName, 
final String connectionString,
+            String actualConnectionString, final char[] userName, final char[] 
password, final Property[] properties) {
+        super();
+        this.driverClassName = driverClassName;
+        this.connectionString = connectionString;
+        this.actualConnectionString = actualConnectionString;
+        this.userName = userName;
+        this.password = password;
+        this.properties = properties;
+    }
+
+    public String getActualConnectionString() {
+        return actualConnectionString;
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        loadDriver();
+        // No, you cannot see the user name and password.
+        final String actualConnectionString = getActualConnectionString();
+        LOGGER.debug("Getting connection from DriverManage for '{}'", 
actualConnectionString);
+        if (properties != null && properties.length > 0) {
+            if (userName != null || password != null) {
+                throw new SQLException("Either set the userName and password, 
or set the Properties, but not both.");
+            }
+            return DriverManager.getConnection(actualConnectionString, 
toProperties(properties));
+        }
+        return DriverManager.getConnection(actualConnectionString, 
toString(userName), toString(password));
+    }
+
+    public String getConnectionString() {
+        return connectionString;
+    }
+
+    public String getDriverClassName() {
+        return driverClassName;
+    }
+
+    public char[] getPassword() {
+        return password;
+    }
+
+    public Property[] getProperties() {
+        return properties;
+    }
+
+    public char[] getUserName() {
+        return userName;
+    }
+
+    protected void loadDriver() throws SQLException {
+        loadDriver(driverClassName);
+    }
+
+    /**
+     * Loads a JDBC driver for the given class name
+     *
+     * @param className
+     *            the fully-qualified class name for a JDBC Driver.
+     * @throws SQLException
+     *             thrown when loading the driver throws an exception.
+     */
+    protected void loadDriver(final String className) throws SQLException {
+        if (className != null) {
+            // Hack for old JDBC drivers.
+            try {
+                Class.forName(className);
+            } catch (final Exception e) {
+                throw new SQLException(String.format("The %s could not load 
the JDBC driver %s: %s",
+                        getClass().getSimpleName(), className, e.toString()), 
e);
+            }
+        }
+    }
+
+    private Properties toProperties(final Property[] properties) {
+        final Properties props = new Properties();
+        for (final Property property : properties) {
+            props.setProperty(property.getName(), property.getValue());
+        }
+        return props;
+    }
+
+    @Override
+    public String toString() {
+        return this.connectionString;
+    }
+
+    private String toString(final char[] value) {
+        return value == null ? null : String.valueOf(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.java
index b803ac5..2a25b25 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/ConnectionSource.java
@@ -19,11 +19,13 @@ package org.apache.logging.log4j.core.appender.db.jdbc;
 import java.sql.Connection;
 import java.sql.SQLException;
 
+import org.apache.logging.log4j.core.LifeCycle;
+
 /**
  * Configuration element for {@link JdbcAppender}. If you want to use the 
{@link JdbcAppender} but none of the provided
  * connection sources meet your needs, you can simply create your own 
connection source.
  */
-public interface ConnectionSource {
+public interface ConnectionSource extends LifeCycle{
     
     /**
      * This should return a new connection every time it is called.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java
index 389586e..a791df9 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DataSourceConnectionSource.java
@@ -35,7 +35,7 @@ import org.apache.logging.log4j.util.Strings;
  * A {@link JdbcAppender} connection source that uses a {@link DataSource} to 
connect to the database.
  */
 @Plugin(name = "DataSource", category = Core.CATEGORY_NAME, elementType = 
"connectionSource", printObject = true)
-public final class DataSourceConnectionSource implements ConnectionSource {
+public final class DataSourceConnectionSource extends AbstractConnectionSource 
{
     private static final Logger LOGGER = StatusLogger.getLogger();
 
     private final DataSource dataSource;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DriverManagerConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DriverManagerConnectionSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DriverManagerConnectionSource.java
index 544c835..e390c5e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DriverManagerConnectionSource.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/DriverManagerConnectionSource.java
@@ -16,20 +16,12 @@
  */
 package org.apache.logging.log4j.core.appender.db.jdbc;
 
-import java.sql.Connection;
 import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.Properties;
 
-import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.Core;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
-import org.apache.logging.log4j.core.config.plugins.PluginElement;
-import 
org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
-import org.apache.logging.log4j.status.StatusLogger;
 
 /**
  * A {@link ConnectionSource} that uses a JDBC connection string, a user name, 
and a password to call
@@ -40,199 +32,33 @@ import org.apache.logging.log4j.status.StatusLogger;
  * </p>
  */
 @Plugin(name = "DriverManager", category = Core.CATEGORY_NAME, elementType = 
"connectionSource", printObject = true)
-public class DriverManagerConnectionSource implements ConnectionSource {
+public class DriverManagerConnectionSource extends 
AbstractDriverManagerConnectionSource {
 
     /**
      * Builds DriverManagerConnectionSource instances.
      *
      * @param <B>
      *            This builder type or a subclass.
-     * @param <T>
-     *            The type to build.
      */
-    public static class Builder<B extends Builder<B, T>, T extends 
DriverManagerConnectionSource>
-            implements org.apache.logging.log4j.core.util.Builder<T> {
+    public static class Builder<B extends Builder<B>> extends 
AbstractDriverManagerConnectionSource.Builder<B>
+            implements 
org.apache.logging.log4j.core.util.Builder<DriverManagerConnectionSource> {
 
-        @PluginBuilderAttribute
-        @Required
-        private String connectionString;
-
-        @PluginBuilderAttribute
-        private String driverClassName;
-
-        @PluginBuilderAttribute
-        private char[] password;
-
-        @PluginElement("Properties")
-        private Property[] properties;
-
-        @PluginBuilderAttribute
-        private char[] userName;
-
-        @SuppressWarnings("unchecked")
-        protected B asBuilder() {
-            return (B) this;
-        }
-
-        @SuppressWarnings("unchecked")
         @Override
-        public T build() {
-            return (T) new DriverManagerConnectionSource(driverClassName, 
connectionString, connectionString, userName,
-                    password, properties);
-        }
-
-        public String getConnectionString() {
-            return connectionString;
-        }
-
-        public String getDriverClassName() {
-            return driverClassName;
-        }
-
-        public char[] getPassword() {
-            return password;
-        }
-
-        public Property[] getProperties() {
-            return properties;
+        public DriverManagerConnectionSource build() {
+            return new DriverManagerConnectionSource(getDriverClassName(), 
getConnectionString(), getConnectionString(),
+                    getUserName(), getPassword(), getProperties());
         }
 
-        public char[] getUserName() {
-            return userName;
-        }
-
-        public B setConnectionString(final String connectionString) {
-            this.connectionString = connectionString;
-            return asBuilder();
-        }
-
-        public B setDriverClassName(final String driverClassName) {
-            this.driverClassName = driverClassName;
-            return asBuilder();
-        }
-
-        public B setPassword(final char[] password) {
-            this.password = password;
-            return asBuilder();
-        }
-
-        public B setProperties(final Property[] properties) {
-            this.properties = properties;
-            return asBuilder();
-        }
-
-        public B setUserName(final char[] userName) {
-            this.userName = userName;
-            return asBuilder();
-        }
-    }
-
-    private static final Logger LOGGER = StatusLogger.getLogger();
-
-    public static Logger getLogger() {
-        return LOGGER;
     }
 
     @PluginBuilderFactory
-    public static <B extends Builder<B, T>, T extends 
DriverManagerConnectionSource> B newBuilder() {
-        return new Builder<B, T>().asBuilder();
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
     }
 
-    private final String actualConnectionString;
-    private final String connectionString;
-    private final String driverClassName;
-    private final char[] password;
-    private final Property[] properties;
-    private final char[] userName;
-
     public DriverManagerConnectionSource(final String driverClassName, final 
String connectionString,
             String actualConnectionString, final char[] userName, final char[] 
password, final Property[] properties) {
-        super();
-        this.driverClassName = driverClassName;
-        this.connectionString = connectionString;
-        this.actualConnectionString = actualConnectionString;
-        this.userName = userName;
-        this.password = password;
-        this.properties = properties;
+        super(driverClassName, connectionString, actualConnectionString, 
userName, password, properties);
     }
 
-    public String getActualConnectionString() {
-        return actualConnectionString;
-    }
-
-    @Override
-    public Connection getConnection() throws SQLException {
-        loadDriver();
-        // No, you cannot see the user name and password.
-        final String actualConnectionString = getActualConnectionString();
-        LOGGER.debug("Getting connection from DriverManage for '{}'", 
actualConnectionString);
-        if (properties != null && properties.length > 0) {
-            if (userName != null || password != null) {
-                throw new SQLException("Either set the userName and password, 
or set the Properties, but not both.");
-            }
-            return DriverManager.getConnection(actualConnectionString, 
toProperties(properties));
-        }
-        return DriverManager.getConnection(actualConnectionString, 
toString(userName), toString(password));
-    }
-
-    public String getConnectionString() {
-        return connectionString;
-    }
-
-    public String getDriverClassName() {
-        return driverClassName;
-    }
-
-    public char[] getPassword() {
-        return password;
-    }
-
-    public Property[] getProperties() {
-        return properties;
-    }
-
-    public char[] getUserName() {
-        return userName;
-    }
-
-    protected void loadDriver() throws SQLException {
-        loadDriver(driverClassName);
-    }
-
-    /**
-     * Loads a JDBC driver for the given class name
-     *
-     * @param className
-     *            the fully-qualified class name for a JDBC Driver.
-     * @throws SQLException
-     *             thrown when loading the driver throws an exception.
-     */
-    protected void loadDriver(final String className) throws SQLException {
-        if (className != null) {
-            // Hack for old JDBC drivers.
-            try {
-                Class.forName(className);
-            } catch (final Exception e) {
-                throw new SQLException(String.format("The %s could not load 
the JDBC driver %s: %s",
-                        getClass().getSimpleName(), className, e.toString()), 
e);
-            }
-        }
-    }
-
-    private Properties toProperties(final Property[] properties) {
-        final Properties props = new Properties();
-        for (final Property property : properties) {
-            props.setProperty(property.getName(), property.getValue());
-        }
-        return props;
-    }
-
-    @Override
-    public String toString() {
-        return this.connectionString;
-    }
-
-    private String toString(final char[] value) {
-        return value == null ? null : String.valueOf(value);
-    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java
index d69859b..20bf2f3 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/FactoryMethodConnectionSource.java
@@ -37,7 +37,7 @@ import org.apache.logging.log4j.util.Strings;
  * {@link DataSource}.
  */
 @Plugin(name = "ConnectionFactory", category = Core.CATEGORY_NAME, elementType 
= "connectionSource", printObject = true)
-public final class FactoryMethodConnectionSource implements ConnectionSource {
+public final class FactoryMethodConnectionSource extends 
AbstractConnectionSource {
     private static final Logger LOGGER = StatusLogger.getLogger();
 
     private final DataSource dataSource;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcDatabaseManager.java
----------------------------------------------------------------------
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 2e86dab..2952288 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
@@ -94,6 +94,9 @@ public final class JdbcDatabaseManager extends 
AbstractDatabaseManager {
         if (this.connection != null || this.statement != null) {
             return this.commitAndClose();
         }
+        if (connectionSource != null) {
+            connectionSource.stop();
+        }
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbDataSourceTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbDataSourceTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbDataSourceTest.java
index 1b35a76..79560ff 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbDataSourceTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbDataSourceTest.java
@@ -28,7 +28,7 @@ import org.apache.logging.log4j.junit.JdbcRule;
 public class JdbcAppenderHsqldbDataSourceTest extends 
AbstractJdbcAppenderDataSourceTest {
     public JdbcAppenderHsqldbDataSourceTest() {
         super(new JdbcRule(
-            new ConnectionSource() {
+            new AbstractConnectionSource() {
                 @Override
                 public Connection getConnection() throws SQLException {
                     return 
DriverManager.getConnection("jdbc:hsqldb:mem:Log4j", "sa", "");

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbFactoryMethodTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbFactoryMethodTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbFactoryMethodTest.java
index 5eb1d28..0d76ac1 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbFactoryMethodTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcAppenderHsqldbFactoryMethodTest.java
@@ -28,7 +28,7 @@ import org.apache.logging.log4j.junit.JdbcRule;
 public class JdbcAppenderHsqldbFactoryMethodTest extends 
AbstractJdbcAppenderFactoryMethodTest {
     public JdbcAppenderHsqldbFactoryMethodTest() {
         super(new JdbcRule(
-                new ConnectionSource() {
+                new AbstractConnectionSource() {
                     @Override
                     public Connection getConnection() throws SQLException {
                         return 
JdbcAppenderHsqldbFactoryMethodTest.getConnection();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcH2TestHelper.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcH2TestHelper.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcH2TestHelper.java
index 2007cd4..1bb1f37 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcH2TestHelper.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/JdbcH2TestHelper.java
@@ -26,7 +26,7 @@ public class JdbcH2TestHelper {
     static final String USER_NAME = "sa";
     static final String PASSWORD = "";
     
-    public static ConnectionSource TEST_CONFIGURATION_SOURCE = new 
ConnectionSource() {
+    public static ConnectionSource TEST_CONFIGURATION_SOURCE = new 
AbstractConnectionSource() {
         @Override
         public Connection getConnection() throws SQLException {
             return JdbcH2TestHelper.getConnection();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-jdbc-dbcp2/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSource.java
----------------------------------------------------------------------
diff --git 
a/log4j-jdbc-dbcp2/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSource.java
 
b/log4j-jdbc-dbcp2/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSource.java
index 80adbb3..f408d26 100644
--- 
a/log4j-jdbc-dbcp2/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSource.java
+++ 
b/log4j-jdbc-dbcp2/src/main/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSource.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.appender.db.jdbc;
 
 import java.sql.DriverManager;
 import java.sql.SQLException;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.commons.dbcp2.ConnectionFactory;
 import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
@@ -37,7 +38,7 @@ import 
org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
  * <a href="http://commons.apache.org/proper/commons-dbcp/";>Apache Commons 
DBCP</a> pooling driver.
  */
 @Plugin(name = "PoolingDriver", category = Core.CATEGORY_NAME, elementType = 
"connectionSource", printObject = true)
-public final class PoolingDriverConnectionSource extends 
DriverManagerConnectionSource {
+public final class PoolingDriverConnectionSource extends 
AbstractDriverManagerConnectionSource {
 
     /**
      * Builds PoolingDriverConnectionSource instances.
@@ -45,8 +46,8 @@ public final class PoolingDriverConnectionSource extends 
DriverManagerConnection
      * @param <B>
      *            This builder type or a subclass.
      */
-    public static class Builder<B extends Builder<B>>
-            extends DriverManagerConnectionSource.Builder<B, 
PoolingDriverConnectionSource> {
+    public static class Builder<B extends Builder<B>> extends 
AbstractDriverManagerConnectionSource.Builder<B>
+    implements 
org.apache.logging.log4j.core.util.Builder<PoolingDriverConnectionSource> {
 
         public static final String DEFAULT_POOL_NAME = "example";
         private String poolName = DEFAULT_POOL_NAME;
@@ -57,8 +58,7 @@ public final class PoolingDriverConnectionSource extends 
DriverManagerConnection
                 return new PoolingDriverConnectionSource(getDriverClassName(), 
getConnectionString(), getUserName(),
                         getPassword(), getProperties(), poolName);
             } catch (final SQLException e) {
-                getLogger().error("Exception constructing {} for {}", 
PoolingDriverConnectionSource.class,
-                        getConnectionString(), e);
+                getLogger().error("Exception constructing {} to '{}'", 
getClass(), getConnectionString(), e);
                 return null;
             }
         }
@@ -98,7 +98,7 @@ public final class PoolingDriverConnectionSource extends 
DriverManagerConnection
     private PoolingDriver getPoolingDriver() throws SQLException {
         final PoolingDriver driver = (PoolingDriver) 
DriverManager.getDriver(URL_PREFIX);
         if (driver == null) {
-            getLogger().error("No JDBC driver for {}", URL_PREFIX);
+            getLogger().error("No JDBC driver for '{}'", URL_PREFIX);
         }
         return driver;
     }
@@ -138,6 +138,7 @@ public final class PoolingDriverConnectionSource extends 
DriverManagerConnection
         loadDriver(poolingDriverClassName);
         final PoolingDriver driver = getPoolingDriver();
         if (driver != null) {
+            getLogger().debug("Registering DBCP pool '{}'", poolName);
             driver.registerPool(poolName, connectionPool);
         }
         //
@@ -146,10 +147,19 @@ public final class PoolingDriverConnectionSource extends 
DriverManagerConnection
         //
     }
 
-    public void shutdownDriver() throws SQLException {
-        final PoolingDriver driver = getPoolingDriver();
-        if (driver != null) {
-            driver.closePool(poolName);
+    @Override
+    public boolean stop(long timeout, TimeUnit timeUnit) {
+        try {
+            final PoolingDriver driver = getPoolingDriver();
+            if (driver != null) {
+                getLogger().debug("Closing DBCP pool '{}'", poolName);
+                driver.closePool(poolName);
+            }
+            return true;
+        } catch (Exception e) {
+            getLogger().error("Exception stopping connection source for '{}' 
→ '{}'", getConnectionString(),
+                    getActualConnectionString(), e);
+            return false;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSourceTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSourceTest.java
 
b/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSourceTest.java
index 2b7b886..72dc3d4 100644
--- 
a/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSourceTest.java
+++ 
b/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/core/appender/db/jdbc/PoolingDriverConnectionSourceTest.java
@@ -35,7 +35,7 @@ public class PoolingDriverConnectionSourceTest {
                 // @formatter:on
         };
         // @formatter:off
-        final PoolingDriverConnectionSource source = 
PoolingDriverConnectionSource.newPoolingDriverConnectionSourceBuilder()
+        final PoolingDriverConnectionSource source = 
(PoolingDriverConnectionSource) 
PoolingDriverConnectionSource.newPoolingDriverConnectionSourceBuilder()
             .setConnectionString(JdbcH2TestHelper.CONNECTION_STRING)
             .setProperties(properties)
             .build();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/log4j-samples/log4j-samples-flume-embedded/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-samples/log4j-samples-flume-embedded/pom.xml 
b/log4j-samples/log4j-samples-flume-embedded/pom.xml
index 8930bb5..e889279 100644
--- a/log4j-samples/log4j-samples-flume-embedded/pom.xml
+++ b/log4j-samples/log4j-samples-flume-embedded/pom.xml
@@ -119,7 +119,7 @@
       <plugin>
         <groupId>org.mortbay.jetty</groupId>
         <artifactId>maven-jetty-plugin</artifactId>
-        <version>6.1.10</version>
+        <version>6.1.26</version>
         <configuration>
           <contextPath>flumeAgent</contextPath>
           <webXml>${project.build.directory}/web.xml</webXml>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83f24c09/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 6398bb0..de414e9 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -107,6 +107,9 @@
       <action issue="LOG4J2-2186" dev="ggregory" type="add">
         Add a JDBC ConnectionSource that provides pooling through Apache 
Commons DBCP 2.
       </action>
+      <action issue="LOG4J2-2187" dev="ggregory" type="add">
+        Add a hook for a Connection Source for a JDBC Appender to release its 
resources.
+      </action>
     </release>
     <release version="2.10.0" date="2017-11-18" description="GA Release 
2.10.0">
       <action issue="LOG4J2-2120" dev="mikes" type="add" due-to="Carter 
Douglas Kozak ">

Reply via email to