Class ClassLoaderResolverImpl

  • All Implemented Interfaces:
    ClassLoaderResolver

    public class ClassLoaderResolverImpl
    extends java.lang.Object
    implements ClassLoaderResolver
    A basic implementation of a ClassLoaderResolver. A ClassLoaderResolver provides a series of methods for resolving classes from their names. It supports up to 3 class loaders, based loosely on JDO Spec section 12.5. The class loaders will be used in this order:
    • The loader that loaded the class or instance referred to in the API that caused this class to be loaded.
      • In case of query, this is the loader of the candidate class, or the loader of the object passed to the newQuery
      • In case of navigation from a persistent instance, this is the loader of the class of the instance.
      • In the case of getExtent with subclasses, this is the loader of the candidate class.
      • In the case of getObjectById, this is the loader of the object id instance.
      • Other cases do not have an explicit loader.
    • The loader returned in the current context by Thread.getContextClassLoader().
    • The loader returned by Thread.getContextClassLoader() at the time of creating an ExecutionContext.
    • The loader registered for dynamically creating and loading classes at runtime.
    TODO Provide a way of flushing a classname from the cached classes so we can reload a class
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected java.lang.ClassLoader contextLoader
      ClassLoader initialised by the context (ExecutionContext).
      protected int contextLoaderHashCode
      Hash code cache for performance improvement
      protected java.util.Map<java.lang.String,​java.lang.Class> jreClasses  
      protected java.util.Map<java.lang.String,​java.lang.Class> loadedClasses
      Cache for loaded classes
      (package private) java.lang.ThreadLocal primary
      The primary class
      protected java.util.Map<java.lang.String,​java.net.URL> resources
      Cache for resources
      protected java.lang.ClassLoader runtimeLoader
      ClassLoader registered to load runtime created classes.
      protected int runtimeLoaderHashCode
      Hash code cache for performance improvement
      protected java.util.Map<java.lang.String,​java.lang.Class> unloadedClasses
      Cache for loaded classes
      protected java.lang.ClassLoader userRegisteredLoader
      ClassLoader registered to load classes (e.g set in the persistence properties as the primary loader).
      protected int userRegisteredLoaderHashCode
      Hash code cache for performance improvement
    • Constructor Summary

      Constructors 
      Constructor Description
      ClassLoaderResolverImpl()
      Constructor for non-PersistenceManager cases so there is no PM context loader.
      ClassLoaderResolverImpl​(java.lang.ClassLoader ctxLoader)
      Constructor for ExecutionContext cases.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.lang.Class classForName​(java.lang.String name)
      JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
      java.lang.Class classForName​(java.lang.String name, boolean initialize)
      JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
      java.lang.Class classForName​(java.lang.String name, java.lang.ClassLoader primary)
      JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
      java.lang.Class classForName​(java.lang.String name, java.lang.ClassLoader primary, boolean initialize)
      JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
      private java.lang.Class classForNameWithInitialize​(java.lang.String name, java.lang.ClassLoader primary)
      JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
      private java.lang.Class classOrNull​(java.lang.String name, java.lang.ClassLoader loader)
      Returns the Class.
      private java.lang.Class ClassOrNullWithInitialize​(java.lang.String name, java.lang.ClassLoader loader)
      Returns the Class.
      java.net.URL getResource​(java.lang.String resourceName, java.lang.ClassLoader primary)
      Finds the resource with the given name.
      java.util.Enumeration getResources​(java.lang.String resourceName, java.lang.ClassLoader primary)
      Finds all the resources with the given name.
      boolean isAssignableFrom​(java.lang.Class class_1, java.lang.String class_name_2)
      Utility to check the assignability of 2 classes in accordance with JDO's Class Loading mechanism.
      boolean isAssignableFrom​(java.lang.String class_name_1, java.lang.Class class_2)
      Utility to check the assignability of 2 classes in accordance with JDO's Class Loading mechanism.
      boolean isAssignableFrom​(java.lang.String class_name_1, java.lang.String class_name_2)
      Utility to check the assignability of 2 classes in accordance with JDO's Class Loading mechanism.
      protected void loadJreClasses()  
      private java.lang.String newCacheKey​(java.lang.String prefix, java.lang.ClassLoader primary, java.lang.ClassLoader contextClassLoader)
      Compute the key hashCode based for all classLoaders
      void registerUserClassLoader​(java.lang.ClassLoader loader)
      ClassLoader registered by users to load classes.
      void setPrimary​(java.lang.ClassLoader primary)
      Sets the primary classloader for the current thread
      void setRuntimeClassLoader​(java.lang.ClassLoader loader)
      ClassLoader registered to load classes created at runtime.
      java.lang.String toString()  
      void unsetPrimary()
      Unsets the primary classloader for the current thread
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • contextLoader

        protected final java.lang.ClassLoader contextLoader
        ClassLoader initialised by the context (ExecutionContext).
      • contextLoaderHashCode

        protected int contextLoaderHashCode
        Hash code cache for performance improvement
      • runtimeLoader

        protected java.lang.ClassLoader runtimeLoader
        ClassLoader registered to load runtime created classes.
      • runtimeLoaderHashCode

        protected int runtimeLoaderHashCode
        Hash code cache for performance improvement
      • userRegisteredLoader

        protected java.lang.ClassLoader userRegisteredLoader
        ClassLoader registered to load classes (e.g set in the persistence properties as the primary loader).
      • userRegisteredLoaderHashCode

        protected int userRegisteredLoaderHashCode
        Hash code cache for performance improvement
      • jreClasses

        protected java.util.Map<java.lang.String,​java.lang.Class> jreClasses
      • loadedClasses

        protected java.util.Map<java.lang.String,​java.lang.Class> loadedClasses
        Cache for loaded classes
      • unloadedClasses

        protected java.util.Map<java.lang.String,​java.lang.Class> unloadedClasses
        Cache for loaded classes
      • resources

        protected java.util.Map<java.lang.String,​java.net.URL> resources
        Cache for resources
      • primary

        java.lang.ThreadLocal primary
        The primary class
    • Constructor Detail

      • ClassLoaderResolverImpl

        public ClassLoaderResolverImpl​(java.lang.ClassLoader ctxLoader)
        Constructor for ExecutionContext cases.
        Parameters:
        ctxLoader - Loader from ExecutionContext initialisation time.
      • ClassLoaderResolverImpl

        public ClassLoaderResolverImpl()
        Constructor for non-PersistenceManager cases so there is no PM context loader.
    • Method Detail

      • loadJreClasses

        protected void loadJreClasses()
      • classForName

        public java.lang.Class classForName​(java.lang.String name,
                                            java.lang.ClassLoader primary)
        JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5). Try 3 loaders, starting with user-supplied loader, then try the current thread's loader, and finally try the PM context loader. This method does not initialize the class itself.
        Specified by:
        classForName in interface ClassLoaderResolver
        Parameters:
        name - Name of the Class to be loaded
        primary - primary ClassLoader to use (or null)
        Returns:
        The class given the name, using the required loader.
        Throws:
        ClassNotResolvedException - if the class can't be found in the classpath
      • classForNameWithInitialize

        private java.lang.Class classForNameWithInitialize​(java.lang.String name,
                                                           java.lang.ClassLoader primary)
        JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5). Try 3 loaders, starting with user-supplied loader, then try the current thread's loader, and finally try the PM context loader.
        Parameters:
        name - Name of the Class to be loaded
        primary - primary ClassLoader to use (or null)
        Returns:
        The class given the name, using the required loader.
        Throws:
        ClassNotResolvedException - if the class can't be found in the classpath
      • newCacheKey

        private java.lang.String newCacheKey​(java.lang.String prefix,
                                             java.lang.ClassLoader primary,
                                             java.lang.ClassLoader contextClassLoader)
        Compute the key hashCode based for all classLoaders
        Parameters:
        prefix - the key prefix
        primary - the primary ClassLoader, or null
        contextClassLoader - the context ClassLoader, or null
        Returns:
        the computed hashCode
      • classForName

        public java.lang.Class classForName​(java.lang.String name,
                                            java.lang.ClassLoader primary,
                                            boolean initialize)
        JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
        Specified by:
        classForName in interface ClassLoaderResolver
        Parameters:
        name - Name of the Class to be loaded
        primary - the primary ClassLoader to use (or null)
        initialize - whether to initialize the class or not.
        Returns:
        The Class given the name, using the specified ClassLoader
        Throws:
        ClassNotResolvedException - if the class can't be found in the classpath
      • classForName

        public java.lang.Class classForName​(java.lang.String name)
        JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5). This method does not initialize the class itself.
        Specified by:
        classForName in interface ClassLoaderResolver
        Parameters:
        name - Name of the Class to be loaded
        Returns:
        The class given the name, using the required loader.
      • classForName

        public java.lang.Class classForName​(java.lang.String name,
                                            boolean initialize)
        JDO's Class Loading mechanism (Spec 1.0.1 Chapter 12.5).
        Specified by:
        classForName in interface ClassLoaderResolver
        Parameters:
        name - Name of the Class to be loaded
        initialize - whether to initialize the class or not.
        Returns:
        The Class given the name, using the specified ClassLoader
        Throws:
        ClassNotResolvedException - if the class can't be found in the classpath
      • isAssignableFrom

        public boolean isAssignableFrom​(java.lang.String class_name_1,
                                        java.lang.String class_name_2)
        Utility to check the assignability of 2 classes in accordance with JDO's Class Loading mechanism. This will check class_1.isAssignableFrom(class_2);
        Specified by:
        isAssignableFrom in interface ClassLoaderResolver
        Parameters:
        class_name_1 - Name of first class
        class_name_2 - Name of second class
        Returns:
        Whether Class 2 is assignable from Class 1
      • isAssignableFrom

        public boolean isAssignableFrom​(java.lang.String class_name_1,
                                        java.lang.Class class_2)
        Utility to check the assignability of 2 classes in accordance with JDO's Class Loading mechanism. This will check class_1.isAssignableFrom(class_2);
        Specified by:
        isAssignableFrom in interface ClassLoaderResolver
        Parameters:
        class_name_1 - Name of first class
        class_2 - Second class
        Returns:
        Whether Class 2 is assignable from Class 1
      • isAssignableFrom

        public boolean isAssignableFrom​(java.lang.Class class_1,
                                        java.lang.String class_name_2)
        Utility to check the assignability of 2 classes in accordance with JDO's Class Loading mechanism. This will check class_1.isAssignableFrom(class_2);
        Specified by:
        isAssignableFrom in interface ClassLoaderResolver
        Parameters:
        class_1 - First class
        class_name_2 - Name of second class
        Returns:
        Whether Class 2 is assignable from Class 1
      • classOrNull

        private java.lang.Class classOrNull​(java.lang.String name,
                                            java.lang.ClassLoader loader)
        Returns the Class. This method does not initialize the class
        Parameters:
        name - the class name
        loader - the ClassLoader
        Returns:
        Class the class loaded; null if not found
      • ClassOrNullWithInitialize

        private java.lang.Class ClassOrNullWithInitialize​(java.lang.String name,
                                                          java.lang.ClassLoader loader)
        Returns the Class. Initializes it if found
        Parameters:
        name - the class name
        loader - the ClassLoader
        Returns:
        Class the class loaded; null if not found
      • setRuntimeClassLoader

        public void setRuntimeClassLoader​(java.lang.ClassLoader loader)
        ClassLoader registered to load classes created at runtime.
        Specified by:
        setRuntimeClassLoader in interface ClassLoaderResolver
        Parameters:
        loader - The ClassLoader in which classes are defined
      • registerUserClassLoader

        public void registerUserClassLoader​(java.lang.ClassLoader loader)
        ClassLoader registered by users to load classes. One ClassLoader can be registered, and if one ClassLoader is already registered, the registered ClassLoader is replaced by loader.
        Specified by:
        registerUserClassLoader in interface ClassLoaderResolver
        Parameters:
        loader - The ClassLoader in which classes are loaded
      • getResources

        public java.util.Enumeration getResources​(java.lang.String resourceName,
                                                  java.lang.ClassLoader primary)
                                           throws java.io.IOException
        Finds all the resources with the given name.
        Specified by:
        getResources in interface ClassLoaderResolver
        Parameters:
        resourceName - the resource name. If resourceName starts with "/", remove it before searching.
        primary - the primary ClassLoader to use (or null)
        Returns:
        An enumeration of URL objects for the resource. If no resources could be found, the enumeration will be empty. Resources that the class loader doesn't have access to will not be in the enumeration.
        Throws:
        java.io.IOException - If I/O errors occur
        See Also:
        ClassLoader.getResources(java.lang.String)
      • getResource

        public java.net.URL getResource​(java.lang.String resourceName,
                                        java.lang.ClassLoader primary)
        Finds the resource with the given name.
        Specified by:
        getResource in interface ClassLoaderResolver
        Parameters:
        resourceName - the path to resource name relative to the classloader root path. If resourceName starts with "/", remove it before searching.
        primary - the primary ClassLoader to use (or null)
        Returns:
        A URL object for reading the resource, or null if the resource could not be found or the invoker doesn't have adequate privileges to get the resource.
        See Also:
        ClassLoader.getResource(java.lang.String)
      • setPrimary

        public void setPrimary​(java.lang.ClassLoader primary)
        Sets the primary classloader for the current thread
        Specified by:
        setPrimary in interface ClassLoaderResolver
        Parameters:
        primary - the primary classloader
      • unsetPrimary

        public void unsetPrimary()
        Unsets the primary classloader for the current thread
        Specified by:
        unsetPrimary in interface ClassLoaderResolver
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object