Author: rony Date: Sun Jan 15 16:10:37 2012 New Revision: 1231698 URL: http://svn.apache.org/viewvc?rev=1231698&view=rev Log: [BSF-21]
Modified: commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java Modified: commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java URL: http://svn.apache.org/viewvc/commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java?rev=1231698&r1=1231697&r2=1231698&view=diff ============================================================================== --- commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java (original) +++ commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/AdapterClassLoader.java Sun Jan 15 16:10:37 2012 @@ -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 @@ public class AdapterClassLoader extends 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 @@ public class AdapterClassLoader extends 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 @@ public class AdapterClassLoader extends 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 @@ public class AdapterClassLoader extends 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); + } + } + } Modified: commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java URL: http://svn.apache.org/viewvc/commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java?rev=1231698&r1=1231697&r2=1231698&view=diff ============================================================================== --- commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java (original) +++ commons/proper/bsf/trunk/src/main/java/org/apache/bsf/util/event/generator/EventAdapterGenerator.java Sun Jan 15 16:10:37 2012 @@ -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 @@ public class EventAdapterGenerator // 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 @@ public class EventAdapterGenerator " 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; }