ariba.util.core
Class NonCachingClassLoader
java.lang.Object
java.lang.ClassLoader
ariba.util.core.NonCachingClassLoader
public class NonCachingClassLoader
- extends java.lang.ClassLoader
Implementation of a ClassLoader that can be used to force
reloading of class files from the file system. This is useful for
applications that provide API's for clients to write
implementations for. If the NonCachingClassLoader is used to load
those implementations, then authors of those implementations do
not need to restart the application that calls their
implementations.
For this to work properly, you need to instantiate the class and
assign it to a variable that is of the type of a superclass or an
interface of the class that is getting loaded. If not you will
get a ClassCastException. Contrary to popular belief, classes are
not unique within a VM; they are unique within a class loader
within a VM. Thus you can create what you think is a singleton
class, such as ClassUtil but find that it gets loaded multiple
times if you use the NonCachingClassLoader. Each class called
ClassUtil is scoped by the class loader instance that loaded it.
If you try to compare the two objects, you will get a
ClassCastException.
The code that calls the loadClass method and then calls
ClassUtil.newInstance with the returned class needs to cast the
result to an Interface or superclass that was loaded by the
classloader that also loaded the code that calls loadClass. If
not, you will get a ClassCastException.
Reloading a class necessarily creates multiple copies within the
VM, each constrained to the scope of the instance of
NonCachingClassLoader that loaded it. There are other classes
you'll want reloaded by this classloader. For example, if you
want to reload config.java.foo.Bar and config.java.foo.FooUtil
which contains utils that Bar calls, then you can instantiate a
NonCachingClassLoader with the pattern of "/config.S/" (where S
stands for *, which I cannot actually type in a javadoc comment or
else it will interpret the star slash as the end of this comment).
However, you probably do not want ariba.util.core.ClassUtil
reloaded. You can prevent that by making sure you choose a
pattern that ariba.util.core.ClassUtil does not conform to.
Here is an example usage in which DummyClass implements DummyInterface:
public class ClassUtilTest
{
public void classForNameNonCachingTest ()
{
String className = "test.ariba.util.core.DummyClass";
Class c = ClassUtil.classForNameNonCaching(className, "/test.*Class/", false);
DummyInterface inst = (DummyInterface)ClassUtil.newInstance(c);
Assert.that(inst.alwaysTrue(), "expected true");
}
}
Furthermore this is the logging you will see:
Loading test.ariba.util.core.DummyClass with NonCachingClassLoader
Letting java.lang.Object be loaded by primordial class loader
Letting test.ariba.util.core.DummyInterface be loaded by primordial class loader
See that DummyInterface is loaded by the primordial class loader?
That is the same class loader that loaded ClassUtilTest. The
following code will throw a ClassCastException:
public class ClassUtilTest
{
public void classForNameNonCachingTest ()
{
String className = "test.ariba.util.core.DummyClass";
Class c = ClassUtil.classForNameNonCaching(className, "/test.*Class/", false);
DummyClass inst = (DummyClass)ClassUtil.newInstance(c);
Assert.that(inst.alwaysTrue(), "expected true");
}
}
Loading test.ariba.util.core.DummyClass with NonCachingClassLoader
Letting java.lang.Object be loaded by primordial class loader
Letting test.ariba.util.core.DummyInterface be loaded by primordial class loader
java.lang.ClassCastException: test.ariba.util.core.DummyClass
at test.ariba.util.core.ClassUtilTest.classForNameNonCachingTest(ClassUtilTest.java:240)
at test.ariba.util.core.ClassUtilTest.runTests(ClassUtilTest.java:54)
at test.ariba.util.core.ClassUtilTest.main(ClassUtilTest.java:37)
Field Summary |
static java.lang.String |
ClassName
|
Constructor Summary |
NonCachingClassLoader(java.lang.ClassLoader parent,
java.lang.String pattern)
Performs initialization for NonCachingClassLoader by calling
the super and setting the pattern for the class. |
NonCachingClassLoader(java.lang.String pattern)
Performs initialization for NonCachingClassLoader by calling
the super and setting the pattern for the class. |
Method Summary |
java.lang.Class |
loadClass(java.lang.String className)
Simple version of loadClass for external clients
since they will always want the class resolved before it is
returned to them. |
java.lang.Class |
loadClass(java.lang.String className,
boolean resolveIt)
Main loadClass method for loading a class and forcing a reload
of the class from disk if the class name conforms to the pattern
set as the 'pattern' for the class. |
Methods inherited from class java.lang.ClassLoader |
clearAssertionStatus, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus |
Methods inherited from class java.lang.Object |
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
ClassName
public static final java.lang.String ClassName
- See Also:
- Constant Field Values
NonCachingClassLoader
public NonCachingClassLoader(java.lang.String pattern)
- Performs initialization for NonCachingClassLoader by calling
the super and setting the pattern for the class. The
pattern is the pattern that will be used to identify
classes that NonCachingClassLoader should always reload from
disk.
- Parameters:
pattern
- for identifying classes to reload
NonCachingClassLoader
public NonCachingClassLoader(java.lang.ClassLoader parent,
java.lang.String pattern)
- Performs initialization for NonCachingClassLoader by calling
the super and setting the pattern for the class. The
pattern is the pattern that will be used to identify
classes that NonCachingClassLoader should always reload from
disk.
- Parameters:
parent
- parent class loader used for delegationpattern
- for identifying classes to reload
loadClass
public java.lang.Class loadClass(java.lang.String className)
throws java.lang.ClassNotFoundException
- Simple version of loadClass for external clients
since they will always want the class resolved before it is
returned to them.
- Overrides:
loadClass
in class java.lang.ClassLoader
- Parameters:
className
- the name of the desired Class
- Throws:
java.lang.ClassNotFoundException
loadClass
public java.lang.Class loadClass(java.lang.String className,
boolean resolveIt)
throws java.lang.ClassNotFoundException
- Main loadClass method for loading a class and forcing a reload
of the class from disk if the class name conforms to the pattern
set as the 'pattern' for the class.
- Overrides:
loadClass
in class java.lang.ClassLoader
- Parameters:
className
- the name of the desired ClassresolveIt
- true if the Class needs to be resolved
- Throws:
java.lang.ClassNotFoundException
AribaWeb User Interface Development Framework
Copyright © 2000-2014 Ariba, Inc. All Rights Reserved.