[ 
https://issues.apache.org/jira/browse/LOG4J2-493?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14970543#comment-14970543
 ] 

Remko Popma commented on LOG4J2-493:
------------------------------------

{code}
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index 872c01d..6605129 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
@@ -74,7 +74,7 @@
      */
     private volatile Configuration configuration = new DefaultConfiguration();
     private Object externalContext;
-    private final String contextName;
+    private String contextName;
     private volatile URI configLocation;
     private Cancellable shutdownCallback;
 
@@ -318,6 +318,16 @@
     public String getName() {
         return contextName;
     }
+    
+    /**
+     * Sets the name.
+     * 
+     * @param name the new LoggerContext name
+     * @throws NullPointerException if the specified name is {@code null}
+     */
+    public void setName(final String name) {
+       contextName = Objects.requireNonNull(name);
+    }
 
     /**
      * Sets the external context.
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
index 6636eba..1efdd18 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigHelper.java
@@ -116,22 +116,23 @@
         disruptor.handleEventsWith(handlers);
 
         LOGGER.debug(
-                "Starting AsyncLoggerConfig disruptor with ringbuffer size={}, 
waitStrategy={}, exceptionHandler={}...",
+                "Starting AsyncLoggerConfig disruptor with ringbufferSize={}, 
waitStrategy={}, exceptionHandler={}...",
                 disruptor.getRingBuffer().getBufferSize(), 
waitStrategy.getClass().getSimpleName(), errorHandler);
         disruptor.start();
     }
 
     private static WaitStrategy createWaitStrategy() {
         final String strategy = 
System.getProperty("AsyncLoggerConfig.WaitStrategy");
-        LOGGER.trace("property AsyncLoggerConfig.WaitStrategy={}", strategy);
-        if ("Sleep".equals(strategy)) {
-            return new SleepingWaitStrategy();
-        } else if ("Yield".equals(strategy)) {
-            return new YieldingWaitStrategy();
-        } else if ("Block".equals(strategy)) {
-            return new BlockingWaitStrategy();
+        if (strategy != null) {
+               LOGGER.trace("property AsyncLoggerConfig.WaitStrategy={}", 
strategy);
+               if ("Sleep".equals(strategy)) {
+                   return new SleepingWaitStrategy();
+               } else if ("Yield".equals(strategy)) {
+                   return new YieldingWaitStrategy();
+               } else if ("Block".equals(strategy)) {
+                   return new BlockingWaitStrategy();
+               }
         }
-        LOGGER.trace("AsyncLoggerConfigHelper disruptor event handler uses 
BlockingWaitStrategy");
         return new BlockingWaitStrategy();
     }
 
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
index 4efd7cc..70c3568 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContext.java
@@ -21,8 +21,10 @@
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.jmx.RingBufferAdmin;
 import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.status.StatusLogger;
 
 /**
  * {@code LoggerContext} that creates {@code AsyncLogger} objects.
@@ -57,6 +59,12 @@
     protected Logger newInstance(final LoggerContext ctx, final String name, 
final MessageFactory messageFactory) {
         return new AsyncLogger(ctx, name, messageFactory, helper);
     }
+    
+    @Override
+    public void setName(final String name) {
+       super.setName("AsyncContext[" + name + "]");
+       helper.setContextName(name);
+    }
 
     /*
      * (non-Javadoc)
@@ -65,7 +73,7 @@
      */
     @Override
     public void start() {
-        helper.start();
+       maybeStartHelper(getConfiguration());
         super.start();
     }
 
@@ -76,10 +84,21 @@
      */
     @Override
     public void start(Configuration config) {
-        helper.start();
+       maybeStartHelper(config);
         super.start(config);
     }
 
+       private void maybeStartHelper(Configuration config) {
+               // If no log4j configuration was found, there are no loggers
+       // and there is no point in starting the disruptor (which takes up
+       // significant memory and starts a thread).
+       if (config instanceof DefaultConfiguration) {
+               StatusLogger.getLogger().debug("[{}] Not starting Disruptor for 
DefaultConfiguration.", getName());
+       } else {
+               helper.start();
+       }
+       }
+
     @Override
     public void stop() {
         helper.stop(); // first stop Disruptor
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector.java
index 4d739e3..c9fc58b 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector.java
@@ -25,6 +25,8 @@
 
 /**
  * {@code ContextSelector} that manages {@code AsyncLoggerContext} instances.
+ * <p>
+ * As of version 2.5, this class extends ClassLoaderContextSelector for better 
web app support.
  */
 public class AsyncLoggerContextSelector extends ClassLoaderContextSelector {
 
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerHelper.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerHelper.java
index 027fa0d..5c90eae 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerHelper.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerHelper.java
@@ -41,14 +41,14 @@
  * life cycle of the context. The AsyncLoggerHelper of the context is shared 
by all AsyncLogger objects created by that
  * AsyncLoggerContext.
  */
-public class AsyncLoggerHelper {
+class AsyncLoggerHelper {
     private static final int SLEEP_MILLIS_BETWEEN_DRAIN_ATTEMPTS = 50;
     private static final int MAX_DRAIN_ATTEMPTS_BEFORE_SHUTDOWN = 200;
     private static final int RINGBUFFER_MIN_SIZE = 128;
     private static final int RINGBUFFER_DEFAULT_SIZE = 256 * 1024;
     private static final StatusLogger LOGGER = StatusLogger.getLogger();
 
-    private final String contextName;
+    private String contextName;
     private ExecutorService executor;
     private volatile Disruptor<RingBufferLogEvent> disruptor;
 
@@ -58,6 +58,10 @@
 
     public String getContextName() {
         return contextName;
+    }
+
+    public void setContextName(String name) {
+        contextName = name;
     }
 
     Disruptor<RingBufferLogEvent> getDisruptor() {
@@ -77,18 +81,22 @@
         LOGGER.trace("[{}] AsyncLoggerHelper creating new disruptor.", 
contextName);
         final int ringBufferSize = calculateRingBufferSize();
         final WaitStrategy waitStrategy = createWaitStrategy();
-        executor = Executors.newSingleThreadExecutor(new 
DaemonThreadFactory(contextName + "-Logger-"));
+        executor = Executors.newSingleThreadExecutor(new 
DaemonThreadFactory("AsyncLogger[" + contextName + "]"));
         Info.initExecutorThreadInstance(executor);
 
         disruptor = new Disruptor<>(RingBufferLogEvent.FACTORY, 
ringBufferSize, executor, ProducerType.MULTI,
                 waitStrategy);
-        disruptor.handleExceptionsWith(getExceptionHandler());
+
+        final ExceptionHandler<RingBufferLogEvent> errorHandler = 
getExceptionHandler();
+        disruptor.handleExceptionsWith(errorHandler);
 
         final RingBufferLogEventHandler[] handlers = {new 
RingBufferLogEventHandler()};
         disruptor.handleEventsWith(handlers);
 
-        LOGGER.debug("[{}] Starting AsyncLogger disruptor with ringbuffer size 
{}...", contextName, disruptor
-                .getRingBuffer().getBufferSize());
+        LOGGER.debug(
+                       "[{}] Starting AsyncLogger disruptor with 
ringbufferSize={}, waitStrategy={}, exceptionHandler={}...",
+                       contextName, disruptor.getRingBuffer().getBufferSize(), 
waitStrategy.getClass().getSimpleName(),
+                       errorHandler);
         disruptor.start();
     }
 
@@ -113,22 +121,22 @@
 
     private WaitStrategy createWaitStrategy() {
         final String strategy = 
PropertiesUtil.getProperties().getStringProperty("AsyncLogger.WaitStrategy");
-        LOGGER.debug("[{}] property AsyncLogger.WaitStrategy={}", contextName, 
strategy);
-        if ("Sleep".equals(strategy)) {
-            return new SleepingWaitStrategy();
-        } else if ("Yield".equals(strategy)) {
-            return new YieldingWaitStrategy();
-        } else if ("Block".equals(strategy)) {
-            return new BlockingWaitStrategy();
+        if (strategy != null) {
+               LOGGER.trace("[{}] property AsyncLogger.WaitStrategy={}", 
contextName, strategy);
+               if ("Sleep".equals(strategy)) {
+                   return new SleepingWaitStrategy();
+               } else if ("Yield".equals(strategy)) {
+                   return new YieldingWaitStrategy();
+               } else if ("Block".equals(strategy)) {
+                   return new BlockingWaitStrategy();
+               }
         }
-        LOGGER.debug("[{}] disruptor event handler uses BlockingWaitStrategy", 
contextName);
         return new BlockingWaitStrategy();
     }
 
     private ExceptionHandler<RingBufferLogEvent> getExceptionHandler() {
         final String cls = 
PropertiesUtil.getProperties().getStringProperty("AsyncLogger.ExceptionHandler");
         if (cls == null) {
-            LOGGER.debug("[{}] No AsyncLogger.ExceptionHandler specified", 
contextName);
             return null;
         }
         try {
@@ -163,7 +171,8 @@
      * @return a new {@code RingBufferAdmin} that instruments the ringbuffer
      */
     public RingBufferAdmin createRingBufferAdmin(final String contextName) {
-        return RingBufferAdmin.forAsyncLogger(disruptor.getRingBuffer(), 
contextName);
+       final RingBuffer<RingBufferLogEvent> ring = disruptor == null ? null : 
disruptor.getRingBuffer();
+        return RingBufferAdmin.forAsyncLogger(ring, contextName);
     }
 
     /**
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
index 5c6ebfe..f54fa2d 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
@@ -222,6 +222,9 @@
         if (externalContext != null && ctx.getExternalContext() == null) {
             ctx.setExternalContext(externalContext);
         }
+        if (name != null) {
+               ctx.setName(name);
+        }
         if (ctx.getState() == LifeCycle.State.INITIALIZED) {
             if (configLocation != null || name != null) {
                 ContextAnchor.THREAD_CONTEXT.set(ctx);
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/RingBufferAdmin.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/RingBufferAdmin.java
index 71c14f7..15a9e56 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/RingBufferAdmin.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/RingBufferAdmin.java
@@ -16,8 +16,6 @@
  */
 package org.apache.logging.log4j.core.jmx;
 
-import java.util.Objects;
-
 import javax.management.ObjectName;
 
 import com.lmax.disruptor.RingBuffer;
@@ -45,7 +43,7 @@
     }
     
     protected RingBufferAdmin(final RingBuffer<?> ringBuffer, final String 
mbeanName) {
-        this.ringBuffer = Objects.requireNonNull(ringBuffer, "ringbuffer");    
    
+        this.ringBuffer = ringBuffer;        
         try {
             objectName = new ObjectName(mbeanName);
         } catch (final Exception e) {
@@ -55,12 +53,12 @@
     
     @Override
     public long getBufferSize() {
-        return ringBuffer.getBufferSize();
+        return ringBuffer == null ? 0 : ringBuffer.getBufferSize();
     }
     
     @Override
     public long getRemainingCapacity() {
-        return ringBuffer.remainingCapacity();
+        return ringBuffer == null ? 0 : ringBuffer.remainingCapacity();
     }
 
     /**
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
index c4f596d..5baef72 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
@@ -174,7 +174,10 @@
 
                 if (ctx instanceof AsyncLoggerContext) {
                     final RingBufferAdmin rbmbean = ((AsyncLoggerContext) 
ctx).createRingBufferAdmin();
-                    register(mbs, rbmbean, rbmbean.getObjectName());
+                    if (rbmbean.getBufferSize() > 0) {
+                       // don't register if Disruptor not started 
(DefaultConfiguration: config not found)
+                       register(mbs, rbmbean, rbmbean.getObjectName());
+                    }
                 }
 
                 // register the status logger and the context selector
{code}


> Problem with AsyncLogger when web app is deployed/undeployed multiple times
> ---------------------------------------------------------------------------
>
>                 Key: LOG4J2-493
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-493
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 2.0-beta9, 2.0-rc1
>         Environment: tomcat 7.0.42
>            Reporter: Kireet Reddy
>            Assignee: Remko Popma
>              Labels: Async
>             Fix For: 2.5
>
>
> |_This ticket tracks Async Logger issues in Tomcat when making all loggers 
> async with LoggerContextSelector system property. For Tomcat issues with 
> AsyncRoot/AsyncLogger in the configuration file, see LOG4J2-323._|
> When redeploying my application in tomcat multiple times, I get an exception:
> {code}
> Exception in thread "Thread-29" java.lang.NullPointerException
>         at 
> org.apache.logging.log4j.core.async.AsyncLogger.stop(AsyncLogger.java:249)
>         at 
> org.apache.logging.log4j.core.async.AsyncLoggerContext.stop(AsyncLoggerContext.java:56)
>         at 
> org.apache.logging.log4j.core.LoggerContext$ShutdownThread.run(LoggerContext.java:437)
> {code}
> This seems to be due to the fact that some initialization code happens in the 
> class initializer but is undone in the stop() method which is called during 
> webapp undeployment. This causes issues because in this case the log4j jar is 
> loaded by the shared classloader ($catalina.home/lib) rather than the webapp 
> classloader. This means the AsyncLogger class is not re-created during webapp 
> deployment. 
> I am using this structure because I have many 3rd party libraries and want to 
> keep redeployments lightweight. 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to