ariba.util.core
Class NonCachingClassLoader

java.lang.Object
  extended by java.lang.ClassLoader
      extended by 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
 

Field Detail

ClassName

public static final java.lang.String ClassName
See Also:
Constant Field Values
Constructor Detail

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 delegation
pattern - for identifying classes to reload
Method Detail

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 Class
resolveIt - 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.