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/07/28 03:27:48 UTC

[logging-log4j2] 01/02: LOG4J2-2556 - Make Log4j Core optional

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 be81f5922024b67ba9d4c52d79b98349cc03df4f
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sat Jul 27 20:24:07 2019 -0700

    LOG4J2-2556 - Make Log4j Core optional
---
 log4j-1.2-api/pom.xml                              |   1 +
 .../src/main/java/org/apache/log4j/Category.java   | 100 +++++++++++++++------
 .../src/main/java/org/apache/log4j/LogManager.java |  25 +++++-
 .../src/main/java/org/apache/log4j/Logger.java     |   4 +-
 .../org/apache/log4j/legacy/core/CategoryUtil.java |  65 ++++++++++++++
 .../org/apache/log4j/legacy/core/ContextUtil.java  |  34 +++++++
 log4j-1.2-api/src/site/markdown/index.md           |  20 ++++-
 .../test/java/org/apache/log4j/CategoryTest.java   |   4 +-
 .../src/test/java/org/apache/log4j/LoggerTest.java |  40 ++++-----
 src/site/xdoc/runtime-dependencies.xml             |   2 +-
 10 files changed, 236 insertions(+), 59 deletions(-)

diff --git a/log4j-1.2-api/pom.xml b/log4j-1.2-api/pom.xml
index 8a40ed6..d42fe62 100644
--- a/log4j-1.2-api/pom.xml
+++ b/log4j-1.2-api/pom.xml
@@ -63,6 +63,7 @@
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
+      <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java b/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
index 873aa0e..84a18d8 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/Category.java
@@ -24,10 +24,11 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.log4j.helpers.NullEnumeration;
+import org.apache.log4j.legacy.core.CategoryUtil;
 import org.apache.log4j.spi.LoggerFactory;
 import org.apache.log4j.spi.LoggingEvent;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.util.NameUtil;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.message.LocalizedMessage;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ObjectMessage;
@@ -47,12 +48,26 @@ public class Category {
 
     private static final String FQCN = Category.class.getName();
 
+    private static final boolean isCoreAvailable;
+
+
+    static {
+        boolean available;
+
+        try {
+            available = Class.forName("org.apache.logging.log4j.core.Logger") != null;
+        } catch (Exception ex) {
+            available = false;
+        }
+        isCoreAvailable = available;
+    }
+
     /**
      * Resource bundle for localized messages.
      */
     protected ResourceBundle bundle = null;
 
-    private final org.apache.logging.log4j.core.Logger logger;
+    private final org.apache.logging.log4j.Logger logger;
 
     /**
      * Constructor used by Logger to specify a LoggerContext.
@@ -71,7 +86,7 @@ public class Category {
         this(PrivateManager.getContext(), name);
     }
 
-    private Category(final org.apache.logging.log4j.core.Logger logger) {
+    private Category(final org.apache.logging.log4j.Logger logger) {
         this.logger = logger;
     }
 
@@ -117,16 +132,20 @@ public class Category {
         return logger.getName();
     }
 
-    org.apache.logging.log4j.core.Logger getLogger() {
+    org.apache.logging.log4j.Logger getLogger() {
         return logger;
     }
 
     public final Category getParent() {
-        final org.apache.logging.log4j.core.Logger parent = logger.getParent();
-        if (parent == null) {
+        if (!isCoreAvailable) {
+            return null;
+        }
+        org.apache.logging.log4j.Logger parent = CategoryUtil.getParent(logger);
+        LoggerContext loggerContext = CategoryUtil.getLoggerContext(logger);
+        if (parent == null || loggerContext == null) {
             return null;
         }
-        final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
+        final ConcurrentMap<String, Logger> loggers = getLoggersMap(loggerContext);
         final Logger l = loggers.get(parent.getName());
         return l == null ? new Category(parent) : l;
     }
@@ -182,8 +201,6 @@ public class Category {
             return Level.ERROR;
         case FATAL:
             return Level.FATAL;
-        case OFF:
-            return Level.OFF;
         default:
             // TODO Should this be an IllegalStateException?
             return Level.OFF;
@@ -199,7 +216,7 @@ public class Category {
     }
 
     public void setLevel(final Level level) {
-        logger.setLevel(org.apache.logging.log4j.Level.toLevel(level.levelStr));
+        setLevel(level.levelStr);
     }
 
     public final Level getPriority() {
@@ -207,7 +224,13 @@ public class Category {
     }
 
     public void setPriority(final Priority priority) {
-        logger.setLevel(org.apache.logging.log4j.Level.toLevel(priority.levelStr));
+        setLevel(priority.levelStr);
+    }
+
+    private void setLevel(final String levelStr) {
+        if (isCoreAvailable) {
+            CategoryUtil.setLevel(logger, org.apache.logging.log4j.Level.toLevel(levelStr));
+        }
     }
 
     public void debug(final Object message) {
@@ -354,7 +377,11 @@ public class Category {
     public void forcedLog(final String fqcn, final Priority level, final Object message, final Throwable t) {
         final org.apache.logging.log4j.Level lvl = org.apache.logging.log4j.Level.toLevel(level.toString());
         final Message msg = message instanceof Message ? (Message) message : new ObjectMessage(message);
-        logger.logMessage(fqcn, lvl, null, msg, t);
+        if (logger instanceof ExtendedLogger) {
+            ((ExtendedLogger) logger).logMessage(fqcn, lvl, null, new ObjectMessage(message), t);
+        } else {
+            logger.log(lvl, msg, t);
+        }
     }
 
     public boolean exists(final String name) {
@@ -362,11 +389,13 @@ public class Category {
     }
 
     public boolean getAdditivity() {
-        return logger.isAdditive();
+        return isCoreAvailable ? CategoryUtil.isAdditive(logger) : false;
     }
 
     public void setAdditivity(final boolean additivity) {
-        logger.setAdditive(additivity);
+        if (isCoreAvailable) {
+            CategoryUtil.setAdditivity(logger, additivity);
+        }
     }
 
     public void setResourceBundle(final ResourceBundle bundle) {
@@ -378,19 +407,32 @@ public class Category {
             return bundle;
         }
         String name = logger.getName();
-        final ConcurrentMap<String, Logger> loggers = getLoggersMap(logger.getContext());
-        while ((name = NameUtil.getSubName(name)) != null) {
-            final Logger subLogger = loggers.get(name);
-            if (subLogger != null) {
-				final ResourceBundle rb = subLogger.bundle;
-                if (rb != null) {
-                    return rb;
+        if (isCoreAvailable) {
+            LoggerContext ctx = CategoryUtil.getLoggerContext(logger);
+            if (ctx != null) {
+                final ConcurrentMap<String, Logger> loggers = getLoggersMap(ctx);
+                while ((name = getSubName(name)) != null) {
+                    final Logger subLogger = loggers.get(name);
+                    if (subLogger != null) {
+                        final ResourceBundle rb = subLogger.bundle;
+                        if (rb != null) {
+                            return rb;
+                        }
+                    }
                 }
             }
         }
         return null;
     }
 
+    private static  String getSubName(final String name) {
+        if (Strings.isEmpty(name)) {
+            return null;
+        }
+        final int i = name.lastIndexOf('.');
+        return i > 0 ? name.substring(0, i) : Strings.EMPTY;
+    }
+
     /**
      If <code>assertion</code> parameter is {@code false}, then
      logs <code>msg</code> as an {@link #error(Object) error} statement.
@@ -448,8 +490,12 @@ public class Category {
 
     private void maybeLog(final String fqcn, final org.apache.logging.log4j.Level level,
             final Object message, final Throwable throwable) {
-        if (logger.isEnabled(level, null, message, throwable)) {
-            logger.logMessage(FQCN, level, null, new ObjectMessage(message), throwable);
+        if (logger.isEnabled(level)) {
+            if (logger instanceof ExtendedLogger) {
+                ((ExtendedLogger) logger).logMessage(fqcn, level, null, new ObjectMessage(message), throwable);
+            } else {
+                logger.log(level, message, throwable);
+            }
         }
     }
 
@@ -457,7 +503,7 @@ public class Category {
 
         @Override
         protected Logger newLogger(final String name, final org.apache.logging.log4j.spi.LoggerContext context) {
-            return new Logger((LoggerContext) context, name);
+            return new Logger(context, name);
         }
 
         @Override
@@ -473,7 +519,7 @@ public class Category {
         private static final String FQCN = Category.class.getName();
 
         public static LoggerContext getContext() {
-            return (LoggerContext) getContext(FQCN, false);
+            return getContext(FQCN, false);
         }
 
         public static org.apache.logging.log4j.Logger getLogger(final String name) {
@@ -482,7 +528,7 @@ public class Category {
     }
 
     private boolean isEnabledFor(final org.apache.logging.log4j.Level level) {
-        return logger.isEnabled(level, null, null);
+        return logger.isEnabled(level);
     }
 
 }
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java b/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java
index 751cb86..a4b6802 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/LogManager.java
@@ -19,11 +19,12 @@ package org.apache.log4j;
 import java.util.Enumeration;
 
 import org.apache.log4j.helpers.NullEnumeration;
+import org.apache.log4j.legacy.core.ContextUtil;
 import org.apache.log4j.spi.HierarchyEventListener;
 import org.apache.log4j.spi.LoggerFactory;
 import org.apache.log4j.spi.LoggerRepository;
 import org.apache.log4j.spi.RepositorySelector;
-import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.util.Strings;
 
 /**
@@ -63,6 +64,20 @@ public final class LogManager {
 
     private static final LoggerRepository REPOSITORY = new Repository();
 
+    private static final boolean isLog4jCore;
+
+    static {
+        boolean core = false;
+        try {
+            if (Class.forName("org.apache.logging.log4j.core.LoggerContext") != null) {
+                core = true;
+            }
+        } catch (Exception ex) {
+            // Ignore the exception;
+        }
+        isLog4jCore = core;
+    }
+
     private LogManager() {
     }
 
@@ -96,8 +111,10 @@ public final class LogManager {
     }
 
     static void reconfigure() {
-        final LoggerContext ctx = PrivateManager.getContext();
-        ctx.reconfigure();
+        if (isLog4jCore) {
+            final LoggerContext ctx = PrivateManager.getContext();
+            ContextUtil.reconfigure(ctx);
+        }
     }
 
     /**
@@ -212,7 +229,7 @@ public final class LogManager {
         private static final String FQCN = LogManager.class.getName();
 
         public static LoggerContext getContext() {
-            return (LoggerContext) getContext(FQCN, false);
+            return getContext(FQCN, false);
         }
 
         public static org.apache.logging.log4j.Logger getLogger(final String name) {
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/Logger.java b/log4j-1.2-api/src/main/java/org/apache/log4j/Logger.java
index fb7277b..fe1f26a 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/Logger.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/Logger.java
@@ -18,7 +18,7 @@ package org.apache.log4j;
 
 
 import org.apache.log4j.spi.LoggerFactory;
-import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.spi.LoggerContext;
 
 /**
  *
@@ -56,7 +56,7 @@ public class Logger extends Category {
         private static final String FQCN = Logger.class.getName();
 
         public static LoggerContext getContext() {
-            return (LoggerContext) getContext(FQCN, false);
+            return getContext(FQCN, false);
         }
 
         public static org.apache.logging.log4j.Logger getLogger(final String name) {
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/legacy/core/CategoryUtil.java b/log4j-1.2-api/src/main/java/org/apache/log4j/legacy/core/CategoryUtil.java
new file mode 100644
index 0000000..f9e9f7c
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/legacy/core/CategoryUtil.java
@@ -0,0 +1,65 @@
+/*
+ * 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.log4j.legacy.core;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * Provide access to Log4j Core Logger methods.
+ */
+public final class CategoryUtil {
+
+    private CategoryUtil() {
+    }
+
+    public static boolean isAdditive(Logger logger) {
+        if (logger instanceof org.apache.logging.log4j.core.Logger) {
+            return ((org.apache.logging.log4j.core.Logger) logger).isAdditive();
+        }
+        return false;
+    }
+
+    public static void setAdditivity(Logger logger, boolean additivity) {
+        if (logger instanceof org.apache.logging.log4j.core.Logger) {
+            ((org.apache.logging.log4j.core.Logger) logger).setAdditive(additivity);
+        }
+    }
+
+    public static Logger getParent(Logger logger) {
+        if (logger instanceof org.apache.logging.log4j.core.Logger) {
+            return ((org.apache.logging.log4j.core.Logger) logger).getParent();
+
+        }
+        return null;
+    }
+
+    public static LoggerContext getLoggerContext(Logger logger) {
+        if (logger instanceof org.apache.logging.log4j.core.Logger) {
+            return ((org.apache.logging.log4j.core.Logger) logger).getContext();
+        }
+        return null;
+    }
+
+    public static void setLevel(Logger logger, Level level) {
+        if (logger instanceof org.apache.logging.log4j.core.Logger) {
+            ((org.apache.logging.log4j.core.Logger) logger).setLevel(level);
+
+        }
+    }
+}
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/legacy/core/ContextUtil.java b/log4j-1.2-api/src/main/java/org/apache/log4j/legacy/core/ContextUtil.java
new file mode 100644
index 0000000..d3b99fa
--- /dev/null
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/legacy/core/ContextUtil.java
@@ -0,0 +1,34 @@
+/*
+ * 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.log4j.legacy.core;
+
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * Implements LoggerContext methods specific to log4j-core.
+ */
+public final class ContextUtil {
+
+    private ContextUtil() {
+    }
+
+    public static void reconfigure(LoggerContext ctx) {
+        if (ctx instanceof org.apache.logging.log4j.core.LoggerContext) {
+            ((org.apache.logging.log4j.core.LoggerContext) ctx).reconfigure();
+        }
+    }
+}
diff --git a/log4j-1.2-api/src/site/markdown/index.md b/log4j-1.2-api/src/site/markdown/index.md
index a80e687..696e0bb 100644
--- a/log4j-1.2-api/src/site/markdown/index.md
+++ b/log4j-1.2-api/src/site/markdown/index.md
@@ -18,12 +18,26 @@
 
 # Log4j 1.2 Bridge
 
-The Log4j 1.2 Bridge allows applications coded to use Log4j 1.2 API to use
-Log4j 2 instead.
+The Log4j 1.2 Bridge allows applications coded to use Log4j 1.2 API to use Log4j 2 instead.
 
 ## Requirements
 
-The Log4j 1.2 bridge is dependent on the Log4j 2 API and implementation.
+The Log4j 1.2 bridge is dependent on the Log4j 2 API. The following Log4j 1.x methods will behave differently when
+the Log4j 2 Core module is included then when it is not:
+
+| Method                        | Without log4j-core | With log4j-core                      |
+| ----------------------------- | ------------------ | ------------------------------------ |
+| Category.getParent()          | Returns null       | Returns parent logger                |
+| Category.setLevel()           | NoOp               | Sets Logger Level                    |
+| Category.setPriority()        | NoOp               | Sets Logger Level                    | 
+| Category.getAdditivity()      | Returns false      | Returns Logger's additivity setting  | 
+| Category.setAdditivity()      | NoOp               | Sets additivity of LoggerConfig      |
+| Category.getResourceBundle()  | NoOp               | Returns the resource bundle associated with the Logger |
+| BasicConfigurator.configure() | NoOp               | Reconfigures Log4j 2                 |
+
+If log4j-core is not present location information will not be accurate in calls using the Log4j 1.2 API. The config
+package which attempts tp convert Log4j 1.x configurations to Log4j 2 is not supported without Log4j 2.    
+
 For more information, see [Runtime Dependencies](../runtime-dependencies.html).
 
 ## Usage
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
index f671193..6a8af76 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/CategoryTest.java
@@ -74,7 +74,7 @@ public class CategoryTest {
     public void testForcedLog() {
         final MockCategory category = new MockCategory("org.example.foo");
         category.setAdditivity(false);
-        category.getLogger().addAppender(appender);
+        ((org.apache.logging.log4j.core.Logger) category.getLogger()).addAppender(appender);
         category.info("Hello, World");
         final List<LogEvent> list = appender.getEvents();
         int events = list.size();
@@ -172,7 +172,7 @@ public class CategoryTest {
         final ListAppender appender = new ListAppender("List2", null, layout, false, false);
         appender.start();
         category.setAdditivity(false);
-        category.getLogger().addAppender(appender);
+        ((org.apache.logging.log4j.core.Logger) category.getLogger()).addAppender(appender);
         category.error("Test Message");
         final List<String> msgs = appender.getMessages();
         assertTrue("Incorrect number of messages. Expected 1 got " + msgs.size(), msgs.size() == 1);
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
index 48b073d..0c4308f 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
@@ -122,7 +122,7 @@ public class LoggerTest {
         final CountingAppender coutingAppender = new CountingAppender();
         coutingAppender.start();
         try {
-            loggerA.getLogger().addAppender(coutingAppender);
+            ((org.apache.logging.log4j.core.Logger) loggerA.getLogger()).addAppender(coutingAppender);
 
             assertEquals(0, coutingAppender.counter);
             loggerAB.debug(MSG);
@@ -135,7 +135,7 @@ public class LoggerTest {
             assertEquals(4, coutingAppender.counter);
             coutingAppender.stop();
         } finally {
-            loggerA.getLogger().removeAppender(coutingAppender);
+            ((org.apache.logging.log4j.core.Logger) loggerA.getLogger()).removeAppender(coutingAppender);
         }
     }
 
@@ -155,8 +155,8 @@ public class LoggerTest {
         ca2.start();
 
         try {
-            a.getLogger().addAppender(ca1);
-            abc.getLogger().addAppender(ca2);
+            ((org.apache.logging.log4j.core.Logger) a.getLogger()).addAppender(ca1);
+            ((org.apache.logging.log4j.core.Logger) abc.getLogger()).addAppender(ca2);
 
             assertEquals(ca1.counter, 0);
             assertEquals(ca2.counter, 0);
@@ -175,8 +175,8 @@ public class LoggerTest {
             ca1.stop();
             ca2.stop();
         } finally {
-            a.getLogger().removeAppender(ca1);
-            abc.getLogger().removeAppender(ca2);
+            ((org.apache.logging.log4j.core.Logger) a.getLogger()).removeAppender(ca1);
+            ((org.apache.logging.log4j.core.Logger) abc.getLogger()).removeAppender(ca2);
         }}
 
     /**
@@ -197,9 +197,9 @@ public class LoggerTest {
         final CountingAppender caABC = new CountingAppender();
         caABC.start();
         try {
-            root.getLogger().addAppender(caRoot);
-            a.getLogger().addAppender(caA);
-            abc.getLogger().addAppender(caABC);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).addAppender(caRoot);
+            ((org.apache.logging.log4j.core.Logger) a.getLogger()).addAppender(caA);
+            ((org.apache.logging.log4j.core.Logger) abc.getLogger()).addAppender(caABC);
 
             assertEquals(caRoot.counter, 0);
             assertEquals(caA.counter, 0);
@@ -225,9 +225,9 @@ public class LoggerTest {
             caA.stop();
             caABC.stop();
         } finally {
-            root.getLogger().removeAppender(caRoot);
-            a.getLogger().removeAppender(caA);
-            abc.getLogger().removeAppender(caABC);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).removeAppender(caRoot);
+            ((org.apache.logging.log4j.core.Logger) a.getLogger()).removeAppender(caA);
+            ((org.apache.logging.log4j.core.Logger) abc.getLogger()).removeAppender(caABC);
         }}
 
     /* Don't support getLoggerRepository
@@ -390,7 +390,7 @@ public class LoggerTest {
         final ListAppender appender = new ListAppender("List");
         appender.start();
         final Logger root = Logger.getRootLogger();
-        root.getLogger().addAppender(appender);
+        ((org.apache.logging.log4j.core.Logger) root.getLogger()).addAppender(appender);
         root.setLevel(Level.INFO);
 
         final Logger tracer = Logger.getLogger("com.example.Tracer");
@@ -406,7 +406,7 @@ public class LoggerTest {
         assertEquals(org.apache.logging.log4j.Level.TRACE, event.getLevel());
         assertEquals("Message 1", event.getMessage().getFormat());
         appender.stop();
-        root.getLogger().removeAppender(appender);
+        ((org.apache.logging.log4j.core.Logger) root.getLogger()).removeAppender(appender);
     }
 
     /**
@@ -418,7 +418,7 @@ public class LoggerTest {
         appender.start();
         final Logger root = Logger.getRootLogger();
         try {
-            root.getLogger().addAppender(appender);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).addAppender(appender);
             root.setLevel(Level.INFO);
 
             final Logger tracer = Logger.getLogger("com.example.Tracer");
@@ -436,7 +436,7 @@ public class LoggerTest {
             assertEquals("Message 1", event.getMessage().getFormattedMessage());
             appender.stop();
         } finally {
-            root.getLogger().removeAppender(appender);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).removeAppender(appender);
         }
     }
 
@@ -449,7 +449,7 @@ public class LoggerTest {
         appender.start();
         final Logger root = Logger.getRootLogger();
         try {
-            root.getLogger().addAppender(appender);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).addAppender(appender);
             root.setLevel(Level.INFO);
 
             final Logger tracer = Logger.getLogger("com.example.Tracer");
@@ -459,7 +459,7 @@ public class LoggerTest {
             assertFalse(root.isTraceEnabled());
             appender.stop();
         } finally {
-            root.getLogger().removeAppender(appender);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).removeAppender(appender);
         }
     }
 
@@ -471,7 +471,7 @@ public class LoggerTest {
         appender.start();
         final Logger root = Logger.getRootLogger();
         try {
-            root.getLogger().addAppender(appender);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).addAppender(appender);
             root.setLevel(Level.INFO);
             final MyLogger log = new MyLogger(root);
             log.logInfo("This is a test", null);
@@ -483,7 +483,7 @@ public class LoggerTest {
             assertTrue("Message contains incorrect class name: " + msg, msg.contains(LoggerTest.class.getName()));
             appender.stop();
         } finally {
-            root.getLogger().removeAppender(appender);
+            ((org.apache.logging.log4j.core.Logger) root.getLogger()).removeAppender(appender);
         }
     }
 
diff --git a/src/site/xdoc/runtime-dependencies.xml b/src/site/xdoc/runtime-dependencies.xml
index 4a5c118..5ce30ff 100644
--- a/src/site/xdoc/runtime-dependencies.xml
+++ b/src/site/xdoc/runtime-dependencies.xml
@@ -314,7 +314,7 @@
       <h4>log4j-1.2-api</h4>
       <p>
         The <a href="log4j-1.2-api/index.html">Log4j 1.2 Bridge</a> has no external dependencies.
-        This only requires the Log4j API and Log4j Core.
+        This only requires the Log4j API. Including Log4j Core provides optional, extra functionality.
       </p>
 
       <a name="log4j-slf4j-impl" />