Skip to content

Commit 5a5224e

Browse files
committed
Move JNDI DataSource to separate module (#2915)
We move the [`DataSource` connection source](https://logging.staged.apache.org/log4j/3.x/manual/appenders/database.html#DataSourceConnectionSource) to a new module `log4j-jdbc-jndi`. The main rationale for this change is to remove the **optional** dependency on `log4j-jndi` from `log4j-jdbc`. This change forces users to opt-in for the JNDI `DataSource` by adding `log4j-jdbc-jndi` to their classpath. After this change, the `log4j-jdbc` artifact contains: * the `JDBC` Appender, * a connection source based on `DriverManager`, * a connection source based on a static factory method. Closes #1914
1 parent 22dcdd3 commit 5a5224e

File tree

35 files changed

+468
-203
lines changed

35 files changed

+468
-203
lines changed

log4j-jdbc-dbcp2/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
</parent>
2828

2929
<artifactId>log4j-jdbc-dbcp2</artifactId>
30-
<name>Apache Log4j JDBC DBCP 2</name>
30+
<name>Apache Log4j JDBC: DBCP 2 datasource</name>
3131
<description>Connection source for the JDBC Appender using Apache Commons DBCP2.</description>
3232

3333
<properties>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This file is here to activate the `plugin-processing` Maven profile.

log4j-jdbc-jndi/pom.xml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to you under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
19+
<modelVersion>4.0.0</modelVersion>
20+
<parent>
21+
<groupId>org.apache.logging.log4j</groupId>
22+
<artifactId>log4j</artifactId>
23+
<version>${revision}</version>
24+
<relativePath>../log4j-parent</relativePath>
25+
</parent>
26+
27+
<artifactId>log4j-jdbc-jndi</artifactId>
28+
<name>Apache Log4j JDBC: JNDI datasource</name>
29+
<description>Connection source for the JDBC Appender using JNDI.</description>
30+
31+
<dependencies>
32+
33+
<dependency>
34+
<groupId>org.apache.logging.log4j</groupId>
35+
<artifactId>log4j-api</artifactId>
36+
</dependency>
37+
38+
<dependency>
39+
<groupId>org.apache.logging.log4j</groupId>
40+
<artifactId>log4j-core</artifactId>
41+
</dependency>
42+
43+
<dependency>
44+
<groupId>org.apache.logging.log4j</groupId>
45+
<artifactId>log4j-jdbc</artifactId>
46+
</dependency>
47+
48+
<dependency>
49+
<groupId>org.apache.logging.log4j</groupId>
50+
<artifactId>log4j-jndi</artifactId>
51+
</dependency>
52+
53+
<dependency>
54+
<groupId>org.apache.logging.log4j</groupId>
55+
<artifactId>log4j-plugins</artifactId>
56+
</dependency>
57+
58+
<dependency>
59+
<groupId>org.apache.logging.log4j</groupId>
60+
<artifactId>log4j-core-test</artifactId>
61+
<scope>test</scope>
62+
</dependency>
63+
64+
<dependency>
65+
<groupId>org.apache.logging.log4j</groupId>
66+
<artifactId>log4j-jndi-test</artifactId>
67+
<scope>test</scope>
68+
</dependency>
69+
70+
<dependency>
71+
<groupId>org.apache.commons</groupId>
72+
<artifactId>commons-lang3</artifactId>
73+
<scope>test</scope>
74+
</dependency>
75+
76+
<dependency>
77+
<groupId>com.h2database</groupId>
78+
<artifactId>h2</artifactId>
79+
<scope>test</scope>
80+
</dependency>
81+
82+
<dependency>
83+
<groupId>org.hsqldb</groupId>
84+
<artifactId>hsqldb</artifactId>
85+
<scope>test</scope>
86+
</dependency>
87+
88+
<dependency>
89+
<groupId>junit</groupId>
90+
<artifactId>junit</artifactId>
91+
<scope>test</scope>
92+
</dependency>
93+
94+
<dependency>
95+
<groupId>org.junit.vintage</groupId>
96+
<artifactId>junit-vintage-engine</artifactId>
97+
<scope>test</scope>
98+
</dependency>
99+
100+
<!-- Mocking framework for use with JUnit -->
101+
<dependency>
102+
<groupId>org.mockito</groupId>
103+
<artifactId>mockito-core</artifactId>
104+
<scope>test</scope>
105+
</dependency>
106+
107+
</dependencies>
108+
109+
</project>
Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package org.apache.logging.log4j.jdbc.appender;
17+
package org.apache.logging.log4j.jdbc.jndi;
1818

1919
import java.sql.Connection;
2020
import java.sql.SQLException;
21+
import javax.naming.NamingException;
2122
import javax.sql.DataSource;
2223
import org.apache.logging.log4j.Logger;
23-
import org.apache.logging.log4j.jdbc.appender.internal.JndiUtil;
24+
import org.apache.logging.log4j.jdbc.appender.AbstractConnectionSource;
25+
import org.apache.logging.log4j.jndi.JndiManager;
2426
import org.apache.logging.log4j.plugins.Configurable;
2527
import org.apache.logging.log4j.plugins.Plugin;
2628
import org.apache.logging.log4j.plugins.PluginAttribute;
@@ -29,11 +31,14 @@
2931
import org.apache.logging.log4j.util.Strings;
3032

3133
/**
32-
* A {@link JdbcAppender} connection source that uses a {@link DataSource} to connect to the database.
34+
* A {@link org.apache.logging.log4j.jdbc.appender.JdbcAppender} connection source that uses a {@link DataSource} to connect to the database.
3335
*/
3436
@Configurable(elementType = "connectionSource", printObject = true)
3537
@Plugin("DataSource")
3638
public final class DataSourceConnectionSource extends AbstractConnectionSource {
39+
private static final String DOC_URL =
40+
"https://logging.staged.apache.org/log4j/3.x/manual/systemproperties.html#properties-jndi-support";
41+
static final String JNDI_MANAGER_NAME = "org.apache.logging.log4j.jdbc.jndi.DataSourceConnectionSource";
3742
private static final Logger LOGGER = StatusLogger.getLogger();
3843

3944
private final DataSource dataSource;
@@ -62,20 +67,27 @@ public String toString() {
6267
*/
6368
@PluginFactory
6469
public static DataSourceConnectionSource createConnectionSource(@PluginAttribute final String jndiName) {
65-
if (!JndiUtil.isJndiJdbcEnabled()) {
66-
LOGGER.error("JNDI must be enabled by setting log4j2.enableJndiJdbc=true");
70+
if (!JndiManager.isJndiJdbcEnabled()) {
71+
LOGGER.error(
72+
"JNDI must be enabled by setting `log4j.jndi.enableJdbc=\"true\"`\nSee {} for more details.",
73+
DOC_URL);
6774
return null;
6875
}
6976
if (Strings.isEmpty(jndiName)) {
7077
LOGGER.error("No JNDI name provided.");
7178
return null;
7279
}
7380

74-
final DataSource dataSource = JndiUtil.getDataSource(jndiName);
75-
if (dataSource == null) {
76-
return null;
81+
try {
82+
final DataSource dataSource =
83+
JndiManager.getDefaultManager(JNDI_MANAGER_NAME).lookup(jndiName);
84+
if (dataSource != null) {
85+
return new DataSourceConnectionSource(jndiName, dataSource);
86+
}
87+
LOGGER.error("Failed to retrieve JNDI data source with name {}.", jndiName);
88+
} catch (final NamingException e) {
89+
LOGGER.error("Failed to retrieve JNDI data source with name {}.", jndiName, e);
7790
}
78-
79-
return new DataSourceConnectionSource(jndiName, dataSource);
91+
return null;
8092
}
8193
}
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package org.apache.logging.log4j.jdbc.appender;
17+
package org.apache.logging.log4j.jdbc.jndi;
1818

1919
import static org.apache.logging.log4j.core.test.TestConstants.JNDI_ENABLE_JDBC;
2020
import static org.junit.Assert.assertEquals;
@@ -34,14 +34,12 @@
3434
import org.apache.logging.log4j.Logger;
3535
import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
3636
import org.apache.logging.log4j.core.util.Throwables;
37-
import org.apache.logging.log4j.jdbc.appender.internal.JndiUtil;
3837
import org.apache.logging.log4j.jndi.test.junit.JndiRule;
3938
import org.h2.util.IOUtils;
4039
import org.junit.BeforeClass;
4140
import org.junit.Rule;
4241
import org.junit.Test;
4342
import org.junit.rules.RuleChain;
44-
import org.mockito.invocation.InvocationOnMock;
4543
import org.mockito.stubbing.Answer;
4644

4745
/**
@@ -62,23 +60,19 @@ public static void beforeClass() {
6260
protected AbstractJdbcAppenderDataSourceTest(final JdbcRule jdbcRule) {
6361
this.rules = RuleChain.emptyRuleChain()
6462
.around(new JndiRule(
65-
JndiUtil.JNDI_MANAGER_NAME,
63+
DataSourceConnectionSource.JNDI_MANAGER_NAME,
6664
"java:/comp/env/jdbc/TestDataSourceAppender",
6765
createMockDataSource()))
6866
.around(jdbcRule)
69-
.around(new LoggerContextRule("org/apache/logging/log4j/jdbc/appender/log4j2-data-source.xml"));
67+
.around(new LoggerContextRule("AbstractJdbcAppenderDataSourceTest.xml"));
7068
this.jdbcRule = jdbcRule;
7169
}
7270

7371
private DataSource createMockDataSource() {
7472
try {
7573
final DataSource dataSource = mock(DataSource.class);
76-
given(dataSource.getConnection()).willAnswer(new Answer<Connection>() {
77-
@Override
78-
public Connection answer(final InvocationOnMock invocation) throws Throwable {
79-
return jdbcRule.getConnectionSource().getConnection();
80-
}
81-
});
74+
given(dataSource.getConnection()).willAnswer((Answer<Connection>)
75+
invocation -> jdbcRule.getConnectionSource().getConnection());
8276
return dataSource;
8377
} catch (final SQLException e) {
8478
Throwables.rethrow(e);
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,20 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package org.apache.logging.log4j.jdbc.appender;
17+
package org.apache.logging.log4j.jdbc.jndi;
1818

1919
import static org.apache.logging.log4j.core.test.TestConstants.JNDI_ENABLE_JDBC;
2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertNotNull;
2222
import static org.junit.Assert.assertNull;
2323
import static org.junit.Assert.assertSame;
2424
import static org.mockito.BDDMockito.given;
25-
import static org.mockito.Mockito.mock;
25+
import static org.mockito.BDDMockito.mock;
2626

2727
import java.sql.Connection;
2828
import java.sql.SQLException;
2929
import javax.sql.DataSource;
3030
import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
31-
import org.apache.logging.log4j.jdbc.appender.internal.JndiUtil;
3231
import org.apache.logging.log4j.jndi.test.junit.JndiRule;
3332
import org.junit.Rule;
3433
import org.junit.Test;
@@ -45,7 +44,7 @@ public static Object[][] data() {
4544
return new Object[][] {{"java:/comp/env/jdbc/Logging01"}, {"java:/comp/env/jdbc/Logging02"}};
4645
}
4746

48-
private static final String CONFIG = "log4j-fatalOnly.xml";
47+
private static final String CONFIG = "DataSourceConnectionSourceTest.xml";
4948

5049
@Rule
5150
public final RuleChain rules;
@@ -54,7 +53,8 @@ public static Object[][] data() {
5453
private final String jndiURL;
5554

5655
public DataSourceConnectionSourceTest(final String jndiURL) {
57-
this.rules = RuleChain.outerRule(new JndiRule(JndiUtil.JNDI_MANAGER_NAME, jndiURL, dataSource))
56+
this.rules = RuleChain.outerRule(
57+
new JndiRule(DataSourceConnectionSource.JNDI_MANAGER_NAME, jndiURL, dataSource))
5858
.around(new LoggerContextRule(CONFIG));
5959
this.jndiURL = jndiURL;
6060
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package org.apache.logging.log4j.jdbc.appender;
17+
package org.apache.logging.log4j.jdbc.jndi;
1818

19-
/**
20-
*
21-
*/
2219
public class JdbcAppenderH2DataSourceTest extends AbstractJdbcAppenderDataSourceTest {
20+
2321
public JdbcAppenderH2DataSourceTest() {
2422
super(new JdbcRule(
2523
JdbcH2TestHelper.TEST_CONFIGURATION_SOURCE_MEM,
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package org.apache.logging.log4j.jdbc.appender;
17+
package org.apache.logging.log4j.jdbc.jndi;
1818

1919
import java.sql.Connection;
2020
import java.sql.DriverManager;
2121
import java.sql.SQLException;
22+
import org.apache.logging.log4j.jdbc.appender.AbstractConnectionSource;
2223

2324
/**
2425
*
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
package org.apache.logging.log4j.jdbc.appender;
17+
package org.apache.logging.log4j.jdbc.jndi;
1818

1919
import static org.apache.logging.log4j.core.test.TestConstants.JNDI_ENABLE_JDBC;
2020
import static org.junit.Assert.assertFalse;
@@ -34,7 +34,6 @@
3434
import org.apache.logging.log4j.Logger;
3535
import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
3636
import org.apache.logging.log4j.core.util.Throwables;
37-
import org.apache.logging.log4j.jdbc.appender.internal.JndiUtil;
3837
import org.apache.logging.log4j.jndi.test.junit.JndiRule;
3938
import org.apache.logging.log4j.message.MapMessage;
4039
import org.junit.Assert;
@@ -73,12 +72,11 @@ protected JdbcAppenderMapMessageDataSourceTest(final JdbcRule jdbcRule) {
7372
// @formatter:off
7473
this.rules = RuleChain.emptyRuleChain()
7574
.around(new JndiRule(
76-
JndiUtil.JNDI_MANAGER_NAME,
75+
DataSourceConnectionSource.JNDI_MANAGER_NAME,
7776
"java:/comp/env/jdbc/TestDataSourceAppender",
7877
createMockDataSource()))
7978
.around(jdbcRule)
80-
.around(new LoggerContextRule(
81-
"org/apache/logging/log4j/jdbc/appender/log4j2-data-source-map-message.xml"));
79+
.around(new LoggerContextRule("JdbcAppenderMapMessageDataSourceTest.xml"));
8280
// @formatter:on
8381
this.jdbcRule = jdbcRule;
8482
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.jdbc.jndi;
18+
19+
import java.sql.Connection;
20+
import java.sql.DriverManager;
21+
import java.sql.SQLException;
22+
import org.apache.logging.log4j.jdbc.appender.AbstractConnectionSource;
23+
import org.apache.logging.log4j.jdbc.appender.ConnectionSource;
24+
25+
public class JdbcH2TestHelper {
26+
27+
private static final String CONNECTION_STRING = "jdbc:h2:mem:Log4j";
28+
private static final String USERNAME = "sa";
29+
private static final String PASSWORD = "";
30+
31+
public static ConnectionSource TEST_CONFIGURATION_SOURCE_MEM = new AbstractConnectionSource() {
32+
@Override
33+
public Connection getConnection() throws SQLException {
34+
return DriverManager.getConnection(CONNECTION_STRING, USERNAME, PASSWORD);
35+
}
36+
};
37+
}

0 commit comments

Comments
 (0)