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