[BSF-21]

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/bsf/trunk@1231698 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java b/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java
index 71a7c69..f849550 100644
--- a/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java
+++ b/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java
@@ -17,6 +17,14 @@
  * @author   Rony G. Flatscher (added BSF_Log[Factory] to allow BSF to run without org.apache.commons.logging present)
  */
 
+ /* changes:
+
+    2012-01-15, Rony G. Flatscher: take into account that the current context class loader may be null, JIRA [BSF-21]
+
+    2008-07-04, rgf: if classes cannot be defined or found, try to use the current Thread's
+                     content class loader using a new inner class "LocalThreadClassLoader"
+ */
+
 package org.apache.bsf.util.event.generator;
 
 import org.apache.bsf.BSF_Log;
@@ -38,11 +46,41 @@
     super();
         logger = BSF_LogFactory.getLog(this.getClass().getName());
   }
+
   public synchronized Class defineClass(String name, byte[] b)
   {
     if ((c = getLoadedClass(name)) == null)
     {
-      c = defineClass(name.replace('/','.'), b, 0, b.length);   // rgf, 2006-02-03
+       final String tmpName=name.replace('/','.');
+
+       try
+       {
+          c = defineClass(tmpName, b, 0, b.length);   // rgf, 2006-02-03
+       }
+       catch (NoClassDefFoundError e)  // note "Error": Java thread would be killed otherwise!
+       {
+          // now try the Thread's current context class loader, but don't cache it
+          ClassLoader tccl=Thread.currentThread().getContextClassLoader();
+          if (tccl!=null)
+          {
+             try
+             {
+                LocalThreadClassLoader ltcl=new LocalThreadClassLoader(tccl);
+                return ltcl.defineClass(tmpName,b);
+             }
+             catch (NoClassDefFoundError e1) // (NoClassDefFoundError e1)
+             {
+                logger.error("AdapterClassLoader: NoClassDefFoundError ERROR for class ["+tmpName+"]!");
+                throw e1;      // rethrow error
+             }
+          }
+          else
+          {
+             logger.error("AdapterClassLoader: NoClassDefFoundError ERROR for class ["+tmpName+"] (info: Thread context class loader is 'null'.)!");
+             throw e;      // rethrow error
+          }
+       }
+
       put(name, c);
     }
     else
@@ -53,14 +91,17 @@
 
     return c;
   }
+
   final protected Class findClass(String name)
   {
     return get(name);
   }
+
   final protected Class get(String name)
   {
     return (Class)classCache.get(name);
   }
+
   public synchronized Class getLoadedClass(String name)
   {
     Class c = findLoadedClass(name);
@@ -81,8 +122,34 @@
       c = findClass(name);
     }
 
+        // rgf, 2008-07-04
+        if (c==null)        // not found so far, try to use the current Thread's context class loader instead
+        {
+            LocalThreadClassLoader ltcl=new LocalThreadClassLoader(Thread.currentThread().getContextClassLoader());
+
+            c = ltcl.findLoadedClass(name,'0');
+
+            if (c == null)
+            {
+              try
+              {
+                    c = ltcl.findSystemClass(name,'0');
+              }
+              catch (ClassNotFoundException e)
+              {
+                  try
+                  {
+                      c = ltcl.findClass(name,'0');
+                  }
+                  catch (ClassNotFoundException e1)
+                  {}
+              }
+            }
+        }
+
     return c;
   }
+
   protected synchronized Class loadClass(String name, boolean resolve)
     throws ClassNotFoundException
   {
@@ -95,14 +162,44 @@
 
     return c;
   }
-  // Not in JDK 1.1, only in JDK 1.2.
-//  public AdapterClassLoader(ClassLoader loader)
-//  {
-//    super(loader);
-//  }
 
   final protected void put(String name, Class c)
   {
     classCache.put(name, c);
   }
+
+  /** Inner class to create a ClassLoader with the current Thread's class loader as parent.
+  */
+  class LocalThreadClassLoader extends ClassLoader
+  {
+     // public LocalThreadClassLoader(){super (Thread.currentThread().getContextClassLoader());};
+     public LocalThreadClassLoader (ClassLoader cl)
+     {
+         super (cl);
+     }
+
+     public Class defineClass(String name, byte[] b)
+     {
+         return defineClass(name, b, 0, b.length);     // protected in ClassLoader, hence invoking it this way
+     }
+
+           // use a signature that allows invoking super's protected method via inheritance resolution
+     Class findLoadedClass(String name, char nixi)
+     {
+         return findLoadedClass(name);
+     }
+
+           // use a signature that allows invoking super's protected method via inheritance resolution
+     Class findClass(String name, char nixi)          throws ClassNotFoundException
+     {
+         return findClass(name);
+     }
+
+           // use a signature that allows invoking super's protected method via inheritance resolution
+     Class findSystemClass(String name, char nixi)    throws ClassNotFoundException
+     {
+         return findSystemClass(name);
+     }
+  }
+
 }
diff --git a/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java b/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java
index ce35ca1..78c2872 100644
--- a/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java
+++ b/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java
@@ -17,12 +17,14 @@
 
 
  /*
- 2007-01-29: Rony G. Flatscher: added BSF_Log[Factory] to allow BSF to run without org.apache.commons.logging present
+     2015-01-15, rgf: take into account that a context thread class loader may be null (not set)
 
- 2007-09-21: Rony G. Flatscher, new class loading sequence:
+     2007-09-21: Rony G. Flatscher, new class loading sequence:
 
-        - Thread's context class loader
-        - BSFManager's defining class loader
+            - Thread's context class loader
+            - BSFManager's defining class loader
+
+     2007-01-29: Rony G. Flatscher: added BSF_Log[Factory] to allow BSF to run without org.apache.commons.logging present
  */
 
 package org.apache.bsf.util.event.generator;
@@ -93,10 +95,19 @@
             // EVENTLISTENER = Thread.currentThread().getContextClassLoader().loadClass ("java.util.EventListener"); // rgf, 2006-01-05
 
             // rgf, 20070917: first try context class loader, then BSFManager's defining class loader
-            try {
-                 EVENTLISTENER = Thread.currentThread().getContextClassLoader().loadClass ("java.util.EventListener");
+            EVENTLISTENER=null;
+            ClassLoader tccl=Thread.currentThread().getContextClassLoader();
+
+            if (tccl!=null)
+            {
+                try {
+                     EVENTLISTENER = tccl.loadClass ("java.util.EventListener");
+                }
+                catch(ClassNotFoundException ex01)
+                {}
             }
-            catch(ClassNotFoundException ex01)
+
+            if (EVENTLISTENER==null)    // did not work, try to load it via the definedClassLoader
             {
                 EVENTLISTENER = BSFManager.getDefinedClassLoader().loadClass ("java.util.EventListener");
             }
@@ -583,11 +594,12 @@
                                        " dynamically generated");
         return ret;
       }
-      catch(Exception ex)
+
+      catch(Throwable ex)           // rgf, 2012-01-15
       {
-              System.err.println(ex.getMessage());
-              ex.printStackTrace();
-          }
+        System.err.println(ex.getMessage());
+        ex.printStackTrace();
+      }
     }
     return null;
   }