You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2021/12/20 20:47:26 UTC
[logging-log4j2] branch log4j-2.12 updated: [LOG4J2-3242] Limit JNDI to the java protocol only. (#645)
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch log4j-2.12
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/log4j-2.12 by this push:
new bf8ba18 [LOG4J2-3242] Limit JNDI to the java protocol only. (#645)
bf8ba18 is described below
commit bf8ba18f63ab9f9ffd54387c5c527ecc7a681037
Author: Gary Gregory <ga...@users.noreply.github.com>
AuthorDate: Mon Dec 20 15:47:21 2021 -0500
[LOG4J2-3242] Limit JNDI to the java protocol only. (#645)
* [LOG4J2-3242] Limit JNDI to the java protocol only. JNDI will remain
disabled by default. The enablement property has been renamed to
'log4j2.enableJndiJava'.
* Do not declare log4j-api-java9 and log4j-core-java9 as depdendencies as
it causes problems with the Maven enforcer plugin.
I'm not updating changes.xml to avoid git conflicts.
* [LOG4J2-3242] Limit JNDI to the java protocol only. JNDI will remain
disabled by default. The enablement property has been renamed to
'log4j2.enableJndiJava'.
Oops, add missing test fixture for RoutingAppenderWithJndiTest.
---
log4j-api/pom.xml | 6 -
log4j-core/pom.xml | 7 --
.../log4j/core/appender/AbstractManager.java | 3 +-
.../log4j/core/appender/mom/JmsManager.java | 13 +--
.../logging/log4j/core/lookup/Interpolator.java | 13 ++-
.../logging/log4j/core/lookup/JndiLookup.java | 52 ++++++++-
.../apache/logging/log4j/core/net/JndiManager.java | 39 +++++--
.../log4j/core/selector/JndiContextSelector.java | 4 +-
.../log4j/core/appender/mom/JmsAppenderTest.java | 7 +-
.../routing/RoutingAppenderWithJndiTest.java | 125 +++++++++++++++++++++
.../log4j/core/lookup/InterpolatorTest.java | 2 +
.../log4j/core/lookup/JndiDisabledLookupTest.java | 38 +++++++
.../logging/log4j/core/lookup/JndiLookupTest.java | 42 ++++++-
.../core/lookup/JndiRestrictedLookupTest.java | 43 +++++++
.../logging/log4j/core/net/JndiManagerTest.java | 98 ++++++++++++++++
.../apache/logging/log4j/test/JUnit5Bridge.java | 35 ++++++
.../src/test/resources/log4j-routing-by-jndi.xml | 59 ++++++++++
17 files changed, 542 insertions(+), 44 deletions(-)
diff --git a/log4j-api/pom.xml b/log4j-api/pom.xml
index 059e23f..755d0a9 100644
--- a/log4j-api/pom.xml
+++ b/log4j-api/pom.xml
@@ -33,12 +33,6 @@
<projectDir>/api</projectDir>
</properties>
<dependencies>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-api-java9</artifactId>
- <scope>provided</scope>
- <type>zip</type>
- </dependency>
<!-- Place Felix before Equinox because Felix is signed. / also place it before org.osgi.core so that its versions of the OSGi classes are used -->
<dependency>
<groupId>org.apache.felix</groupId>
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 7e86130..f1bdc22 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -39,13 +39,6 @@
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
- <!-- Classes and resources to be shaded into the core jar -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core-java9</artifactId>
- <scope>provided</scope>
- <type>zip</type>
- </dependency>
<!-- Used for OSGi bundle support -->
<dependency>
<groupId>org.osgi</groupId>
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java
index e85871f..bf2c53a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractManager.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.appender;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -110,7 +111,7 @@ public abstract class AbstractManager implements AutoCloseable {
@SuppressWarnings("unchecked")
M manager = (M) MAP.get(name);
if (manager == null) {
- manager = factory.createManager(name, data);
+ manager = Objects.requireNonNull(factory, "factory").createManager(name, data);
if (manager == null) {
throw new IllegalStateException("ManagerFactory [" + factory + "] unable to create manager for ["
+ name + "] with data [" + data + "]");
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
index c9f105b..d2d397d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
@@ -125,17 +125,16 @@ public class JmsManager extends AbstractManager {
@Override
public JmsManager createManager(final String name, final JmsManagerConfiguration data) {
- if (JndiManager.isJndiEnabled()) {
+ if (JndiManager.isJndiJmsEnabled()) {
try {
return new JmsManager(name, data);
} catch (final Exception e) {
logger().error("Error creating JmsManager using JmsManagerConfiguration [{}]", data, e);
return null;
}
- } else {
- logger().error("Jndi has not been enabled. The log4j2.enableJndi property must be set to true");
- return null;
}
+ logger().error("JNDI must be enabled by setting log4j2.enableJndiJms=true");
+ return null;
}
}
@@ -354,7 +353,7 @@ public class JmsManager extends AbstractManager {
* @param object
* The LogEvent or String message to wrap.
* @return A new JMS message containing the provided object.
- * @throws JMSException
+ * @throws JMSException if the JMS provider fails to create a message due to some internal error.
*/
public Message createMessage(final Serializable object) throws JMSException {
if (object instanceof String) {
@@ -375,7 +374,7 @@ public class JmsManager extends AbstractManager {
* Creates a MessageConsumer on this Destination using the current Session.
*
* @return A MessageConsumer on this Destination.
- * @throws JMSException
+ * @throws JMSException if the session fails to create a consumer due to some internal error.
*/
public MessageConsumer createMessageConsumer() throws JMSException {
return this.session.createConsumer(this.destination);
@@ -389,7 +388,7 @@ public class JmsManager extends AbstractManager {
* @param destination
* The JMS Destination for the MessageProducer
* @return A MessageProducer on this Destination.
- * @throws JMSException
+ * @throws JMSException if the session fails to create a MessageProducer due to some internal error.
*/
public MessageProducer createMessageProducer(final Session session, final Destination destination)
throws JMSException {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
index c8409ab..3d8c07d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.ConfigurationAware;
import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
import org.apache.logging.log4j.core.config.plugins.util.PluginType;
+import org.apache.logging.log4j.core.net.JndiManager;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.ReflectionUtil;
import org.apache.logging.log4j.status.StatusLogger;
@@ -73,7 +74,7 @@ public class Interpolator extends AbstractConfigurationAwareLookup {
for (final Map.Entry<String, PluginType<?>> entry : plugins.entrySet()) {
try {
final Class<? extends StrLookup> clazz = entry.getValue().getPluginClass().asSubclass(StrLookup.class);
- if (!clazz.getName().equals("org.apache.logging.log4j.core.lookup.JndiLookup")) {
+ if (!clazz.getName().equals("org.apache.logging.log4j.core.lookup.JndiLookup") || JndiManager.isJndiLookupEnabled()) {
strLookupMap.put(entry.getKey().toLowerCase(), ReflectionUtil.instantiate(clazz));
}
} catch (final Throwable t) {
@@ -101,6 +102,16 @@ public class Interpolator extends AbstractConfigurationAwareLookup {
strLookupMap.put("main", MainMapLookup.MAIN_SINGLETON);
strLookupMap.put("marker", new MarkerLookup());
strLookupMap.put("java", new JavaLookup());
+ // JNDI
+ if (JndiManager.isJndiLookupEnabled()) {
+ try {
+ // [LOG4J2-703] We might be on Android
+ strLookupMap.put(LOOKUP_KEY_JNDI,
+ Loader.newCheckedInstanceOf("org.apache.logging.log4j.core.lookup.JndiLookup", StrLookup.class));
+ } catch (final LinkageError | Exception e) {
+ handleError(LOOKUP_KEY_JNDI, e);
+ }
+ }
// JMX input args
try {
// We might be on Android
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
index bd19e54..a783ea4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/JndiLookup.java
@@ -16,9 +16,16 @@
*/
package org.apache.logging.log4j.core.lookup;
+import java.util.Objects;
+
+import javax.naming.NamingException;
+
import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.net.JndiManager;
import org.apache.logging.log4j.status.StatusLogger;
/**
@@ -26,17 +33,54 @@ import org.apache.logging.log4j.status.StatusLogger;
*/
@Plugin(name = "jndi", category = StrLookup.CATEGORY)
public class JndiLookup extends AbstractLookup {
+
private static final Logger LOGGER = StatusLogger.getLogger();
- private static final String RESULT = "JNDI is not supported";
+ private static final Marker LOOKUP = MarkerManager.getMarker("LOOKUP");
+
+ /** JNDI resource path prefix used in a J2EE container */
+ static final String CONTAINER_JNDI_RESOURCE_PATH_PREFIX = "java:comp/env/";
+
+ /**
+ * Constructs a new instance or throw IllegalStateException if this feature is disabled.
+ */
+ public JndiLookup() {
+ if (!JndiManager.isJndiLookupEnabled()) {
+ throw new IllegalStateException("JNDI must be enabled by setting log4j2.enableJndiLookup=true");
+ }
+ }
+
/**
* Looks up the value of the JNDI resource.
+ *
* @param event The current LogEvent (is ignored by this StrLookup).
- * @param key the JNDI resource name to be looked up, may be null
+ * @param key the JNDI resource name to be looked up, may be null
* @return The String value of the JNDI resource.
*/
@Override
public String lookup(final LogEvent event, final String key) {
- LOGGER.warn("Attempt to use JNDI Lookup");
- return RESULT;
+ if (key == null) {
+ return null;
+ }
+ final String jndiName = convertJndiName(key);
+ try (final JndiManager jndiManager = JndiManager.getDefaultManager()) {
+ return Objects.toString(jndiManager.lookup(jndiName), null);
+ } catch (final NamingException e) {
+ LOGGER.warn(LOOKUP, "Error looking up JNDI resource [{}].", jndiName, e);
+ return null;
+ }
+ }
+
+ /**
+ * Convert the given JNDI name to the actual JNDI name to use. Default implementation applies the "java:comp/env/"
+ * prefix unless other scheme like "java:" is given.
+ *
+ * @param jndiName The name of the resource.
+ * @return The fully qualified name to look up.
+ */
+ private String convertJndiName(final String jndiName) {
+ if (!jndiName.startsWith(CONTAINER_JNDI_RESOURCE_PATH_PREFIX) && jndiName.indexOf(':') == -1) {
+ return CONTAINER_JNDI_RESOURCE_PATH_PREFIX + jndiName;
+ }
+ return jndiName;
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java
index 06e2793..e005c62 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java
@@ -39,11 +39,29 @@ import org.apache.logging.log4j.util.PropertiesUtil;
public class JndiManager extends AbstractManager {
private static final JndiManagerFactory FACTORY = new JndiManagerFactory();
+ private static final String PREFIX = "log4j2.enableJndi";
+ private static final String JAVA_SCHEME = "java";
private final Context context;
+ private static boolean isJndiEnabled(final String subKey) {
+ return PropertiesUtil.getProperties().getBooleanProperty(PREFIX + subKey, false);
+ }
+
public static boolean isJndiEnabled() {
- return PropertiesUtil.getProperties().getBooleanProperty("log4j2.enableJndi", false);
+ return isJndiContextSelectorEnabled() || isJndiJmsEnabled() || isJndiLookupEnabled();
+ }
+
+ public static boolean isJndiContextSelectorEnabled() {
+ return isJndiEnabled("ContextSelector");
+ }
+
+ public static boolean isJndiJmsEnabled() {
+ return isJndiEnabled("Jms");
+ }
+
+ public static boolean isJndiLookupEnabled() {
+ return isJndiEnabled("Lookup");
}
private JndiManager(final String name, final Context context) {
@@ -181,7 +199,7 @@ public class JndiManager extends AbstractManager {
}
try {
URI uri = new URI(name);
- if (uri.getScheme() == null || uri.getScheme().equals("java")) {
+ if (uri.getScheme() == null || uri.getScheme().equals(JAVA_SCHEME)) {
return (T) this.context.lookup(name);
}
LOGGER.warn("Unsupported JNDI URI - {}", name);
@@ -195,15 +213,14 @@ public class JndiManager extends AbstractManager {
@Override
public JndiManager createManager(final String name, final Properties data) {
- if (isJndiEnabled()) {
- try {
- return new JndiManager(name, new InitialContext(data));
- } catch (final NamingException e) {
- LOGGER.error("Error creating JNDI InitialContext.", e);
- return null;
- }
- } else {
- return new JndiManager(name, null);
+ if (!isJndiEnabled()) {
+ throw new IllegalStateException(String.format("JNDI must be enabled by setting one of the %s* properties to true", PREFIX));
+ }
+ try {
+ return new JndiManager(name, new InitialContext(data));
+ } catch (final NamingException e) {
+ LOGGER.error("Error creating JNDI InitialContext for '{}'.", name, e);
+ return null;
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java
index 81ec3f3..7da852d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java
@@ -93,8 +93,8 @@ public class JndiContextSelector implements NamedContextSelector {
private static final StatusLogger LOGGER = StatusLogger.getLogger();
public JndiContextSelector() {
- if (!JndiManager.isJndiEnabled()) {
- throw new IllegalStateException("JNDI must be enabled by setting log4j2.enableJndi=true");
+ if (!JndiManager.isJndiContextSelectorEnabled()) {
+ throw new IllegalStateException("JNDI must be enabled by setting log4j2.enableJndiContextSelector=true");
}
}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java
index daf2d0e..4c5b1a9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java
@@ -85,8 +85,13 @@ public class JmsAppenderTest {
public RuleChain rules = RuleChain.outerRule(jndiRule).around(ctx);
@BeforeClass
+ public static void afterClass() throws Exception {
+ System.clearProperty("log4j2.enableJndiJms");
+ }
+
+ @BeforeClass
public static void beforeClass() throws Exception {
- System.setProperty("log4j2.enableJndi", "true");
+ System.setProperty("log4j2.enableJndiJms", "true");
}
public JmsAppenderTest() throws Exception {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
new file mode 100644
index 0000000..899fd5e
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.routing;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.logging.log4j.EventLogger;
+import org.apache.logging.log4j.junit.JndiRule;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+import static org.junit.Assert.*;
+
+/**
+ * RoutingAppenderWithJndiTest
+ */
+public class RoutingAppenderWithJndiTest {
+
+ public static final String JNDI_CONTEXT_NAME = "java:comp/env/logging/context-name";
+ private ListAppender listAppender1;
+ private ListAppender listAppender2;
+
+ public static LoggerContextRule loggerContextRule = new LoggerContextRule("log4j-routing-by-jndi.xml");
+
+ @ClassRule
+ public static RuleChain rules = RuleChain.outerRule(new JndiRule(initBindings())).around(loggerContextRule);
+
+ private static Map<String, Object> initBindings() {
+ System.setProperty("log4j2.enableJndiLookup", "true");
+ //System.setProperty("log4j2.enableJndiJms", "true");
+ //System.setProperty("log4j2.enableJndiContextSelector", "true");
+ return Collections.emptyMap();
+ }
+
+ @Before
+ public void before() {
+ listAppender1 = RoutingAppenderWithJndiTest.loggerContextRule.getListAppender("List1");
+ listAppender2 = RoutingAppenderWithJndiTest.loggerContextRule.getListAppender("List2");
+ }
+
+ @After
+ public void after() {
+ if (listAppender1 != null) {
+ listAppender1.clear();
+ }
+ if (listAppender2 != null) {
+ listAppender2.clear();
+ }
+ }
+
+ @Test
+ public void routingTest() throws NamingException {
+ // default route when there's no jndi resource
+ StructuredDataMessage msg = new StructuredDataMessage("Test", "This is a message from unknown context", "Context");
+ EventLogger.logEvent(msg);
+ final File defaultLogFile = new File("target/routingbyjndi/routingbyjnditest-unknown.log");
+ assertTrue("The default log file was not created", defaultLogFile.exists());
+
+ // now set jndi resource to Application1
+ final Context context = new InitialContext();
+ context.bind(JNDI_CONTEXT_NAME, "Application1");
+
+ msg = new StructuredDataMessage("Test", "This is a message from Application1", "Context");
+ EventLogger.logEvent(msg);
+ assertNotNull("No events generated", listAppender1.getEvents());
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender1.getEvents().size(), listAppender1.getEvents().size() == 1);
+
+ // now set jndi resource to Application2
+ context.rebind(JNDI_CONTEXT_NAME, "Application2");
+
+ msg = new StructuredDataMessage("Test", "This is a message from Application2", "Context");
+ EventLogger.logEvent(msg);
+ assertNotNull("No events generated", listAppender2.getEvents());
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender2.getEvents().size(), listAppender2.getEvents().size() == 1);
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender1.getEvents().size(), listAppender1.getEvents().size() == 1);
+
+ msg = new StructuredDataMessage("Test", "This is another message from Application2", "Context");
+ EventLogger.logEvent(msg);
+ assertNotNull("No events generated", listAppender2.getEvents());
+ assertTrue("Incorrect number of events. Expected 2, got " + listAppender2.getEvents().size(), listAppender2.getEvents().size() == 2);
+ assertTrue("Incorrect number of events. Expected 1, got " + listAppender1.getEvents().size(), listAppender1.getEvents().size() == 1);
+
+ // now set jndi resource to Application3.
+ // The context name, 'Application3', will be used as log file name by the default route.
+ context.rebind("java:comp/env/logging/context-name", "Application3");
+ msg = new StructuredDataMessage("Test", "This is a message from Application3", "Context");
+ EventLogger.logEvent(msg);
+ final File application3LogFile = new File("target/routingbyjndi/routingbyjnditest-Application3.log");
+ assertTrue("The Application3 log file was not created", application3LogFile.exists());
+
+ // now set jndi resource to Application4
+ // The context name, 'Application4', will be used as log file name by the default route.
+ context.rebind("java:comp/env/logging/context-name", "Application4");
+ msg = new StructuredDataMessage("Test", "This is a message from Application4", "Context");
+ EventLogger.logEvent(msg);
+ final File application4LogFile = new File("target/routingbyjndi/routingbyjnditest-Application4.log");
+ assertTrue("The Application3 log file was not created", application4LogFile.exists());
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
index 0af36fd..fc6f3d8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
@@ -44,12 +44,14 @@ public class InterpolatorTest {
protected void before() throws Throwable {
System.setProperty(TESTKEY, TESTVAL);
System.setProperty(TESTKEY2, TESTVAL);
+ System.setProperty("log4j2.enableJndiLookup", "true");
}
@Override
protected void after() {
System.clearProperty(TESTKEY);
System.clearProperty(TESTKEY2);
+ System.clearProperty("log4j2.enableJndiLookup");
}
});
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiDisabledLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiDisabledLookupTest.java
new file mode 100644
index 0000000..362a67d
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiDisabledLookupTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.lookup;
+
+import org.apache.logging.log4j.test.JUnit5Bridge;
+import org.junit.Test;
+
+/**
+ * JndiDisabledLookupTest
+ *
+ * Verifies the Lookups are disabled without the log4j2.enableJndiLookup property set to true.
+ */
+public class JndiDisabledLookupTest {
+
+ @Test
+ public void testLookup() {
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ new JndiLookup();
+ }
+ });
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
index ba45808..0675aa1 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
@@ -16,17 +16,20 @@
*/
package org.apache.logging.log4j.core.lookup;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.junit.JndiRule;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
-import static org.junit.Assert.*;
-
/**
* JndiLookupTest
*/
@@ -42,8 +45,22 @@ public class JndiLookupTest {
@Rule
public JndiRule jndiRule = new JndiRule(createBindings());
+ @AfterClass
+ public static void afterClass() {
+ System.clearProperty("log4j2.enableJndiLookup");
+ }
+
+ @BeforeClass
+ public static void beforeClass() {
+ System.setProperty("log4j2.enableJndiLookup", "true");
+ }
+
private Map<String, Object> createBindings() {
- return new HashMap<>();
+ final Map<String, Object> map = new HashMap<>();
+ map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);
+ map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_INTEGRAL_NAME, TEST_INTEGRAL_VALUE);
+ map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_STRINGS_NAME, TEST_STRINGS_COLLECTION);
+ return map;
}
@Test
@@ -51,6 +68,23 @@ public class JndiLookupTest {
final StrLookup lookup = new JndiLookup();
String contextName = lookup.lookup(TEST_CONTEXT_RESOURCE_NAME);
- assertEquals("JNDI is not supported", contextName);
+ assertEquals(TEST_CONTEXT_NAME, contextName);
+
+ contextName = lookup.lookup(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME);
+ assertEquals(TEST_CONTEXT_NAME, contextName);
+
+ final String nonExistingResource = lookup.lookup("logging/non-existing-resource");
+ assertNull(nonExistingResource);
+ }
+
+ @Test
+ public void testNonStringLookup() throws Exception {
+ // LOG4J2-1310
+ final StrLookup lookup = new JndiLookup();
+ final String integralValue = lookup.lookup(TEST_INTEGRAL_NAME);
+ assertEquals(String.valueOf(TEST_INTEGRAL_VALUE), integralValue);
+ final String collectionValue = lookup.lookup(TEST_STRINGS_NAME);
+ assertEquals(String.valueOf(TEST_STRINGS_COLLECTION), collectionValue);
}
+
}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java
new file mode 100644
index 0000000..e40cdb2
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.lookup;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNull;
+
+/**
+ * JndiLookupTest
+ */
+public class JndiRestrictedLookupTest {
+
+ private static final String DOMAIN = "apache.org";
+
+ @BeforeClass
+ public static void beforeClass() {
+ System.setProperty("log4j2.enableJndiLookup", "true");
+ }
+
+ @Test
+ public void testDnsLookup() throws Exception {
+ final StrLookup lookup = new JndiLookup();
+ String result = lookup.lookup("dns:/" + DOMAIN);
+ assertNull("DNS data returend", result);
+
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java
new file mode 100644
index 0000000..e2fd8f7
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/JndiManagerTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.net;
+
+import static org.junit.Assert.assertFalse;
+
+import java.util.Properties;
+
+import org.apache.logging.log4j.test.JUnit5Bridge;
+import org.junit.Test;
+
+/**
+ * Tests {@link JndiManager}.
+ */
+public class JndiManagerTest {
+
+ @Test
+ public void testIsJndiEnabled() {
+ assertFalse(JndiManager.isJndiEnabled());
+ }
+
+ @Test
+ public void testIsJndiContextSelectorEnabled() {
+ assertFalse(JndiManager.isJndiContextSelectorEnabled());
+ }
+
+ @Test
+ public void testIsJndiJmsEnabled() {
+ assertFalse(JndiManager.isJndiJmsEnabled());
+ }
+
+ @Test
+ public void testIsJndiLookupEnabled() {
+ assertFalse(JndiManager.isJndiLookupEnabled());
+ }
+
+ @Test
+ public void testNoInstanceByDefault() {
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getDefaultManager();
+ }
+ });
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getDefaultManager(null);
+ }
+ });
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getDefaultManager("A");
+ }
+ });
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getJndiManager(null);
+ }
+ });
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getJndiManager(new Properties());
+ }
+ });
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getJndiManager(null, null, null, null, null, null);
+ }
+ });
+ JUnit5Bridge.assertThrows(IllegalStateException.class, new Runnable() {
+ @Override
+ public void run() {
+ JndiManager.getJndiManager("A", "A", "A", "A", "A", new Properties());
+ }
+ });
+ }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/test/JUnit5Bridge.java b/log4j-core/src/test/java/org/apache/logging/log4j/test/JUnit5Bridge.java
new file mode 100644
index 0000000..c331433
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/test/JUnit5Bridge.java
@@ -0,0 +1,35 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class JUnit5Bridge {
+
+ /** This branch is on Java 7 and uses JUnit 4, hence this hack. */
+ public static <T> void assertThrows(Class<T> expectedType, Runnable runnable) {
+ try {
+ runnable.run();
+ fail("Expected " + expectedType.getCanonicalName());
+ } catch (Throwable t) {
+ assertEquals(expectedType, t.getClass());
+ }
+
+ }
+
+}
diff --git a/log4j-core/src/test/resources/log4j-routing-by-jndi.xml b/log4j-core/src/test/resources/log4j-routing-by-jndi.xml
new file mode 100644
index 0000000..2967eaa
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-routing-by-jndi.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+
+-->
+<Configuration status="OFF" name="RoutingByJndiTest">
+
+ <ThresholdFilter level="debug"/>
+
+ <Appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m%n"/>
+ </Console>
+ <List name="List1">
+ <ThresholdFilter level="debug"/>
+ </List>
+ <List name="List2">
+ <ThresholdFilter level="debug"/>
+ </List>
+ <Routing name="Routing">
+ <Routes pattern="$${jndi:logging/context-name}">
+ <Route>
+ <File name="DefaultApplicationLogFile" fileName="target/routingbyjndi/routingbyjnditest-${jndi:logging/context-name:-unknown}.log" append="false">
+ <PatternLayout>
+ <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+ </PatternLayout>
+ </File>
+ </Route>
+ <Route ref="List1" key="Application1"/>
+ <Route ref="List2" key="Application2"/>
+ </Routes>
+ </Routing>
+ </Appenders>
+
+ <Loggers>
+ <Logger name="EventLogger" level="info" additivity="false">
+ <AppenderRef ref="Routing"/>
+ <AppenderRef ref="STDOUT"/>
+ </Logger>
+
+ <Root level="error">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file