[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;
}