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 2019/05/05 05:27:22 UTC
[logging-log4j2] 01/12: LOG4J2-913 - Access configurations by
HTTP/S. Support Spring Cloud Config
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 22a0ca71e6220b37ce0c76bc8ab3399c8fb6012f
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Thu Jan 24 20:41:26 2019 -0700
LOG4J2-913 - Access configurations by HTTP/S. Support Spring Cloud Config
LOG4J2-913 - App works with Cloud Config
LOG4j2-913 - Integration with Spring Cloud Config
---
.../apache/logging/log4j/util/PropertiesUtil.java | 15 +
.../logging/log4j/util/PropertiesUtilTest.java | 15 +-
.../src/test/resources/log4j2.system.properties | 1 +
log4j-core/revapi.json | 346 +-
.../log4j/core/config/AbstractConfiguration.java | 26 +
.../log4j/core/config/ConfigurationFactory.java | 25 +-
.../core/config/ConfigurationFileWatcher.java | 72 +
.../log4j/core/config/ConfigurationSource.java | 107 +-
.../logging/log4j/core/config/HttpWatcher.java | 186 ++
.../config/builder/impl/BuiltConfiguration.java | 18 +-
.../builder/impl/DefaultConfigurationBuilder.java | 2 +-
.../config/composite/CompositeConfiguration.java | 24 +-
.../log4j/core/config/json/JsonConfiguration.java | 16 +-
.../log4j/core/config/xml/XmlConfiguration.java | 19 +-
.../log4j/core/net/ssl/SslConfiguration.java | 29 +-
.../core/net/ssl/SslConfigurationFactory.java | 79 +
.../AbstractWatcher.java} | 42 +-
.../org/apache/logging/log4j/core/util/Source.java | 135 +
.../logging/log4j/core/util/WatchManager.java | 152 +-
.../apache/logging/log4j/core/util/Watcher.java | 78 +
.../logging/log4j/core/util/WatcherFactory.java | 89 +
.../log4j/core/util/WrappedFileWatcher.java | 90 +
.../logging/log4j/core/util/WatchHttpTest.java | 175 +
.../src/test/resources/__files/log4j-test1.xml | 58 +
.../log4j-spring-cloud-config-client/pom.xml | 196 ++
.../client/Log4j2CloudConfigLoggingSystem.java | 127 +
.../src/main/resources/log4j2.system.properties | 1 +
.../log4j-spring-cloud-config-server/pom.xml | 205 ++
.../server/controller/Log4jResourceController.java | 200 ++
.../src/main/resources/META-INF/spring.factories | 1 +
log4j-spring-cloud-config/pom.xml | 95 +
pom.xml | 3439 ++++++++++----------
32 files changed, 4199 insertions(+), 1864 deletions(-)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
index c4104f7..4feb207 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
@@ -46,6 +46,8 @@ import java.util.concurrent.ConcurrentHashMap;
public final class PropertiesUtil {
private static final String LOG4J_PROPERTIES_FILE_NAME = "log4j2.component.properties";
+ private static final String LOG4J_SYSTEM_PROPERTIES_FILE_NAME = "log4j2.system.properties";
+ private static final String SYSTEM = "system:";
private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil(LOG4J_PROPERTIES_FILE_NAME);
private final Environment environment;
@@ -315,6 +317,19 @@ public final class PropertiesUtil {
private final Map<List<CharSequence>, String> tokenized = new ConcurrentHashMap<>();
private Environment(final PropertySource propertySource) {
+ PropertyFilePropertySource sysProps = new PropertyFilePropertySource(LOG4J_SYSTEM_PROPERTIES_FILE_NAME);
+ try {
+ sysProps.forEach(new BiConsumer<String, String>() {
+ @Override
+ public void accept(String key, String value) {
+ if (System.getProperty(key) == null) {
+ System.setProperty(key, value);
+ }
+ }
+ });
+ } catch (SecurityException ex) {
+ // Access to System Properties is restricted so just skip it.
+ }
sources.add(propertySource);
for (final ClassLoader classLoader : LoaderUtil.getClassLoaders()) {
try {
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
index 3ac9c92..a5dc873 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
@@ -17,14 +17,14 @@
package org.apache.logging.log4j.util;
-import org.junit.Before;
-import org.junit.Test;
-
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;
+import org.junit.Before;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -108,4 +108,13 @@ public class PropertiesUtilTest {
System.getProperties().remove(key2);
}
}
+
+ @Test
+ public void testPublish() {
+ final Properties props = new Properties();
+ final PropertiesUtil util = new PropertiesUtil(props);
+ String value = System.getProperty("Application");
+ assertNotNull("System property was not published", value);
+ assertEquals("Log4j", value);
+ }
}
diff --git a/log4j-api/src/test/resources/log4j2.system.properties b/log4j-api/src/test/resources/log4j2.system.properties
new file mode 100644
index 0000000..6e4f8ae
--- /dev/null
+++ b/log4j-api/src/test/resources/log4j2.system.properties
@@ -0,0 +1 @@
+Application=Log4j
\ No newline at end of file
diff --git a/log4j-core/revapi.json b/log4j-core/revapi.json
index fb4b256..3c12553 100644
--- a/log4j-core/revapi.json
+++ b/log4j-core/revapi.json
@@ -31,58 +31,332 @@
"extension": "revapi.ignore",
"configuration": [
{
- "code": "java.method.numberOfParametersChanged",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.SslSocketManager::createSocket(java.lang.String, int) throws java.io.IOException",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException @ org.apache.logging.log4j.core.net.SslSocketManager",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.class.removed",
+ "old": "class org.apache.logging.log4j.core.config.ConfiguratonFileWatcher",
+ "justification": "LOG4J2-913 - This class name was misspelled"
},
{
- "code": "java.method.nowStatic",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.SslSocketManager::createSocket(java.lang.String, int) throws java.io.IOException",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException @ org.apache.logging.log4j.core.net.SslSocketManager",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.AsyncAppender.Builder org.apache.logging.log4j.core.appender.AsyncAppender.Builder::setFilter(org.apache.logging.log4j.core.Filter)",
+ "new": "method B org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B>>>::setFilter(org.apache.logging.log4j.core.Filter) @ org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Buil [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
},
{
- "code": "java.method.numberOfParametersChanged",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String, int, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException @ org.apache.logging.log4j.core.net.SslSocketManager",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.SslSocketManager::createSocket(java.net.InetSocketAddress) throws java.io.IOException",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.AsyncAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
},
{
- "code": "java.method.noLongerStatic",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String, int, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException @ org.apache.logging.log4j.core.net.SslSocketManager",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.SslSocketManager::createSocket(java.net.InetSocketAddress) throws java.io.IOException",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.generics.elementNowParameterized",
+ "old": "class org.apache.logging.log4j.core.appender.AsyncAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
},
{
- "code": "java.method.numberOfParametersChanged",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String, int) throws java.io.IOException",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.generics.formalTypeParameterAdded",
+ "old": "class org.apache.logging.log4j.core.appender.AsyncAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B>>",
+ "typeParameter": "B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B extends org.apache.logging.log4j.core.appender.AsyncAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
},
{
- "code": "java.method.nowStatic",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String, int) throws java.io.IOException",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.annotation.attributeAdded",
+ "old": "parameter org.apache.logging.log4j.core.appender.NullAppender org.apache.logging.log4j.core.appender.NullAppender::createAppender(===java.lang.String===)",
+ "new": "parameter org.apache.logging.log4j.core.appender.NullAppender org.apache.logging.log4j.core.appender.NullAppender::createAppender(===java.lang.String===)",
+ "annotation": "@org.apache.logging.log4j.core.config.plugins.PluginAttribute(value = \"name\", defaultString = \"null\")",
+ "attribute": "defaultString",
+ "justification": "LOG4J2-2447 - Allow NullAppender to default its name to null"
+
},
{
- "code": "java.method.numberOfParametersChanged",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String, int, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress) throws java.io.IOException",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder::setFilter(org.apache.logging.log4j.core.Filter)",
+ "new": "method B org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B>>>::setFilter(org.apache.logging.log4j.core.Filter) @ org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.Outp [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
},
{
- "code": "java.method.noLongerStatic",
- "old": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.lang.String, int, org.apache.logging.log4j.core.net.SocketOptions, int) throws java.io.IOException",
- "new": "method java.net.Socket org.apache.logging.log4j.core.net.TcpSocketManager::createSocket(java.net.InetSocketAddress) throws java.io.IOException",
- "justification": "LOG4J2-2586 - Support the host name resolving to mulitple ip addresses"
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder::setFollow(boolean)",
+ "new": "method B org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>>::setFollow(boolean)",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder::setIgnoreExceptions(boolean)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setIgnoreExceptions(boolean) @ org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Bu [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder::setLayout(org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setLayout(org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>) @ org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache. [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder::setName(java.lang.String)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setName(java.lang.String) @ org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Build [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder::setTarget(java.io.OutputStream)",
+ "new": "method B org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>>::setTarget(java.io.OutputStream)",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.generics.elementNowParameterized",
+ "old": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.generics.formalTypeParameterAdded",
+ "old": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "typeParameter": "B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B extends org.apache.logging.log4j.core.appender.OutputStreamAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setFilter(org.apache.logging.log4j.core.Filter)",
+ "new": "method B org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B>>>::setFilter(org.apache.logging.log4j.core.Filter) @ org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.B [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setFollow(boolean)",
+ "new": "method B org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>>::setFollow(boolean)",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setIgnoreExceptions(boolean)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setIgnoreExceptions(boolean) @ org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.parameterTypeChanged",
+ "old": "parameter org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setLayout(===org.apache.logging.log4j.core.StringLayout===)",
+ "new": "parameter B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setLayout(===org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>===) @ org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.log [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setLayout(org.apache.logging.log4j.core.StringLayout)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setLayout(org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>) @ org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4 [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setName(java.lang.String)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setName(java.lang.String) @ org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.WriterAppender.Builder org.apache.logging.log4j.core.appender.WriterAppender.Builder::setTarget(java.io.Writer)",
+ "new": "method B org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>>::setTarget(java.io.Writer)",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.generics.elementNowParameterized",
+ "old": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.generics.formalTypeParameterAdded",
+ "old": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "typeParameter": "B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender.Builder<B extends org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender.Builder<B>>",
+ "new": "class org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender.Builder<B extends org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender.Builder<B extends org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
},
{
"code": "java.method.numberOfParametersChanged",
- "old": "method void org.apache.logging.log4j.core.layout.JsonLayout::<init>(org.apache.logging.log4j.core.config.Configuration, boolean, boolean, boolean, boolean, boolean, boolean, java.lang.String, java.lang.String, java.nio.charset.Charset, boolean)",
- "new": "method void org.apache.logging.log4j.core.layout.JsonLayout::<init>(org.apache.logging.log4j.core.config.Configuration, boolean, boolean, boolean, boolean, boolean, boolean, java.lang.String, java.lang.String, java.lang.String, java.nio.charset.Charset, boolean)",
- "justification": "LOG4J2-2337 - Allow to specify custom end-of-line for JSON layout"
+ "old": "method org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager::getManager(java.lang.String, int, org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource, java.lang.String, org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig[], org.apache.logging.log4j.core.appender.db.ColumnMapping[])",
+ "new": "method org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager org.apache.logging.log4j.core.appender.db.jdbc.JdbcDatabaseManager::getManager(java.lang.String, int, org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>, org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource, java.lang.String, org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig[], org.apache.logging.log4j.core.appender.db.ColumnMapping[], boolean, long)",
+ "justification": "LOG4J2-2500 - Allow a JDBC Appender to truncate string to match a table's metadata column length limit"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder::setFilter(org.apache.logging.log4j.core.Filter)",
+ "new": "method B org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B>>>::setFilter(org.apache.logging.log4j.core.Filter) @ org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppende [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder::setIgnoreExceptions(boolean)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setIgnoreExceptions(boolean) @ org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder::setLayout(org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setLayout(org.apache.logging.log4j.core.Layout<? extends java.io.Serializable>) @ org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.lo [...]
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder::setName(java.lang.String)",
+ "new": "method B org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B>>>::setName(java.lang.String) @ org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.appender.AbstractAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.class.nonFinalClassInheritsFromNewClass",
+ "old": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "superClass": "org.apache.logging.log4j.core.filter.AbstractFilterable.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.generics.elementNowParameterized",
+ "old": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.generics.formalTypeParameterAdded",
+ "old": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder",
+ "new": "class org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "typeParameter": "B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.JmsAppender.Builder<B>>",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.removed",
+ "old": "method org.apache.logging.log4j.core.config.Property[] org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender.Builder<B>>>::getProperties()",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.removed",
+ "old": "method B org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender.Builder<B extends org.apache.logging.log4j.core.appender.mom.kafka.KafkaAppender.Builder<B>>>::setProperties(org.apache.logging.log4j.core.config.Property[])",
+ "justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
+
+ },
+ {
+ "code": "java.method.returnTypeChanged",
+ "old": "method void org.apache.logging.log4j.core.util.Closer::close(java.lang.AutoCloseable) throws java.lang.Exception",
+ "new": "method boolean org.apache.logging.log4j.core.util.Closer::close(java.lang.AutoCloseable) throws java.lang.Exception",
+ "justification": "LOG4J2-2496 - JDBC Appender should reconnect to the database when a connection goes stale"
+ },
+ {
+ "code": "java.method.returnTypeTypeParametersChanged",
+ "old": "method java.lang.Object org.apache.logging.log4j.core.util.Loader::newInstanceOf(java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException",
+ "new": "method <T> T org.apache.logging.log4j.core.util.Loader::newInstanceOf(java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException",
+ "justification": "LOG4J2-2482 - BasicContextSelector cannot be used in an OSGi application"
+ },
+ {
+ "code": "java.generics.elementNowParameterized",
+ "old": "method java.lang.Object org.apache.logging.log4j.core.util.Loader::newInstanceOf(java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException",
+ "new": "method <T> T org.apache.logging.log4j.core.util.Loader::newInstanceOf(java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException",
+ "justification": "LOG4J2-2482 - BasicContextSelector cannot be used in an OSGi application"
+ },
+ {
+ "code": "java.generics.formalTypeParameterAdded",
+ "old": "method java.lang.Object org.apache.logging.log4j.core.util.Loader::newInstanceOf(java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException",
+ "new": "method <T> T org.apache.logging.log4j.core.util.Loader::newInstanceOf(java.lang.String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException",
+ "typeParameter": "T",
+ "justification": "LOG4J2-2482 - BasicContextSelector cannot be used in an OSGi application"
+ },
+ {
+ "code": "java.field.enumConstantOrderChanged",
+ "old": "field org.apache.logging.log4j.core.util.datetime.FixedDateFormat.FixedFormat.ISO8601_PERIOD",
+ "new": "field org.apache.logging.log4j.core.util.datetime.FixedDateFormat.FixedFormat.ISO8601_PERIOD",
+ "justification": "LOG4J2-1247 - PatternLayout %date conversion pattern should render time zone designator"
+
+ },
+ {
+ "code": "java.method.addedToInterface",
+ "new": "method void org.apache.logging.log4j.core.appender.rolling.DirectFileRolloverStrategy::clearCurrentFileName()",
+ "justification": "Required to reset file name so it can be calculated at the appropriate time"
},
{
"code": "java.method.returnTypeTypeParametersChanged",
@@ -102,7 +376,7 @@
"new": "method <B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>> B org.apache.logging.log4j.core.appender.WriterAppender::newBuilder()",
"typeParameter": "B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B extends org.apache.logging.log4j.core.appender.WriterAppender.Builder<B>>",
"justification": "LOG4J2-2491 - Allow all appenders to optionally carry a property array"
- }
+ }
]
}
]
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index ecaf4b3..de0d6eb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -67,7 +67,10 @@ import org.apache.logging.log4j.core.util.DummyNanoClock;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.NameUtil;
import org.apache.logging.log4j.core.util.NanoClock;
+import org.apache.logging.log4j.core.util.Source;
import org.apache.logging.log4j.core.util.WatchManager;
+import org.apache.logging.log4j.core.util.Watcher;
+import org.apache.logging.log4j.core.util.WatcherFactory;
import org.apache.logging.log4j.util.PropertiesUtil;
/**
@@ -240,6 +243,29 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
LOGGER.debug("Configuration {} initialized", this);
}
+ protected void initializeWatchers(Reconfigurable reconfigurable, ConfigurationSource configSource,
+ int monitorIntervalSeconds) {
+ if ((configSource.getFile() != null || configSource.getURL() != null) && monitorIntervalSeconds > 0) {
+ watchManager.setIntervalSeconds(monitorIntervalSeconds);
+ if (configSource.getFile() != null) {
+ final Source cfgSource = new Source(configSource);
+ final long lastModifeid = configSource.getFile().lastModified();
+ final ConfigurationFileWatcher watcher = new ConfigurationFileWatcher(this, reconfigurable,
+ listeners, lastModifeid);
+ watchManager.watch(cfgSource, watcher);
+ } else if (configSource.getURL() != null) {
+ if (configSource.getLastModified() > 0) {
+ final Source cfgSource = new Source(configSource);
+ final Watcher watcher = WatcherFactory.getInstance(pluginPackages)
+ .newWatcher(cfgSource, this, reconfigurable, listeners, configSource.getLastModified());
+ watchManager.watch(cfgSource, watcher);
+ } else {
+ LOGGER.info("{} does not support dynamic reconfiguration", configSource.getURI());
+ }
+ }
+ }
+ }
+
/**
* Start the configuration.
*/
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
index 8c05959..f4adea0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
@@ -21,6 +21,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;
import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -29,6 +30,8 @@ import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import javax.net.ssl.HttpsURLConnection;
+
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
@@ -38,6 +41,9 @@ 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.lookup.Interpolator;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
+import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.NetUtils;
@@ -128,6 +134,8 @@ public abstract class ConfigurationFactory extends ConfigurationBuilderFactory {
private static final Lock LOCK = new ReentrantLock();
+ private static final String HTTPS = "https";
+
/**
* Returns the ConfigurationFactory.
* @return the ConfigurationFactory.
@@ -294,7 +302,22 @@ public abstract class ConfigurationFactory extends ConfigurationBuilderFactory {
protected ConfigurationSource getInputFromString(final String config, final ClassLoader loader) {
try {
final URL url = new URL(config);
- return new ConfigurationSource(url.openStream(), FileUtils.fileFromUri(url.toURI()));
+ URLConnection urlConnection = url.openConnection();
+ if (url.getProtocol().equals(HTTPS)) {
+ SslConfiguration sslConfiguration = SslConfigurationFactory.getSslConfiguration();
+ if (sslConfiguration != null) {
+ ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ if (!sslConfiguration.isVerifyHostName()) {
+ ((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
+ }
+ }
+ }
+ File file = FileUtils.fileFromUri(url.toURI());
+ if (file != null) {
+ return new ConfigurationSource(urlConnection.getInputStream(), FileUtils.fileFromUri(url.toURI()));
+ } else {
+ return new ConfigurationSource(urlConnection.getInputStream(), url, urlConnection.getLastModified());
+ }
} catch (final Exception ex) {
final ConfigurationSource source = ConfigurationSource.fromResource(config, loader);
if (source == null) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFileWatcher.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFileWatcher.java
new file mode 100644
index 0000000..e777fbf
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFileWatcher.java
@@ -0,0 +1,72 @@
+/*
+ * 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.config;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.logging.log4j.core.util.AbstractWatcher;
+import org.apache.logging.log4j.core.util.FileWatcher;
+import org.apache.logging.log4j.core.util.Source;
+import org.apache.logging.log4j.core.util.Watcher;
+
+/**
+ * Watcher for configuration files. Causes a reconfiguration when a file changes.
+ */
+public class ConfigurationFileWatcher extends AbstractWatcher implements FileWatcher {
+
+ private File file;
+ private long lastModifiedMillis;
+
+ public ConfigurationFileWatcher(final Configuration configuration, final Reconfigurable reconfigurable,
+ final List<ConfigurationListener> configurationListeners, long lastModifiedMillis) {
+ super(configuration, reconfigurable, configurationListeners);
+ this.lastModifiedMillis = lastModifiedMillis;
+ }
+
+ public long getLastModified() {
+ return file != null ? file.lastModified() : 0;
+ }
+
+ @Override
+ public void fileModified(final File file) {
+ lastModifiedMillis = file.lastModified();
+ }
+
+ @Override
+ public void watching(Source source) {
+ file = source.getFile();
+ lastModifiedMillis = file.lastModified();
+ super.watching(source);
+ }
+
+ @Override
+ public boolean isModified() {
+ return lastModifiedMillis != file.lastModified();
+ }
+
+ @Override
+ public Watcher newWatcher(final Reconfigurable reconfigurable, final List<ConfigurationListener> listeners,
+ long lastModifiedMillis) {
+ ConfigurationFileWatcher watcher = new ConfigurationFileWatcher(getConfiguration(), reconfigurable, listeners,
+ lastModifiedMillis);
+ if (getSource() != null) {
+ watcher.watching(getSource());
+ }
+ return watcher;
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
index 21558fc..d7c1808 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
@@ -28,11 +28,18 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.net.URLConnection;
import java.util.Objects;
+import javax.net.ssl.HttpsURLConnection;
+
import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.core.util.Source;
import org.apache.logging.log4j.util.LoaderUtil;
/**
@@ -43,13 +50,18 @@ public class ConfigurationSource {
/**
* ConfigurationSource to use with Configurations that do not require a "real" configuration source.
*/
- public static final ConfigurationSource NULL_SOURCE = new ConfigurationSource(new byte[0]);
+ public static final ConfigurationSource NULL_SOURCE = new ConfigurationSource(new byte[0], null, 0);
+ private static final String HTTPS = "https";
private final File file;
private final URL url;
private final String location;
private final InputStream stream;
- private final byte[] data;
+ private volatile byte[] data;
+ private volatile Source source = null;
+ private final long lastModified;
+ // Set when the configuration has been updated so reset can use it for the next lastModified timestamp.
+ private volatile long modifiedMillis;
/**
* Constructs a new {@code ConfigurationSource} with the specified input stream that originated from the specified
@@ -64,6 +76,13 @@ public class ConfigurationSource {
this.location = file.getAbsolutePath();
this.url = null;
this.data = null;
+ long modified = 0;
+ try {
+ modified = file.lastModified();
+ } catch (Exception ex) {
+ // There is a problem with the file. It will be handled somewhere else.
+ }
+ this.lastModified = modified;
}
/**
@@ -79,6 +98,24 @@ public class ConfigurationSource {
this.location = url.toString();
this.file = null;
this.data = null;
+ this.lastModified = 0;
+ }
+
+ /**
+ * Constructs a new {@code ConfigurationSource} with the specified input stream that originated from the specified
+ * url.
+ *
+ * @param stream the input stream
+ * @param url the URL where the input stream originated
+ * @param lastModified when the source was last modified.
+ */
+ public ConfigurationSource(final InputStream stream, final URL url, long lastModified) {
+ this.stream = Objects.requireNonNull(stream, "stream is null");
+ this.url = Objects.requireNonNull(url, "URL is null");
+ this.location = url.toString();
+ this.file = null;
+ this.data = null;
+ this.lastModified = lastModified;
}
/**
@@ -89,15 +126,26 @@ public class ConfigurationSource {
* @throws IOException if an exception occurred reading from the specified stream
*/
public ConfigurationSource(final InputStream stream) throws IOException {
- this(toByteArray(stream));
+ this(toByteArray(stream), null, 0);
}
- private ConfigurationSource(final byte[] data) {
+ public ConfigurationSource(final Source source, final byte[] data, long lastModified) throws IOException {
+ Objects.requireNonNull(source, "source is null");
this.data = Objects.requireNonNull(data, "data is null");
this.stream = new ByteArrayInputStream(data);
+ this.file = source.getFile();
+ this.url = source.getURI().toURL();
+ this.location = source.getLocation();
+ this.lastModified = lastModified;
+ }
+
+ private ConfigurationSource(final byte[] data, final URL url, long lastModified) {
+ Objects.requireNonNull(data, "data is null");
+ this.stream = new ByteArrayInputStream(data);
this.file = null;
- this.url = null;
+ this.url = url;
this.location = null;
+ this.lastModified = lastModified;
}
/**
@@ -140,6 +188,18 @@ public class ConfigurationSource {
return url;
}
+ public void setSource(Source source) {
+ this.source = source;
+ }
+
+ public void setData(byte[] data) {
+ this.data = data;
+ }
+
+ public void setModifiedMillis(long modifiedMillis) {
+ this.modifiedMillis = modifiedMillis;
+ }
+
/**
* Returns a URI representing the configuration resource or null if it cannot be determined.
* @return The URI.
@@ -172,6 +232,14 @@ public class ConfigurationSource {
}
/**
+ * Returns the time the resource was last modified or 0 if it is not available.
+ * @return the last modified time of the resource.
+ */
+ public long getLastModified() {
+ return lastModified;
+ }
+
+ /**
* Returns a string describing the configuration source file or URL, or {@code null} if this configuration source
* has neither a file nor an URL.
*
@@ -197,13 +265,19 @@ public class ConfigurationSource {
* @throws IOException if a problem occurred while opening the new input stream
*/
public ConfigurationSource resetInputStream() throws IOException {
- if (file != null) {
+ if (source != null) {
+ return new ConfigurationSource(source, data, this.lastModified);
+ } else if (file != null) {
return new ConfigurationSource(new FileInputStream(file), file);
+ } else if (url != null && data != null) {
+ // Creates a ConfigurationSource without accessing the URL since the data was provided.
+ return new ConfigurationSource(data, url, modifiedMillis == 0 ? lastModified : modifiedMillis);
} else if (url != null) {
- return new ConfigurationSource(url.openStream(), url);
- } else {
- return new ConfigurationSource(data);
+ return fromUri(getURI());
+ } else if (data != null) {
+ return new ConfigurationSource(data, null, lastModified);
}
+ return null;
}
@Override
@@ -245,7 +319,20 @@ public class ConfigurationSource {
return null;
}
try {
- return new ConfigurationSource(configLocation.toURL().openStream(), configLocation.toURL());
+ URL url = configLocation.toURL();
+ URLConnection urlConnection = url.openConnection();
+ if (url.getProtocol().equals(HTTPS)) {
+ SslConfiguration sslConfiguration = SslConfigurationFactory.getSslConfiguration();
+ if (sslConfiguration != null) {
+ ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ if (!sslConfiguration.isVerifyHostName()) {
+ ((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
+ }
+ }
+ }
+ InputStream is = urlConnection.getInputStream();
+ long lastModified = urlConnection.getLastModified();
+ return new ConfigurationSource(configLocation.toURL().openStream(), configLocation.toURL(), lastModified);
} catch (final MalformedURLException ex) {
ConfigurationFactory.LOGGER.error("Invalid URL {}", configLocation.toString(), ex);
} catch (final Exception ex) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/HttpWatcher.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/HttpWatcher.java
new file mode 100644
index 0000000..a2d1220
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/HttpWatcher.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2019 Nextiva, Inc. to Present.
+ * All rights reserved.
+ */
+package org.apache.logging.log4j.core.config;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+
+import javax.net.ssl.HttpsURLConnection;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAliases;
+import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
+import org.apache.logging.log4j.core.util.AbstractWatcher;
+import org.apache.logging.log4j.core.util.Source;
+import org.apache.logging.log4j.core.util.Watcher;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+/**
+ *
+ */
+@Plugin(name = "http", category = Watcher.CATEGORY, printObject = true)
+@PluginAliases("https")
+public class HttpWatcher extends AbstractWatcher {
+
+ private Logger LOGGER = StatusLogger.getLogger();
+
+ private static int DEFAULT_TIMEOUT = 60000;
+ private int connectTimeoutMillis = DEFAULT_TIMEOUT;
+ private int readTimeoutMillis = DEFAULT_TIMEOUT;
+ private SslConfiguration sslConfiguration;
+ private URL url;
+ private volatile long lastModifiedMillis;
+ private static final String JSON = "application/json";
+ private static final String XML = "application/xml";
+ private static final String PROPERTIES = "text/x-java-properties";
+ private static final String TEXT = "text/plain";
+ private static final int NOT_MODIFIED = 304;
+ private static final int OK = 200;
+ private static final int BUF_SIZE = 1024;
+ private static final String HTTP = "http";
+ private static final String HTTPS = "https";
+
+ public HttpWatcher(final Configuration configuration, final Reconfigurable reconfigurable,
+ final List<ConfigurationListener> configurationListeners, long lastModifiedMillis) {
+ super(configuration, reconfigurable, configurationListeners);
+ sslConfiguration = SslConfigurationFactory.getSslConfiguration();
+ this.lastModifiedMillis = lastModifiedMillis;
+ }
+
+ @Override
+ public long getLastModified() {
+ return lastModifiedMillis;
+ }
+
+ @Override
+ public boolean isModified() {
+ return refreshConfiguration();
+ }
+
+ @Override
+ public void watching(Source source) {
+ if (!source.getURI().getScheme().equals(HTTP) && !source.getURI().getScheme().equals(HTTPS)) {
+ throw new IllegalArgumentException("HttpWatcher requires a url using the HTTP or HTTPS protocol, not " +
+ source.getURI().getScheme());
+ }
+ try {
+ url = source.getURI().toURL();
+ } catch (MalformedURLException ex) {
+ throw new IllegalArgumentException("Invalid URL for HttpWatcher " + source.getURI(), ex);
+ }
+ super.watching(source);
+ }
+
+ @Override
+ public Watcher newWatcher(Reconfigurable reconfigurable, List<ConfigurationListener> listeners,
+ long lastModifiedMillis) {
+ HttpWatcher watcher = new HttpWatcher(getConfiguration(), reconfigurable, listeners, lastModifiedMillis);
+ if (getSource() != null) {
+ watcher.watching(getSource());
+ }
+ return watcher;
+ }
+
+ private boolean refreshConfiguration() {
+ try {
+ final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ urlConnection.setAllowUserInteraction(false);
+ urlConnection.setDoOutput(true);
+ urlConnection.setDoInput(true);
+ urlConnection.setRequestMethod("GET");
+ if (connectTimeoutMillis > 0) {
+ urlConnection.setConnectTimeout(connectTimeoutMillis);
+ }
+ if (readTimeoutMillis > 0) {
+ urlConnection.setReadTimeout(readTimeoutMillis);
+ }
+ String[] fileParts = url.getFile().split("\\.");
+ String type = fileParts[fileParts.length - 1].trim();
+ String contentType = isXml(type) ? XML : isJson(type) ? JSON : isProperties(type) ? PROPERTIES : TEXT;
+ urlConnection.setRequestProperty("Content-Type", contentType);
+ urlConnection.setIfModifiedSince(lastModifiedMillis);
+ if (url.getProtocol().equals(HTTPS) && sslConfiguration != null) {
+ ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ if (!sslConfiguration.isVerifyHostName()) {
+ ((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
+ }
+ }
+
+ urlConnection.connect();
+
+ try {
+ int code = urlConnection.getResponseCode();
+ switch (code) {
+ case NOT_MODIFIED: {
+ return false;
+ }
+ case OK: {
+ try (InputStream is = urlConnection.getInputStream()) {
+ ConfigurationSource configSource = getConfiguration().getConfigurationSource();
+ configSource.setData(readStream(is));
+ lastModifiedMillis = urlConnection.getLastModified();
+ configSource.setModifiedMillis(lastModifiedMillis);
+ LOGGER.debug("Content was modified for {}", url.toString());
+ return true;
+ } catch (final IOException e) {
+ try (InputStream es = urlConnection.getErrorStream()) {
+ LOGGER.info("Error accessing configuration at {}: {}", url,
+ readStream(es));
+ } catch (final IOException ioe) {
+ LOGGER.error("Error accessing configuration at {}: {}", url, e.getMessage());
+ }
+ return false;
+ }
+ }
+ default : {
+ if (code < 0) {
+ LOGGER.info("Invalid response code returned");
+ } else {
+ LOGGER.info("Unexpected response code returned {}", code);
+ }
+ return false;
+ }
+ }
+ } catch (final IOException ioe) {
+ LOGGER.error("Error accessing configuration at {}: {}", url, ioe.getMessage());
+ }
+ } catch (final IOException ioe) {
+ LOGGER.error("Error connecting to configuration at {}: {}", url, ioe.getMessage());
+ }
+ return false;
+ }
+
+ private byte[] readStream(InputStream is) throws IOException {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ byte[] buffer = new byte[BUF_SIZE];
+ int length;
+ while ((length = is.read(buffer)) != -1) {
+ result.write(buffer, 0, length);
+ }
+ return result.toByteArray();
+ }
+
+ private boolean isXml(String type) {
+ return type.equalsIgnoreCase("xml");
+ }
+
+ private boolean isJson(String type) {
+ return type.equalsIgnoreCase("json") || type.equalsIgnoreCase("jsn");
+ }
+
+ private boolean isProperties(String type) {
+ return type.equalsIgnoreCase("properties");
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
index ae932ee..741859c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java
@@ -16,7 +16,6 @@
*/
package org.apache.logging.log4j.core.config.builder.impl;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
@@ -25,7 +24,7 @@ import java.util.List;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
-import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
+import org.apache.logging.log4j.core.config.ConfigurationFileWatcher;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.Reconfigurable;
import org.apache.logging.log4j.core.config.builder.api.Component;
@@ -35,6 +34,9 @@ import org.apache.logging.log4j.core.config.plugins.util.ResolverUtil;
import org.apache.logging.log4j.core.config.status.StatusConfiguration;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.Patterns;
+import org.apache.logging.log4j.core.util.Source;
+import org.apache.logging.log4j.core.util.Watcher;
+import org.apache.logging.log4j.core.util.WatcherFactory;
/**
* This is the general version of the Configuration created by the Builder. It may be extended to
@@ -153,17 +155,7 @@ public class BuiltConfiguration extends AbstractConfiguration {
public void setMonitorInterval(final int intervalSeconds) {
if (this instanceof Reconfigurable && intervalSeconds > 0) {
- final ConfigurationSource configSource = getConfigurationSource();
- if (configSource != null) {
- final File configFile = configSource.getFile();
- if (intervalSeconds > 0) {
- getWatchManager().setIntervalSeconds(intervalSeconds);
- if (configFile != null) {
- final FileWatcher watcher = new ConfiguratonFileWatcher((Reconfigurable) this, listeners);
- getWatchManager().watchFile(configFile, watcher);
- }
- }
- }
+ initializeWatchers((Reconfigurable) this, getConfigurationSource(), intervalSeconds);
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
index c0595d7..0a6c2d1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultConfigurationBuilder.java
@@ -170,7 +170,6 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
}
final Constructor<T> constructor = clazz.getConstructor(LoggerContext.class, ConfigurationSource.class, Component.class);
configuration = constructor.newInstance(loggerContext, source, root);
- configuration.setMonitorInterval(monitorInterval);
configuration.getRootNode().getAttributes().putAll(root.getAttributes());
if (name != null) {
configuration.setName(name);
@@ -196,6 +195,7 @@ public class DefaultConfigurationBuilder<T extends BuiltConfiguration> implement
if (advertiser != null) {
configuration.createAdvertiser(advertiser, source);
}
+ configuration.setMonitorInterval(monitorInterval);
} catch (final Exception ex) {
throw new IllegalArgumentException("Invalid Configuration class specified", ex);
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
index 9b6b11a..2267639 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/composite/CompositeConfiguration.java
@@ -29,7 +29,7 @@ import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
-import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
+import org.apache.logging.log4j.core.config.ConfigurationFileWatcher;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.Reconfigurable;
import org.apache.logging.log4j.core.config.plugins.util.ResolverUtil;
@@ -37,7 +37,10 @@ import org.apache.logging.log4j.core.config.status.StatusConfiguration;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Patterns;
+import org.apache.logging.log4j.core.util.Source;
import org.apache.logging.log4j.core.util.WatchManager;
+import org.apache.logging.log4j.core.util.Watcher;
+import org.apache.logging.log4j.core.util.WatcherFactory;
import org.apache.logging.log4j.util.PropertiesUtil;
/**
@@ -106,14 +109,12 @@ public class CompositeConfiguration extends AbstractConfiguration implements Rec
staffChildConfiguration(targetConfiguration);
final WatchManager watchManager = getWatchManager();
final WatchManager targetWatchManager = targetConfiguration.getWatchManager();
- final FileWatcher fileWatcher = new ConfiguratonFileWatcher(this, listeners);
if (targetWatchManager.getIntervalSeconds() > 0) {
watchManager.setIntervalSeconds(targetWatchManager.getIntervalSeconds());
- final Map<File, FileWatcher> watchers = targetWatchManager.getWatchers();
- for (final Map.Entry<File, FileWatcher> entry : watchers.entrySet()) {
- if (entry.getValue() instanceof ConfiguratonFileWatcher) {
- watchManager.watchFile(entry.getKey(), fileWatcher);
- }
+ final Map<Source, Watcher> watchers = targetWatchManager.getConfigurationWatchers();
+ for (final Map.Entry<Source, Watcher> entry : watchers.entrySet()) {
+ watchManager.watch(entry.getKey(), entry.getValue().newWatcher(this, listeners,
+ entry.getValue().getLastModified()));
}
}
for (final AbstractConfiguration sourceConfiguration : configurations.subList(1, configurations.size())) {
@@ -132,11 +133,10 @@ public class CompositeConfiguration extends AbstractConfiguration implements Rec
watchManager.setIntervalSeconds(monitorInterval);
}
final WatchManager sourceWatchManager = sourceConfiguration.getWatchManager();
- final Map<File, FileWatcher> watchers = sourceWatchManager.getWatchers();
- for (final Map.Entry<File, FileWatcher> entry : watchers.entrySet()) {
- if (entry.getValue() instanceof ConfiguratonFileWatcher) {
- watchManager.watchFile(entry.getKey(), fileWatcher);
- }
+ final Map<Source, Watcher> watchers = sourceWatchManager.getConfigurationWatchers();
+ for (final Map.Entry<Source, Watcher> entry : watchers.entrySet()) {
+ watchManager.watch(entry.getKey(), entry.getValue().newWatcher(this, listeners,
+ entry.getValue().getLastModified()));
}
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
index 5b38dfb..c9d7162 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
@@ -33,7 +33,7 @@ import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
-import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
+import org.apache.logging.log4j.core.config.ConfigurationFileWatcher;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.Reconfigurable;
@@ -42,6 +42,9 @@ import org.apache.logging.log4j.core.config.plugins.util.ResolverUtil;
import org.apache.logging.log4j.core.config.status.StatusConfiguration;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.Patterns;
+import org.apache.logging.log4j.core.util.Source;
+import org.apache.logging.log4j.core.util.Watcher;
+import org.apache.logging.log4j.core.util.WatcherFactory;
/**
* Creates a Node hierarchy from a JSON file.
@@ -70,6 +73,7 @@ public class JsonConfiguration extends AbstractConfiguration implements Reconfig
processAttributes(rootNode, root);
final StatusConfiguration statusConfig = new StatusConfiguration().withVerboseClasses(VERBOSE_CLASSES)
.withStatus(getDefaultStatus());
+ int monitorIntervalSeconds = 0;
for (final Map.Entry<String, String> entry : rootNode.getAttributes().entrySet()) {
final String key = entry.getKey();
final String value = getStrSubstitutor().replace(entry.getValue());
@@ -89,18 +93,12 @@ public class JsonConfiguration extends AbstractConfiguration implements Reconfig
} else if ("name".equalsIgnoreCase(key)) {
setName(value);
} else if ("monitorInterval".equalsIgnoreCase(key)) {
- final int intervalSeconds = Integer.parseInt(value);
- if (intervalSeconds > 0) {
- getWatchManager().setIntervalSeconds(intervalSeconds);
- if (configFile != null) {
- final FileWatcher watcher = new ConfiguratonFileWatcher(this, listeners);
- getWatchManager().watchFile(configFile, watcher);
- }
- }
+ monitorIntervalSeconds = Integer.parseInt(value);
} else if ("advertiser".equalsIgnoreCase(key)) {
createAdvertiser(value, configSource, buffer, "application/json");
}
}
+ initializeWatchers(this, configSource, monitorIntervalSeconds);
statusConfig.initialize();
if (getName() == null) {
setName(configSource.getLocation());
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
index 6b0e79a..0e5fa98 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
@@ -28,7 +28,6 @@ import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
@@ -38,7 +37,7 @@ import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AbstractConfiguration;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
-import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
+import org.apache.logging.log4j.core.config.ConfigurationFileWatcher;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.Reconfigurable;
import org.apache.logging.log4j.core.config.plugins.util.PluginType;
@@ -48,7 +47,10 @@ import org.apache.logging.log4j.core.util.Closer;
import org.apache.logging.log4j.core.util.FileWatcher;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Patterns;
+import org.apache.logging.log4j.core.util.Source;
import org.apache.logging.log4j.core.util.Throwables;
+import org.apache.logging.log4j.core.util.Watcher;
+import org.apache.logging.log4j.core.util.WatcherFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -110,6 +112,7 @@ public class XmlConfiguration extends AbstractConfiguration implements Reconfigu
final Map<String, String> attrs = processAttributes(rootNode, rootElement);
final StatusConfiguration statusConfig = new StatusConfiguration().withVerboseClasses(VERBOSE_CLASSES)
.withStatus(getDefaultStatus());
+ int monitorIntervalSeconds = 0;
for (final Map.Entry<String, String> entry : attrs.entrySet()) {
final String key = entry.getKey();
final String value = getStrSubstitutor().replace(entry.getValue());
@@ -132,18 +135,12 @@ public class XmlConfiguration extends AbstractConfiguration implements Reconfigu
} else if ("schema".equalsIgnoreCase(key)) {
schemaResource = value;
} else if ("monitorInterval".equalsIgnoreCase(key)) {
- final int intervalSeconds = Integer.parseInt(value);
- if (intervalSeconds > 0) {
- getWatchManager().setIntervalSeconds(intervalSeconds);
- if (configFile != null) {
- final FileWatcher watcher = new ConfiguratonFileWatcher(this, listeners);
- getWatchManager().watchFile(configFile, watcher);
- }
- }
+ monitorIntervalSeconds = Integer.parseInt(value);
} else if ("advertiser".equalsIgnoreCase(key)) {
createAdvertiser(value, configSource, buffer, "text/xml");
}
}
+ initializeWatchers(this, configSource, monitorIntervalSeconds);
statusConfig.initialize();
} catch (final SAXException | IOException | ParserConfigurationException e) {
LOGGER.error("Error parsing " + configSource.getLocation(), e);
@@ -151,7 +148,7 @@ public class XmlConfiguration extends AbstractConfiguration implements Reconfigu
if (strict && schemaResource != null && buffer != null) {
try (InputStream is = Loader.getResourceAsStream(schemaResource, XmlConfiguration.class.getClassLoader())) {
if (is != null) {
- final Source src = new StreamSource(is, LOG4J_XSD);
+ final javax.xml.transform.Source src = new StreamSource(is, LOG4J_XSD);
final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = null;
try {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
index 5603e89..5d341d6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
@@ -46,13 +46,15 @@ public class SslConfiguration {
private final TrustStoreConfiguration trustStoreConfig;
private final SSLContext sslContext;
private final String protocol;
+ private final boolean verifyHostName;
private SslConfiguration(final String protocol, final KeyStoreConfiguration keyStoreConfig,
- final TrustStoreConfiguration trustStoreConfig) {
+ final TrustStoreConfiguration trustStoreConfig, boolean verifyHostName) {
this.keyStoreConfig = keyStoreConfig;
this.trustStoreConfig = trustStoreConfig;
this.protocol = protocol == null ? SslConfigurationDefaults.PROTOCOL : protocol;
this.sslContext = this.createSslContext();
+ this.verifyHostName = verifyHostName;
}
/**
@@ -232,7 +234,26 @@ public class SslConfiguration {
@PluginElement("KeyStore") final KeyStoreConfiguration keyStoreConfig,
@PluginElement("TrustStore") final TrustStoreConfiguration trustStoreConfig) {
// @formatter:on
- return new SslConfiguration(protocol, keyStoreConfig, trustStoreConfig);
+ return new SslConfiguration(protocol, keyStoreConfig, trustStoreConfig, false);
+ }
+
+ /**
+ * Creates an SslConfiguration from a KeyStoreConfiguration and a TrustStoreConfiguration.
+ *
+ * @param protocol The protocol, see http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext
+ * @param keyStoreConfig The KeyStoreConfiguration.
+ * @param trustStoreConfig The TrustStoreConfiguration.
+ * @return a new SslConfiguration
+ * @since 2.12
+ */
+ public static SslConfiguration createSSLConfiguration(
+ // @formatter:off
+ @PluginAttribute("protocol") final String protocol,
+ @PluginElement("KeyStore") final KeyStoreConfiguration keyStoreConfig,
+ @PluginElement("TrustStore") final TrustStoreConfiguration trustStoreConfig,
+ @PluginElement("verifyHostName") final boolean verifyHostName) {
+ // @formatter:on
+ return new SslConfiguration(protocol, keyStoreConfig, trustStoreConfig, verifyHostName);
}
@Override
@@ -304,4 +325,8 @@ public class SslConfiguration {
public String getProtocol() {
return protocol;
}
+
+ public boolean isVerifyHostName() {
+ return verifyHostName;
+ }
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
new file mode 100644
index 0000000..e3cc4d3
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 Nextiva, Inc. to Present.
+ * All rights reserved.
+ */
+package org.apache.logging.log4j.core.net.ssl;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+/**
+ * Creates an SSL configuration from Log4j properties.
+ */
+public class SslConfigurationFactory {
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+ private static SslConfiguration sslConfiguration = null;
+
+ private static final String trustStorelocation = "log4j2.trustStore.location";
+ private static final String trustStorePassword = "log4j2.trustStore.password";
+ private static final String trustStorePasswordFile = "log4j2.trustStore.passwordFile";
+ private static final String trustStorePasswordEnvVar = "log4j2.trustStore.passwordEnvironmentVariable";
+ private static final String trustStoreKeyStoreType = "log4j2.trustStore.keyStoreType";
+ private static final String trustStoreKeyManagerFactoryAlgorithm = "log4j2.trustStore.keyManagerFactoryAlgorithm";
+ private static final String keyStoreLocation = "log4j2.keyStore.location";
+ private static final String keyStorePassword = "log4j2.keyStorePassword";
+ private static final String keyStorePasswordFile = "log4j2.keyStorePasswordFile";
+ private static final String keyStorePasswordEnvVar = "log4j2.keyStorePasswordEnvironmentVariable";
+ private static final String keyStoreType = "log4j2.keyStore.type";
+ private static final String keyStoreKeyManagerFactoryAlgorithm = "log4j2.keyStore.keyManagerFactoryAlgorithm";
+ private static final String verifyHostName = "log4j2.ssl.verifyHostName";
+
+ static {
+ PropertiesUtil props = PropertiesUtil.getProperties();
+ KeyStoreConfiguration keyStoreConfiguration = null;
+ TrustStoreConfiguration trustStoreConfiguration = null;
+ String location = props.getStringProperty(trustStorelocation);
+ if (location != null) {
+ String password = props.getStringProperty(trustStorePassword);
+ char[] passwordChars = null;
+ if (password != null) {
+ passwordChars = password.toCharArray();
+ }
+ try {
+ trustStoreConfiguration = TrustStoreConfiguration.createKeyStoreConfiguration(location, passwordChars,
+ props.getStringProperty(trustStorePasswordEnvVar), props.getStringProperty(trustStorePasswordFile),
+ props.getStringProperty(trustStoreKeyStoreType), props.getStringProperty(trustStoreKeyManagerFactoryAlgorithm));
+ } catch (Exception ex) {
+ LOGGER.warn("Unable to create trust store configuration due to: {} {}", ex.getClass().getName(),
+ ex.getMessage());
+ }
+ }
+ location = props.getStringProperty(keyStoreLocation);
+ if (location != null) {
+ String password = props.getStringProperty(keyStorePassword);
+ char[] passwordChars = null;
+ if (password != null) {
+ passwordChars = password.toCharArray();
+ }
+ try {
+ keyStoreConfiguration = KeyStoreConfiguration.createKeyStoreConfiguration(location, passwordChars,
+ props.getStringProperty(keyStorePasswordEnvVar), props.getStringProperty(keyStorePasswordFile),
+ props.getStringProperty(keyStoreType), props.getStringProperty(keyStoreKeyManagerFactoryAlgorithm));
+ } catch (Exception ex) {
+ LOGGER.warn("Unable to create key store configuration due to: {} {}", ex.getClass().getName(),
+ ex.getMessage());
+ }
+ }
+ if (trustStoreConfiguration != null || keyStoreConfiguration != null) {
+ boolean isVerifyHostName = props.getBooleanProperty(verifyHostName, false);
+ sslConfiguration = SslConfiguration.createSSLConfiguration("https", keyStoreConfiguration,
+ trustStoreConfiguration, isVerifyHostName);
+ }
+ }
+
+ public static SslConfiguration getSslConfiguration() {
+ return sslConfiguration;
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/AbstractWatcher.java
similarity index 65%
rename from log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java
rename to log4j-core/src/main/java/org/apache/logging/log4j/core/util/AbstractWatcher.java
index 38491f2..3dbb111 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfiguratonFileWatcher.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/AbstractWatcher.java
@@ -14,46 +14,70 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.core.config;
+package org.apache.logging.log4j.core.util;
import java.io.File;
import java.util.List;
-import org.apache.logging.log4j.core.util.FileWatcher;
-import org.apache.logging.log4j.core.util.Log4jThreadFactory;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationListener;
+import org.apache.logging.log4j.core.config.Reconfigurable;
/**
* Watcher for configuration files. Causes a reconfiguration when a file changes.
*/
-public class ConfiguratonFileWatcher implements FileWatcher {
+public abstract class AbstractWatcher implements Watcher {
private final Reconfigurable reconfigurable;
private final List<ConfigurationListener> configurationListeners;
private final Log4jThreadFactory threadFactory;
+ private final Configuration configuration;
+ private Source source;
- public ConfiguratonFileWatcher(final Reconfigurable reconfigurable, final List<ConfigurationListener> configurationListeners) {
+ public AbstractWatcher(final Configuration configuration, final Reconfigurable reconfigurable,
+ final List<ConfigurationListener> configurationListeners) {
+ this.configuration = configuration;
this.reconfigurable = reconfigurable;
this.configurationListeners = configurationListeners;
- this.threadFactory = Log4jThreadFactory.createDaemonThreadFactory("ConfiguratonFileWatcher");
+ this.threadFactory = configurationListeners != null ?
+ Log4jThreadFactory.createDaemonThreadFactory("ConfiguratonFileWatcher") : null;
}
+ @Override
public List<ConfigurationListener> getListeners() {
return configurationListeners;
}
-
@Override
- public void fileModified(final File file) {
+ public void modified() {
for (final ConfigurationListener configurationListener : configurationListeners) {
final Thread thread = threadFactory.newThread(new ReconfigurationRunnable(configurationListener, reconfigurable));
thread.start();
}
}
+ public Configuration getConfiguration() {
+ return configuration;
+ }
+
+ public abstract long getLastModified();
+
+ public abstract boolean isModified();
+
+ @Override
+ public void watching(Source source) {
+ this.source = source;
+ }
+
+ @Override
+ public Source getSource() {
+ return source;
+ }
+
/**
* Helper class for triggering a reconfiguration in a background thread.
*/
- private static class ReconfigurationRunnable implements Runnable {
+ public static class ReconfigurationRunnable implements Runnable {
private final ConfigurationListener configurationListener;
private final Reconfigurable reconfigurable;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
new file mode 100644
index 0000000..a0aa548
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
@@ -0,0 +1,135 @@
+/*
+ * 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.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Objects;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.util.LoaderUtil;
+
+/**
+ * Represents the source for the logging configuration.
+ */
+public class Source {
+
+ /**
+ * Captures a URI or File.
+ */
+
+ private final File file;
+ private final URI uri;
+ private final String location;
+
+ /**
+ * Constructs a Source from a ConfigurationSource.
+ * @param source The ConfigurationSource.
+ */
+ public Source(ConfigurationSource source) {
+ this.file = source.getFile();
+ this.uri = source.getURI();
+ this.location = source.getLocation();
+ }
+
+ /**
+ * Constructs a new {@code Source} with the specified file.
+ * file.
+ *
+ * @param file the file where the input stream originated
+ */
+ public Source(final File file) {
+ this.file = Objects.requireNonNull(file, "file is null");
+ this.location = file.getAbsolutePath();
+ this.uri = null;
+ }
+
+ /**
+ * Constructs a new {@code Source} from the specified URI.
+ *
+ * @param uri the URL where the input stream originated
+ */
+ public Source(final URI uri, final long lastModified) {
+ this.uri = Objects.requireNonNull(uri, "URI is null");
+ this.location = uri.toString();
+ this.file = null;
+ }
+
+ /**
+ * Returns the file configuration source, or {@code null} if this configuration source is based on an URL or has
+ * neither a file nor an URL.
+ *
+ * @return the configuration source file, or {@code null}
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * Returns the configuration source URL, or {@code null} if this configuration source is based on a file or has
+ * neither a file nor an URL.
+ *
+ * @return the configuration source URL, or {@code null}
+ */
+ public URI getURI() {
+ return uri;
+ }
+
+ /**
+ * Returns a string describing the configuration source file or URL, or {@code null} if this configuration source
+ * has neither a file nor an URL.
+ *
+ * @return a string describing the configuration source file or URL, or {@code null}
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ @Override
+ public String toString() {
+ return location;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Source)) {
+ return false;
+ }
+ Source source = (Source) o;
+ return Objects.equals(location, source.location);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(location);
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
index 31a98ef..37e0a44 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
@@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.AbstractLifeCycle;
+import org.apache.logging.log4j.core.config.ConfigurationFileWatcher;
import org.apache.logging.log4j.core.config.ConfigurationScheduler;
import org.apache.logging.log4j.status.StatusLogger;
@@ -39,7 +40,7 @@ import org.apache.logging.log4j.status.StatusLogger;
public class WatchManager extends AbstractLifeCycle {
private static Logger logger = StatusLogger.getLogger();
- private final ConcurrentMap<File, FileMonitor> watchers = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Source, ConfigurationMonitor> watchers = new ConcurrentHashMap<>();
private int intervalSeconds = 0;
private ScheduledFuture<?> future;
private final ConfigurationScheduler scheduler;
@@ -60,8 +61,8 @@ public class WatchManager extends AbstractLifeCycle {
*/
public void reset() {
logger.debug("Resetting {}", this);
- for (final File file : watchers.keySet()) {
- reset(file);
+ for (final Source source: watchers.keySet()) {
+ reset(source);
}
}
@@ -81,16 +82,38 @@ public class WatchManager extends AbstractLifeCycle {
if (file == null) {
return;
}
- final FileMonitor fileMonitor = watchers.get(file);
- if (fileMonitor != null) {
- final long lastModifiedMillis = file.lastModified();
- if (lastModifiedMillis != fileMonitor.lastModifiedMillis) {
+ Source source = new Source(file);
+ reset(source);
+ }
+
+
+ /**
+ * Resets the configuration monitor for the given file being watched to its current last modified time. If this
+ * manager does not watch the given configuration, nothing happens.
+ * <p>
+ * This allows you to start, stop, reset and start again a manager, without triggering file modified events if the
+ * given watched configuration has changed during the period of time when the manager was stopped.
+ * </p>
+ *
+ * @param source
+ * the Source for the monitor to reset.
+ * @since 2.11.2
+ */
+ public void reset(final Source source) {
+ if (source == null) {
+ return;
+ }
+ final ConfigurationMonitor monitor = watchers.get(source);
+ if (monitor != null) {
+ Watcher watcher = monitor.getWatcher();
+ if (watcher.isModified()) {
+ final long lastModifiedMillis = watcher.getLastModified();
if (logger.isDebugEnabled()) {
- logger.debug("Resetting file monitor for '{}' from {} ({}) to {} ({})", file,
- millisToString(fileMonitor.lastModifiedMillis), fileMonitor.lastModifiedMillis,
- millisToString(lastModifiedMillis), lastModifiedMillis);
+ logger.debug("Resetting file monitor for '{}' from {} ({}) to {} ({})", source.getLocation(),
+ millisToString(monitor.lastModifiedMillis), monitor.lastModifiedMillis,
+ millisToString(lastModifiedMillis), lastModifiedMillis);
}
- fileMonitor.setLastModifiedMillis(lastModifiedMillis);
+ monitor.setLastModifiedMillis(lastModifiedMillis);
}
}
}
@@ -140,8 +163,20 @@ public class WatchManager extends AbstractLifeCycle {
* @since 2.11.0
*/
public void unwatchFile(final File file) {
- logger.debug("Unwatching file '{}'", file);
- watchers.remove(file);
+ Source source = new Source(file);
+ unwatch(source);
+ }
+
+ /**
+ * Unwatches the given file.
+ *
+ * @param source the Source to stop watching.
+ * the file to stop watching.
+ * @since 2.11.2
+ */
+ public void unwatch(final Source source) {
+ logger.debug("Unwatching configuration {}", source);
+ watchers.remove(source);
}
/**
@@ -149,21 +184,62 @@ public class WatchManager extends AbstractLifeCycle {
*
* @param file
* the file to watch.
+ * @param fileWatcher
+ * the watcher to notify of file changes.
+ */
+ public void watchFile(final File file, final FileWatcher fileWatcher) {
+ Watcher watcher;
+ if (fileWatcher instanceof Watcher) {
+ watcher = (Watcher) fileWatcher;
+ } else {
+ watcher = new WrappedFileWatcher(fileWatcher);
+ }
+ Source source = new Source(file);
+ watch(source, watcher);
+ }
+
+ /**
+ * Watches the given file.
+ *
+ * @param source the source to watch.
* @param watcher
* the watcher to notify of file changes.
*/
- public void watchFile(final File file, final FileWatcher watcher) {
- final long lastModified = file.lastModified();
+ public void watch(final Source source, final Watcher watcher) {
+ watcher.watching(source);
+ final long lastModified = watcher.getLastModified();
if (logger.isDebugEnabled()) {
- logger.debug("Watching file '{}' for lastModified {} ({})", file, millisToString(lastModified), lastModified);
+ logger.debug("Watching configuration '{}' for lastModified {} ({})", source, millisToString(lastModified), lastModified);
}
- watchers.put(file, new FileMonitor(lastModified, watcher));
+ watchers.put(source, new ConfigurationMonitor(lastModified, watcher));
}
+ /**
+ * Returns a Map of the file watchers.
+ * @return A Map of the file watchers.
+ * @deprecated use getConfigurationWatchers.
+ */
public Map<File, FileWatcher> getWatchers() {
final Map<File, FileWatcher> map = new HashMap<>(watchers.size());
- for (final Map.Entry<File, FileMonitor> entry : watchers.entrySet()) {
- map.put(entry.getKey(), entry.getValue().fileWatcher);
+ for (Map.Entry<Source, ConfigurationMonitor> entry : watchers.entrySet()) {
+ if (entry.getValue().getWatcher() instanceof ConfigurationFileWatcher) {
+ map.put(entry.getKey().getFile(), (FileWatcher) entry.getValue().getWatcher());
+ } else {
+ map.put(entry.getKey().getFile(), new WrappedFileWatcher((FileWatcher)entry.getValue().getWatcher()));
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Return the ConfigurationWaatchers.
+ * @return the ConfigurationWatchers.
+ * @since 2.11.2
+ */
+ public Map<Source, Watcher> getConfigurationWatchers() {
+ final Map<Source, Watcher> map = new HashMap<>(watchers.size());
+ for (final Map.Entry<Source, ConfigurationMonitor> entry : watchers.entrySet()) {
+ map.put(entry.getKey(), entry.getValue().getWatcher());
}
return map;
}
@@ -180,34 +256,34 @@ public class WatchManager extends AbstractLifeCycle {
@Override
public void run() {
logger.trace("{} run triggered.", SIMPLE_NAME);
- for (final Map.Entry<File, FileMonitor> entry : watchers.entrySet()) {
- final File file = entry.getKey();
- final FileMonitor fileMonitor = entry.getValue();
- final long lastModfied = file.lastModified();
- if (fileModified(fileMonitor, lastModfied)) {
+ for (final Map.Entry<Source, ConfigurationMonitor> entry : watchers.entrySet()) {
+ final Source source = entry.getKey();
+ final ConfigurationMonitor monitor = entry.getValue();
+ if (monitor.getWatcher().isModified()) {
+ final long lastModified = monitor.getWatcher().getLastModified();
if (logger.isInfoEnabled()) {
- logger.info("File '{}' was modified on {} ({}), previous modification was on {} ({})", file,
- millisToString(lastModfied), lastModfied, millisToString(fileMonitor.lastModifiedMillis),
- fileMonitor.lastModifiedMillis);
+ logger.info("Source '{}' was modified on {} ({}), previous modification was on {} ({})", source,
+ millisToString(lastModified), lastModified, millisToString(monitor.lastModifiedMillis),
+ monitor.lastModifiedMillis);
}
- fileMonitor.lastModifiedMillis = lastModfied;
- fileMonitor.fileWatcher.fileModified(file);
+ monitor.lastModifiedMillis = lastModified;
+ monitor.getWatcher().modified();
}
}
logger.trace("{} run ended.", SIMPLE_NAME);
}
-
- private boolean fileModified(final FileMonitor fileMonitor, final long lastModifiedMillis) {
- return lastModifiedMillis != fileMonitor.lastModifiedMillis;
- }
}
- private final class FileMonitor {
- private final FileWatcher fileWatcher;
+ private final class ConfigurationMonitor {
+ private final Watcher watcher;
private volatile long lastModifiedMillis;
- public FileMonitor(final long lastModifiedMillis, final FileWatcher fileWatcher) {
- this.fileWatcher = fileWatcher;
+ public Watcher getWatcher() {
+ return watcher;
+ }
+
+ public ConfigurationMonitor(final long lastModifiedMillis, final Watcher watcher) {
+ this.watcher = watcher;
this.lastModifiedMillis = lastModifiedMillis;
}
@@ -217,7 +293,7 @@ public class WatchManager extends AbstractLifeCycle {
@Override
public String toString() {
- return "FileMonitor [fileWatcher=" + fileWatcher + ", lastModifiedMillis=" + lastModifiedMillis + "]";
+ return "ConfigurationMonitor [watcher=" + watcher + ", lastModifiedMillis=" + lastModifiedMillis + "]";
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Watcher.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Watcher.java
new file mode 100644
index 0000000..7ae9cd0
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Watcher.java
@@ -0,0 +1,78 @@
+/*
+ * 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.util;
+
+import java.util.List;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationListener;
+import org.apache.logging.log4j.core.config.Reconfigurable;
+
+/**
+ * Watches for changes in a Source and performs an action when it is modified.
+ *
+ * @see WatchManager
+ */
+public interface Watcher {
+
+ public static final String CATEGORY = "Watcher";
+
+ /**
+ * Returns the list of listeners for this configuration.
+ * @return The list of listeners.
+ */
+ List<ConfigurationListener> getListeners();
+
+ /**
+ * Called when the configuration has been modified.
+ * @param source The location of the configuration that was modified.
+ */
+ void modified();
+
+ /**
+ * Periodically called to determine if the configuration has been modified.
+ * @return true if the configuration was modified, false otherwise.
+ */
+ boolean isModified();
+
+ /**
+ * Returns the time the source was last modified or 0 if it is not available.
+ * @return the time the soruce was last modified.
+ */
+ long getLastModified();
+
+ /**
+ * Called when the Watcher is registered.
+ * @param source the Source that is being watched.
+ */
+ void watching(Source source);
+
+ /**
+ * Returns the Source being monitored.
+ * @return the Source.
+ */
+ Source getSource();
+
+ /**
+ * Creates a new Watcher by copying the original and using the new Reconfigurable and listeners.
+ * @param reconfigurable The Reconfigurable.
+ * @param listeners the listeners.
+ * @param lastModifiedMillis The time the resource was last modified in milliseconds.
+ * @return A new Watcher.
+ */
+ Watcher newWatcher(Reconfigurable reconfigurable, List<ConfigurationListener> listeners, long lastModifiedMillis);
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatcherFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatcherFactory.java
new file mode 100644
index 0000000..ab9e86c
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatcherFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2019 Nextiva, Inc. to Present.
+ * All rights reserved.
+ */
+package org.apache.logging.log4j.core.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationFileWatcher;
+import org.apache.logging.log4j.core.config.ConfigurationListener;
+import org.apache.logging.log4j.core.config.Reconfigurable;
+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.status.StatusLogger;
+
+/**
+ * Creates Watchers of various types.
+ */
+public class WatcherFactory {
+
+ private static Logger LOGGER = StatusLogger.getLogger();
+ private static PluginManager pluginManager = new PluginManager(Watcher.CATEGORY);
+
+ private static volatile WatcherFactory factory = null;
+
+ private final Map<String, PluginType<?>> plugins;
+
+ private WatcherFactory(List<String> packages) {
+ pluginManager.collectPlugins(packages);
+ plugins = pluginManager.getPlugins();
+ }
+
+ public static WatcherFactory getInstance(List<String> packages) {
+ if (factory == null) {
+ synchronized(pluginManager) {
+ if (factory == null) {
+ factory = new WatcherFactory(packages);
+ }
+ }
+ }
+ return factory;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Watcher newWatcher(Source source, final Configuration configuration, final Reconfigurable reconfigurable,
+ final List<ConfigurationListener> configurationListeners, long lastModifiedMillis) {
+ if (source.getFile() != null) {
+ return new ConfigurationFileWatcher(configuration, reconfigurable, configurationListeners,
+ lastModifiedMillis);
+ } else {
+ String name = source.getURI().getScheme();
+ PluginType<?> pluginType = plugins.get(name);
+ if (pluginType != null) {
+ return instantiate(name, (Class<? extends Watcher>) pluginType.getPluginClass(),
+ configuration, reconfigurable, configurationListeners, lastModifiedMillis);
+ }
+ LOGGER.info("No Watcher plugin is available for protocol '{}'", name);
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T extends Watcher> T instantiate(String name, final Class<T> clazz, final Configuration configuration,
+ final Reconfigurable reconfigurable, final List<ConfigurationListener> listeners, long lastModifiedMillis) {
+ Objects.requireNonNull(clazz, "No class provided");
+ try {
+ Constructor constructor = clazz.getConstructor(Configuration.class, Reconfigurable.class, List.class, long.class);
+ return (T) constructor.newInstance(configuration, reconfigurable, listeners, lastModifiedMillis);
+ } catch (NoSuchMethodException ex) {
+ throw new IllegalArgumentException("No valid constructor for Watcher plugin " + name, ex);
+ } catch (final LinkageError | InstantiationException e) {
+ // LOG4J2-1051
+ // On platforms like Google App Engine and Android, some JRE classes are not supported: JMX, JNDI, etc.
+ throw new IllegalArgumentException(e);
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ } catch (final InvocationTargetException e) {
+ Throwables.rethrow(e.getCause());
+ throw new InternalError("Unreachable");
+ }
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WrappedFileWatcher.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WrappedFileWatcher.java
new file mode 100644
index 0000000..ffab8bb
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WrappedFileWatcher.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2019 Nextiva, Inc. to Present.
+ * All rights reserved.
+ */
+package org.apache.logging.log4j.core.util;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationListener;
+import org.apache.logging.log4j.core.config.Reconfigurable;
+
+/**
+ *
+ */
+public class WrappedFileWatcher extends AbstractWatcher implements FileWatcher {
+
+ private final FileWatcher watcher;
+ private volatile long lastModifiedMillis;
+
+ public WrappedFileWatcher(FileWatcher watcher, final Configuration configuration,
+ final Reconfigurable reconfigurable, final List<ConfigurationListener> configurationListeners,
+ final long lastModifiedMillis) {
+ super(configuration, reconfigurable, configurationListeners);
+ this.watcher = watcher;
+ this.lastModifiedMillis = lastModifiedMillis;
+ }
+
+
+ public WrappedFileWatcher(FileWatcher watcher) {
+ super(null, null, null);
+ this.watcher = watcher;
+ }
+
+ public long getLastModified() {
+ return lastModifiedMillis;
+ }
+
+ @Override
+ public void fileModified(File file) {
+ watcher.fileModified(file);
+ }
+
+ @Override
+ public boolean isModified() {
+ long lastModified = getSource().getFile().lastModified();
+ if (lastModifiedMillis != lastModified) {
+ lastModifiedMillis = lastModified;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public List<ConfigurationListener> getListeners() {
+ if (super.getListeners() != null) {
+ return Collections.unmodifiableList(super.getListeners());
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void modified() {
+ if (getListeners() != null) {
+ super.modified();
+ }
+ fileModified(getSource().getFile());
+ lastModifiedMillis = getSource().getFile().lastModified();
+ }
+
+ @Override
+ public void watching(Source source) {
+ lastModifiedMillis = source.getFile().lastModified();
+ super.watching(source);
+ }
+
+ @Override
+ public Watcher newWatcher(final Reconfigurable reconfigurable, final List<ConfigurationListener> listeners,
+ long lastModifiedMillis) {
+ WrappedFileWatcher watcher = new WrappedFileWatcher(this.watcher, getConfiguration(), reconfigurable, listeners,
+ lastModifiedMillis);
+ if (getSource() != null) {
+ watcher.watching(getSource());
+ }
+ return watcher;
+ }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/WatchHttpTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/WatchHttpTest.java
new file mode 100644
index 0000000..f9b5abf
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/WatchHttpTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.util;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Queue;
+import java.util.TimeZone;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationListener;
+import org.apache.logging.log4j.core.config.ConfigurationScheduler;
+import org.apache.logging.log4j.core.config.DefaultConfiguration;
+import org.apache.logging.log4j.core.config.HttpWatcher;
+import org.apache.logging.log4j.core.config.Reconfigurable;
+import org.apache.logging.log4j.core.net.ssl.TestConstants;
+import org.apache.logging.log4j.core.util.datetime.FastDateFormat;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.github.tomakehurst.wiremock.junit.WireMockRule;
+import com.github.tomakehurst.wiremock.stubbing.StubMapping;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.removeStub;
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test the WatchManager
+ */
+public class WatchHttpTest {
+
+ private static final String FORCE_RUN_KEY = WatchHttpTest.class.getSimpleName() + ".forceRun";
+ private final String file = "log4j-test1.xml";
+ private static FastDateFormat formatter;
+ private static final String XML = "application/xml";
+
+ private static final boolean IS_WINDOWS = PropertiesUtil.getProperties().isOsWindows();
+
+ @BeforeClass
+ public static void beforeClass() {
+ try {
+ formatter = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss", TimeZone.getTimeZone("UTC"));
+ } catch (Exception ex) {
+ System.err.println("Unable to create date format.");
+ ex.printStackTrace();
+ throw ex;
+ }
+ }
+
+ @Rule
+ public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort().dynamicHttpsPort()
+ .keystorePath(TestConstants.KEYSTORE_FILE)
+ .keystorePassword(String.valueOf(TestConstants.KEYSTORE_PWD()))
+ .keystoreType(TestConstants.KEYSTORE_TYPE));
+
+ @Test
+ public void testWatchManager() throws Exception {
+ BlockingQueue<String> queue = new LinkedBlockingQueue<>();
+ List<ConfigurationListener> listeners = new ArrayList<>();
+ listeners.add(new TestConfigurationListener(queue, "log4j-test1.xml"));
+ TimeZone timeZone = TimeZone.getTimeZone("UTC");
+ Calendar now = Calendar.getInstance(timeZone);
+ Calendar previous = now;
+ previous.add(Calendar.MINUTE, -5);
+ Configuration configuration = new DefaultConfiguration();
+ Assume.assumeTrue(!IS_WINDOWS || Boolean.getBoolean(FORCE_RUN_KEY));
+ URL url = new URL("http://localhost:" + wireMockRule.port() + "/log4j-test1.xml");
+ StubMapping stubMapping = stubFor(get(urlPathEqualTo("/log4j-test1.xml"))
+ .willReturn(aResponse()
+ .withBodyFile(file)
+ .withStatus(200)
+ .withHeader("Last-Modified", formatter.format(previous) + " GMT")
+ .withHeader("Content-Type", XML)));
+ final ConfigurationScheduler scheduler = new ConfigurationScheduler();
+ scheduler.incrementScheduledItems();
+ final WatchManager watchManager = new WatchManager(scheduler);
+ watchManager.setIntervalSeconds(1);
+ scheduler.start();
+ watchManager.start();
+ try {
+ watchManager.watch(new Source(url.toURI(), previous.getTimeInMillis()), new HttpWatcher(configuration, null,
+ listeners, previous.getTimeInMillis()));
+ Thread.sleep(1500);
+ final String str = queue.poll(1, TimeUnit.SECONDS);
+ assertNotNull("File change not detected", str);
+ } finally {
+ removeStub(stubMapping);
+ watchManager.stop();
+ scheduler.stop();
+ }
+ }
+
+ @Test
+ public void testNotModified() throws Exception {
+ BlockingQueue<String> queue = new LinkedBlockingQueue<>();
+ List<ConfigurationListener> listeners = new ArrayList<>();
+ listeners.add(new TestConfigurationListener(queue, "log4j-test2.xml"));
+ TimeZone timeZone = TimeZone.getTimeZone("UTC");
+ Calendar now = Calendar.getInstance(timeZone);
+ Calendar previous = now;
+ previous.add(Calendar.MINUTE, -5);
+ Configuration configuration = new DefaultConfiguration();
+ Assume.assumeTrue(!IS_WINDOWS || Boolean.getBoolean(FORCE_RUN_KEY));
+ URL url = new URL("http://localhost:" + wireMockRule.port() + "/log4j-test2.xml");
+ StubMapping stubMapping = stubFor(get(urlPathEqualTo("/log4j-test2.xml"))
+ .willReturn(aResponse()
+ .withBodyFile(file)
+ .withStatus(304)
+ .withHeader("Last-Modified", formatter.format(now) + " GMT")
+ .withHeader("Content-Type", XML)));
+ final ConfigurationScheduler scheduler = new ConfigurationScheduler();
+ scheduler.incrementScheduledItems();
+ final WatchManager watchManager = new WatchManager(scheduler);
+ watchManager.setIntervalSeconds(1);
+ scheduler.start();
+ watchManager.start();
+ try {
+ watchManager.watch(new Source(url.toURI(), previous.getTimeInMillis()), new HttpWatcher(configuration, null,
+ listeners, previous.getTimeInMillis()));
+ Thread.sleep(1500);
+ final String str = queue.poll(1, TimeUnit.SECONDS);
+ assertNull("File changed.", str);
+ } finally {
+ removeStub(stubMapping);
+ watchManager.stop();
+ scheduler.stop();
+ }
+ }
+
+ private class TestConfigurationListener implements ConfigurationListener {
+ private final Queue<String> queue;
+ private final String name;
+
+ public TestConfigurationListener(final Queue<String> queue, String name) {
+ this.queue = queue;
+ this.name = name;
+ }
+
+ @Override
+ public void onChange(Reconfigurable reconfigurable) {
+ //System.out.println("Reconfiguration detected for " + name);
+ queue.add(name);
+ }
+ }
+}
diff --git a/log4j-core/src/test/resources/__files/log4j-test1.xml b/log4j-core/src/test/resources/__files/log4j-test1.xml
new file mode 100644
index 0000000..3598aec
--- /dev/null
+++ b/log4j-core/src/test/resources/__files/log4j-test1.xml
@@ -0,0 +1,58 @@
+<?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="XMLConfigTest">
+ <Properties>
+ <Property name="filename">target/test-xml.log</Property>
+ </Properties>
+ <ThresholdFilter level="debug"/>
+
+ <Appenders>
+ <Console name="STDOUT">
+ <PatternLayout pattern="%m%n"/>
+ </Console>
+ <File name="File" fileName="${filename}" bufferedIO="false">
+ <PatternLayout>
+ <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+ </PatternLayout>
+ </File>
+ <List name="List">
+ <Filters>
+ <ThresholdFilter level="error"/>
+ </Filters>
+ </List>
+ </Appenders>
+
+ <Loggers>
+ <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
+ <ThreadContextMapFilter>
+ <KeyValuePair key="test" value="123"/>
+ </ThreadContextMapFilter>
+ <AppenderRef ref="STDOUT"/>
+ </Logger>
+
+ <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
+ <AppenderRef ref="File"/>
+ </Logger>
+
+ <Root level="error">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+
+</Configuration>
\ No newline at end of file
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
new file mode 100644
index 0000000..8799078
--- /dev/null
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/pom.xml
@@ -0,0 +1,196 @@
+<?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.
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-spring-cloud-config</artifactId>
+ <version>2.11.2-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <artifactId>log4j-spring-cloud-config-client</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Log4j Spring Cloud Config Client Support</name>
+ <description></description>
+ <properties>
+ <log4jParentDir>${basedir}/..</log4jParentDir>
+ <docLabel>Log4j Spring Cloud Config Client Documentation</docLabel>
+ <projectDir>/log4j-spring-cloud-config-client</projectDir>
+ <module.name>org.apache.logging.log4j.spring.cloud.config.client</module.name>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-config-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <!-- Include the standard NOTICE and LICENSE -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>org.apache.logging.log4j.spring.cloud.config.controller</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
+ <useJql>true</useJql>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>${checkstyle.plugin.version}</version>
+ <configuration>
+ <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
+ <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+ <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+ <enableRulesSummary>false</enableRulesSummary>
+ <propertyExpansion>basedir=${basedir}</propertyExpansion>
+ <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <configuration>
+ <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+ Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+ and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+ <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
+ project -->
+ <detectOfflineLinks>false</detectOfflineLinks>
+ <linksource>true</linksource>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>javadoc</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs.plugin.version}</version>
+ <configuration>
+ <fork>true</fork>
+ <jvmArgs>-Duser.language=en</jvmArgs>
+ <threshold>Normal</threshold>
+ <effort>Default</effort>
+ <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>${jxr.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>jxr</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <version>${pmd.plugin.version}</version>
+ <configuration>
+ <targetJdk>${maven.compiler.target}</targetJdk>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2CloudConfigLoggingSystem.java b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2CloudConfigLoggingSystem.java
new file mode 100644
index 0000000..05b02f9
--- /dev/null
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2CloudConfigLoggingSystem.java
@@ -0,0 +1,127 @@
+/*
+ * 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.spring.cloud.config.client;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import javax.net.ssl.HttpsURLConnection;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfigurationFactory;
+import org.apache.logging.log4j.core.util.FileUtils;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.springframework.boot.logging.LogFile;
+import org.springframework.boot.logging.LoggingInitializationContext;
+import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ResourceUtils;
+
+/**
+ *
+ */
+public class Log4j2CloudConfigLoggingSystem extends Log4J2LoggingSystem {
+ private static final String FILE_PROTOCOL = "file";
+ private static final String HTTPS = "https";
+ private Logger LOGGER = StatusLogger.getLogger();
+
+ public Log4j2CloudConfigLoggingSystem(ClassLoader loader) {
+ super(loader);
+ }
+
+ @Override
+ protected String[] getStandardConfigLocations() {
+ String[] locations = super.getStandardConfigLocations();
+ PropertiesUtil props = new PropertiesUtil(new Properties());
+ String location = props.getStringProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+ if (location != null) {
+ List<String> list = Arrays.asList(super.getStandardConfigLocations());
+ list.add(location);
+ locations = list.toArray(new String[list.size()]);
+ }
+ return locations;
+ }
+
+ @Override
+ protected void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile) {
+ if (logFile != null) {
+ this.loadConfiguration(this.getBootPackagedConfigFile("log4j2-file.xml"), logFile);
+ } else {
+ this.loadConfiguration(this.getBootPackagedConfigFile("log4j2.xml"), logFile);
+ }
+ }
+
+ private String getBootPackagedConfigFile(String fileName) {
+ String defaultPath = ClassUtils.getPackageName(Log4J2LoggingSystem.class);
+ defaultPath = defaultPath.replace('.', '/');
+ defaultPath = defaultPath + "/" + fileName;
+ defaultPath = "classpath:" + defaultPath;
+ return defaultPath;
+ }
+
+ @Override
+ protected void loadConfiguration(String location, LogFile logFile) {
+ Assert.notNull(location, "Location must not be null");
+ try {
+ LoggerContext ctx = getLoggerContext();
+ URL url = ResourceUtils.getURL(location);
+ ConfigurationSource source = getConfigurationSource(url);
+ ctx.start(ConfigurationFactory.getInstance().getConfiguration(ctx, source));
+ }
+ catch (Exception ex) {
+ throw new IllegalStateException(
+ "Could not initialize Log4J2 logging from " + location, ex);
+ }
+ }
+
+ private ConfigurationSource getConfigurationSource(URL url) throws IOException, URISyntaxException {
+ URLConnection urlConnection = url.openConnection();
+ if (url.getProtocol().equals(HTTPS)) {
+ SslConfiguration sslConfiguration = SslConfigurationFactory.getSslConfiguration();
+ if (sslConfiguration != null) {
+ ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
+ if (!sslConfiguration.isVerifyHostName()) {
+ ((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
+ }
+ }
+ }
+ File file = FileUtils.fileFromUri(url.toURI());
+ if (file != null) {
+ return new ConfigurationSource(urlConnection.getInputStream(), FileUtils.fileFromUri(url.toURI()));
+ } else {
+ return new ConfigurationSource(urlConnection.getInputStream(), url, urlConnection.getLastModified());
+ }
+ }
+
+ private LoggerContext getLoggerContext() {
+ return (LoggerContext) LogManager.getContext(false);
+ }
+}
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.system.properties b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.system.properties
new file mode 100644
index 0000000..918a074
--- /dev/null
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/main/resources/log4j2.system.properties
@@ -0,0 +1 @@
+org.springframework.boot.logging.LoggingSystem=org.apache.logging.log4j.spring.cloud.config.client.Log4j2CloudConfigLoggingSystem
\ No newline at end of file
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-server/pom.xml b/log4j-spring-cloud-config/log4j-spring-cloud-config-server/pom.xml
new file mode 100644
index 0000000..6a31ce6
--- /dev/null
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-server/pom.xml
@@ -0,0 +1,205 @@
+<?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.
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-spring-cloud-config</artifactId>
+ <version>2.11.2-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <artifactId>log4j-spring-cloud-config-server</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Log4j Spring Cloud Config Server Support</name>
+ <description></description>
+ <properties>
+ <log4jParentDir>${basedir}/..</log4jParentDir>
+ <docLabel>Log4j Spring Cloud Config Server Documentation</docLabel>
+ <projectDir>/log4j-spring-cloud-config-server</projectDir>
+ <module.name>org.apache.logging.log4j.spring.cloud.config.controller</module.name>
+ <log4j.version>2.11.2-SNAPSHOT</log4j.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-config-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <!-- Include the standard NOTICE and LICENSE -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Package>org.apache.logging.log4j.spring.cloud.config.controller</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
+ <useJql>true</useJql>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>${checkstyle.plugin.version}</version>
+ <configuration>
+ <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
+ <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+ <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+ <enableRulesSummary>false</enableRulesSummary>
+ <propertyExpansion>basedir=${basedir}</propertyExpansion>
+ <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <configuration>
+ <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+ Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+ and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+ <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
+ project -->
+ <detectOfflineLinks>false</detectOfflineLinks>
+ <linksource>true</linksource>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>javadoc</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs.plugin.version}</version>
+ <configuration>
+ <fork>true</fork>
+ <jvmArgs>-Duser.language=en</jvmArgs>
+ <threshold>Normal</threshold>
+ <effort>Default</effort>
+ <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>${jxr.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>jxr</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <version>${pmd.plugin.version}</version>
+ <configuration>
+ <targetJdk>${maven.compiler.target}</targetJdk>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-server/src/main/java/org/apache/logging/log4j/spring/cloud/config/server/controller/Log4jResourceController.java b/log4j-spring-cloud-config/log4j-spring-cloud-config-server/src/main/java/org/apache/logging/log4j/spring/cloud/config/server/controller/Log4jResourceController.java
new file mode 100644
index 0000000..e6bdd66
--- /dev/null
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-server/src/main/java/org/apache/logging/log4j/spring/cloud/config/server/controller/Log4jResourceController.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2015-2016 the original author or authors.
+ *
+ * Licensed 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.spring.cloud.config.server.controller;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.config.environment.Environment;
+import org.springframework.cloud.config.server.environment.EnvironmentRepository;
+import org.springframework.cloud.config.server.resource.NoSuchResourceException;
+import org.springframework.cloud.config.server.resource.ResourceRepository;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.context.request.ServletWebRequest;
+import org.springframework.web.util.UrlPathHelper;
+
+import static org.springframework.cloud.config.server.support.EnvironmentPropertySource.prepareEnvironment;
+import static org.springframework.cloud.config.server.support.EnvironmentPropertySource.resolvePlaceholders;
+
+/**
+ * Modified version of Spring Cloud Config's ResourceController to support If-Modified-Since.
+ * Should be dropeed when Spring implements this.
+ *
+ * An HTTP endpoint for serving up templated plain text resources from an underlying
+ * repository. Can be used to supply config files for consumption by a wide variety of
+ * applications and services. A {@link ResourceRepository} is used to locate a
+ * {@link Resource}, specific to an application, and the contents are transformed to text.
+ * Then an {@link EnvironmentRepository} is used to supply key-value pairs which are used
+ * to replace placeholders in the resource text.
+ *
+ * @author Dave Syer
+ * @author Daniel Lavoie
+ *
+ */
+@RestController
+@RequestMapping(method = RequestMethod.GET, path = "${spring.cloud.config.server.prefix:}/resource")
+public class Log4jResourceController {
+
+ @Autowired
+ private ResourceRepository resourceRepository;
+
+ @Autowired
+ private EnvironmentRepository environmentRepository;
+
+ private UrlPathHelper helper = new UrlPathHelper();
+
+ public Log4jResourceController(ResourceRepository resourceRepository,
+ EnvironmentRepository environmentRepository) {
+ this.resourceRepository = resourceRepository;
+ this.environmentRepository = environmentRepository;
+ this.helper.setAlwaysUseFullPath(true);
+ }
+
+ @RequestMapping("/{name}/{profile}/{label}/**")
+ public String retrieve(@PathVariable String name, @PathVariable String profile,
+ @PathVariable String label, ServletWebRequest request,
+ @RequestParam(defaultValue = "true") boolean resolvePlaceholders)
+ throws IOException {
+ String path = getFilePath(request, name, profile, label);
+ return retrieve(request, name, profile, label, path, resolvePlaceholders);
+ }
+
+ @RequestMapping(value = "/{name}/{profile}/**", params = "useDefaultLabel")
+ public String retrieve(@PathVariable String name, @PathVariable String profile,
+ ServletWebRequest request, @RequestParam(defaultValue = "true") boolean resolvePlaceholders)
+ throws IOException {
+ String path = getFilePath(request, name, profile, null);
+ return retrieve(request, name, profile, null, path, resolvePlaceholders);
+ }
+
+ private String getFilePath(ServletWebRequest request, String name, String profile,
+ String label) {
+ String stem;
+ if(label != null ) {
+ stem = String.format("/%s/%s/%s/", name, profile, label);
+ }else {
+ stem = String.format("/%s/%s/", name, profile);
+ }
+ String path = this.helper.getPathWithinApplication(request.getRequest());
+ path = path.substring(path.indexOf(stem) + stem.length());
+ return path;
+ }
+
+ private synchronized String retrieve(ServletWebRequest request, String name, String profile, String label,
+ String path, boolean resolvePlaceholders) throws IOException {
+ name = resolveName(name);
+ label = resolveLabel(label);
+ Resource resource = this.resourceRepository.findOne(name, profile, label, path);
+ if (checkNotModified(request, resource)) {
+ // Content was not modified. Just return.
+ return null;
+ }
+ // ensure InputStream will be closed to prevent file locks on Windows
+ try (InputStream is = resource.getInputStream()) {
+ String text = StreamUtils.copyToString(is, Charset.forName("UTF-8"));
+ if (resolvePlaceholders) {
+ Environment environment = this.environmentRepository.findOne(name, profile, label);
+ text = resolvePlaceholders(prepareEnvironment(environment), text);
+ }
+ return text;
+ }
+ }
+
+ /*
+ * Used only for unit tests.
+ */
+ String retrieve(String name, String profile, String label, String path,
+ boolean resolvePlaceholders) throws IOException {
+ return retrieve(null, name, profile, label, path, resolvePlaceholders);
+ }
+
+ @RequestMapping(value = "/{name}/{profile}/{label}/**", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ public synchronized byte[] binary(@PathVariable String name,
+ @PathVariable String profile, @PathVariable String label,
+ ServletWebRequest request) throws IOException {
+ String path = getFilePath(request, name, profile, label);
+ return binary(request, name, profile, label, path);
+ }
+
+ /*
+ * Used only for unit tests.
+ */
+ byte[] binary(String name, String profile, String label, String path) throws IOException {
+ return binary(null, name, profile, label, path);
+ }
+
+ private synchronized byte[] binary(ServletWebRequest request, String name, String profile, String label,
+ String path) throws IOException {
+ name = resolveName(name);
+ label = resolveLabel(label);
+ Resource resource = this.resourceRepository.findOne(name, profile, label, path);
+ if (checkNotModified(request, resource)) {
+ // Content was not modified. Just return.
+ return null;
+ }
+ // TODO: is this line needed for side effects?
+ prepareEnvironment(this.environmentRepository.findOne(name, profile, label));
+ try (InputStream is = resource.getInputStream()) {
+ return StreamUtils.copyToByteArray(is);
+ }
+ }
+
+ private boolean checkNotModified(ServletWebRequest request, Resource resource) {
+ try {
+ return request != null && request.checkNotModified(resource.lastModified());
+ } catch (Exception ex) {
+ // Ignore the exception since caching is optional.
+ }
+ return false;
+ }
+
+ private String resolveName(String name) {
+ if (name != null && name.contains("(_)")) {
+ // "(_)" is uncommon in a git repo name, but "/" cannot be matched
+ // by Spring MVC
+ name = name.replace("(_)", "/");
+ }
+ return name;
+ }
+
+ private String resolveLabel(String label) {
+ if (label != null && label.contains("(_)")) {
+ // "(_)" is uncommon in a git branch name, but "/" cannot be matched
+ // by Spring MVC
+ label = label.replace("(_)", "/");
+ }
+ return label;
+ }
+
+ @ExceptionHandler(NoSuchResourceException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public void notFound(NoSuchResourceException e) {
+ }
+
+}
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-server/src/main/resources/META-INF/spring.factories b/log4j-spring-cloud-config/log4j-spring-cloud-config-server/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..dadd13c
--- /dev/null
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-server/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.apache.logging.log4j.spring.cloud.config.server.controller.Log4jResourceController
\ No newline at end of file
diff --git a/log4j-spring-cloud-config/pom.xml b/log4j-spring-cloud-config/pom.xml
new file mode 100644
index 0000000..a736e86
--- /dev/null
+++ b/log4j-spring-cloud-config/pom.xml
@@ -0,0 +1,95 @@
+<?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.
+-->
+<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">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>2.11.2-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-spring-cloud-config</artifactId>
+ <packaging>pom</packaging>
+ <name>Apache Log4j Spring Cloud Config Support</name>
+ <url>http://maven.apache.org</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <revapi.skip>true</revapi.skip>
+ <spring-cloud-config.version>2.0.3.BUILD-SNAPSHOT</spring-cloud-config.version>
+ <spring-boot.version>2.1.1.RELEASE</spring-boot.version>
+ <spring.version>5.0.5.RELEASE</spring.version>
+ </properties>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-config-dependencies</artifactId>
+ <version>${spring-cloud-config.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot</artifactId>
+ <version>${spring-boot.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <modules>
+ <module>log4j-spring-cloud-config-server</module>
+ <module>log4j-spring-cloud-config-client</module>
+ </modules>
+ <build>
+ <plugins>
+ <!-- Include the standard NOTICE and LICENSE -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/pom.xml b/pom.xml
index 3b9a7c4..04f33cb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,1719 +1,1720 @@
-<?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.
- --><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/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j</artifactId>
- <packaging>pom</packaging>
- <name>Apache Log4j 2</name>
- <version>2.12.0-SNAPSHOT</version>
- <parent>
- <groupId>org.apache</groupId>
- <artifactId>apache</artifactId>
- <version>21</version>
- </parent>
- <prerequisites>
- <maven>3.0.5</maven>
- </prerequisites>
- <description>Apache Log4j 2</description>
- <url>https://logging.apache.org/log4j/2.x/</url>
- <issueManagement>
- <system>JIRA</system>
- <url>https://issues.apache.org/jira/browse/LOG4J2</url>
- </issueManagement>
- <ciManagement>
- <system>Jenkins</system>
- <url>https://builds.apache.org/job/Log4j%202.x/</url>
- </ciManagement>
- <inceptionYear>1999</inceptionYear>
- <developers>
- <developer>
- <id>rgoers</id>
- <name>Ralph Goers</name>
- <email>rgoers@apache.org</email>
- <organization>Nextiva</organization>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>America/Phoenix</timezone>
- </developer>
- <developer>
- <id>ggregory</id>
- <name>Gary Gregory</name>
- <email>ggregory@apache.org</email>
- <organization>Rocket Software</organization>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>America/Denver</timezone>
- </developer>
- <developer>
- <id>sdeboy</id>
- <name>Scott Deboy</name>
- <email>sdeboy@apache.org</email>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>America/Los_Angeles</timezone>
- </developer>
- <developer>
- <id>rpopma</id>
- <name>Remko Popma</name>
- <email>rpopma@apache.org</email>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>Asia/Tokyo</timezone>
- <properties>
- <picUrl>http://people.apache.org/~rpopma/img/profilepic.jpg</picUrl>
- </properties>
- </developer>
- <developer>
- <id>nickwilliams</id>
- <name>Nick Williams</name>
- <email>nickwilliams@apache.org</email>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>America/Chicago</timezone>
- </developer>
- <developer>
- <id>mattsicker</id>
- <name>Matt Sicker</name>
- <email>mattsicker@apache.org</email>
- <organization>CloudBees</organization>
- <roles>
- <role>PMC Chair</role>
- </roles>
- <timezone>America/Chicago</timezone>
- </developer>
- <developer>
- <id>bbrouwer</id>
- <name>Bruce Brouwer</name>
- <email>bruce.brouwer@gmail.com</email>
- <roles>
- <role>Committer</role>
- </roles>
- <timezone>America/Detroit</timezone>
- </developer>
- <developer>
- <id>mikes</id>
- <name>Mikael Ståldal</name>
- <email>mikes@apache.org</email>
- <organization>Spotify</organization>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>Europe/Stockholm</timezone>
- </developer>
- <developer>
- <id>ckozak</id>
- <name>Carter Kozak</name>
- <email>ckozak@apache.org</email>
- <roles>
- <role>PMC Member</role>
- </roles>
- <timezone>America/New York</timezone>
- </developer>
- </developers>
- <!-- Contributors -->
- <contributors>
- <contributor>
- <name>Murad Ersoy</name>
- <email>muradersoy@gmail.com</email>
- <url>https://www.behance.net/muradersoy</url>
- <roles>
- <role>Illustrator and Designer</role>
- <role>created the new Log4j 2 logo.</role>
- </roles>
- <timezone>Europe/Istanbul</timezone>
- <properties>
- <picUrl>https://mir-s3-cdn-cf.behance.net/user/138/403dcf1521581.54d67f8fb01f7.jpg</picUrl>
- </properties>
- </contributor>
- </contributors>
- <mailingLists>
- <mailingList>
- <name>log4j-user</name>
- <subscribe>log4j-user-subscribe@logging.apache.org</subscribe>
- <unsubscribe>log4j-user-unsubscribe@logging.apache.org</unsubscribe>
- <post>log4j-user@logging.apache.org</post>
- <archive>https://lists.apache.org/list.html?log4j-user@logging.apache.org</archive>
- <otherArchives>
- <otherArchive>http://mail-archives.apache.org/mod_mbox/logging-log4j-user/</otherArchive>
- <otherArchive>http://marc.info/?l=log4j-user</otherArchive>
- <otherArchive>http://dir.gmane.org/gmane.comp.jakarta.log4j.user</otherArchive>
- </otherArchives>
- </mailingList>
- <mailingList>
- <name>dev</name>
- <subscribe>dev-subscribe@logging.apache.org</subscribe>
- <unsubscribe>dev-unsubscribe@logging.apache.org</unsubscribe>
- <post>dev@logging.apache.org</post>
- <archive>https://lists.apache.org/list.html?dev@logging.apache.org</archive>
- <otherArchives>
- <otherArchive>http://mail-archives.apache.org/mod_mbox/logging-dev/</otherArchive>
- <otherArchive>http://marc.info/?l=dev</otherArchive>
- <otherArchive>http://dir.gmane.org/gmane.comp.jakarta.log4j.devel</otherArchive>
- </otherArchives>
- </mailingList>
- </mailingLists>
- <scm>
- <connection>scm:git:https://git-wip-us.apache.org/repos/asf/logging-log4j2.git</connection>
- <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/logging-log4j2.git</developerConnection>
- <url>https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=summary</url>
- <tag>log4j-${Log4jReleaseVersion}</tag>
- </scm>
- <properties>
- <!-- make sure to update these for each release! -->
- <log4jParentDir>${basedir}</log4jParentDir>
- <Log4jReleaseVersion>2.11.2</Log4jReleaseVersion>
- <Log4jReleaseManager>Ralph Goers</Log4jReleaseManager>
- <Log4jReleaseKey>B3D8E1BA</Log4jReleaseKey>
- <!--<Log4jReleaseManager>Matt Sicker</Log4jReleaseManager> -->
- <!--<Log4jReleaseKey>748F15B2CF9BA8F024155E6ED7C92B70FA1C814D</Log4jReleaseKey> -->
- <!-- note that any properties you want available in velocity templates must not use periods! -->
- <slf4jVersion>1.7.25</slf4jVersion>
- <logbackVersion>1.2.3</logbackVersion>
- <jackson1Version>1.9.13</jackson1Version>
- <jackson2Version>2.9.8</jackson2Version>
- <springVersion>3.2.18.RELEASE</springVersion>
- <flumeVersion>1.7.0</flumeVersion> <!-- Version 1.8.0 requires Java 8 -->
- <disruptorVersion>3.4.2</disruptorVersion>
- <conversantDisruptorVersion>1.2.10</conversantDisruptorVersion> <!-- Version 1.2.11 requires Java 8 -->
- <mongodb2.version>2.14.3</mongodb2.version>
- <mongodb3.version>3.10.1</mongodb3.version>
- <groovy.version>2.5.6</groovy.version>
- <compiler.plugin.version>3.8.0</compiler.plugin.version>
- <pmd.plugin.version>3.10.0</pmd.plugin.version>
- <findbugs.plugin.version>3.0.5</findbugs.plugin.version>
- <changes.plugin.version>2.12.1</changes.plugin.version>
- <javadoc.plugin.version>3.0.1</javadoc.plugin.version>
- <!-- surefire.plugin.version 2.18 yields http://jira.codehaus.org/browse/SUREFIRE-1121, which is fixed in 2.18.1 -->
- <!-- surefire.plugin.version 2.19 yields https://issues.apache.org/jira/browse/SUREFIRE-1193. -->
- <!-- all versions after 2.13 yield https://issues.apache.org/jira/browse/SUREFIRE-720 -->
- <surefire.plugin.version>2.21.0</surefire.plugin.version>
- <failsafe.plugin.version>2.21.0</failsafe.plugin.version>
- <checkstyle.plugin.version>3.0.0</checkstyle.plugin.version>
- <deploy.plugin.version>2.8.2</deploy.plugin.version>
- <rat.plugin.version>0.12</rat.plugin.version>
- <pdf.plugin.version>1.2</pdf.plugin.version>
- <cobertura.plugin.version>2.7</cobertura.plugin.version>
- <jacoco.plugin.version>0.8.1</jacoco.plugin.version>
- <release.plugin.version>2.5.3</release.plugin.version>
- <scm.plugin.version>1.9.5</scm.plugin.version>
- <jxr.plugin.version>2.5</jxr.plugin.version>
- <revapi.plugin.version>0.10.5</revapi.plugin.version>
- <revapi.skip>false</revapi.skip>
- <clirr.plugin.version>2.8</clirr.plugin.version>
- <!-- Maven site 3.7 uses the wrong stylesheet? -->
- <site.plugin.version>3.4</site.plugin.version>
- <!-- Maven site depends on Velocity and the escaping rules are different in newer versions. -->
- <!-- See https://maven.apache.org/plugins/maven-site-plugin/migrate.html -->
- <velocity.plugin.version>1.5</velocity.plugin.version>
- <remote.resources.plugin.version>1.5</remote.resources.plugin.version>
- <manifestfile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestfile>
- <maven.compiler.source>1.7</maven.compiler.source>
- <maven.compiler.target>1.7</maven.compiler.target>
- <docLabel>Site Documentation</docLabel>
- <projectDir />
- <commonsLoggingVersion>1.2</commonsLoggingVersion>
- <javax.persistence>2.1.1</javax.persistence>
- <!-- The OSGi API version MUST always be the MINIMUM version Log4j supports -->
- <osgi.api.version>4.3.1</osgi.api.version>
- <!-- Version 5.15.0 requires Java 8 -->
- <activemq.version>5.14.5</activemq.version>
- <!-- Allow Clirr severity to be overriden by the command-line option -DminSeverity=level -->
- <minSeverity>info</minSeverity>
- <jctoolsVersion>1.2.1</jctoolsVersion>
- <mockitoVersion>2.25.1</mockitoVersion>
- <argLine>-Xms256m -Xmx1024m</argLine>
- <javaTargetVersion>1.7</javaTargetVersion>
- <module.name />
- </properties>
- <pluginRepositories>
- <pluginRepository>
- <id>apache</id>
- <url>https://repository.apache.org/content/repositories/releases/</url>
- </pluginRepository>
-<!-- <pluginRepository> -->
-<!-- <id>apache.snapshots</id> -->
-<!-- <name>Apache snapshots repository</name> -->
-<!-- <url>http://repository.apache.org/content/groups/snapshots</url> -->
-<!-- <snapshots> -->
-<!-- <enabled>true</enabled> -->
-<!-- </snapshots> -->
-<!-- </pluginRepository> -->
- </pluginRepositories>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4jVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-ext</artifactId>
- <version>${slf4jVersion}</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <version>${logbackVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <type>test-jar</type>
- <version>${logbackVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.tycho</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <version>3.12.1.v20170821-1548</version>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.framework</artifactId>
- <version>5.6.10</version>
- </dependency>
- <dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-core</artifactId>
- <version>3.6.0</version>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>1.11</version>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.7</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>${logbackVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>${logbackVersion}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-api-java9</artifactId>
- <version>${project.version}</version>
- <type>zip</type>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-api</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core-java9</artifactId>
- <version>${project.version}</version>
- <type>zip</type>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
- <version>${project.version}</version>
- <type>zip</type>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j18-impl</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-jcl</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>${commonsLoggingVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-1.2-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-flume-ng</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-iostreams</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-jul</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-taglib</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-web</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.sleepycat</groupId>
- <artifactId>je</artifactId>
- <version>5.0.73</version>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>${osgi.api.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.fusesource.jansi</groupId>
- <artifactId>jansi</artifactId>
- <version>1.17.1</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.apache.flume</groupId>
- <artifactId>flume-ng-sdk</artifactId>
- <version>${flumeVersion}</version>
- <exclusions>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.flume</groupId>
- <artifactId>flume-ng-core</artifactId>
- <version>${flumeVersion}</version>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.flume</groupId>
- <artifactId>flume-ng-embedded-agent</artifactId>
- <version>${flumeVersion}</version>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.flume</groupId>
- <artifactId>flume-ng-node</artifactId>
- <version>${flumeVersion}</version>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.flume.flume-ng-channels</groupId>
- <artifactId>flume-file-channel</artifactId>
- <version>${flumeVersion}</version>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- <exclusion>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api-2.5</artifactId>
- </exclusion>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.hadoop</groupId>
- <artifactId>hadoop-core</artifactId>
- <version>1.2.1</version>
- <exclusions>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <!-- Jackson 1 start -->
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-core-asl</artifactId>
- <version>${jackson1Version}</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.codehaus.jackson</groupId>
- <artifactId>jackson-mapper-asl</artifactId>
- <version>${jackson1Version}</version>
- <scope>runtime</scope>
- </dependency>
- <!-- Jackson 1 end -->
- <!-- Jackson 2 start -->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>${jackson2Version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>${jackson2Version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>${jackson2Version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-yaml</artifactId>
- <version>${jackson2Version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-xml</artifactId>
- <version>${jackson2Version}</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.module</groupId>
- <artifactId>jackson-module-jaxb-annotations</artifactId>
- <version>${jackson2Version}</version>
- <optional>true</optional>
- </dependency>
- <!-- Jackson 2 end -->
- <dependency>
- <groupId>com.sun.mail</groupId>
- <artifactId>javax.mail</artifactId>
- <version>1.6.2</version>
- </dependency>
- <dependency>
- <groupId>org.jboss.spec.javax.jms</groupId>
- <artifactId>jboss-jms-api_1.1_spec</artifactId>
- <version>1.0.1.Final</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>activemq-broker</artifactId>
- <version>${activemq.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.kafka</groupId>
- <artifactId>kafka-clients</artifactId>
- <version>1.1.1</version>
- </dependency>
- <dependency>
- <groupId>org.zeromq</groupId>
- <artifactId>jeromq</artifactId>
- <version>0.4.3</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.lmax</groupId>
- <artifactId>disruptor</artifactId>
- <version>${disruptorVersion}</version>
- </dependency>
- <dependency>
- <groupId>com.conversantmedia</groupId>
- <artifactId>disruptor</artifactId>
- <version>${conversantDisruptorVersion}</version>
- <!-- TODO: this can be switched based on a profile -->
- <classifier>jdk7</classifier>
- </dependency>
- <dependency>
- <groupId>org.jctools</groupId>
- <artifactId>jctools-core</artifactId>
- <version>${jctoolsVersion}</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <version>1.3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- <version>3.1.0</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>${mockitoVersion}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-beans</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-oxm</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${springVersion}</version>
- </dependency>
- <dependency>
- <groupId>org.hsqldb</groupId>
- <artifactId>hsqldb</artifactId>
- <version>2.3.5</version>
- <!-- version 2.4.0 requires Java 8 -->
- </dependency>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- <version>1.4.199</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.persistence</groupId>
- <artifactId>org.eclipse.persistence.jpa</artifactId>
- <version>2.6.5</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.persistence</groupId>
- <artifactId>javax.persistence</artifactId>
- <version>${javax.persistence}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.mongodb</groupId>
- <artifactId>mongo-java-driver</artifactId>
- <version>${mongodb2.version}</version>
- </dependency>
- <dependency>
- <groupId>org.mongodb</groupId>
- <artifactId>mongodb-driver</artifactId>
- <version>${mongodb3.version}</version>
- </dependency>
- <dependency>
- <groupId>org.mongodb</groupId>
- <artifactId>bson</artifactId>
- <version>${mongodb3.version}</version>
- </dependency>
- <dependency>
- <groupId>org.lightcouch</groupId>
- <artifactId>lightcouch</artifactId>
- <version>0.0.6</version>
- </dependency>
- <dependency>
- <groupId>com.datastax.cassandra</groupId>
- <artifactId>cassandra-driver-core</artifactId>
- <version>3.1.4</version>
- </dependency>
- <dependency>
- <groupId>org.liquibase</groupId>
- <artifactId>liquibase-core</artifactId>
- <version>3.5.3</version>
- </dependency>
- <dependency>
- <groupId>net.javacrumbs.json-unit</groupId>
- <artifactId>json-unit</artifactId>
- <version>1.31.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.xmlunit</groupId>
- <artifactId>xmlunit-core</artifactId>
- <version>2.5.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.xmlunit</groupId>
- <artifactId>xmlunit-matchers</artifactId>
- <version>2.5.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.6</version>
- <scope>test</scope>
- </dependency>
- <!-- Used for testing HttpAppender -->
- <dependency>
- <groupId>com.github.tomakehurst</groupId>
- <artifactId>wiremock</artifactId>
- <scope>test</scope>
- <version>2.19.0</version>
- </dependency>
- <!-- Used for compressing to formats other than zip and gz -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-compress</artifactId>
- <version>1.18</version>
- </dependency>
- <dependency>
- <groupId>org.tukaani</groupId>
- <artifactId>xz</artifactId>
- <version>1.8</version>
- <scope>test</scope>
- </dependency>
- <!-- Used for the CSV layout -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-csv</artifactId>
- <version>1.6</version>
- </dependency>
- <!-- GC-free -->
- <dependency>
- <groupId>com.google.code.java-allocation-instrumenter</groupId>
- <artifactId>java-allocation-instrumenter</artifactId>
- <version>3.0.1</version>
- </dependency>
- <dependency>
- <groupId>org.hdrhistogram</groupId>
- <artifactId>HdrHistogram</artifactId>
- <version>2.1.9</version>
- </dependency>
- <dependency>
- <groupId>org.apache-extras.beanshell</groupId>
- <artifactId>bsh</artifactId>
- <version>2.0b6</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-jsr223</artifactId>
- <version>${groovy.version}</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-dateutil</artifactId>
- <version>${groovy.version}</version>
- </dependency>
- <dependency>
- <!-- Testing MongoDB -->
- <groupId>de.flapdoodle.embed</groupId>
- <artifactId>de.flapdoodle.embed.mongo</artifactId>
- <version>2.2.0</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>3.5.0</version>
- <inherited>true</inherited>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>manifest</goal>
- </goals>
- <phase>process-classes</phase>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-changes-plugin</artifactId>
- <version>${changes.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-release-plugin</artifactId>
- <version>${release.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-scm-plugin</artifactId>
- <version>${scm.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <version>${checkstyle.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>${javadoc.plugin.version}</version>
- <configuration>
- <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
- Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
- and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
- <doclint>none</doclint>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pmd-plugin</artifactId>
- <version>${pmd.plugin.version}</version>
- </plugin>
- <!-- some nice default compiler options -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>${compiler.plugin.version}</version>
- <configuration>
- <source>${maven.compiler.source}</source>
- <target>${maven.compiler.target}</target>
- <showDeprecation>true</showDeprecation>
- <showWarnings>true</showWarnings>
- <encoding>UTF-8</encoding>
- <fork>true</fork>
- <meminitial>256</meminitial>
- <maxmem>1024</maxmem>
- <compilerArguments>
- <Xmaxwarns>10000</Xmaxwarns>
- <Xlint />
- </compilerArguments>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>${surefire.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <version>${failsafe.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>3.0.1</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <phase>verify</phase>
- <goals>
- <goal>jar-no-fork</goal>
- <goal>test-jar-no-fork</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jxr-plugin</artifactId>
- <version>${jxr.plugin.version}</version>
- </plugin>
- <plugin>
- <groupId>org.eluder.coveralls</groupId>
- <artifactId>coveralls-maven-plugin</artifactId>
- <version>4.3.0</version>
- </plugin>
- <plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
- <version>${jacoco.plugin.version}</version>
- <executions>
- <execution>
- <id>prepare-agent</id>
- <goals>
- <goal>prepare-agent</goal>
- </goals>
- </execution>
- <execution>
- <id>default-report</id>
- <phase>prepare-package</phase>
- <goals>
- <goal>report</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>3.1.0</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <version>3.1.0</version>
- <executions>
- <execution>
- <id>default-jar</id>
- <goals>
- <goal>jar</goal>
- </goals>
- <configuration>
- <archive>
- <manifestFile>${manifestfile}</manifestFile>
- <manifestEntries>
- <Specification-Title>${project.name}</Specification-Title>
- <Specification-Version>${project.version}</Specification-Version>
- <Specification-Vendor>${project.organization.name}</Specification-Vendor>
- <Implementation-Title>${project.name}</Implementation-Title>
- <Implementation-Version>${project.version}</Implementation-Version>
- <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
- <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
- <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
- <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
- <Automatic-Module-Name>${module.name}</Automatic-Module-Name>
- </manifestEntries>
- </archive>
- </configuration>
- </execution>
- </executions>
-
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <version>3.1.0</version>
- </plugin>
- <plugin>
- <artifactId>maven-resources-plugin</artifactId>
- <version>3.0.2</version>
- <executions>
- <execution>
- <id>copy-sitecss</id>
- <!-- fetch site.xml before creating site documentation -->
- <phase>pre-site</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.build.directory}/site</outputDirectory>
- <resources>
- <resource>
- <directory>${log4jParentDir}/src/site/resources</directory>
- <includes>
- <include>**/*</include>
- </includes>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <version>${surefire.plugin.version}</version>
- <configuration>
- <systemPropertyVariables>
- <java.awt.headless>true</java.awt.headless>
- </systemPropertyVariables>
- <forkCount>1</forkCount>
- <reuseForks>false</reuseForks>
- <excludes>
- <exclude>${log4j.skip.test1}</exclude>
- <exclude>${log4j.skip.test2}</exclude>
- </excludes>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <version>${failsafe.plugin.version}</version>
- <executions>
- <execution>
- <goals>
- <goal>integration-test</goal>
- <goal>verify</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <systemPropertyVariables>
- <java.awt.headless>true</java.awt.headless>
- </systemPropertyVariables>
- <argLine>-Xms256m -Xmx1024m</argLine>
- <forkCount>1</forkCount>
- <reuseForks>false</reuseForks>
- <encoding>UTF-8</encoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-site-plugin</artifactId>
- <version>${site.plugin.version}</version>
- <dependencies>
- <dependency>
- <groupId>org.apache.velocity</groupId>
- <artifactId>velocity</artifactId>
- <version>${velocity.plugin.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.wagon</groupId>
- <artifactId>wagon-ssh</artifactId>
- <version>3.1.0</version>
- </dependency>
- </dependencies>
- <configuration>
- <!-- only build English site even on other language OS -->
- <locales>en</locales>
- <!-- Exclude the navigation file for Maven 1 sites
- and the changes file used by the changes-plugin,
- as they interfere with the site generation. -->
- <moduleExcludes>
- <xdoc>navigation.xml,changes.xml</xdoc>
- </moduleExcludes>
- <templateDirectory>${log4jParentDir}/src/site</templateDirectory>
- <template>site.vm</template>
- </configuration>
- </plugin>
- <!-- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>cobertura-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>clean</id>
- <goals>
- <goal>clean</goal>
- </goals>
- </execution>
- </executions>
- </plugin> -->
- <!-- We need to disable the standard ASF configuration to be able to publish our own notice and license files -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-remote-resources-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>process</goal>
- </goals>
- <configuration>
- <skip>true</skip>
- <resourceBundles />
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pdf-plugin</artifactId>
- <version>${pdf.plugin.version}</version>
- <executions>
- <execution>
- <id>pdf</id>
- <phase>site</phase>
- <goals>
- <goal>pdf</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- </plugin>
- <!-- RAT report -->
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <version>${rat.plugin.version}</version>
- <configuration>
- <excludes>
- <!-- Matches other RAT configurations in this POM -->
- <exclude>src/main/resources/META-INF/services/**/*</exclude>
- <!-- IntelliJ files -->
- <exclude>.idea/**/*</exclude>
- <exclude>src/test/resources/**/*</exclude>
- <!-- IDE settings imports -->
- <exclude>src/ide/**</exclude>
- <!-- does it even make sense to apply a license to a GPG signature? -->
- <exclude>**/*.asc</exclude>
- <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
- <exclude>src/site/resources/js/jquery.js</exclude>
- <exclude>src/site/resources/js/jquery.min.js</exclude>
- <!-- Generated files -->
- <exclude>log4j-distribution/target/**/*</exclude>
- <exclude>log4j-distribution/.project</exclude>
- <exclude>log4j-distribution/.settings/**</exclude>
- <exclude>velocity.log</exclude>
- <!-- Other -->
- <exclude>felix-cache/**</exclude>
- <exclude>RELEASE-NOTES.md</exclude>
- <exclude>**/revapi.json</exclude>
- </excludes>
- </configuration>
- </plugin>
- <!-- DOAP (RDF) metadata generation -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-doap-plugin</artifactId>
- <version>1.2</version>
- <configuration>
- <doapOptions>
- <programmingLanguage>Java</programmingLanguage>
- <category>library</category>
- </doapOptions>
- <asfExtOptions>
- <charter>
- The Apache Logging Services Project creates and maintains open-source software related to the logging of
- application behavior and released at no charge to the public.
- </charter>
- <pmc>https://logging.apache.org</pmc>
- </asfExtOptions>
- </configuration>
- <executions>
- <execution>
- <id>site</id>
- <phase>site</phase>
- <goals>
- <goal>generate</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <reporting>
- <plugins>
- <!-- Changes report -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-changes-plugin</artifactId>
- <version>${changes.plugin.version}</version>
- <reportSets>
- <reportSet>
- <reports>
- <report>changes-report</report>
- <report>jira-report</report>
- </reports>
- </reportSet>
- </reportSets>
- <configuration>
- <statusIds>Resolved, Closed</statusIds>
- <columnNames>Type,Key,Summary,Assignee,Status,Resolution,Fix Version</columnNames>
- <useJql>true</useJql>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-project-info-reports-plugin</artifactId>
- <version>2.9</version>
- <reportSets>
- <reportSet>
- <reports>
- <report>index</report>
- <report>dependencies</report>
- <report>dependency-info</report>
- <report>dependency-convergence</report>
- <report>dependency-management</report>
- <report>project-team</report>
- <report>mailing-list</report>
- <report>issue-tracking</report>
- <report>license</report>
- <report>scm</report>
- <report>summary</report>
- </reports>
- </reportSet>
- </reportSets>
- <configuration>
- <!-- you'd think these would be the defaults, right? -->
- <customBundle>${project.basedir}/src/site/custom/project-info-report.properties</customBundle>
- <webAccessUrl>${project.scm.url}</webAccessUrl>
- <anonymousConnection>${project.scm.connection}</anonymousConnection>
- <developerConnection>${project.scm.developerConnection}</developerConnection>
- <scmTag>log4j-${Log4jReleaseVersion}</scmTag>
- </configuration>
- </plugin>
- <!-- Surefire report -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-report-plugin</artifactId>
- <version>${surefire.plugin.version}</version>
- <reportSets>
- <reportSet>
- <id>integration-tests</id>
- <reports>
- <report>failsafe-report-only</report>
- </reports>
- </reportSet>
- </reportSets>
- </plugin>
- <!-- RAT report -->
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <version>${rat.plugin.version}</version>
- <configuration>
- <excludes>
- <!-- Matches other RAT configurations in this POM -->
- <exclude>src/main/resources/META-INF/services/**/*</exclude>
- <!-- IntelliJ files -->
- <exclude>.idea/**/*</exclude>
- <exclude>src/test/resources/**/*</exclude>
- <!-- IDE settings imports -->
- <exclude>src/ide/**</exclude>
- <!-- does it even make sense to apply a license to a GPG signature? -->
- <exclude>**/*.asc</exclude>
- <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
- <exclude>src/site/resources/js/jquery.js</exclude>
- <exclude>src/site/resources/js/jquery.min.js</exclude>
- <!-- Generated files -->
- <exclude>log4j-distribution/target/**/*</exclude>
- <exclude>log4j-distribution/.project</exclude>
- <exclude>log4j-distribution/.settings/**</exclude>
- <exclude>velocity.log</exclude>
- <!-- Other -->
- <exclude>felix-cache/**</exclude>
- <exclude>RELEASE-NOTES.txt</exclude>
- <exclude>**/revapi.json</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
- <distributionManagement>
- <downloadUrl>https://logging.apache.org/log4j/2.x/download.html</downloadUrl>
- <!-- site is only included to make maven-site-plugin stop complaining -->
- <site>
- <id>www.example.com</id>
- <url>scp://www.example.com/www/docs/project/</url>
- </site>
- </distributionManagement>
- <modules>
- <module>log4j-api-java9</module>
- <module>log4j-api</module>
- <module>log4j-core-java9</module>
- <module>log4j-core</module>
- <module>log4j-core-its</module>
- <module>log4j-1.2-api</module>
- <module>log4j-slf4j-impl</module>
- <module>log4j-slf4j18-impl</module>
- <module>log4j-to-slf4j</module>
- <module>log4j-jcl</module>
- <module>log4j-flume-ng</module>
- <module>log4j-taglib</module>
- <module>log4j-jmx-gui</module>
- <module>log4j-samples</module>
- <module>log4j-bom</module>
- <module>log4j-jdbc-dbcp2</module>
- <module>log4j-jpa</module>
- <module>log4j-couchdb</module>
- <module>log4j-mongodb2</module>
- <module>log4j-mongodb3</module>
- <module>log4j-cassandra</module>
- <module>log4j-web</module>
- <module>log4j-perf</module>
- <module>log4j-iostreams</module>
- <module>log4j-jul</module>
- <module>log4j-liquibase</module>
- <module>log4j-appserver</module>
- <module>log4j-osgi</module>
- </modules>
- <profiles>
- <profile>
- <id>pdf</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-pdf-plugin</artifactId>
- <version>${pdf.plugin.version}</version>
- <executions>
- <execution>
- <id>pdf</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>pdf</goal>
- </goals>
- <configuration>
- <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>release-notes</id>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-changes-plugin</artifactId>
- <version>${changes.plugin.version}</version>
- <configuration>
- <template>announcement.vm</template>
- <templateDirectory>src/changes</templateDirectory>
- <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
- <announcementDirectory>.</announcementDirectory>
- <announcementFile>RELEASE-NOTES.md</announcementFile>
- <issueManagementSystems>
- <issueManagementSystem>changes.xml</issueManagementSystem>
- <!--<issueManagementSystem>JIRA</issueManagementSystem> -->
- </issueManagementSystems>
- <version>${Log4jReleaseVersion}</version>
- <announceParameters>
- <releaseVersion>${Log4jReleaseVersion}</releaseVersion>
- <releaseCount>${Log4jReleaseCount}</releaseCount>
- </announceParameters>
- <useJql>true</useJql>
- </configuration>
- <executions>
- <execution>
- <id>create-release-notes</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>announcement-generate</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>apache-release</id>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>source-release-assembly</id>
- <configuration>
- <skipAssembly>true</skipAssembly>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <modules>
- <module>log4j-distribution</module>
- </modules>
- </profile>
- <profile>
- <id>rat</id>
- <build>
- <plugins>
- <!-- RAT report -->
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <version>${rat.plugin.version}</version>
- <configuration>
- <excludes>
- <!-- Matches other RAT configurations in this POM -->
- <exclude>src/main/resources/META-INF/services/**/*</exclude>
- <!-- IntelliJ files -->
- <exclude>.idea/**/*</exclude>
- <exclude>src/test/resources/**/*</exclude>
- <!-- IDE settings imports -->
- <exclude>src/ide/**</exclude>
- <!-- does it even make sense to apply a license to a GPG signature? -->
- <exclude>**/*.asc</exclude>
- <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
- <exclude>src/site/resources/js/jquery.js</exclude>
- <exclude>src/site/resources/js/jquery.min.js</exclude>
- <!-- Generated files -->
- <exclude>log4j-distribution/target/**/*</exclude>
- <exclude>log4j-distribution/.project</exclude>
- <exclude>log4j-distribution/.settings/**</exclude>
- <exclude>velocity.log</exclude>
- <!-- Other -->
- <exclude>felix-cache/**</exclude>
- <exclude>RELEASE-NOTES.md</exclude>
- <exclude>**/revapi.json</exclude>
- </excludes>
- </configuration>
- <executions>
- <execution>
- <phase>verify</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <!-- http://www.yourkit.com/docs/80/help/agent.jsp -->
- <id>yourkit-mac</id>
- <!--
- <activation>
- <os>
- <family>Mac</family>
- </os>
- <file>
- <exists>${yourkit.home}/bin/mac/libyjpagent.jnilib</exists>
- </file>
- </activation>
- -->
- <properties>
- <yourkit.home>/Applications/YJP.app</yourkit.home>
- </properties>
- <dependencies>
- <dependency>
- <groupId>com.yourkit</groupId>
- <artifactId>yjp-controller-api-redist</artifactId>
- <version>2013</version>
- <scope>system</scope>
- <systemPath>${yourkit.home}/lib/yjp-controller-api-redist.jar</systemPath>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-failsafe-plugin</artifactId>
- <configuration>
- <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>jdk8orGreater</id>
- <activation>
- <jdk>[1.8,)</jdk>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.revapi</groupId>
- <artifactId>revapi-maven-plugin</artifactId>
- <version>${revapi.plugin.version}</version>
- <dependencies>
- <dependency>
- <groupId>org.revapi</groupId>
- <artifactId>revapi-java</artifactId>
- <version>0.18.2</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <goals><goal>check</goal></goals>
- <configuration>
- <checkDependencies>false</checkDependencies>
- <skip>${revapi.skip}</skip>
- <failOnMissingConfigurationFiles>false</failOnMissingConfigurationFiles>
- <analysisConfigurationFiles>
- <path>revapi.json</path>
- </analysisConfigurationFiles>
- <analysisConfiguration><![CDATA[
-[
- {
- "extension": "revapi.java",
- "configuration": {
- "missing-classes": {
- "behavior": "report",
- "ignoreMissingAnnotations": false
- },
- "reportUsesFor": [
- "java.missing.newClass",
- "java.class.nonPublicPartOfAPI"
- ],
- "filter": {
- "classes": {
- "regex": true,
- "include": [
- "org\\.apache\\.logging\\.log4j(\\..+)?"
- ]
- },
- "packages": {
- "regex": true,
- "include": [
- "org\\.apache\\.logging\\.log4j(\\..+)?"
- ]
- }
- }
- }
- }
-]
- ]]></analysisConfiguration>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.revapi</groupId>
- <artifactId>revapi-maven-plugin</artifactId>
- <version>${revapi.plugin.version}</version>
- <reportSets>
- <reportSet>
- <inherited>false</inherited>
- <reports>
- <report>report-aggregate</report>
- </reports>
- </reportSet>
- <reportSet>
- <reports>
- <report>report</report>
- </reports>
- </reportSet>
- </reportSets>
- </plugin>
- </plugins>
- </reporting>
- </profile>
- <profile>
- <id>jdk7</id>
- <activation>
- <jdk>1.7</jdk>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>clirr-maven-plugin</artifactId>
- <version>${clirr.plugin.version}</version>
- <dependencies>
- <dependency>
- <groupId>org.apache.bcel</groupId>
- <artifactId>bcel</artifactId>
- <version>6.2</version>
- </dependency>
- </dependencies>
- <configuration>
- <minSeverity>${minSeverity}</minSeverity>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <argLine>-XX:MaxPermSize=512m</argLine>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-failsafe-plugin</artifactId>
- <configuration>
- <argLine>-XX:MaxPermSize=512m</argLine>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>useJava7</id>
- <activation>
- <property>
- <name>useJava7</name>
- </property>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-toolchains-plugin</artifactId>
- <version>1.1</version>
- <executions>
- <execution>
- <goals>
- <goal>toolchain</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <toolchains>
- <jdk>
- <version>1.7</version>
- </jdk>
- </toolchains>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>java8-doclint-disabled</id>
- <activation>
- <jdk>[1.8,)</jdk>
- </activation>
- <properties>
- <javadoc.opts>-Xdoclint:none</javadoc.opts>
- </properties>
- </profile>
- </profiles>
-</project>
+<?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.
+ --><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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <packaging>pom</packaging>
+ <name>Apache Log4j 2</name>
+ <version>2.12.0-SNAPSHOT</version>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>21</version>
+ </parent>
+ <prerequisites>
+ <maven>3.0.5</maven>
+ </prerequisites>
+ <description>Apache Log4j 2</description>
+ <url>https://logging.apache.org/log4j/2.x/</url>
+ <issueManagement>
+ <system>JIRA</system>
+ <url>https://issues.apache.org/jira/browse/LOG4J2</url>
+ </issueManagement>
+ <ciManagement>
+ <system>Jenkins</system>
+ <url>https://builds.apache.org/job/Log4j%202.x/</url>
+ </ciManagement>
+ <inceptionYear>1999</inceptionYear>
+ <developers>
+ <developer>
+ <id>rgoers</id>
+ <name>Ralph Goers</name>
+ <email>rgoers@apache.org</email>
+ <organization>Nextiva</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>America/Phoenix</timezone>
+ </developer>
+ <developer>
+ <id>ggregory</id>
+ <name>Gary Gregory</name>
+ <email>ggregory@apache.org</email>
+ <organization>Rocket Software</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>America/Denver</timezone>
+ </developer>
+ <developer>
+ <id>sdeboy</id>
+ <name>Scott Deboy</name>
+ <email>sdeboy@apache.org</email>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>America/Los_Angeles</timezone>
+ </developer>
+ <developer>
+ <id>rpopma</id>
+ <name>Remko Popma</name>
+ <email>rpopma@apache.org</email>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>Asia/Tokyo</timezone>
+ <properties>
+ <picUrl>http://people.apache.org/~rpopma/img/profilepic.jpg</picUrl>
+ </properties>
+ </developer>
+ <developer>
+ <id>nickwilliams</id>
+ <name>Nick Williams</name>
+ <email>nickwilliams@apache.org</email>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>America/Chicago</timezone>
+ </developer>
+ <developer>
+ <id>mattsicker</id>
+ <name>Matt Sicker</name>
+ <email>mattsicker@apache.org</email>
+ <organization>CloudBees</organization>
+ <roles>
+ <role>PMC Chair</role>
+ </roles>
+ <timezone>America/Chicago</timezone>
+ </developer>
+ <developer>
+ <id>bbrouwer</id>
+ <name>Bruce Brouwer</name>
+ <email>bruce.brouwer@gmail.com</email>
+ <roles>
+ <role>Committer</role>
+ </roles>
+ <timezone>America/Detroit</timezone>
+ </developer>
+ <developer>
+ <id>mikes</id>
+ <name>Mikael Ståldal</name>
+ <email>mikes@apache.org</email>
+ <organization>Spotify</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>Europe/Stockholm</timezone>
+ </developer>
+ <developer>
+ <id>ckozak</id>
+ <name>Carter Kozak</name>
+ <email>ckozak@apache.org</email>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>America/New York</timezone>
+ </developer>
+ </developers>
+ <!-- Contributors -->
+ <contributors>
+ <contributor>
+ <name>Murad Ersoy</name>
+ <email>muradersoy@gmail.com</email>
+ <url>https://www.behance.net/muradersoy</url>
+ <roles>
+ <role>Illustrator and Designer</role>
+ <role>created the new Log4j 2 logo.</role>
+ </roles>
+ <timezone>Europe/Istanbul</timezone>
+ <properties>
+ <picUrl>https://mir-s3-cdn-cf.behance.net/user/138/403dcf1521581.54d67f8fb01f7.jpg</picUrl>
+ </properties>
+ </contributor>
+ </contributors>
+ <mailingLists>
+ <mailingList>
+ <name>log4j-user</name>
+ <subscribe>log4j-user-subscribe@logging.apache.org</subscribe>
+ <unsubscribe>log4j-user-unsubscribe@logging.apache.org</unsubscribe>
+ <post>log4j-user@logging.apache.org</post>
+ <archive>https://lists.apache.org/list.html?log4j-user@logging.apache.org</archive>
+ <otherArchives>
+ <otherArchive>http://mail-archives.apache.org/mod_mbox/logging-log4j-user/</otherArchive>
+ <otherArchive>http://marc.info/?l=log4j-user</otherArchive>
+ <otherArchive>http://dir.gmane.org/gmane.comp.jakarta.log4j.user</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>dev</name>
+ <subscribe>dev-subscribe@logging.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@logging.apache.org</unsubscribe>
+ <post>dev@logging.apache.org</post>
+ <archive>https://lists.apache.org/list.html?dev@logging.apache.org</archive>
+ <otherArchives>
+ <otherArchive>http://mail-archives.apache.org/mod_mbox/logging-dev/</otherArchive>
+ <otherArchive>http://marc.info/?l=dev</otherArchive>
+ <otherArchive>http://dir.gmane.org/gmane.comp.jakarta.log4j.devel</otherArchive>
+ </otherArchives>
+ </mailingList>
+ </mailingLists>
+ <scm>
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/logging-log4j2.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/logging-log4j2.git</developerConnection>
+ <url>https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=summary</url>
+ <tag>log4j-${Log4jReleaseVersion}</tag>
+ </scm>
+ <properties>
+ <!-- make sure to update these for each release! -->
+ <log4jParentDir>${basedir}</log4jParentDir>
+ <Log4jReleaseVersion>2.11.2</Log4jReleaseVersion>
+ <Log4jReleaseManager>Ralph Goers</Log4jReleaseManager>
+ <Log4jReleaseKey>B3D8E1BA</Log4jReleaseKey>
+ <!--<Log4jReleaseManager>Matt Sicker</Log4jReleaseManager> -->
+ <!--<Log4jReleaseKey>748F15B2CF9BA8F024155E6ED7C92B70FA1C814D</Log4jReleaseKey> -->
+ <!-- note that any properties you want available in velocity templates must not use periods! -->
+ <slf4jVersion>1.7.25</slf4jVersion>
+ <logbackVersion>1.2.3</logbackVersion>
+ <jackson1Version>1.9.13</jackson1Version>
+ <jackson2Version>2.9.8</jackson2Version>
+ <springVersion>3.2.18.RELEASE</springVersion>
+ <flumeVersion>1.7.0</flumeVersion> <!-- Version 1.8.0 requires Java 8 -->
+ <disruptorVersion>3.4.2</disruptorVersion>
+ <conversantDisruptorVersion>1.2.10</conversantDisruptorVersion> <!-- Version 1.2.11 requires Java 8 -->
+ <mongodb2.version>2.14.3</mongodb2.version>
+ <mongodb3.version>3.10.1</mongodb3.version>
+ <groovy.version>2.5.6</groovy.version>
+ <compiler.plugin.version>3.8.0</compiler.plugin.version>
+ <pmd.plugin.version>3.10.0</pmd.plugin.version>
+ <findbugs.plugin.version>3.0.5</findbugs.plugin.version>
+ <changes.plugin.version>2.12.1</changes.plugin.version>
+ <javadoc.plugin.version>3.0.1</javadoc.plugin.version>
+ <!-- surefire.plugin.version 2.18 yields http://jira.codehaus.org/browse/SUREFIRE-1121, which is fixed in 2.18.1 -->
+ <!-- surefire.plugin.version 2.19 yields https://issues.apache.org/jira/browse/SUREFIRE-1193. -->
+ <!-- all versions after 2.13 yield https://issues.apache.org/jira/browse/SUREFIRE-720 -->
+ <surefire.plugin.version>2.21.0</surefire.plugin.version>
+ <failsafe.plugin.version>2.21.0</failsafe.plugin.version>
+ <checkstyle.plugin.version>3.0.0</checkstyle.plugin.version>
+ <deploy.plugin.version>2.8.2</deploy.plugin.version>
+ <rat.plugin.version>0.12</rat.plugin.version>
+ <pdf.plugin.version>1.2</pdf.plugin.version>
+ <cobertura.plugin.version>2.7</cobertura.plugin.version>
+ <jacoco.plugin.version>0.8.1</jacoco.plugin.version>
+ <release.plugin.version>2.5.3</release.plugin.version>
+ <scm.plugin.version>1.9.5</scm.plugin.version>
+ <jxr.plugin.version>2.5</jxr.plugin.version>
+ <revapi.plugin.version>0.10.5</revapi.plugin.version>
+ <revapi.skip>false</revapi.skip>
+ <clirr.plugin.version>2.8</clirr.plugin.version>
+ <!-- Maven site 3.7 uses the wrong stylesheet? -->
+ <site.plugin.version>3.4</site.plugin.version>
+ <!-- Maven site depends on Velocity and the escaping rules are different in newer versions. -->
+ <!-- See https://maven.apache.org/plugins/maven-site-plugin/migrate.html -->
+ <velocity.plugin.version>1.5</velocity.plugin.version>
+ <remote.resources.plugin.version>1.5</remote.resources.plugin.version>
+ <manifestfile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestfile>
+ <maven.compiler.source>1.7</maven.compiler.source>
+ <maven.compiler.target>1.7</maven.compiler.target>
+ <docLabel>Site Documentation</docLabel>
+ <projectDir />
+ <commonsLoggingVersion>1.2</commonsLoggingVersion>
+ <javax.persistence>2.1.1</javax.persistence>
+ <!-- The OSGi API version MUST always be the MINIMUM version Log4j supports -->
+ <osgi.api.version>4.3.1</osgi.api.version>
+ <!-- Version 5.15.0 requires Java 8 -->
+ <activemq.version>5.14.5</activemq.version>
+ <!-- Allow Clirr severity to be overriden by the command-line option -DminSeverity=level -->
+ <minSeverity>info</minSeverity>
+ <jctoolsVersion>1.2.1</jctoolsVersion>
+ <mockitoVersion>2.25.1</mockitoVersion>
+ <argLine>-Xms256m -Xmx1024m</argLine>
+ <javaTargetVersion>1.7</javaTargetVersion>
+ <module.name />
+ </properties>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache</id>
+ <url>https://repository.apache.org/content/repositories/releases/</url>
+ </pluginRepository>
+<!-- <pluginRepository> -->
+<!-- <id>apache.snapshots</id> -->
+<!-- <name>Apache snapshots repository</name> -->
+<!-- <url>http://repository.apache.org/content/groups/snapshots</url> -->
+<!-- <snapshots> -->
+<!-- <enabled>true</enabled> -->
+<!-- </snapshots> -->
+<!-- </pluginRepository> -->
+ </pluginRepositories>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4jVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-ext</artifactId>
+ <version>${slf4jVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <version>${logbackVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <type>test-jar</type>
+ <version>${logbackVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <version>3.12.1.v20170821-1548</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>5.6.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>3.6.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.11</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.7</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${logbackVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${logbackVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api-java9</artifactId>
+ <version>${project.version}</version>
+ <type>zip</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core-java9</artifactId>
+ <version>${project.version}</version>
+ <type>zip</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>${project.version}</version>
+ <type>zip</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j18-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-jcl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>${commonsLoggingVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-1.2-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-flume-ng</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-iostreams</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-jul</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-taglib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-web</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sleepycat</groupId>
+ <artifactId>je</artifactId>
+ <version>5.0.73</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${osgi.api.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.fusesource.jansi</groupId>
+ <artifactId>jansi</artifactId>
+ <version>1.17.1</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.flume</groupId>
+ <artifactId>flume-ng-sdk</artifactId>
+ <version>${flumeVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.flume</groupId>
+ <artifactId>flume-ng-core</artifactId>
+ <version>${flumeVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.flume</groupId>
+ <artifactId>flume-ng-embedded-agent</artifactId>
+ <version>${flumeVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.flume</groupId>
+ <artifactId>flume-ng-node</artifactId>
+ <version>${flumeVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.flume.flume-ng-channels</groupId>
+ <artifactId>flume-file-channel</artifactId>
+ <version>${flumeVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api-2.5</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-core</artifactId>
+ <version>1.2.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- Jackson 1 start -->
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-core-asl</artifactId>
+ <version>${jackson1Version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>${jackson1Version}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <!-- Jackson 1 end -->
+ <!-- Jackson 2 start -->
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ <version>${jackson2Version}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson2Version}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>${jackson2Version}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>${jackson2Version}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-xml</artifactId>
+ <version>${jackson2Version}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
+ <version>${jackson2Version}</version>
+ <optional>true</optional>
+ </dependency>
+ <!-- Jackson 2 end -->
+ <dependency>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>javax.mail</artifactId>
+ <version>1.6.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.spec.javax.jms</groupId>
+ <artifactId>jboss-jms-api_1.1_spec</artifactId>
+ <version>1.0.1.Final</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>activemq-broker</artifactId>
+ <version>${activemq.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.kafka</groupId>
+ <artifactId>kafka-clients</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.zeromq</groupId>
+ <artifactId>jeromq</artifactId>
+ <version>0.4.3</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.lmax</groupId>
+ <artifactId>disruptor</artifactId>
+ <version>${disruptorVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.conversantmedia</groupId>
+ <artifactId>disruptor</artifactId>
+ <version>${conversantDisruptorVersion}</version>
+ <!-- TODO: this can be switched based on a profile -->
+ <classifier>jdk7</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.jctools</groupId>
+ <artifactId>jctools-core</artifactId>
+ <version>${jctoolsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
+ <version>1.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>3.1.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>${mockitoVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-expression</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-oxm</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${springVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>2.3.5</version>
+ <!-- version 2.4.0 requires Java 8 -->
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <version>1.4.199</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.jpa</artifactId>
+ <version>2.6.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>javax.persistence</artifactId>
+ <version>${javax.persistence}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongo-java-driver</artifactId>
+ <version>${mongodb2.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongodb-driver</artifactId>
+ <version>${mongodb3.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>bson</artifactId>
+ <version>${mongodb3.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.lightcouch</groupId>
+ <artifactId>lightcouch</artifactId>
+ <version>0.0.6</version>
+ </dependency>
+ <dependency>
+ <groupId>com.datastax.cassandra</groupId>
+ <artifactId>cassandra-driver-core</artifactId>
+ <version>3.1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.liquibase</groupId>
+ <artifactId>liquibase-core</artifactId>
+ <version>3.5.3</version>
+ </dependency>
+ <dependency>
+ <groupId>net.javacrumbs.json-unit</groupId>
+ <artifactId>json-unit</artifactId>
+ <version>1.31.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.xmlunit</groupId>
+ <artifactId>xmlunit-core</artifactId>
+ <version>2.5.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.xmlunit</groupId>
+ <artifactId>xmlunit-matchers</artifactId>
+ <version>2.5.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.6</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- Used for testing HttpAppender -->
+ <dependency>
+ <groupId>com.github.tomakehurst</groupId>
+ <artifactId>wiremock</artifactId>
+ <scope>test</scope>
+ <version>2.19.0</version>
+ </dependency>
+ <!-- Used for compressing to formats other than zip and gz -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>1.18</version>
+ </dependency>
+ <dependency>
+ <groupId>org.tukaani</groupId>
+ <artifactId>xz</artifactId>
+ <version>1.8</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- Used for the CSV layout -->
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-csv</artifactId>
+ <version>1.6</version>
+ </dependency>
+ <!-- GC-free -->
+ <dependency>
+ <groupId>com.google.code.java-allocation-instrumenter</groupId>
+ <artifactId>java-allocation-instrumenter</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hdrhistogram</groupId>
+ <artifactId>HdrHistogram</artifactId>
+ <version>2.1.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache-extras.beanshell</groupId>
+ <artifactId>bsh</artifactId>
+ <version>2.0b6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-jsr223</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-dateutil</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <!-- Testing MongoDB -->
+ <groupId>de.flapdoodle.embed</groupId>
+ <artifactId>de.flapdoodle.embed.mongo</artifactId>
+ <version>2.2.0</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>3.5.0</version>
+ <inherited>true</inherited>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ <phase>process-classes</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>${release.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-scm-plugin</artifactId>
+ <version>${scm.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>${checkstyle.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <configuration>
+ <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+ Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+ and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+ <doclint>none</doclint>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <version>${pmd.plugin.version}</version>
+ </plugin>
+ <!-- some nice default compiler options -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${compiler.plugin.version}</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ <showDeprecation>true</showDeprecation>
+ <showWarnings>true</showWarnings>
+ <encoding>UTF-8</encoding>
+ <fork>true</fork>
+ <meminitial>256</meminitial>
+ <maxmem>1024</maxmem>
+ <compilerArguments>
+ <Xmaxwarns>10000</Xmaxwarns>
+ <Xlint />
+ </compilerArguments>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>3.0.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>${jxr.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.eluder.coveralls</groupId>
+ <artifactId>coveralls-maven-plugin</artifactId>
+ <version>4.3.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <version>${jacoco.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>prepare-agent</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>default-report</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>3.1.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.1.0</version>
+ <executions>
+ <execution>
+ <id>default-jar</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <archive>
+ <manifestFile>${manifestfile}</manifestFile>
+ <manifestEntries>
+ <Specification-Title>${project.name}</Specification-Title>
+ <Specification-Version>${project.version}</Specification-Version>
+ <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+ <Implementation-Title>${project.name}</Implementation-Title>
+ <Implementation-Version>${project.version}</Implementation-Version>
+ <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+ <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+ <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
+ <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
+ <Automatic-Module-Name>${module.name}</Automatic-Module-Name>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.1.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.2</version>
+ <executions>
+ <execution>
+ <id>copy-sitecss</id>
+ <!-- fetch site.xml before creating site documentation -->
+ <phase>pre-site</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/site</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${log4jParentDir}/src/site/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.plugin.version}</version>
+ <configuration>
+ <systemPropertyVariables>
+ <java.awt.headless>true</java.awt.headless>
+ </systemPropertyVariables>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <excludes>
+ <exclude>${log4j.skip.test1}</exclude>
+ <exclude>${log4j.skip.test2}</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe.plugin.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <systemPropertyVariables>
+ <java.awt.headless>true</java.awt.headless>
+ </systemPropertyVariables>
+ <argLine>-Xms256m -Xmx1024m</argLine>
+ <forkCount>1</forkCount>
+ <reuseForks>false</reuseForks>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>${site.plugin.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <version>${velocity.plugin.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>3.1.0</version>
+ </dependency>
+ </dependencies>
+ <configuration>
+ <!-- only build English site even on other language OS -->
+ <locales>en</locales>
+ <!-- Exclude the navigation file for Maven 1 sites
+ and the changes file used by the changes-plugin,
+ as they interfere with the site generation. -->
+ <moduleExcludes>
+ <xdoc>navigation.xml,changes.xml</xdoc>
+ </moduleExcludes>
+ <templateDirectory>${log4jParentDir}/src/site</templateDirectory>
+ <template>site.vm</template>
+ </configuration>
+ </plugin>
+ <!-- <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>clean</id>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin> -->
+ <!-- We need to disable the standard ASF configuration to be able to publish our own notice and license files -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <skip>true</skip>
+ <resourceBundles />
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pdf-plugin</artifactId>
+ <version>${pdf.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>pdf</id>
+ <phase>site</phase>
+ <goals>
+ <goal>pdf</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ <!-- RAT report -->
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <version>${rat.plugin.version}</version>
+ <configuration>
+ <excludes>
+ <!-- Matches other RAT configurations in this POM -->
+ <exclude>src/main/resources/META-INF/services/**/*</exclude>
+ <!-- IntelliJ files -->
+ <exclude>.idea/**/*</exclude>
+ <exclude>src/test/resources/**/*</exclude>
+ <!-- IDE settings imports -->
+ <exclude>src/ide/**</exclude>
+ <!-- does it even make sense to apply a license to a GPG signature? -->
+ <exclude>**/*.asc</exclude>
+ <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
+ <exclude>src/site/resources/js/jquery.js</exclude>
+ <exclude>src/site/resources/js/jquery.min.js</exclude>
+ <!-- Generated files -->
+ <exclude>log4j-distribution/target/**/*</exclude>
+ <exclude>log4j-distribution/.project</exclude>
+ <exclude>log4j-distribution/.settings/**</exclude>
+ <exclude>velocity.log</exclude>
+ <!-- Other -->
+ <exclude>felix-cache/**</exclude>
+ <exclude>RELEASE-NOTES.md</exclude>
+ <exclude>**/revapi.json</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <!-- DOAP (RDF) metadata generation -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-doap-plugin</artifactId>
+ <version>1.2</version>
+ <configuration>
+ <doapOptions>
+ <programmingLanguage>Java</programmingLanguage>
+ <category>library</category>
+ </doapOptions>
+ <asfExtOptions>
+ <charter>
+ The Apache Logging Services Project creates and maintains open-source software related to the logging of
+ application behavior and released at no charge to the public.
+ </charter>
+ <pmc>https://logging.apache.org</pmc>
+ </asfExtOptions>
+ </configuration>
+ <executions>
+ <execution>
+ <id>site</id>
+ <phase>site</phase>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <!-- Changes report -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ <report>jira-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <statusIds>Resolved, Closed</statusIds>
+ <columnNames>Type,Key,Summary,Assignee,Status,Resolution,Fix Version</columnNames>
+ <useJql>true</useJql>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.9</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>index</report>
+ <report>dependencies</report>
+ <report>dependency-info</report>
+ <report>dependency-convergence</report>
+ <report>dependency-management</report>
+ <report>project-team</report>
+ <report>mailing-list</report>
+ <report>issue-tracking</report>
+ <report>license</report>
+ <report>scm</report>
+ <report>summary</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <!-- you'd think these would be the defaults, right? -->
+ <customBundle>${project.basedir}/src/site/custom/project-info-report.properties</customBundle>
+ <webAccessUrl>${project.scm.url}</webAccessUrl>
+ <anonymousConnection>${project.scm.connection}</anonymousConnection>
+ <developerConnection>${project.scm.developerConnection}</developerConnection>
+ <scmTag>log4j-${Log4jReleaseVersion}</scmTag>
+ </configuration>
+ </plugin>
+ <!-- Surefire report -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>${surefire.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <id>integration-tests</id>
+ <reports>
+ <report>failsafe-report-only</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <!-- RAT report -->
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <version>${rat.plugin.version}</version>
+ <configuration>
+ <excludes>
+ <!-- Matches other RAT configurations in this POM -->
+ <exclude>src/main/resources/META-INF/services/**/*</exclude>
+ <!-- IntelliJ files -->
+ <exclude>.idea/**/*</exclude>
+ <exclude>src/test/resources/**/*</exclude>
+ <!-- IDE settings imports -->
+ <exclude>src/ide/**</exclude>
+ <!-- does it even make sense to apply a license to a GPG signature? -->
+ <exclude>**/*.asc</exclude>
+ <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
+ <exclude>src/site/resources/js/jquery.js</exclude>
+ <exclude>src/site/resources/js/jquery.min.js</exclude>
+ <!-- Generated files -->
+ <exclude>log4j-distribution/target/**/*</exclude>
+ <exclude>log4j-distribution/.project</exclude>
+ <exclude>log4j-distribution/.settings/**</exclude>
+ <exclude>velocity.log</exclude>
+ <!-- Other -->
+ <exclude>felix-cache/**</exclude>
+ <exclude>RELEASE-NOTES.txt</exclude>
+ <exclude>**/revapi.json</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+ <distributionManagement>
+ <downloadUrl>https://logging.apache.org/log4j/2.x/download.html</downloadUrl>
+ <!-- site is only included to make maven-site-plugin stop complaining -->
+ <site>
+ <id>www.example.com</id>
+ <url>scp://www.example.com/www/docs/project/</url>
+ </site>
+ </distributionManagement>
+ <modules>
+ <module>log4j-api-java9</module>
+ <module>log4j-api</module>
+ <module>log4j-core-java9</module>
+ <module>log4j-core</module>
+ <module>log4j-core-its</module>
+ <module>log4j-1.2-api</module>
+ <module>log4j-slf4j-impl</module>
+ <module>log4j-slf4j18-impl</module>
+ <module>log4j-to-slf4j</module>
+ <module>log4j-jcl</module>
+ <module>log4j-flume-ng</module>
+ <module>log4j-taglib</module>
+ <module>log4j-jmx-gui</module>
+ <module>log4j-samples</module>
+ <module>log4j-bom</module>
+ <module>log4j-jdbc-dbcp2</module>
+ <module>log4j-jpa</module>
+ <module>log4j-couchdb</module>
+ <module>log4j-mongodb2</module>
+ <module>log4j-mongodb3</module>
+ <module>log4j-cassandra</module>
+ <module>log4j-web</module>
+ <module>log4j-perf</module>
+ <module>log4j-iostreams</module>
+ <module>log4j-jul</module>
+ <module>log4j-liquibase</module>
+ <module>log4j-appserver</module>
+ <module>log4j-osgi</module>
+ <module>log4j-spring-cloud-config</module>
+ </modules>
+ <profiles>
+ <profile>
+ <id>pdf</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pdf-plugin</artifactId>
+ <version>${pdf.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>pdf</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>pdf</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.reporting.outputDirectory}</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>release-notes</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ <configuration>
+ <template>announcement.vm</template>
+ <templateDirectory>src/changes</templateDirectory>
+ <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+ <announcementDirectory>.</announcementDirectory>
+ <announcementFile>RELEASE-NOTES.md</announcementFile>
+ <issueManagementSystems>
+ <issueManagementSystem>changes.xml</issueManagementSystem>
+ <!--<issueManagementSystem>JIRA</issueManagementSystem> -->
+ </issueManagementSystems>
+ <version>${Log4jReleaseVersion}</version>
+ <announceParameters>
+ <releaseVersion>${Log4jReleaseVersion}</releaseVersion>
+ <releaseCount>${Log4jReleaseCount}</releaseCount>
+ </announceParameters>
+ <useJql>true</useJql>
+ </configuration>
+ <executions>
+ <execution>
+ <id>create-release-notes</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>announcement-generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>apache-release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>source-release-assembly</id>
+ <configuration>
+ <skipAssembly>true</skipAssembly>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <modules>
+ <module>log4j-distribution</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>rat</id>
+ <build>
+ <plugins>
+ <!-- RAT report -->
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <version>${rat.plugin.version}</version>
+ <configuration>
+ <excludes>
+ <!-- Matches other RAT configurations in this POM -->
+ <exclude>src/main/resources/META-INF/services/**/*</exclude>
+ <!-- IntelliJ files -->
+ <exclude>.idea/**/*</exclude>
+ <exclude>src/test/resources/**/*</exclude>
+ <!-- IDE settings imports -->
+ <exclude>src/ide/**</exclude>
+ <!-- does it even make sense to apply a license to a GPG signature? -->
+ <exclude>**/*.asc</exclude>
+ <!-- jQuery is MIT-licensed, but RAT can't figure it out -->
+ <exclude>src/site/resources/js/jquery.js</exclude>
+ <exclude>src/site/resources/js/jquery.min.js</exclude>
+ <!-- Generated files -->
+ <exclude>log4j-distribution/target/**/*</exclude>
+ <exclude>log4j-distribution/.project</exclude>
+ <exclude>log4j-distribution/.settings/**</exclude>
+ <exclude>velocity.log</exclude>
+ <!-- Other -->
+ <exclude>felix-cache/**</exclude>
+ <exclude>RELEASE-NOTES.md</exclude>
+ <exclude>**/revapi.json</exclude>
+ </excludes>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>verify</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <!-- http://www.yourkit.com/docs/80/help/agent.jsp -->
+ <id>yourkit-mac</id>
+ <!--
+ <activation>
+ <os>
+ <family>Mac</family>
+ </os>
+ <file>
+ <exists>${yourkit.home}/bin/mac/libyjpagent.jnilib</exists>
+ </file>
+ </activation>
+ -->
+ <properties>
+ <yourkit.home>/Applications/YJP.app</yourkit.home>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>com.yourkit</groupId>
+ <artifactId>yjp-controller-api-redist</artifactId>
+ <version>2013</version>
+ <scope>system</scope>
+ <systemPath>${yourkit.home}/lib/yjp-controller-api-redist.jar</systemPath>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+ <argLine>-agentpath:"${yourkit.home}/bin/mac/libyjpagent.jnilib"</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>jdk8orGreater</id>
+ <activation>
+ <jdk>[1.8,)</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.revapi</groupId>
+ <artifactId>revapi-maven-plugin</artifactId>
+ <version>${revapi.plugin.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.revapi</groupId>
+ <artifactId>revapi-java</artifactId>
+ <version>0.18.2</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <goals><goal>check</goal></goals>
+ <configuration>
+ <checkDependencies>false</checkDependencies>
+ <skip>${revapi.skip}</skip>
+ <failOnMissingConfigurationFiles>false</failOnMissingConfigurationFiles>
+ <analysisConfigurationFiles>
+ <path>revapi.json</path>
+ </analysisConfigurationFiles>
+ <analysisConfiguration><![CDATA[
+[
+ {
+ "extension": "revapi.java",
+ "configuration": {
+ "missing-classes": {
+ "behavior": "report",
+ "ignoreMissingAnnotations": false
+ },
+ "reportUsesFor": [
+ "java.missing.newClass",
+ "java.class.nonPublicPartOfAPI"
+ ],
+ "filter": {
+ "classes": {
+ "regex": true,
+ "include": [
+ "org\\.apache\\.logging\\.log4j(\\..+)?"
+ ]
+ },
+ "packages": {
+ "regex": true,
+ "include": [
+ "org\\.apache\\.logging\\.log4j(\\..+)?"
+ ]
+ }
+ }
+ }
+ }
+]
+ ]]></analysisConfiguration>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.revapi</groupId>
+ <artifactId>revapi-maven-plugin</artifactId>
+ <version>${revapi.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <inherited>false</inherited>
+ <reports>
+ <report>report-aggregate</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <reports>
+ <report>report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+ </profile>
+ <profile>
+ <id>jdk7</id>
+ <activation>
+ <jdk>1.7</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>clirr-maven-plugin</artifactId>
+ <version>${clirr.plugin.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.bcel</groupId>
+ <artifactId>bcel</artifactId>
+ <version>6.2</version>
+ </dependency>
+ </dependencies>
+ <configuration>
+ <minSeverity>${minSeverity}</minSeverity>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-XX:MaxPermSize=512m</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <configuration>
+ <argLine>-XX:MaxPermSize=512m</argLine>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>useJava7</id>
+ <activation>
+ <property>
+ <name>useJava7</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-toolchains-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>toolchain</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <toolchains>
+ <jdk>
+ <version>1.7</version>
+ </jdk>
+ </toolchains>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>java8-doclint-disabled</id>
+ <activation>
+ <jdk>[1.8,)</jdk>
+ </activation>
+ <properties>
+ <javadoc.opts>-Xdoclint:none</javadoc.opts>
+ </properties>
+ </profile>
+ </profiles>
+</project>