You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2014/09/02 06:23:44 UTC

[1/4] git commit: Make log4j-core optional for log4j-jdk.

Repository: logging-log4j2
Updated Branches:
  refs/heads/LOG4J2-608 585b18ed1 -> 923ffa30b


Make log4j-core optional for log4j-jdk.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/77be2636
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/77be2636
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/77be2636

Branch: refs/heads/LOG4J2-608
Commit: 77be2636fcd9cc7be6f3e989b3a613c718fb58cc
Parents: 585b18e
Author: Matt Sicker <ma...@apache.org>
Authored: Mon Sep 1 22:09:28 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Mon Sep 1 22:09:28 2014 -0500

----------------------------------------------------------------------
 log4j-jdk/pom.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/77be2636/log4j-jdk/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-jdk/pom.xml b/log4j-jdk/pom.xml
index 0d978f8..116c7ac 100644
--- a/log4j-jdk/pom.xml
+++ b/log4j-jdk/pom.xml
@@ -38,6 +38,7 @@
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
+      <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>


[4/4] git commit: Refactor log4j-jdk to make log4j-core optional.

Posted by ma...@apache.org.
Refactor log4j-jdk to make log4j-core optional.

  - Split into ApiLogger and CoreLogger.
  - LogManager.static takes care of determining which implementation is to be used.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/923ffa30
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/923ffa30
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/923ffa30

Branch: refs/heads/LOG4J2-608
Commit: 923ffa30b4dde3d900bcc9b09cee998391823d0b
Parents: cb65302
Author: Matt Sicker <ma...@apache.org>
Authored: Mon Sep 1 23:23:06 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Mon Sep 1 23:23:06 2014 -0500

----------------------------------------------------------------------
 .../log4j/jdk/AbstractLoggerRegistry.java       |  45 ++++++
 .../org/apache/logging/log4j/jdk/ApiLogger.java | 100 +++++++++++++
 .../logging/log4j/jdk/ApiLoggerRegistry.java    |  34 +++++
 .../apache/logging/log4j/jdk/CoreLogger.java    |  78 +++++++++++
 .../logging/log4j/jdk/CoreLoggerRegistry.java   |  35 +++++
 .../apache/logging/log4j/jdk/LogManager.java    |  27 +++-
 .../org/apache/logging/log4j/jdk/Logger.java    | 140 -------------------
 .../logging/log4j/jdk/LoggerRegistry.java       |  50 -------
 .../logging/log4j/jdk/CoreLoggerTest.java       | 101 +++++++++++++
 .../apache/logging/log4j/jdk/LoggerTest.java    | 101 -------------
 10 files changed, 416 insertions(+), 295 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/AbstractLoggerRegistry.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/AbstractLoggerRegistry.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/AbstractLoggerRegistry.java
new file mode 100644
index 0000000..e1b9394
--- /dev/null
+++ b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/AbstractLoggerRegistry.java
@@ -0,0 +1,45 @@
+/*
+ * 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.jdk;
+
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.spi.AbstractExternalLoggerContextRegistry;
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * Abstract Logger registry. Due to the optionality of using log4j-core, there are two registries available at runtime
+ * to create: {@link ApiLoggerRegistry} and {@link CoreLoggerRegistry}.
+ *
+ * @since 2.1
+ */
+public abstract class AbstractLoggerRegistry extends AbstractExternalLoggerContextRegistry<Logger> {
+
+    @Override
+    public LoggerContext getContext() {
+        return PrivateManager.getContext();
+    }
+
+    private static class PrivateManager extends org.apache.logging.log4j.LogManager {
+        private static final String FQCN = java.util.logging.LogManager.class.getName();
+
+        public static LoggerContext getContext() {
+            return getContext(FQCN, false);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLogger.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLogger.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLogger.java
new file mode 100644
index 0000000..6beffc9
--- /dev/null
+++ b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLogger.java
@@ -0,0 +1,100 @@
+/*
+ * 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.jdk;
+
+import java.util.logging.Filter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+
+/**
+ * Log4j API implementation of the JUL {@link Logger} class. <strong>Note that this implementation does
+ * <em>not</em> use the {@link java.util.logging.Handler} class.</strong> Instead, logging is delegated to the
+ * underlying Log4j {@link org.apache.logging.log4j.Logger} which may be implemented in one of many different ways.
+ * Consult the documentation for your Log4j Provider for more details.
+ * <p>Note that the methods {@link #getParent()} and {@link #setLevel(java.util.logging.Level)} are not supported by
+ * this implementation. If you need support for these methods, then you'll need to use log4j-core.</p>
+ */
+public class ApiLogger extends Logger {
+
+    private static final String FQCN = java.util.logging.Logger.class.getName();
+
+    private static final String PREFIX = "log4j.jul.";
+
+    /**
+     * The {@link org.apache.logging.log4j.ThreadContext} key where the value of {@link java.util.logging.LogRecord#getThreadID()} will be stored.
+     */
+    public static final String THREAD_ID = PREFIX + "threadID";
+
+    /**
+     * The {@link org.apache.logging.log4j.ThreadContext} key where the value of {@link java.util.logging.LogRecord#getSequenceNumber()} will be stored.
+     */
+    public static final String SEQUENCE_NUMBER = PREFIX + "sequenceNumber";
+
+    /**
+     * The {@link org.apache.logging.log4j.ThreadContext} key where the name of the {@link java.util.logging.Level} will be stored. This is particularly useful
+     * for custom Level implementations as well as for obtaining the exact Level that was used rather than the
+     * equivalent Log4j {@link org.apache.logging.log4j.Level}.
+     */
+    public static final String LEVEL = PREFIX + "level";
+
+    private final ExtendedLogger logger;
+
+    ApiLogger(final ExtendedLogger logger) {
+        super(logger.getName(), null);
+        super.setLevel(Levels.toJavaLevel(logger.getLevel()));
+        this.logger = logger;
+    }
+
+    @Override
+    public void log(final LogRecord record) {
+        if (isFiltered(record)) {
+            return;
+        }
+        ThreadContext.put(THREAD_ID, Integer.toString(record.getThreadID()));
+        ThreadContext.put(SEQUENCE_NUMBER, Long.toString(record.getSequenceNumber()));
+        ThreadContext.put(LEVEL, record.getLevel().getName());
+        final org.apache.logging.log4j.Level level = Levels.toLevel(record.getLevel());
+        final Message message = logger.getMessageFactory().newMessage(record.getMessage(), record.getParameters());
+        final Throwable thrown = record.getThrown();
+        logger.logIfEnabled(FQCN, level, null, message, thrown);
+        ThreadContext.remove(THREAD_ID);
+        ThreadContext.remove(SEQUENCE_NUMBER);
+        ThreadContext.remove(LEVEL);
+    }
+
+    // support for Logger.getFilter()/Logger.setFilter()
+    boolean isFiltered(final LogRecord logRecord) {
+        final Filter filter = getFilter();
+        return filter != null && !filter.isLoggable(logRecord);
+    }
+
+    @Override
+    public boolean isLoggable(final Level level) {
+        return logger.isEnabled(Levels.toLevel(level));
+    }
+
+    @Override
+    public String getName() {
+        return logger.getName();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLoggerRegistry.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLoggerRegistry.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLoggerRegistry.java
new file mode 100644
index 0000000..bd259a0
--- /dev/null
+++ b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/ApiLoggerRegistry.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.logging.log4j.jdk;
+
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * {@link Logger} registry implementation using just log4j-api. This is the fallback registry used when log4j-core is
+ * not available.
+ *
+ * @since 2.1
+ */
+public class ApiLoggerRegistry extends AbstractLoggerRegistry {
+    @Override
+    public Logger newLogger(final String name, final LoggerContext context) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLogger.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLogger.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLogger.java
new file mode 100644
index 0000000..60ff82f
--- /dev/null
+++ b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLogger.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.jdk;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Log4j Core implementation of the JUL {@link Logger} class. <strong>Note that this implementation does
+ * <em>not</em> use the {@link java.util.logging.Handler} class.</strong> Instead, logging is delegated to the
+ * underlying Log4j {@link org.apache.logging.log4j.core.Logger} which uses
+ * {@link org.apache.logging.log4j.core.Appender Appenders} instead.
+ *
+ * @since 2.1
+ */
+public class CoreLogger extends ApiLogger {
+
+    private final org.apache.logging.log4j.core.Logger logger;
+
+    /**
+     * Constructs a Logger using a Log4j {@link org.apache.logging.log4j.core.Logger}.
+     *
+     * @param logger the underlying Logger to base this Logger on
+     */
+    CoreLogger(final org.apache.logging.log4j.core.Logger logger) {
+        super(logger);
+        this.logger = logger;
+    }
+
+    @Override
+    public void setLevel(final Level level) throws SecurityException {
+        logger.setLevel(Levels.toLevel(level));
+        super.setLevel(level);
+    }
+
+    /**
+     * Marks the underlying {@link org.apache.logging.log4j.core.Logger} as additive.
+     *
+     * @param additive {@code true} if this Logger should be additive
+     * @see org.apache.logging.log4j.core.Logger#setAdditive(boolean)
+     */
+    @Override
+    public synchronized void setUseParentHandlers(final boolean additive) {
+        logger.setAdditive(additive);
+    }
+
+    /**
+     * Indicates if the underlying {@link org.apache.logging.log4j.core.Logger} is additive. <strong>Note that the
+     * Log4j version of JDK Loggers do <em>not</em> use Handlers.</strong>
+     *
+     * @return {@code true} if this Logger is additive, or {@code false} otherwise
+     * @see org.apache.logging.log4j.core.Logger#isAdditive()
+     */
+    @Override
+    public synchronized boolean getUseParentHandlers() {
+        return logger.isAdditive();
+    }
+
+    @Override
+    public Logger getParent() {
+        final org.apache.logging.log4j.core.Logger parent = logger.getParent();
+        return parent == null ? null : Logger.getLogger(parent.getName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLoggerRegistry.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLoggerRegistry.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLoggerRegistry.java
new file mode 100644
index 0000000..8c842b2
--- /dev/null
+++ b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/CoreLoggerRegistry.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.jdk;
+
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.spi.LoggerContext;
+
+/**
+ * {@link Logger} registry implementation that uses log4j-core.
+ *
+ * @since 2.1
+ */
+public class CoreLoggerRegistry extends AbstractLoggerRegistry {
+
+    @Override
+    public Logger newLogger(final String name, final LoggerContext context) {
+        return new CoreLogger((org.apache.logging.log4j.core.Logger) context.getLogger(name));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LogManager.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LogManager.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LogManager.java
index fa25f95..b6f6e3e 100644
--- a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LogManager.java
+++ b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LogManager.java
@@ -22,11 +22,13 @@ import java.util.logging.Logger;
 
 import org.apache.logging.log4j.spi.ExternalLoggerContextRegistry;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LoaderUtil;
 
 /**
  * Log4j implementation of {@link java.util.logging.LogManager}. Note that the system property
  * {@code java.util.logging.manager} must be set to {@code org.apache.logging.log4j.jdk.LogManager} in order to use
- * this adaptor. This LogManager requires the {@code log4j-core} library to be available as well as {@code log4j-api}.
+ * this adaptor. This LogManager requires the {@code log4j-api} library to be available. If {@code log4j-core} is
+ * also available, then more features of {@link java.util.logging.Logger} are supported.
  *
  * @since 2.1
  */
@@ -34,7 +36,24 @@ public class LogManager extends java.util.logging.LogManager {
 
     private static final org.apache.logging.log4j.Logger LOGGER = StatusLogger.getLogger();
 
-    private final ExternalLoggerContextRegistry<Logger> registry = new LoggerRegistry();
+    static {
+        // find out if log4j-core is available
+        String registryClassName;
+        try {
+            LoaderUtil.loadClass("org.apache.logging.log4j.core.Logger");
+            registryClassName = "org.apache.logging.log4j.jdk.CoreLoggerRegistry";
+        } catch (final ClassNotFoundException ignored) {
+            registryClassName = "org.apache.logging.log4j.jdk.ApiLoggerRegistry";
+        }
+        LOGGER.debug("Attempting to use {}", registryClassName);
+        try {
+            REGISTRY = LoaderUtil.newCheckedInstanceOf(registryClassName, AbstractLoggerRegistry.class);
+        } catch (final Exception e) {
+            throw LOGGER.throwing(new ExceptionInInitializerError(e));
+        }
+    }
+
+    private static final ExternalLoggerContextRegistry<Logger> REGISTRY;
 
     public LogManager() {
         super();
@@ -51,12 +70,12 @@ public class LogManager extends java.util.logging.LogManager {
     @Override
     public Logger getLogger(final String name) {
         LOGGER.trace("Call to LogManager.getLogger({})", name);
-        return registry.getLogger(name);
+        return REGISTRY.getLogger(name);
     }
 
     @Override
     public Enumeration<String> getLoggerNames() {
-        return Collections.enumeration(registry.getLoggersInContext(registry.getContext()).keySet());
+        return Collections.enumeration(REGISTRY.getLoggersInContext(REGISTRY.getContext()).keySet());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/Logger.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/Logger.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/Logger.java
deleted file mode 100644
index c311822..0000000
--- a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/Logger.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * 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.jdk;
-
-import java.util.logging.Filter;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-
-import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.core.util.Assert;
-import org.apache.logging.log4j.message.Message;
-
-/**
- * Log4j implementation of the JUL {@link java.util.logging.Logger} class. <strong>Note that this implementation does
- * <em>not</em> use the {@link java.util.logging.Handler} class.</strong> Instead, logging is delegated to the
- * underlying Log4j {@link org.apache.logging.log4j.core.Logger} which uses
- * {@link org.apache.logging.log4j.core.Appender Appenders} instead.
- *
- * @since 2.1
- */
-public class Logger extends java.util.logging.Logger {
-
-    private static final String FQCN = java.util.logging.Logger.class.getName();
-
-    private static final String PREFIX = "log4j.jul.";
-
-    /**
-     * The {@link ThreadContext} key where the value of {@link LogRecord#getThreadID()} will be stored.
-     */
-    public static final String THREAD_ID = PREFIX + "threadID";
-
-    /**
-     * The {@link ThreadContext} key where the value of {@link LogRecord#getSequenceNumber()} will be stored.
-     */
-    public static final String SEQUENCE_NUMBER = PREFIX + "sequenceNumber";
-
-    /**
-     * The {@link ThreadContext} key where the name of the {@link Level} will be stored. This is particularly useful
-     * for custom Level implementations as well as for obtaining the exact Level that was used rather than the
-     * equivalent Log4j {@link org.apache.logging.log4j.Level}.
-     */
-    public static final String LEVEL = PREFIX + "level";
-
-    private final org.apache.logging.log4j.core.Logger logger;
-
-    /**
-     * Constructs a Logger using a Log4j {@link org.apache.logging.log4j.core.Logger}.
-     *
-     * @param logger the underlying Logger to base this Logger on
-     */
-    Logger(final org.apache.logging.log4j.core.Logger logger) {
-        super(Assert.requireNonNull(logger, "No Logger provided").getName(), null);
-        super.setLevel(Levels.toJavaLevel(logger.getLevel()));
-        this.logger = logger;
-    }
-
-    @Override
-    public void log(final LogRecord record) {
-        if (isFiltered(record)) {
-            return;
-        }
-        ThreadContext.put(THREAD_ID, Integer.toString(record.getThreadID()));
-        ThreadContext.put(SEQUENCE_NUMBER, Long.toString(record.getSequenceNumber()));
-        ThreadContext.put(LEVEL, record.getLevel().getName());
-        final org.apache.logging.log4j.Level level = Levels.toLevel(record.getLevel());
-        final Message message = logger.getMessageFactory().newMessage(record.getMessage(), record.getParameters());
-        final Throwable thrown = record.getThrown();
-        // TODO: may want to use LoggerConfig.log(LogEvent) with a LogRecord/LogEvent hybrid
-        logger.logIfEnabled(FQCN, level, null, message, thrown);
-        // TODO: support handlers?
-        ThreadContext.remove(THREAD_ID);
-        ThreadContext.remove(SEQUENCE_NUMBER);
-        ThreadContext.remove(LEVEL);
-    }
-
-    // support for Logger.getFilter()/Logger.setFilter()
-    private boolean isFiltered(final LogRecord logRecord) {
-        final Filter filter = getFilter();
-        return filter != null && !filter.isLoggable(logRecord);
-    }
-
-    @Override
-    public void setLevel(final Level level) throws SecurityException {
-        logger.setLevel(Levels.toLevel(level));
-        super.setLevel(level);
-    }
-
-    @Override
-    public boolean isLoggable(final Level level) {
-        return logger.isEnabled(Levels.toLevel(level));
-    }
-
-    @Override
-    public String getName() {
-        return logger.getName();
-    }
-
-    /**
-     * Marks the underlying {@link org.apache.logging.log4j.core.Logger} as additive.
-     *
-     * @param additive {@code true} if this Logger should be additive
-     * @see org.apache.logging.log4j.core.Logger#setAdditive(boolean)
-     */
-    @Override
-    public synchronized void setUseParentHandlers(final boolean additive) {
-        logger.setAdditive(additive);
-    }
-
-    /**
-     * Indicates if the underlying {@link org.apache.logging.log4j.core.Logger} is additive. <strong>Note that the
-     * Log4j version of JDK Loggers do <em>not</em> use Handlers.</strong>
-     *
-     * @return {@code true} if this Logger is additive, or {@code false} otherwise
-     * @see org.apache.logging.log4j.core.Logger#isAdditive()
-     */
-    @Override
-    public synchronized boolean getUseParentHandlers() {
-        return logger.isAdditive();
-    }
-
-    @Override
-    public java.util.logging.Logger getParent() {
-        final org.apache.logging.log4j.core.Logger parent = logger.getParent();
-        return parent == null ? null : java.util.logging.Logger.getLogger(parent.getName());
-    }
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LoggerRegistry.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LoggerRegistry.java b/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LoggerRegistry.java
deleted file mode 100644
index 7ba2d7a..0000000
--- a/log4j-jdk/src/main/java/org/apache/logging/log4j/jdk/LoggerRegistry.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.jdk;
-
-import java.util.logging.Logger;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.spi.AbstractExternalLoggerContextRegistry;
-import org.apache.logging.log4j.spi.LoggerContext;
-
-/**
- * {@link Logger} registry implementation.
- *
- * @since 2.1
- */
-public class LoggerRegistry extends AbstractExternalLoggerContextRegistry<Logger> {
-
-    @Override
-    public Logger newLogger(final String name, final LoggerContext context) {
-        return new org.apache.logging.log4j.jdk.Logger((org.apache.logging.log4j.core.Logger) context.getLogger(name));
-    }
-
-    @Override
-    public LoggerContext getContext() {
-        return PrivateManager.getContext();
-    }
-
-    private static class PrivateManager extends LogManager {
-        private static final String FQCN = java.util.logging.LogManager.class.getName();
-
-        public static LoggerContext getContext() {
-            return getContext(FQCN, false);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/CoreLoggerTest.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/CoreLoggerTest.java b/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/CoreLoggerTest.java
new file mode 100644
index 0000000..16d5831
--- /dev/null
+++ b/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/CoreLoggerTest.java
@@ -0,0 +1,101 @@
+package org.apache.logging.log4j.jdk;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.*;
+
+public class CoreLoggerTest {
+
+    public static final String LOGGER_NAME = "Test";
+    private Logger logger;
+    private ListAppender eventAppender;
+    private ListAppender stringAppender;
+
+    @BeforeClass
+    public static void setUpClass() {
+        System.setProperty("java.util.logging.manager", LogManager.class.getName());
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        logger = Logger.getLogger(LOGGER_NAME);
+        assertThat(logger.getLevel(), equalTo(java.util.logging.Level.FINE));
+        eventAppender = ListAppender.getListAppender("TestAppender");
+        stringAppender = ListAppender.getListAppender("StringAppender");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        eventAppender.clear();
+    }
+
+    @Test
+    public void testLog() throws Exception {
+        logger.info("Informative message here.");
+        final List<LogEvent> events = eventAppender.getEvents();
+        assertThat(events, hasSize(1));
+        final LogEvent event = events.get(0);
+        assertThat(event, instanceOf(Log4jLogEvent.class));
+        assertEquals(Level.INFO, event.getLevel());
+        assertEquals(LOGGER_NAME, event.getLoggerName());
+        assertEquals("Informative message here.", event.getMessage().getFormattedMessage());
+        assertEquals(Logger.class.getName(), event.getLoggerFqcn());
+    }
+
+    @Test
+    public void testLogWithCallingClass() throws Exception {
+        final Logger log = Logger.getLogger("Test.CallerClass");
+        log.config("Calling from LoggerTest");
+        final List<String> messages = stringAppender.getMessages();
+        assertThat(messages, hasSize(1));
+        final String message = messages.get(0);
+        assertEquals(getClass().getName(), message);
+    }
+
+    @Test
+    public void testLogUsingCustomLevel() throws Exception {
+        logger.log(CustomJdkLevel.TEST, "Test level");
+        final List<LogEvent> events = eventAppender.getEvents();
+        assertThat(events, hasSize(1));
+        final LogEvent event = events.get(0);
+        assertThat(event.getLevel(), equalTo(Level.INFO));
+        final String levelName = event.getContextMap().get(ApiLogger.LEVEL);
+        assertThat(levelName, equalTo(CustomJdkLevel.TEST.getName()));
+    }
+
+    @Test
+    public void testSetLevel() throws Exception {
+        logger.setLevel(java.util.logging.Level.SEVERE);
+        assertThat(logger.getLevel(), equalTo(java.util.logging.Level.SEVERE));
+    }
+
+    @Test
+    public void testIsLoggable() throws Exception {
+        assertThat(logger.isLoggable(java.util.logging.Level.SEVERE), equalTo(true));
+        assertThat(logger.isLoggable(CustomJdkLevel.DEFCON_1), equalTo(true));
+    }
+
+    @Test
+    public void testGetName() throws Exception {
+        assertThat(logger.getName(), equalTo(LOGGER_NAME));
+    }
+
+    @Test
+    public void testGlobalLoggerName() throws Exception {
+        final Logger root = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+        assertThat(root.getName(), equalTo(Logger.GLOBAL_LOGGER_NAME));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/923ffa30/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/LoggerTest.java
----------------------------------------------------------------------
diff --git a/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/LoggerTest.java b/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/LoggerTest.java
deleted file mode 100644
index 007e3a6..0000000
--- a/log4j-jdk/src/test/java/org/apache/logging/log4j/jdk/LoggerTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.apache.logging.log4j.jdk;
-
-import java.util.List;
-import java.util.logging.Logger;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.test.appender.ListAppender;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.*;
-
-public class LoggerTest {
-
-    public static final String LOGGER_NAME = "Test";
-    private Logger logger;
-    private ListAppender eventAppender;
-    private ListAppender stringAppender;
-
-    @BeforeClass
-    public static void setUpClass() {
-        System.setProperty("java.util.logging.manager", LogManager.class.getName());
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        logger = Logger.getLogger(LOGGER_NAME);
-        assertThat(logger.getLevel(), equalTo(java.util.logging.Level.FINE));
-        eventAppender = ListAppender.getListAppender("TestAppender");
-        stringAppender = ListAppender.getListAppender("StringAppender");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        eventAppender.clear();
-    }
-
-    @Test
-    public void testLog() throws Exception {
-        logger.info("Informative message here.");
-        final List<LogEvent> events = eventAppender.getEvents();
-        assertThat(events, hasSize(1));
-        final LogEvent event = events.get(0);
-        assertThat(event, instanceOf(Log4jLogEvent.class));
-        assertEquals(Level.INFO, event.getLevel());
-        assertEquals(LOGGER_NAME, event.getLoggerName());
-        assertEquals("Informative message here.", event.getMessage().getFormattedMessage());
-        assertEquals(Logger.class.getName(), event.getLoggerFqcn());
-    }
-
-    @Test
-    public void testLogWithCallingClass() throws Exception {
-        final Logger log = Logger.getLogger("Test.CallerClass");
-        log.config("Calling from LoggerTest");
-        final List<String> messages = stringAppender.getMessages();
-        assertThat(messages, hasSize(1));
-        final String message = messages.get(0);
-        assertEquals(getClass().getName(), message);
-    }
-
-    @Test
-    public void testLogUsingCustomLevel() throws Exception {
-        logger.log(CustomJdkLevel.TEST, "Test level");
-        final List<LogEvent> events = eventAppender.getEvents();
-        assertThat(events, hasSize(1));
-        final LogEvent event = events.get(0);
-        assertThat(event.getLevel(), equalTo(Level.INFO));
-        final String levelName = event.getContextMap().get(org.apache.logging.log4j.jdk.Logger.LEVEL);
-        assertThat(levelName, equalTo(CustomJdkLevel.TEST.getName()));
-    }
-
-    @Test
-    public void testSetLevel() throws Exception {
-        logger.setLevel(java.util.logging.Level.SEVERE);
-        assertThat(logger.getLevel(), equalTo(java.util.logging.Level.SEVERE));
-    }
-
-    @Test
-    public void testIsLoggable() throws Exception {
-        assertThat(logger.isLoggable(java.util.logging.Level.SEVERE), equalTo(true));
-        assertThat(logger.isLoggable(CustomJdkLevel.DEFCON_1), equalTo(true));
-    }
-
-    @Test
-    public void testGetName() throws Exception {
-        assertThat(logger.getName(), equalTo(LOGGER_NAME));
-    }
-
-    @Test
-    public void testGlobalLoggerName() throws Exception {
-        final Logger root = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
-        assertThat(root.getName(), equalTo(Logger.GLOBAL_LOGGER_NAME));
-    }
-}
\ No newline at end of file


Re: [2/4] git commit: Migrate more methods from Loader to LoaderUtil.

Posted by Matt Sicker <bo...@gmail.com>.
http://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties

The current value is indeed the TCL version. I just migrated it. Perhaps
both properties should be supported?

On 2 September 2014 10:32, Gary Gregory <ga...@gmail.com> wrote:

> WRT:
>
>
>
> +    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
>
> Should this be:
>
>
> +    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCCL";
>
> ?
>
> Gary
>
> ---------- Forwarded message ----------
> From: <ma...@apache.org>
> Date: Tue, Sep 2, 2014 at 12:23 AM
> Subject: [2/4] git commit: Migrate more methods from Loader to LoaderUtil.
> To: commits@logging.apache.org
>
>
> Migrate more methods from Loader to LoaderUtil.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
> Commit:
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2a962372
> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2a962372
> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2a962372
>
> Branch: refs/heads/LOG4J2-608
> Commit: 2a96237253823285c90f0c97e4ea4070c6522117
> Parents: 77be263
> Author: Matt Sicker <ma...@apache.org>
> Authored: Mon Sep 1 22:40:29 2014 -0500
> Committer: Matt Sicker <ma...@apache.org>
> Committed: Mon Sep 1 22:40:29 2014 -0500
>
> ----------------------------------------------------------------------
>  .../apache/logging/log4j/util/LoaderUtil.java   | 68 ++++++++++++++++++++
>  .../apache/logging/log4j/core/util/Loader.java  | 37 +----------
>  2 files changed, 71 insertions(+), 34 deletions(-)
> ----------------------------------------------------------------------
>
>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2a962372/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
> ----------------------------------------------------------------------
> diff --git
> a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
> b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
> index 32b23c4..0771054 100644
> --- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
> +++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
> @@ -16,6 +16,7 @@
>   */
>  package org.apache.logging.log4j.util;
>
> +import java.lang.reflect.InvocationTargetException;
>  import java.security.AccessController;
>  import java.security.PrivilegedAction;
>
> @@ -28,6 +29,10 @@ import java.security.PrivilegedAction;
>  public final class LoaderUtil {
>      private LoaderUtil() {}
>
> +    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
> +
> +    private static final boolean IGNORE_TCCL;
> +
>      private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new
> ThreadContextClassLoaderGetter();
>
>      static {
> @@ -35,6 +40,8 @@ public final class LoaderUtil {
>          if (sm != null) {
>              sm.checkPermission(new RuntimePermission("getClassLoader"));
>          }
> +        final String ignoreTccl =
> PropertiesUtil.getProperties().getStringProperty(IGNORE_TCCL_PROPERTY,
> null);
> +        IGNORE_TCCL = ignoreTccl != null &&
> !"false".equalsIgnoreCase(ignoreTccl.trim());
>      }
>
>      /**
> @@ -56,4 +63,65 @@ public final class LoaderUtil {
>              return cl == null ? ClassLoader.getSystemClassLoader() : cl;
>          }
>      }
> +
> +    /**
> +     * Loads a class by name. This method respects the {@link
> #IGNORE_TCCL_PROPERTY} Log4j property. If this property
> +     * is specified and set to anything besides {@code false}, then the
> default ClassLoader will be used.
> +     *
> +     * @param className The class name.
> +     * @return the Class for the given name.
> +     * @throws ClassNotFoundException if the specified class name could
> not be found
> +     */
> +    public static Class<?> loadClass(final String className) throws
> ClassNotFoundException {
> +        if (IGNORE_TCCL) {
> +            return Class.forName(className);
> +        }
> +        try {
> +            return getThreadContextClassLoader().loadClass(className);
> +        } catch (final Throwable e) {
> +            return Class.forName(className);
> +        }
> +    }
> +
> +    /**
> +     * Loads and instantiates a Class using the default constructor.
> +     *
> +     * @param className The class name.
> +     * @return new instance of the class.
> +     * @throws ClassNotFoundException    if the class isn't available to
> the usual ClassLoaders
> +     * @throws IllegalAccessException    if the class can't be
> instantiated through a public constructor
> +     * @throws InstantiationException    if there was an exception whilst
> instantiating the class
> +     * @throws NoSuchMethodException     if there isn't a no-args
> constructor on the class
> +     * @throws InvocationTargetException if there was an exception whilst
> constructing the class
> +     */
> +    public static Object newInstanceOf(final String className)
> +        throws ClassNotFoundException, IllegalAccessException,
> InstantiationException, NoSuchMethodException,
> +        InvocationTargetException {
> +        final Class<?> clazz = loadClass(className);
> +        try {
> +            return clazz.getConstructor().newInstance();
> +        } catch (final NoSuchMethodException e) {
> +            return clazz.newInstance();
> +        }
> +    }
> +
> +    /**
> +     * Loads and instantiates a derived class using its default
> constructor.
> +     *
> +     * @param className The class name.
> +     * @param clazz The class to cast it to.
> +     * @param <T> The type of the class to check.
> +     * @return new instance of the class cast to {@code T}
> +     * @throws ClassNotFoundException if the class isn't available to the
> usual ClassLoaders
> +     * @throws IllegalAccessException if the class can't be instantiated
> through a public constructor
> +     * @throws InstantiationException if there was an exception whilst
> instantiating the class
> +     * @throws NoSuchMethodException if there isn't a no-args constructor
> on the class
> +     * @throws InvocationTargetException if there was an exception whilst
> constructing the class
> +     * @throws ClassCastException if the constructed object isn't type
> compatible with {@code T}
> +     */
> +    public static <T> T newCheckedInstanceOf(final String className,
> final Class<T> clazz)
> +        throws ClassNotFoundException, NoSuchMethodException,
> InvocationTargetException, InstantiationException,
> +        IllegalAccessException {
> +        return clazz.cast(newInstanceOf(className));
> +    }
>  }
>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2a962372/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
> ----------------------------------------------------------------------
> diff --git
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
> index 2fa70bb..9858d4e 100644
> ---
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
> +++
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
> @@ -25,24 +25,17 @@ import java.net.URL;
>  import org.apache.logging.log4j.Logger;
>  import org.apache.logging.log4j.status.StatusLogger;
>  import org.apache.logging.log4j.util.LoaderUtil;
> -import org.apache.logging.log4j.util.PropertiesUtil;
>
>  /**
>   * Load resources (or images) from various sources.
>   */
>  public final class Loader {
>
> -    private static boolean ignoreTCL = false;
> -
>      private static final Logger LOGGER = StatusLogger.getLogger();
>
>      private static final String TSTR = "Caught Exception while in
> Loader.getResource. This may be innocuous.";
>
>      static {
> -        final String ignoreTCLProp =
> PropertiesUtil.getProperties().getStringProperty("log4j.ignoreTCL", null);
> -        if (ignoreTCLProp != null) {
> -            ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);
> -        }
>          final SecurityManager sm = System.getSecurityManager();
>          if (sm != null) {
>              sm.checkPermission(new RuntimePermission("getStackTrace"));
> @@ -55,7 +48,6 @@ public final class Loader {
>       * @return the ClassLoader.
>       */
>      public static ClassLoader getClassLoader() {
> -
>          return getClassLoader(Loader.class, null);
>      }
>
> @@ -248,23 +240,7 @@ public final class Loader {
>       * @throws ClassNotFoundException if the Class could not be found.
>       */
>      public static Class<?> loadClass(final String className) throws
> ClassNotFoundException {
> -        // Just call Class.forName(className) if we are instructed to
> ignore the TCL.
> -        if (ignoreTCL) {
> -            LOGGER.trace("Ignoring TCCL. Trying Class.forName({}).",
> className);
> -            return loadClassWithDefaultClassLoader(className);
> -        }
> -        try {
> -            LOGGER.trace("Trying TCCL for class {}.", className);
> -            // using the TCCL should work the same as the default
> ClassLoader (i.e., init or not)
> -            return Class.forName(className, true, getTcl());
> -        } catch (final Throwable e) {
> -            LOGGER.trace("TCCL didn't work for class {}: {}.", className,
> e.toString());
> -            return loadClassWithDefaultClassLoader(className);
> -        }
> -    }
> -
> -    private static Class<?> loadClassWithDefaultClassLoader(final String
> className) throws ClassNotFoundException {
> -        return Class.forName(className);
> +        return LoaderUtil.loadClass(className);
>      }
>
>      /**
> @@ -314,14 +290,7 @@ public final class Loader {
>                     InstantiationException,
>                     NoSuchMethodException,
>                     InvocationTargetException {
> -        final Class<?> clazz = loadClass(className);
> -        try {
> -            return clazz.getConstructor().newInstance();
> -        } catch (final NoSuchMethodException e) {
> -            // try the default-default constructor
> -            //noinspection ClassNewInstance
> -            return clazz.newInstance();
> -        }
> +        return LoaderUtil.newInstanceOf(className);
>      }
>
>      /**
> @@ -344,7 +313,7 @@ public final class Loader {
>                     IllegalAccessException,
>                     InvocationTargetException,
>                     InstantiationException {
> -        return clazz.cast(newInstanceOf(className));
> +        return LoaderUtil.newCheckedInstanceOf(className, clazz);
>      }
>
>      /**
>
>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>



-- 
Matt Sicker <bo...@gmail.com>

Fwd: [2/4] git commit: Migrate more methods from Loader to LoaderUtil.

Posted by Gary Gregory <ga...@gmail.com>.
WRT:


+    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";

Should this be:


+    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCCL";

?

Gary

---------- Forwarded message ----------
From: <ma...@apache.org>
Date: Tue, Sep 2, 2014 at 12:23 AM
Subject: [2/4] git commit: Migrate more methods from Loader to LoaderUtil.
To: commits@logging.apache.org


Migrate more methods from Loader to LoaderUtil.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit:
http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2a962372
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2a962372
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2a962372

Branch: refs/heads/LOG4J2-608
Commit: 2a96237253823285c90f0c97e4ea4070c6522117
Parents: 77be263
Author: Matt Sicker <ma...@apache.org>
Authored: Mon Sep 1 22:40:29 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Mon Sep 1 22:40:29 2014 -0500

----------------------------------------------------------------------
 .../apache/logging/log4j/util/LoaderUtil.java   | 68 ++++++++++++++++++++
 .../apache/logging/log4j/core/util/Loader.java  | 37 +----------
 2 files changed, 71 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2a962372/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
----------------------------------------------------------------------
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
index 32b23c4..0771054 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.util;

+import java.lang.reflect.InvocationTargetException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;

@@ -28,6 +29,10 @@ import java.security.PrivilegedAction;
 public final class LoaderUtil {
     private LoaderUtil() {}

+    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
+
+    private static final boolean IGNORE_TCCL;
+
     private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new
ThreadContextClassLoaderGetter();

     static {
@@ -35,6 +40,8 @@ public final class LoaderUtil {
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("getClassLoader"));
         }
+        final String ignoreTccl =
PropertiesUtil.getProperties().getStringProperty(IGNORE_TCCL_PROPERTY,
null);
+        IGNORE_TCCL = ignoreTccl != null &&
!"false".equalsIgnoreCase(ignoreTccl.trim());
     }

     /**
@@ -56,4 +63,65 @@ public final class LoaderUtil {
             return cl == null ? ClassLoader.getSystemClassLoader() : cl;
         }
     }
+
+    /**
+     * Loads a class by name. This method respects the {@link
#IGNORE_TCCL_PROPERTY} Log4j property. If this property
+     * is specified and set to anything besides {@code false}, then the
default ClassLoader will be used.
+     *
+     * @param className The class name.
+     * @return the Class for the given name.
+     * @throws ClassNotFoundException if the specified class name could
not be found
+     */
+    public static Class<?> loadClass(final String className) throws
ClassNotFoundException {
+        if (IGNORE_TCCL) {
+            return Class.forName(className);
+        }
+        try {
+            return getThreadContextClassLoader().loadClass(className);
+        } catch (final Throwable e) {
+            return Class.forName(className);
+        }
+    }
+
+    /**
+     * Loads and instantiates a Class using the default constructor.
+     *
+     * @param className The class name.
+     * @return new instance of the class.
+     * @throws ClassNotFoundException    if the class isn't available to
the usual ClassLoaders
+     * @throws IllegalAccessException    if the class can't be
instantiated through a public constructor
+     * @throws InstantiationException    if there was an exception whilst
instantiating the class
+     * @throws NoSuchMethodException     if there isn't a no-args
constructor on the class
+     * @throws InvocationTargetException if there was an exception whilst
constructing the class
+     */
+    public static Object newInstanceOf(final String className)
+        throws ClassNotFoundException, IllegalAccessException,
InstantiationException, NoSuchMethodException,
+        InvocationTargetException {
+        final Class<?> clazz = loadClass(className);
+        try {
+            return clazz.getConstructor().newInstance();
+        } catch (final NoSuchMethodException e) {
+            return clazz.newInstance();
+        }
+    }
+
+    /**
+     * Loads and instantiates a derived class using its default
constructor.
+     *
+     * @param className The class name.
+     * @param clazz The class to cast it to.
+     * @param <T> The type of the class to check.
+     * @return new instance of the class cast to {@code T}
+     * @throws ClassNotFoundException if the class isn't available to the
usual ClassLoaders
+     * @throws IllegalAccessException if the class can't be instantiated
through a public constructor
+     * @throws InstantiationException if there was an exception whilst
instantiating the class
+     * @throws NoSuchMethodException if there isn't a no-args constructor
on the class
+     * @throws InvocationTargetException if there was an exception whilst
constructing the class
+     * @throws ClassCastException if the constructed object isn't type
compatible with {@code T}
+     */
+    public static <T> T newCheckedInstanceOf(final String className, final
Class<T> clazz)
+        throws ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, InstantiationException,
+        IllegalAccessException {
+        return clazz.cast(newInstanceOf(className));
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2a962372/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
----------------------------------------------------------------------
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
index 2fa70bb..9858d4e 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
@@ -25,24 +25,17 @@ import java.net.URL;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.LoaderUtil;
-import org.apache.logging.log4j.util.PropertiesUtil;

 /**
  * Load resources (or images) from various sources.
  */
 public final class Loader {

-    private static boolean ignoreTCL = false;
-
     private static final Logger LOGGER = StatusLogger.getLogger();

     private static final String TSTR = "Caught Exception while in
Loader.getResource. This may be innocuous.";

     static {
-        final String ignoreTCLProp =
PropertiesUtil.getProperties().getStringProperty("log4j.ignoreTCL", null);
-        if (ignoreTCLProp != null) {
-            ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);
-        }
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("getStackTrace"));
@@ -55,7 +48,6 @@ public final class Loader {
      * @return the ClassLoader.
      */
     public static ClassLoader getClassLoader() {
-
         return getClassLoader(Loader.class, null);
     }

@@ -248,23 +240,7 @@ public final class Loader {
      * @throws ClassNotFoundException if the Class could not be found.
      */
     public static Class<?> loadClass(final String className) throws
ClassNotFoundException {
-        // Just call Class.forName(className) if we are instructed to
ignore the TCL.
-        if (ignoreTCL) {
-            LOGGER.trace("Ignoring TCCL. Trying Class.forName({}).",
className);
-            return loadClassWithDefaultClassLoader(className);
-        }
-        try {
-            LOGGER.trace("Trying TCCL for class {}.", className);
-            // using the TCCL should work the same as the default
ClassLoader (i.e., init or not)
-            return Class.forName(className, true, getTcl());
-        } catch (final Throwable e) {
-            LOGGER.trace("TCCL didn't work for class {}: {}.", className,
e.toString());
-            return loadClassWithDefaultClassLoader(className);
-        }
-    }
-
-    private static Class<?> loadClassWithDefaultClassLoader(final String
className) throws ClassNotFoundException {
-        return Class.forName(className);
+        return LoaderUtil.loadClass(className);
     }

     /**
@@ -314,14 +290,7 @@ public final class Loader {
                    InstantiationException,
                    NoSuchMethodException,
                    InvocationTargetException {
-        final Class<?> clazz = loadClass(className);
-        try {
-            return clazz.getConstructor().newInstance();
-        } catch (final NoSuchMethodException e) {
-            // try the default-default constructor
-            //noinspection ClassNewInstance
-            return clazz.newInstance();
-        }
+        return LoaderUtil.newInstanceOf(className);
     }

     /**
@@ -344,7 +313,7 @@ public final class Loader {
                    IllegalAccessException,
                    InvocationTargetException,
                    InstantiationException {
-        return clazz.cast(newInstanceOf(className));
+        return LoaderUtil.newCheckedInstanceOf(className, clazz);
     }

     /**




-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

[2/4] git commit: Migrate more methods from Loader to LoaderUtil.

Posted by ma...@apache.org.
Migrate more methods from Loader to LoaderUtil.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2a962372
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2a962372
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2a962372

Branch: refs/heads/LOG4J2-608
Commit: 2a96237253823285c90f0c97e4ea4070c6522117
Parents: 77be263
Author: Matt Sicker <ma...@apache.org>
Authored: Mon Sep 1 22:40:29 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Mon Sep 1 22:40:29 2014 -0500

----------------------------------------------------------------------
 .../apache/logging/log4j/util/LoaderUtil.java   | 68 ++++++++++++++++++++
 .../apache/logging/log4j/core/util/Loader.java  | 37 +----------
 2 files changed, 71 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2a962372/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
index 32b23c4..0771054 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.util;
 
+import java.lang.reflect.InvocationTargetException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -28,6 +29,10 @@ import java.security.PrivilegedAction;
 public final class LoaderUtil {
     private LoaderUtil() {}
 
+    public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
+
+    private static final boolean IGNORE_TCCL;
+
     private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new ThreadContextClassLoaderGetter();
 
     static {
@@ -35,6 +40,8 @@ public final class LoaderUtil {
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("getClassLoader"));
         }
+        final String ignoreTccl = PropertiesUtil.getProperties().getStringProperty(IGNORE_TCCL_PROPERTY, null);
+        IGNORE_TCCL = ignoreTccl != null && !"false".equalsIgnoreCase(ignoreTccl.trim());
     }
 
     /**
@@ -56,4 +63,65 @@ public final class LoaderUtil {
             return cl == null ? ClassLoader.getSystemClassLoader() : cl;
         }
     }
+
+    /**
+     * Loads a class by name. This method respects the {@link #IGNORE_TCCL_PROPERTY} Log4j property. If this property
+     * is specified and set to anything besides {@code false}, then the default ClassLoader will be used.
+     *
+     * @param className The class name.
+     * @return the Class for the given name.
+     * @throws ClassNotFoundException if the specified class name could not be found
+     */
+    public static Class<?> loadClass(final String className) throws ClassNotFoundException {
+        if (IGNORE_TCCL) {
+            return Class.forName(className);
+        }
+        try {
+            return getThreadContextClassLoader().loadClass(className);
+        } catch (final Throwable e) {
+            return Class.forName(className);
+        }
+    }
+
+    /**
+     * Loads and instantiates a Class using the default constructor.
+     *
+     * @param className The class name.
+     * @return new instance of the class.
+     * @throws ClassNotFoundException    if the class isn't available to the usual ClassLoaders
+     * @throws IllegalAccessException    if the class can't be instantiated through a public constructor
+     * @throws InstantiationException    if there was an exception whilst instantiating the class
+     * @throws NoSuchMethodException     if there isn't a no-args constructor on the class
+     * @throws InvocationTargetException if there was an exception whilst constructing the class
+     */
+    public static Object newInstanceOf(final String className)
+        throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
+        InvocationTargetException {
+        final Class<?> clazz = loadClass(className);
+        try {
+            return clazz.getConstructor().newInstance();
+        } catch (final NoSuchMethodException e) {
+            return clazz.newInstance();
+        }
+    }
+
+    /**
+     * Loads and instantiates a derived class using its default constructor.
+     *
+     * @param className The class name.
+     * @param clazz The class to cast it to.
+     * @param <T> The type of the class to check.
+     * @return new instance of the class cast to {@code T}
+     * @throws ClassNotFoundException if the class isn't available to the usual ClassLoaders
+     * @throws IllegalAccessException if the class can't be instantiated through a public constructor
+     * @throws InstantiationException if there was an exception whilst instantiating the class
+     * @throws NoSuchMethodException if there isn't a no-args constructor on the class
+     * @throws InvocationTargetException if there was an exception whilst constructing the class
+     * @throws ClassCastException if the constructed object isn't type compatible with {@code T}
+     */
+    public static <T> T newCheckedInstanceOf(final String className, final Class<T> clazz)
+        throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException,
+        IllegalAccessException {
+        return clazz.cast(newInstanceOf(className));
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2a962372/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
index 2fa70bb..9858d4e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
@@ -25,24 +25,17 @@ import java.net.URL;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.LoaderUtil;
-import org.apache.logging.log4j.util.PropertiesUtil;
 
 /**
  * Load resources (or images) from various sources.
  */
 public final class Loader {
 
-    private static boolean ignoreTCL = false;
-
     private static final Logger LOGGER = StatusLogger.getLogger();
 
     private static final String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";
 
     static {
-        final String ignoreTCLProp = PropertiesUtil.getProperties().getStringProperty("log4j.ignoreTCL", null);
-        if (ignoreTCLProp != null) {
-            ignoreTCL = OptionConverter.toBoolean(ignoreTCLProp, true);
-        }
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("getStackTrace"));
@@ -55,7 +48,6 @@ public final class Loader {
      * @return the ClassLoader.
      */
     public static ClassLoader getClassLoader() {
-
         return getClassLoader(Loader.class, null);
     }
 
@@ -248,23 +240,7 @@ public final class Loader {
      * @throws ClassNotFoundException if the Class could not be found.
      */
     public static Class<?> loadClass(final String className) throws ClassNotFoundException {
-        // Just call Class.forName(className) if we are instructed to ignore the TCL.
-        if (ignoreTCL) {
-            LOGGER.trace("Ignoring TCCL. Trying Class.forName({}).", className);
-            return loadClassWithDefaultClassLoader(className);
-        }
-        try {
-            LOGGER.trace("Trying TCCL for class {}.", className);
-            // using the TCCL should work the same as the default ClassLoader (i.e., init or not)
-            return Class.forName(className, true, getTcl());
-        } catch (final Throwable e) {
-            LOGGER.trace("TCCL didn't work for class {}: {}.", className, e.toString());
-            return loadClassWithDefaultClassLoader(className);
-        }
-    }
-
-    private static Class<?> loadClassWithDefaultClassLoader(final String className) throws ClassNotFoundException {
-        return Class.forName(className);
+        return LoaderUtil.loadClass(className);
     }
 
     /**
@@ -314,14 +290,7 @@ public final class Loader {
                    InstantiationException,
                    NoSuchMethodException,
                    InvocationTargetException {
-        final Class<?> clazz = loadClass(className);
-        try {
-            return clazz.getConstructor().newInstance();
-        } catch (final NoSuchMethodException e) {
-            // try the default-default constructor
-            //noinspection ClassNewInstance
-            return clazz.newInstance();
-        }
+        return LoaderUtil.newInstanceOf(className);
     }
 
     /**
@@ -344,7 +313,7 @@ public final class Loader {
                    IllegalAccessException,
                    InvocationTargetException,
                    InstantiationException {
-        return clazz.cast(newInstanceOf(className));
+        return LoaderUtil.newCheckedInstanceOf(className, clazz);
     }
 
     /**


[3/4] git commit: Fix circular class linkage in LoaderUtil.

Posted by ma...@apache.org.
Fix circular class linkage in LoaderUtil.

  - As mentioned in the comments, LoaderUtil cannot reference PropertiesUtil in its static initialization block as this will cause mass errors everywhere.


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/cb653024
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/cb653024
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/cb653024

Branch: refs/heads/LOG4J2-608
Commit: cb653024181839703e370f9a58430ddb63709acb
Parents: 2a96237
Author: Matt Sicker <ma...@apache.org>
Authored: Mon Sep 1 23:21:27 2014 -0500
Committer: Matt Sicker <ma...@apache.org>
Committed: Mon Sep 1 23:21:27 2014 -0500

----------------------------------------------------------------------
 .../org/apache/logging/log4j/util/LoaderUtil.java  | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/cb653024/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
index 0771054..ed77589 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
@@ -31,7 +31,9 @@ public final class LoaderUtil {
 
     public static final String IGNORE_TCCL_PROPERTY = "log4j.ignoreTCL";
 
-    private static final boolean IGNORE_TCCL;
+    // this variable must be lazily loaded; otherwise, we get a nice circular class loading problem where LoaderUtil
+    // wants to use PropertiesUtil, but then PropertiesUtil wants to use LoaderUtil.
+    private static Boolean ignoreTCCL;
 
     private static final PrivilegedAction<ClassLoader> TCCL_GETTER = new ThreadContextClassLoaderGetter();
 
@@ -40,8 +42,6 @@ public final class LoaderUtil {
         if (sm != null) {
             sm.checkPermission(new RuntimePermission("getClassLoader"));
         }
-        final String ignoreTccl = PropertiesUtil.getProperties().getStringProperty(IGNORE_TCCL_PROPERTY, null);
-        IGNORE_TCCL = ignoreTccl != null && !"false".equalsIgnoreCase(ignoreTccl.trim());
     }
 
     /**
@@ -73,7 +73,7 @@ public final class LoaderUtil {
      * @throws ClassNotFoundException if the specified class name could not be found
      */
     public static Class<?> loadClass(final String className) throws ClassNotFoundException {
-        if (IGNORE_TCCL) {
+        if (isIgnoreTccl()) {
             return Class.forName(className);
         }
         try {
@@ -124,4 +124,13 @@ public final class LoaderUtil {
         IllegalAccessException {
         return clazz.cast(newInstanceOf(className));
     }
+
+    private static boolean isIgnoreTccl() {
+        // we need to lazily initialize this, but concurrent access is not an issue
+        if (ignoreTCCL == null) {
+            final String ignoreTccl = PropertiesUtil.getProperties().getStringProperty(IGNORE_TCCL_PROPERTY, null);
+            ignoreTCCL = ignoreTccl != null && !"false".equalsIgnoreCase(ignoreTccl.trim());
+        }
+        return ignoreTCCL;
+    }
 }