bsh

Class BshClassManager

Known Direct Subclasses:
ClassManagerImpl

public class BshClassManager
extends java.lang.Object

BshClassManager manages all classloading in BeanShell. It also supports a dynamically loaded extension (bsh.classpath package) which allows classpath extension and class file reloading. Currently the extension relies on 1.2 for BshClassLoader and weak references. See http://www.beanshell.org/manual/classloading.html for details on the bsh classloader architecture.

Bsh has a multi-tiered class loading architecture. No class loader is used unless/until the classpath is modified or a class is reloaded.

Nested Class Summary

static interface
BshClassManager.Listener

Field Summary

protected Hashtable
absoluteClassCache
Global cache for things we know are classes.
protected Hashtable
absoluteNonClasses
Global cache for things we know are *not* classes.
protected Hashtable
definingClasses
protected Hashtable
definingClassesBaseNames
protected ClassLoader
externalClassLoader
An external classloader supplied by the setClassLoader() command.
protected Hashtable
resolvedObjectMethods
Caches for resolved object and static methods.
protected Hashtable
resolvedStaticMethods

Method Summary

void
addClassPath(URL path)
void
addListener(BshClassManager.Listener l)
void
cacheClassInfo(String name, Class value)
Cache info about whether name is a class or not.
void
cacheResolvedMethod(Class clas, Class[] types, Method method)
Cache a resolved (possibly overloaded) method based on the argument types used to invoke it, subject to classloader change.
boolean
classExists(String name)
Class
classForName(String name)
Load the specified class by name, taking into account added classpath and reloaded classes, etc.
protected void
classLoaderChanged()
protected void
clearCaches()
Clear the caches in BshClassManager
protected static UtilEvalError
cmUnavailable()
static BshClassManager
createClassManager(Interpreter interpreter)
Create a new instance of the class manager.
Class
defineClass(String name, byte[] code)
protected void
definingClass(String className)
Flag the class name as being in the process of being defined.
protected void
doSuperImport()
Support for "import *;" Hide details in here as opposed to NameSpace.
protected void
doneDefiningClass(String className)
Indicate that the specified class name has been defined and may be loaded normally.
void
dump(PrintWriter pw)
protected String
getClassBeingDefined(String className)
This method is a temporary workaround used with definingClass.
protected String
getClassNameByUnqName(String name)
Return the name or null if none is found, Throw an ClassPathException containing detail if name is ambigous.
protected Method
getResolvedMethod(Class clas, String methodName, Class[] types, boolean onlyStatic)
Return a previously cached resolved method.
URL
getResource(String path)
Get a resource URL using the BeanShell classpath
InputStream
getResourceAsStream(String path)
Get a resource stream using the BeanShell classpath
protected boolean
hasSuperImport()
A "super import" ("import *") operation has been performed.
protected boolean
isClassBeingDefined(String className)
protected Class
loadSourceClass(String name)
protected static Error
noClassDefFound(String className, Error e)
Annotate the NoClassDefFoundError with some info about the class we were trying to load.
Class
plainClassForName(String name)
Perform a plain Class.forName() or call the externally provided classloader.
void
reloadAllClasses()
Overlay the entire path with a new class loader.
void
reloadClasses(String[] classNames)
Reloading classes means creating a new classloader and using it whenever we are asked for classes in the appropriate space.
void
reloadPackage(String pack)
Reload all classes in the specified package: e.g.
void
removeListener(BshClassManager.Listener l)
void
reset()
Clear all loaders and start over.
void
setClassLoader(ClassLoader externalCL)
Set an external class loader.
void
setClassPath(URL[] cp)
Set a new base classpath and create a new base classloader.

Field Details

absoluteClassCache

protected Hashtable absoluteClassCache
Global cache for things we know are classes. Note: these should probably be re-implemented with Soft references. (as opposed to strong or Weak)


absoluteNonClasses

protected Hashtable absoluteNonClasses
Global cache for things we know are *not* classes. Note: these should probably be re-implemented with Soft references. (as opposed to strong or Weak)


definingClasses

protected Hashtable definingClasses


definingClassesBaseNames

protected Hashtable definingClassesBaseNames


externalClassLoader

protected ClassLoader externalClassLoader
An external classloader supplied by the setClassLoader() command.


resolvedObjectMethods

protected Hashtable resolvedObjectMethods
Caches for resolved object and static methods. We keep these maps separate to support fast lookup in the general case where the method may be either.


resolvedStaticMethods

protected Hashtable resolvedStaticMethods

Method Details

addClassPath

public void addClassPath(URL path)
            throws IOException


addListener

public void addListener(BshClassManager.Listener l)


cacheClassInfo

public void cacheClassInfo(String name,
                           Class value)
Cache info about whether name is a class or not.

Parameters:
value - if value is non-null, cache the class if value is null, set the flag that it is *not* a class to speed later resolution


cacheResolvedMethod

public void cacheResolvedMethod(Class clas,
                                Class[] types,
                                Method method)
Cache a resolved (possibly overloaded) method based on the argument types used to invoke it, subject to classloader change. Static and Object methods are cached separately to support fast lookup in the general case where either will do.


classExists

public boolean classExists(String name)


classForName

public Class classForName(String name)
Load the specified class by name, taking into account added classpath and reloaded classes, etc. Note: Again, this is just a trivial implementation. See bsh.classpath.ClassManagerImpl for the fully functional class management package.

Returns:
the class or null


classLoaderChanged

protected void classLoaderChanged()


clearCaches

protected void clearCaches()
Clear the caches in BshClassManager

See Also:
void #reset() for external usage


cmUnavailable

protected static UtilEvalError cmUnavailable()


createClassManager

public static BshClassManager createClassManager(Interpreter interpreter)
Create a new instance of the class manager. Class manager instnaces are now associated with the interpreter.

See Also:
bsh.Interpreter.getClassManager(), bsh.Interpreter.setClassLoader( ClassLoader )


defineClass

public Class defineClass(String name,
                         byte[] code)


definingClass

protected void definingClass(String className)
Flag the class name as being in the process of being defined. The class manager will not attempt to load it.


doSuperImport

protected void doSuperImport()
            throws UtilEvalError
Support for "import *;" Hide details in here as opposed to NameSpace.


doneDefiningClass

protected void doneDefiningClass(String className)
Indicate that the specified class name has been defined and may be loaded normally.


dump

public void dump(PrintWriter pw)


getClassBeingDefined

protected String getClassBeingDefined(String className)
This method is a temporary workaround used with definingClass. It is to be removed at some point.


getClassNameByUnqName

protected String getClassNameByUnqName(String name)
            throws UtilEvalError
Return the name or null if none is found, Throw an ClassPathException containing detail if name is ambigous.


getResolvedMethod

protected Method getResolvedMethod(Class clas,
                                   String methodName,
                                   Class[] types,
                                   boolean onlyStatic)
Return a previously cached resolved method.

Parameters:
onlyStatic - specifies that only a static method may be returned.

Returns:
the Method or null


getResource

public URL getResource(String path)
Get a resource URL using the BeanShell classpath

Parameters:
path - should be an absolute path


getResourceAsStream

public InputStream getResourceAsStream(String path)
Get a resource stream using the BeanShell classpath

Parameters:
path - should be an absolute path


hasSuperImport

protected boolean hasSuperImport()
A "super import" ("import *") operation has been performed.


isClassBeingDefined

protected boolean isClassBeingDefined(String className)


loadSourceClass

protected Class loadSourceClass(String name)


noClassDefFound

protected static Error noClassDefFound(String className,
                                       Error e)
Annotate the NoClassDefFoundError with some info about the class we were trying to load.


plainClassForName

public Class plainClassForName(String name)
            throws ClassNotFoundException
Perform a plain Class.forName() or call the externally provided classloader. If a BshClassManager implementation is loaded the call will be delegated to it, to allow for additional hooks.

This simply wraps that bottom level class lookup call and provides a central point for monitoring and handling certain Java version dependent bugs, etc.

Returns:
the class

See Also:
classForName(String)


reloadAllClasses

public void reloadAllClasses()
            throws UtilEvalError
Overlay the entire path with a new class loader. Set the base path to the user path + base path. No point in including the boot class path (can't reload thos).


reloadClasses

public void reloadClasses(String[] classNames)
            throws UtilEvalError
Reloading classes means creating a new classloader and using it whenever we are asked for classes in the appropriate space. For this we use a DiscreteFilesClassLoader


reloadPackage

public void reloadPackage(String pack)
            throws UtilEvalError
Reload all classes in the specified package: e.g. "com.sun.tools" The special package name "" can be used to refer to unpackaged classes.


removeListener

public void removeListener(BshClassManager.Listener l)


reset

public void reset()
Clear all loaders and start over. No class loading.


setClassLoader

public void setClassLoader(ClassLoader externalCL)
Set an external class loader. BeanShell will use this at the same point it would otherwise use the plain Class.forName(). i.e. if no explicit classpath management is done from the script (addClassPath(), setClassPath(), reloadClasses()) then BeanShell will only use the supplied classloader. If additional classpath management is done then BeanShell will perform that in addition to the supplied external classloader. However BeanShell is not currently able to reload classes supplied through the external classloader.


setClassPath

public void setClassPath(URL[] cp)
            throws UtilEvalError
Set a new base classpath and create a new base classloader. This means all types change.


B) 2000-2005 pat@pat.net :-)