- InvalidJarIndexException is only available in JDK 1.3.  Referring
   to this exception type caused log4j 1.1b5 to break on earlier JDKs.
   We now avoid referring to it. [*]

 - Aaron Greenhouse found a series of multi-threading related bugs in
   Category and AsyncAppender. See bug ids 1505 and 1507 in our bug
   database for examplary bug reports. [*]

PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/logging/log4j/trunk@309129 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/INSTALL b/INSTALL
index 1446c50..9d4746d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -11,7 +11,7 @@
    number, under PATH_OF_YOUR_CHOICE.
 
 
-3) Add PATH_OF_YOUR_CHOICE\jakarta-log4j-X.X\classes to the CLASSPATH
+3) Add PATH_OF_YOUR_CHOICE\jakarta-log4j-X.X\dist\classes to the CLASSPATH
    variable.
    
 4) You can now test your installation. To do this issue the command:
diff --git a/docs/HISTORY b/docs/HISTORY
index 74c02d6..e753dc8 100644
--- a/docs/HISTORY
+++ b/docs/HISTORY
@@ -5,6 +5,18 @@
        client code. 
  [***] Changes requiring important modifications to existing client code.
 
+ April 26, 2001
+
+ - Release of version 1.1b6
+ 
+ - InvalidJarIndexException is only available in JDK 1.3.  Referring
+   to this exception type caused log4j 1.1b5 to break on earlier JDKs.
+   We now avoid referring to it. [*]
+
+ - Aaron Greenhouse found a series of multi-threading related bugs in
+   Category and AsyncAppender. See bug ids 1505 and 1507 in our bug
+   database for examplary bug reports. [*]
+  
 
  April 22, 2001
 
diff --git a/src/java/org/apache/log4j/AsyncAppender.java b/src/java/org/apache/log4j/AsyncAppender.java
index 02264b0..94e7fe9 100644
--- a/src/java/org/apache/log4j/AsyncAppender.java
+++ b/src/java/org/apache/log4j/AsyncAppender.java
@@ -83,8 +83,10 @@
 
   public
   AsyncAppender() {
+    // Note: The dispatcher code assumes that the aai is set once and
+    // for all!!!
     aai = new AppenderAttachableImpl();
-    dispatcher = new Dispatcher(bf, aai);
+    dispatcher = new Dispatcher(bf, this);
     dispatcher.start();
   }
   
@@ -124,7 +126,9 @@
   /**
      Close this <code>AsyncAppender</code> by interrupting the
      dispatcher thread which will process all pending events before
-     exiting. */
+     exiting. 
+  */
+  synchronized
   public 
   void close() {
     if(closed) // avoid multiple close, otherwise one gets NullPointerException
@@ -143,11 +147,13 @@
     bf = null;
   }
 
+  synchronized
   public
   Enumeration getAllAppenders() {
     return aai.getAllAppenders();
   }
 
+  synchronized
   public
   Appender getAppender(String name) {
     return aai.getAppender(name);
@@ -303,16 +309,18 @@
 }
 // ------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 class Dispatcher extends Thread {
 
   BoundedFIFO bf;
   AppenderAttachableImpl aai;
   boolean interrupted = false;
+  AsyncAppender container;
 
-  Dispatcher(BoundedFIFO bf, AppenderAttachableImpl aai) {
+  Dispatcher(BoundedFIFO bf, AsyncAppender container) {
     this.bf = bf;
-    this.aai = aai;
+    this.container = container;
+    this.aai = container.aai;
     // set the dispatcher priority to lowest possible value
     this.setPriority(Thread.MIN_PRIORITY);
     
@@ -326,7 +334,7 @@
     synchronized(bf) {
       interrupted = true;   
       // We have a waiting dispacther if and only if bf.length is
-      // zero.  In that case, we need to give its death kiss.
+      // zero.  In that case, we need to give it a death kiss.
       if(bf.length() == 0) {
 	bf.notify();
       }
@@ -375,9 +383,14 @@
 	  bf.notify();
 	}
       } // synchronized
-      
-      if(aai != null && event != null)
-	aai.appendLoopOnAppenders(event);
+  
+      // The synchronization on parent is necessary to protect against
+      // operations on the aai object of the parent
+      synchronized(container) {
+	if(aai != null && event != null) {
+	  aai.appendLoopOnAppenders(event);
+	}
+      }
     } // while
   }
 }
diff --git a/src/java/org/apache/log4j/Category.java b/src/java/org/apache/log4j/Category.java
index d4e9838..b4136e8 100644
--- a/src/java/org/apache/log4j/Category.java
+++ b/src/java/org/apache/log4j/Category.java
@@ -27,6 +27,7 @@
 import org.apache.log4j.helpers.NullEnumeration;
 import org.apache.log4j.helpers.OptionConverter;
 import org.apache.log4j.helpers.AppenderAttachableImpl;
+import org.apache.log4j.helpers.Loader;
 import org.apache.log4j.or.RendererMap;
 import org.apache.log4j.or.ObjectRenderer;
 
@@ -132,8 +133,8 @@
 	// so, resource is not a URL:
 	// attempt to get the resource from the class path
 	url = new URL(resource);
-      } catch (MalformedURLException ex) {	
-	url = org.apache.log4j.helpers.Loader.getResource(resource, Category.class);
+      } catch (MalformedURLException ex) {
+	  url = Loader.getResource(resource, Object.class); 
       }	
       
       // If we have a non-null url, then delegate the rest of the
@@ -458,6 +459,7 @@
      is returned.
      
      @return Enumeration An enumeration of the appenders in this category.  */
+  synchronized
   public
   Enumeration getAllAppenders() {
     if(aai == null)
@@ -471,6 +473,7 @@
 
      <p>Return the appender with that name if in the list. Return
      <code>null</code> otherwise.  */
+  synchronized
   public
   Appender getAppender(String name) {
      if(aai == null || name == null)
diff --git a/src/java/org/apache/log4j/Makefile b/src/java/org/apache/log4j/Makefile
index f655870..93869f1 100644
--- a/src/java/org/apache/log4j/Makefile
+++ b/src/java/org/apache/log4j/Makefile
@@ -8,7 +8,6 @@
 	PatternLayout.java\
 	AsyncAppender.java\
 	NDC.java\
-	RollingFileAppenderBeanInfo.java\
 	AppenderSkeleton.java\
 	CategoryKey.java\
 	ProvisionNode.java\
@@ -25,6 +24,11 @@
 	WriterAppender.java\
 	ConsoleAppender.java\
 
+ifdef $(ISJDK1)
+ JSOURCES:=$(JSOURCES) RollingFileAppenderBeanInfo.java
+endif
+
+
 SUBDIRS :=helpers spi config or xml net nt varia test performance examples 
 
 # include master-rule file
diff --git a/src/java/org/apache/log4j/helpers/Loader.java b/src/java/org/apache/log4j/helpers/Loader.java
index bcad2ef..63f2f30 100644
--- a/src/java/org/apache/log4j/helpers/Loader.java
+++ b/src/java/org/apache/log4j/helpers/Loader.java
@@ -18,9 +18,9 @@
   @author Ceki G&uuml;lc&uuml;
  */
 
-public class Loader extends java.lang.Object { 
+public class Loader  { 
 
-  static String JARSTR = "Caught InvalidJarException. This may be innocuous.";
+  static String TSTR = "Caught Exception while in Loader.getResource. This may be innocuous.";
   
   /**
      This method will search for <code>resource</code> in different
@@ -48,24 +48,24 @@
   URL getResource(String resource, Class clazz) {
     
     URL url = null;
-    
+
 
     // Is it under CLAZZ/resource somewhere in the classpath?    
     // where CLAZZ is the fully qualified name of clazz where dots have been
     // changed to directory separators
     LogLog.debug("Trying to find ["+resource+"] using Class.getResource().");
-
-
-
+    
+    
+    
     try {
       url = clazz.getResource(resource);
       if(url != null) 
 	return url;
-    } catch (sun.misc.InvalidJarIndexException e) {
-      LogLog.debug(JARSTR);
+    } catch (Throwable t) {
+      LogLog.warn(TSTR,t);
     }
-
-
+    
+    
     // attempt to get the resource under CLAZZ/resource from the
     // system class path. The system class loader should not throw
     // InvalidJarIndexExceptions
@@ -75,28 +75,30 @@
     url = ClassLoader.getSystemResource(fullyQualified);
     if(url != null) 
       return url;
-
+    
     // Let the class loader of clazz and parents (by the delagation
     // property) seearch for resource
     ClassLoader loader = clazz.getClassLoader();
-    LogLog.debug("Trying to find ["+resource+"] using "+loader
-		 +" class loader.");
-    
-    try {
-      url = loader.getResource(resource); 
-      if(url != null) 
-	return url;
-    } catch(sun.misc.InvalidJarIndexException e) {
-      LogLog.debug(JARSTR);
+    if(loader != null) {
+      try {
+	LogLog.debug("Trying to find ["+resource+"] using "+loader
+		     +" class loader.");
+	url = loader.getResource(resource); 
+	if(url != null) 
+	  return url;
+      } catch(Throwable t) {
+	LogLog.warn(TSTR, t);
+      }
     }
     
-
+    
     // Attempt to get the resource from the class path. It may be the
     // case that clazz was loaded by the Extentsion class loader which
     // the parent of the system class loader. Hence the code below.
     LogLog.debug("Trying to find ["+resource+"] using ClassLoader.getSystemResource().");
     url = ClassLoader.getSystemResource(resource);
     return url;
+
   }
 
   /**
diff --git a/src/java/org/apache/log4j/helpers/Makefile b/src/java/org/apache/log4j/helpers/Makefile
index 2ad830e..5aa974a 100644
--- a/src/java/org/apache/log4j/helpers/Makefile
+++ b/src/java/org/apache/log4j/helpers/Makefile
@@ -6,7 +6,7 @@
 	SyslogWriter.java \
 	QuietWriter.java \
 	CountingQuietWriter.java\
-         SyslogQuietWriter.java\
+        SyslogQuietWriter.java\
 	OptionConverter.java\
 	DateLayout.java\
 	RelativeTimeDateFormat.java\
@@ -21,6 +21,8 @@
 	FileWatchdog.java\
 	Loader.java\
 
+
+
 SUBDIRS := 
 
 # include master-rule file
diff --git a/src/java/org/apache/log4j/test/Makefile b/src/java/org/apache/log4j/test/Makefile
index e111e68..327b4d1 100644
--- a/src/java/org/apache/log4j/test/Makefile
+++ b/src/java/org/apache/log4j/test/Makefile
@@ -25,7 +25,11 @@
  UnitTestOptionConverter.java\
  SocketAppenderTest.java\
  PrintProperties.java\
- UnitTestOR.java\
+
+
+ifdef $(ISJDK1)
+  JSOURCES:=$(JSOURCES)  UnitTestOR.java
+endif
 
 SUBDIRS :=