diff --git a/common/pom.xml b/common/pom.xml
index a9f9fda618..876faf3e5b 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -61,6 +61,16 @@
log4j
true
+
+ org.apache.logging.log4j
+ log4j-api
+ true
+
+
+ org.apache.logging.log4j
+ log4j-core
+ test
+
diff --git a/common/src/main/java/io/netty/util/internal/logging/Log4J2Logger.java b/common/src/main/java/io/netty/util/internal/logging/Log4J2Logger.java
new file mode 100644
index 0000000000..64bdfed2e0
--- /dev/null
+++ b/common/src/main/java/io/netty/util/internal/logging/Log4J2Logger.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2016 The Netty Project
+ *
+ * The Netty Project 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 io.netty.util.internal.logging;
+
+import org.apache.logging.log4j.Logger;
+
+final class Log4J2Logger extends AbstractInternalLogger {
+
+ private static final long serialVersionUID = 5485418394879791397L;
+
+ private final transient Logger logger;
+
+ Log4J2Logger(Logger logger) {
+ super(logger.getName());
+ this.logger = logger;
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return logger.isTraceEnabled();
+ }
+
+ @Override
+ public void trace(String msg) {
+ logger.trace(msg);
+ }
+
+ @Override
+ public void trace(String format, Object arg) {
+ logger.trace(format, arg);
+ }
+
+ @Override
+ public void trace(String format, Object argA, Object argB) {
+ logger.trace(format, argA, argB);
+ }
+
+ @Override
+ public void trace(String format, Object... arguments) {
+ logger.trace(format, arguments);
+ }
+
+ @Override
+ public void trace(String msg, Throwable t) {
+ logger.trace(msg, t);
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return logger.isDebugEnabled();
+ }
+
+ @Override
+ public void debug(String msg) {
+ logger.debug(msg);
+ }
+
+ @Override
+ public void debug(String format, Object arg) {
+ logger.debug(format, arg);
+ }
+
+ @Override
+ public void debug(String format, Object argA, Object argB) {
+ logger.debug(format, argA, argB);
+ }
+
+ @Override
+ public void debug(String format, Object... arguments) {
+ logger.debug(format, arguments);
+ }
+
+ @Override
+ public void debug(String msg, Throwable t) {
+ logger.debug(msg, t);
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return logger.isInfoEnabled();
+ }
+
+ @Override
+ public void info(String msg) {
+ logger.info(msg);
+ }
+
+ @Override
+ public void info(String format, Object arg) {
+ logger.info(format, arg);
+ }
+
+ @Override
+ public void info(String format, Object argA, Object argB) {
+ logger.info(format, argA, argB);
+ }
+
+ @Override
+ public void info(String format, Object... arguments) {
+ logger.info(format, arguments);
+ }
+
+ @Override
+ public void info(String msg, Throwable t) {
+ logger.info(msg, t);
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return logger.isWarnEnabled();
+ }
+
+ @Override
+ public void warn(String msg) {
+ logger.warn(msg);
+ }
+
+ @Override
+ public void warn(String format, Object arg) {
+ logger.warn(format, arg);
+ }
+
+ @Override
+ public void warn(String format, Object... arguments) {
+ logger.warn(format, arguments);
+ }
+
+ @Override
+ public void warn(String format, Object argA, Object argB) {
+ logger.warn(format, argA, argB);
+ }
+
+ @Override
+ public void warn(String msg, Throwable t) {
+ logger.warn(msg, t);
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return logger.isErrorEnabled();
+ }
+
+ @Override
+ public void error(String msg) {
+ logger.error(msg);
+ }
+
+ @Override
+ public void error(String format, Object arg) {
+ logger.error(format, arg);
+ }
+
+ @Override
+ public void error(String format, Object argA, Object argB) {
+ logger.error(format, argA, argB);
+ }
+
+ @Override
+ public void error(String format, Object... arguments) {
+ logger.error(format, arguments);
+ }
+
+ @Override
+ public void error(String msg, Throwable t) {
+ logger.error(msg, t);
+ }
+}
diff --git a/common/src/main/java/io/netty/util/internal/logging/Log4J2LoggerFactory.java b/common/src/main/java/io/netty/util/internal/logging/Log4J2LoggerFactory.java
new file mode 100644
index 0000000000..6dfda57af4
--- /dev/null
+++ b/common/src/main/java/io/netty/util/internal/logging/Log4J2LoggerFactory.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 The Netty Project
+ *
+ * The Netty Project 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 io.netty.util.internal.logging;
+
+import org.apache.logging.log4j.LogManager;
+
+public final class Log4J2LoggerFactory extends InternalLoggerFactory {
+
+ @Override
+ public InternalLogger newInstance(String name) {
+ return new Log4J2Logger(LogManager.getLogger(name));
+ }
+}
diff --git a/common/src/test/java/io/netty/util/internal/logging/Log4J2LoggerFactoryTest.java b/common/src/test/java/io/netty/util/internal/logging/Log4J2LoggerFactoryTest.java
new file mode 100644
index 0000000000..e0db431e9d
--- /dev/null
+++ b/common/src/test/java/io/netty/util/internal/logging/Log4J2LoggerFactoryTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 The Netty Project
+ *
+ * The Netty Project 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 io.netty.util.internal.logging;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class Log4J2LoggerFactoryTest {
+
+ @Test
+ public void testCreation() {
+ InternalLogger logger = new Log4J2LoggerFactory().newInstance("foo");
+ assertTrue(logger instanceof Log4J2Logger);
+ assertEquals("foo", logger.name());
+ }
+}
diff --git a/common/src/test/java/io/netty/util/internal/logging/Log4J2LoggerTest.java b/common/src/test/java/io/netty/util/internal/logging/Log4J2LoggerTest.java
new file mode 100644
index 0000000000..96ee4346c8
--- /dev/null
+++ b/common/src/test/java/io/netty/util/internal/logging/Log4J2LoggerTest.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2016 The Netty Project
+ *
+ * The Netty Project 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 io.netty.util.internal.logging;
+
+import org.junit.Test;
+import org.apache.logging.log4j.Logger;
+
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertTrue;
+
+public class Log4J2LoggerTest {
+ private static final Exception e = new Exception();
+
+ @Test
+ public void testIsTraceEnabled() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ expect(mock.isTraceEnabled()).andReturn(true);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ assertTrue(logger.isTraceEnabled());
+ verify(mock);
+ }
+
+ @Test
+ public void testIsDebugEnabled() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ expect(mock.isDebugEnabled()).andReturn(true);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ assertTrue(logger.isDebugEnabled());
+ verify(mock);
+ }
+
+ @Test
+ public void testIsInfoEnabled() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ expect(mock.isInfoEnabled()).andReturn(true);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ assertTrue(logger.isInfoEnabled());
+ verify(mock);
+ }
+
+ @Test
+ public void testIsWarnEnabled() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ expect(mock.isWarnEnabled()).andReturn(true);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ assertTrue(logger.isWarnEnabled());
+ verify(mock);
+ }
+
+ @Test
+ public void testIsErrorEnabled() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ expect(mock.isErrorEnabled()).andReturn(true);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ assertTrue(logger.isErrorEnabled());
+ verify(mock);
+ }
+
+ @Test
+ public void testTrace() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.trace("a");
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.trace("a");
+ verify(mock);
+ }
+
+ @Test
+ public void testTraceWithException() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.trace("a", e);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.trace("a", e);
+ verify(mock);
+ }
+
+ @Test
+ public void testDebug() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.debug("a");
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.debug("a");
+ verify(mock);
+ }
+
+ @Test
+ public void testDebugWithException() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.debug("a", e);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.debug("a", e);
+ verify(mock);
+ }
+
+ @Test
+ public void testInfo() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.info("a");
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.info("a");
+ verify(mock);
+ }
+
+ @Test
+ public void testInfoWithException() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.info("a", e);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.info("a", e);
+ verify(mock);
+ }
+
+ @Test
+ public void testWarn() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.warn("a");
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.warn("a");
+ verify(mock);
+ }
+
+ @Test
+ public void testWarnWithException() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.warn("a", e);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.warn("a", e);
+ verify(mock);
+ }
+
+ @Test
+ public void testError() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.error("a");
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.error("a");
+ verify(mock);
+ }
+
+ @Test
+ public void testErrorWithException() {
+ Logger mock = createStrictMock(Logger.class);
+
+ expect(mock.getName()).andReturn("foo");
+ mock.error("a", e);
+ replay(mock);
+
+ InternalLogger logger = new Log4J2Logger(mock);
+ logger.error("a", e);
+ verify(mock);
+ }
+}
diff --git a/pom.xml b/pom.xml
index c97a2da337..b7e2c94552 100644
--- a/pom.xml
+++ b/pom.xml
@@ -382,6 +382,11 @@
commons-logging
1.1.3
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.3
+
log4j
log4j
@@ -522,6 +527,14 @@
1.5.7
test
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.3
+ test
+