classpathhelper
Class CGClassLoader

java.lang.Object
  extended byjava.lang.ClassLoader
      extended byclasspathhelper.CGClassLoader

public class CGClassLoader
extends java.lang.ClassLoader

ClassLoader that is capable of also providing ClassDetail objects which represent a static view of a class' dependencies.

Usage

CGClassLoader can be created like almost any other ClassLoader.


   CGClassLoader cl  = new CGClassLoader(parent, classpathString);
 
   or
 
   CGClassLoader cl = new CGClassLoader( classpathString );
 
   and used to references java.lang.Class objects or ClassDetail.
 
   cl.getClassDetail(classname);
   cl.findClass(classname);
 

In addition to familiar classpath constructors, CGClassLoader can also take an array of ClassPathElement objects, which allow store level filters (to hide classes) to also be added. CGClassLoader(ClassPathElement[]).

Implementation Notes

The class loader synchronizes on an internal mutex that is shared by all instances of this class loader. It is important for all classloaders within a hierarchy to share the same synchronization lock because traversal of the hierarchy does not always occur in order (allowing locks to be acquired in order). Instead, because of the referred-to-from information which allows ancestor class loaders to become aware of descendent class loaders (this is unique to CGClassLoader and not usually the case for standard class loaders) the classloaders are searched out of order. When previously using a synchronized (this) approach, deadlock occassionally would occur because one thread was traversing the classloaders descendent to parent (normal ordering) while another (which was calculating referred-to information) was traverssing it in the opposite direction, with each thread hanging on a lock, waiting for the other thread.

ClassLoaders maintain a SessionCache to store values that are computed frequently. Session caches are created by the root classloader and shared by all child classloaders.

Since:
1.0
Author:
bharris

Field Summary
protected  PackageStore packageCache
           
protected  SessionCache sessionCache
           
 
Constructor Summary
CGClassLoader(CGClassLoaderFilter clFilter, ClassPathElement[] elements)
          Constructor that allows for more precise control over the contents of the objects that make up the classpath.
CGClassLoader(CGClassLoaderFilter clFilter, java.lang.String classpath)
           
CGClassLoader(java.lang.ClassLoader parent, CGClassLoaderFilter clFilter, ClassPathElement[] elements)
          Constructor that allows for more precise control over the contents of the objects that make up the classpath.
CGClassLoader(java.lang.ClassLoader parent, CGClassLoaderFilter clFilter, java.lang.String classpath)
           
CGClassLoader(java.lang.ClassLoader parent, ClassPathElement[] elements)
          Constructor that allows for more precise control over the contents of the objects that make up the classpath.
CGClassLoader(java.lang.ClassLoader parent, java.lang.String classpath)
           
CGClassLoader(ClassPathElement[] elements)
          Constructor that allows for more precise control over the contents of the objects that make up the classpath.
CGClassLoader(java.lang.String classpath)
           
 
Method Summary
protected  void addBlockedLocations(ClassDetail detail, java.lang.String likelyPath, boolean callParent)
          Internal method used to add blocked locations to a class detail as well as the locations in this classpath.
protected  void addBlockedLocations(ContentDetail content)
          Internal method that iterates through this class loaders locations, adding any blocked classes to the contexts list.
protected  void addReverseDependencies(ClassDetail detail)
          Internal method that adds this class to the list of classes that this class depends on (their referred to by list).
protected  java.lang.Class findClass(java.lang.String name)
          Method for finding a specific class.
protected  Package findPackage(PackageStore cache, java.lang.String packagename)
          Internal method for finds a specific package visible from this classloader.
 Package findPackage(java.lang.String packagename)
          Finds a specific package visible from this classloader.
 java.lang.String[] getAllLocationDescriptions()
           
protected  void getAllLocationDescriptions(java.util.List results)
          Internal workhorse method for getAllLocationDescriptions() that adds all this classloaders location descriptions, then recursively calls the parents instance of this method (if it is also a CGClassLoader).
 ClassDetail getClassDetail(java.lang.String classname)
          Returns the class details for the given class name.
protected static java.lang.String getClassFromSignature(java.lang.String signature)
          Internal helper method that can extract a classname from a parameter signature by stripping the [] from the signature (if present).
 ContentDetail getContent(ContentDescription desc)
          Get the detail object for a specific content description.
 CGClassLoader[] getHierarchyOrder()
          Calculates a sorted list containing this classloader and its ancestors in the order that they will be searched (zero is the first classloader, etc).
 Location getLocation(java.lang.String locationDescription)
          Get's a location based on its description.
 java.lang.String getLocationDescription(java.lang.Class clazz)
          Return's the location where the class was originally from.
 java.lang.String[] getLocationDescriptions()
           
 Location[] getLocations()
           
protected  java.lang.Object getMutex()
          Returns the object that should be used for synchronizing over this classloader.
 java.lang.String getName()
          Returns the 'name' of this ClassLoader.
 Package[] getPackages(boolean includeSub)
          Gets the packages in this classloader.
protected  Package[] getPackages(PackageStore cache, boolean includeSub)
          Internal method that finds the packages available from this classloader.
 java.net.URL getResource(java.lang.String path)
           
 boolean getSearchParentFirst()
          The search order for looking up classes and class detail objects.
protected  boolean getSearchParentFirst(java.lang.String classname)
          Internal method that combines the typical getSearchParentFirst() with the CGClassLoaderFilter.invertSearchOrder(CGClassLoader, String) method to determine the specific search order for a specific class.
 ContentDetail getURLContent(java.lang.String resourcePath)
          Returns the content object for the URL resource path supplied.
protected  void init(java.lang.ClassLoader parent, CGClassLoaderFilter clFilter, ClassPathElement[] elements)
          Method called to initialize the classloader.
protected  void init(java.lang.ClassLoader parent, CGClassLoaderFilter clFilter, java.lang.String classpath)
          Initializes this class loader by tokenizing the classpath based on standard platform separator tokens.
protected  void innerGetHierarchyOrder(java.util.List order)
          Internal method that recursively computes the order that class loaders will be searched for classes.
protected  void loadAllContentDetails()
          Internal method that loads all the content details in this class load as well as its parents.
protected  void loadContent(Location location)
          Loads all the content at a given location.
protected  java.lang.Object[] returnAggregatedClassDetailMethod(java.lang.String location, java.lang.String methodName, java.lang.Object[] args, java.lang.Class arrayType, classpathhelper.Filter filter)
          Internal method used to aggregate results from methods from ClassDetail.
 void setName(java.lang.String theName)
          Sets the name for this ClassLoader.
 void setSearchParentFirst(boolean parentFirst)
          Method that should be called immediately after construction before any classes or class detail objects are looked up.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.ClassLoader
clearAssertionStatus, defineClass, defineClass, defineClass, definePackage, findLibrary, findLoadedClass, findResource, findResources, findSystemClass, getPackage, getPackages, getParent, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, loadClass, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

sessionCache

protected SessionCache sessionCache

packageCache

protected PackageStore packageCache
Constructor Detail

CGClassLoader

public CGClassLoader(java.lang.ClassLoader parent,
                     java.lang.String classpath)
Parameters:
parent - A parent class loader.
classpath - standard platform classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(java.lang.ClassLoader parent,
                     CGClassLoaderFilter clFilter,
                     java.lang.String classpath)
Parameters:
parent - A parent class loader.
clFilter - The filter to associate with this ClassLoader.
classpath - standard platform classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(java.lang.ClassLoader parent,
                     ClassPathElement[] elements)
Constructor that allows for more precise control over the contents of the objects that make up the classpath.

Parameters:
parent - A parent class loader.
elements - The elements that make up the classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(java.lang.ClassLoader parent,
                     CGClassLoaderFilter clFilter,
                     ClassPathElement[] elements)
Constructor that allows for more precise control over the contents of the objects that make up the classpath.

Parameters:
parent - A parent class loader.
clFilter - The filter to associate with this ClassLoader.
elements - The elements that make up the classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(java.lang.String classpath)
Parameters:
classpath - standard platform classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(CGClassLoaderFilter clFilter,
                     java.lang.String classpath)
Parameters:
clFilter - The filter to associte with this class loader.
classpath - standard platform classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(ClassPathElement[] elements)
Constructor that allows for more precise control over the contents of the objects that make up the classpath.

Parameters:
elements - The elements that make up the classpath.
Since:
1.0

CGClassLoader

public CGClassLoader(CGClassLoaderFilter clFilter,
                     ClassPathElement[] elements)
Constructor that allows for more precise control over the contents of the objects that make up the classpath.

Parameters:
clFilter - The filter to associate with this classloader.
elements - The elements that make up the classpath.
Since:
1.0
Method Detail

getName

public java.lang.String getName()
Returns the 'name' of this ClassLoader. Often times when ClassLoaders are grouped in a hierarchy they have a conceptual name (e.g. 'bootstrap', 'common', etc).

Returns:
The name of this class loader.
Since:
1.0

setName

public void setName(java.lang.String theName)
Sets the name for this ClassLoader. Often times when ClassLoaders are grouped in a hierarchy they have a conceptual name (e.g. 'bootstrap', 'common', etc).

Parameters:
theName -
Since:
1.0

getHierarchyOrder

public CGClassLoader[] getHierarchyOrder()

Calculates a sorted list containing this classloader and its ancestors in the order that they will be searched (zero is the first classloader, etc).

Typically this would be parent->descendent->descendent... but in some cases it is necessary to override this behavior.

Returns:
An array of class loaders from this class loaders ancestor chain sorted in the order they will be searched.
Since:
1.0

setSearchParentFirst

public void setSearchParentFirst(boolean parentFirst)

Method that should be called immediately after construction before any classes or class detail objects are looked up. This method can be used to set the search precedence of this classloader (whether it should look up classes in its parent before or after it searches its own path of locations).

This is typically not recommended but some containers allow this behavior to work around limitations when different versions of various classes are present.

Parameters:
parentFirst - true (default) if the parent class loader should be searched first, false if this ClassLoader should search its internal path before delegating to its parent.

Since:
1.0

getSearchParentFirst

public boolean getSearchParentFirst()
The search order for looking up classes and class detail objects.

Returns:
true If the parent class loaders will be consulted first, otherwise false
Since:
1.0

getLocationDescription

public java.lang.String getLocationDescription(java.lang.Class clazz)
Return's the location where the class was originally from.

Parameters:
clazz - The class.
Returns:
The description of the location (typically a path) or null if the location is not known.
Since:
1.0

getLocation

public Location getLocation(java.lang.String locationDescription)
Get's a location based on its description.

Parameters:
locationDescription - The description (typically a path).
Returns:
The location.
Since:
1.0

getLocationDescriptions

public java.lang.String[] getLocationDescriptions()
Returns:
An array of strings containing the location descriptions (typically paths to each location).
Since:
1.0

getAllLocationDescriptions

public java.lang.String[] getAllLocationDescriptions()
Returns:
An array of strings containing the location descriptions for this classloader and its parents locations.
Since:
1.0

getLocations

public Location[] getLocations()
Returns:
An array of the locations served by this classloader. As a note, even ignored locations are returned by this method.
Since:
1.0
See Also:
Location.isIgnored()

getURLContent

public ContentDetail getURLContent(java.lang.String resourcePath)
Returns the content object for the URL resource path supplied.

Parameters:
resourcePath - A resource path as would be supplied to getResource(String).
Returns:
The content description for the resource.

getClassDetail

public ClassDetail getClassDetail(java.lang.String classname)
                           throws java.lang.ClassNotFoundException
Returns the class details for the given class name.

Parameters:
classname - The class name to acquire the details for.
Returns:
The class details or null if this class was not loaded by this class loader.
Throws:
java.lang.ClassNotFoundException
Since:
1.0

getPackages

public Package[] getPackages(boolean includeSub)
Gets the packages in this classloader. Either the root packages can be returned or all of the packages in this classloader.

Parameters:
includeSub - true if all packages should be returned. false if only the root packages (those with one segment) should be returned.
Returns:
The packages found on this classloader.
Since:
1.2

findPackage

public Package findPackage(java.lang.String packagename)
Finds a specific package visible from this classloader.

Parameters:
packagename - The name of the package to lookup.
Returns:
The package or null if the package cannot be found.
Since:
1.2

getContent

public ContentDetail getContent(ContentDescription desc)
                         throws java.lang.ClassNotFoundException
Get the detail object for a specific content description.

Parameters:
desc - The content description.
Returns:
The loaded detail.
Throws:
java.lang.ClassNotFoundException - If the content is a class description and the class cannot be found.
Since:
1.2

getPackages

protected Package[] getPackages(PackageStore cache,
                                boolean includeSub)
Internal method that finds the packages available from this classloader.

Parameters:
cache - The cache to load packages from.
includeSub - true to include all packages. false to only load root packages (those with one segment).
Returns:
The packages in this classloader.
Since:
1.2

findPackage

protected Package findPackage(PackageStore cache,
                              java.lang.String packagename)
Internal method for finds a specific package visible from this classloader.

Parameters:
cache - The cache to use.
packagename - The package to lookup.
Returns:
The package or null if the package cannot be found.
Since:
1.2

getMutex

protected java.lang.Object getMutex()
Returns the object that should be used for synchronizing over this classloader. It is important to use a common lock because classloaders can be stacked in a hierarchy and that hierarchy is traveresed backwards and forwards. If a standard synchronized (this) approach is taken deadlock can easily ensue.

Returns:
The mutex to used when performing a thread critical operation.
Since:
1.0

init

protected void init(java.lang.ClassLoader parent,
                    CGClassLoaderFilter clFilter,
                    java.lang.String classpath)
Initializes this class loader by tokenizing the classpath based on standard platform separator tokens.

Parameters:
parent - The parent classloader
clFilter - The filter to associate with this class loader.
classpath - A standard classpath string.
Since:
1.0

init

protected void init(java.lang.ClassLoader parent,
                    CGClassLoaderFilter clFilter,
                    ClassPathElement[] elements)
Method called to initialize the classloader.

Parameters:
parent - The parent classloader.
clFilter - The filter to associate with this classloader.
elements - The contents of the classpath broken into elements.
Since:
1.0

getAllLocationDescriptions

protected void getAllLocationDescriptions(java.util.List results)
Internal workhorse method for getAllLocationDescriptions() that adds all this classloaders location descriptions, then recursively calls the parents instance of this method (if it is also a CGClassLoader).

Parameters:
results - The list to store the descriptions in.
Since:
1.0

addReverseDependencies

protected void addReverseDependencies(ClassDetail detail)
Internal method that adds this class to the list of classes that this class depends on (their referred to by list).

Parameters:
detail - The class whose dependents will be updated with this class as a reference.
Since:
1.0

loadAllContentDetails

protected void loadAllContentDetails()
Internal method that loads all the content details in this class load as well as its parents. This is an expensive method but it's needed for some calculations such as who depends on whom.

Since:
1.1

getSearchParentFirst

protected boolean getSearchParentFirst(java.lang.String classname)

Internal method that combines the typical getSearchParentFirst() with the CGClassLoaderFilter.invertSearchOrder(CGClassLoader, String) method to determine the specific search order for a specific class.

Parameters:
classname - The class being looked up.
Returns:
true If this class should be looked up in the parent class loader first, false if this class should be looked up in this classloader first.

innerGetHierarchyOrder

protected void innerGetHierarchyOrder(java.util.List order)

Internal method that recursively computes the order that class loaders will be searched for classes. Typically a parent class loader is consulted before a child classloader but in some instances this can be changed (@link #setSearchParentFirst}.

This method is the workhorse implementation for getHierarchyOrder(), which should be used to publicly access this information.

Parameters:
order - A list that will be populated with all the class loaders (this classloader and its ancestors) in order that they will be searched.
Since:
1.0

getClassFromSignature

protected static java.lang.String getClassFromSignature(java.lang.String signature)
Internal helper method that can extract a classname from a parameter signature by stripping the [] from the signature (if present).

Parameters:
signature - Class description as you'd see it in a method signature.
Returns:
The classname.
Since:
1.0

returnAggregatedClassDetailMethod

protected java.lang.Object[] returnAggregatedClassDetailMethod(java.lang.String location,
                                                               java.lang.String methodName,
                                                               java.lang.Object[] args,
                                                               java.lang.Class arrayType,
                                                               classpathhelper.Filter filter)

Internal method used to aggregate results from methods from ClassDetail.

Since the pattern for aggregating results from ClassDetail is pretty much the same except for the method called, this method uses reflection to call methods on all the detail objects.

Parameters:
location - The location to load the class detail from.
methodName - The name of the method on ClassDetail to execute.
args - arguments required by the method, or null if none are needed.
arrayType - The type of object that return array should be created out of.
filter - An object that can filter out specific items.
Returns:
An array of objects typically corresponding to class names.
Since:
1.1

addBlockedLocations

protected void addBlockedLocations(ContentDetail content)
Internal method that iterates through this class loaders locations, adding any blocked classes to the contexts list.

Parameters:
content - The context
Since:
1.1

addBlockedLocations

protected void addBlockedLocations(ClassDetail detail,
                                   java.lang.String likelyPath,
                                   boolean callParent)

Internal method used to add blocked locations to a class detail as well as the locations in this classpath.

Typically parent class loaders are consulted first, meaning blocked locations only occur later in the classpath or in descendent classloaders, but if the searchParentFirst property is set to false a child might search itself first, in which case blocked classes can appear in the parent. This method handles both the normal case (callParent=false) or the case where parent class loaders need to looked for blocked classes (callParent=true).

Implementation Notes

This method also updates a locations list of blocked classes. If callParent is true this will mean that a parents location is marked with a blocked class. This is fine if only a single chain of class loaders exists, but will be invalid if a tree of classloaders exists, since the list of blocked classes is not maintained per branch. The notion of a blocked class really only applies to a specific chain of classloaders and is different depending on which classloader is the original object called.

Parameters:
detail - The detail object to update.
likelyPath - The likelyPath within the stores of this class. This is passed around as an optimization.
callParent - Flag indicating whether or not this method should recurse upwards to parent classloaders. Calling parents only applies if setSearchParentFirst(boolean) is set to false.
Since:
1.0

loadContent

protected void loadContent(Location location)
Loads all the content at a given location.

Parameters:
location - The location object to load all the content from.
Since:
1.1

findClass

protected java.lang.Class findClass(java.lang.String name)
                             throws java.lang.ClassNotFoundException
Method for finding a specific class. It first looks in its parents class loader and then searches the locations on its class path.

Parameters:
name - The name of the class to look up.
Throws:
java.lang.ClassNotFoundException - if the class cannot be found.

getResource

public java.net.URL getResource(java.lang.String path)

toString

public java.lang.String toString()