Package: org.codehaus.groovy.tools

## [Java] Class RootLoader

- org.codehaus.groovy.tools.RootLoader

-     public class RootLoader
      extends URLClassLoader

  This ClassLoader should be used as root of class loaders. Any RootLoader does have its own classpath. When searching for a class or resource this classpath will be used. Parent Classloaders are ignored first. If a class or resource can't be found in the classpath of the RootLoader, then parent is checked.

  Note: this is very against the normal behavior of classloaders. Normal is to first check parent and then look in the resources you gave this classloader.

  It's possible to add urls to the classpath at runtime through addURL(URL).

  Why using RootLoader? If you have to load classes with multiple classloaders and a classloader does know a class which depends on a class only a child of this loader does know, then you won't be able to load the class. To load the class the child is not allowed to redirect its search for the class to the parent first. That way the child can load the class. If the child does not have all classes to do this, this fails of course.

  For example:

             parentLoader   (has classpath: a.jar;c.jar)
                 |
                 |
             childLoader    (has classpath: a.jar;b.jar;c.jar)

  class C (from c.jar) extends B (from b.jar) childLoader.find("C")

       --> parentLoader does know C.class, try to load it
       --> to load C.class it has to load B.class
       --> parentLoader is unable to find B.class in a.jar or c.jar
       --> NoClassDefFoundException!

  if childLoader had tried to load the class by itself, there would be no problem. Changing childLoader to be a RootLoader instance will solve that problem.

- - ### Constructor Summary

    Constructors
    Constructor and description
    `RootLoader(ClassLoader parent)` Constructs a `RootLoader` without classpath.
    `RootLoader(URL[] urls, ClassLoader parent)` Constructs a `RootLoader` with a parent loader and an array of URLs as its classpath.
    `RootLoader(LoaderConfiguration lc)` Constructs a `RootLoader` with a LoaderConfiguration object which holds the classpath.

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public void` | `addURL(URL url)` Appends the specified URL to the list of URLs to search for classes and resources. If the URL specified is `null` or is already in the list of URLs, or if this loader is closed, then invoking this method has no effect. Parameters: `url` - the URL to be added to the search path of URLs
    `` | `protected Class<?>` | `findClass(String name)` Finds and loads the class with the specified name from the URL search path. Any URLs referring to JAR files are loaded and opened as needed until the class is found. throws: ClassNotFoundException if the class could not be found, or if the loader is closed. throws: NullPointerException if `name` is `null`. Parameters: `name` - the name of the class Returns: the resulting class
    `` | `public URL` | `getResource(String name)` Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code. The name of a resource is a '`/`'-separated path name that identifies the resource. Resources in named modules are subject to the encapsulation rules specified by Module.getResourceAsStream. Additionally, and except for the special case where the resource has a name ending with "`.class`", this method will only find resources in packages of named modules when the package is opened unconditionally (even if the caller of this method is in the same module as the resource). throws: NullPointerException If `name` is `null` revised: 9 Implementation Requirements: The default implementation will first search the parent class loader for the resource; if the parent is `null` the path of the class loader built into the virtual machine is searched. If not found, this method will invoke findResource(String) to find the resource. API Note: Where several modules are defined to the same class loader, and where more than one module contains a resource with the given name, then the ordering that modules are searched is not specified and may be very unpredictable. When overriding this method it is recommended that an implementation ensures that any delegation is consistent with the getResources(java.lang.String) getResources(String) method. Parameters: `name` - The resource name Returns: `URL` object for reading the resource; `null` if the resource could not be found, a `URL` could not be constructed to locate the resource, the resource is in a package that is not opened unconditionally, or access to the resource is denied by the security manager. Since: 1.1
    `` | `public Enumeration<URL>` | `getResources(String name)` Finds all the resources with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code. The name of a resource is a `/`-separated path name that identifies the resource. Resources in named modules are subject to the encapsulation rules specified by Module.getResourceAsStream. Additionally, and except for the special case where the resource has a name ending with "`.class`", this method will only find resources in packages of named modules when the package is opened unconditionally (even if the caller of this method is in the same module as the resource). throws: IOException If I/O errors occur throws: NullPointerException If `name` is `null` revised: 9 Implementation Requirements: The default implementation will first search the parent class loader for the resource; if the parent is `null` the path of the class loader built into the virtual machine is searched. It then invokes findResources(String) to find the resources with the name in this class loader. It returns an enumeration whose elements are the URLs found by searching the parent class loader followed by the elements found with `findResources`. API Note: Where several modules are defined to the same class loader, and where more than one module contains a resource with the given name, then the ordering is not specified and may be very unpredictable. When overriding this method it is recommended that an implementation ensures that any delegation is consistent with the getResource(java.lang.String) getResource(String) method. This should ensure that the first element returned by the Enumeration's `nextElement` method is the same resource that the `getResource(String)` method would return. Parameters: `name` - The resource name Returns: An enumeration of URL objects for the resource. If no resources could be found, the enumeration will be empty. Resources for which a `URL` cannot be constructed, are in a package that is not opened unconditionally, or access to the resource is denied by the security manager, are not returned in the enumeration. Since: 1.2
    `` | `protected Class<?>` | `loadClass(String name, boolean resolve)` Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order: Invoke findLoadedClass(String) to check if the class has already been loaded. Invoke the loadClass method on the parent class loader. If the parent is `null` the class loader built into the virtual machine is used, instead. Invoke the findClass(String) method to find the class. If the class was found using the above steps, and the `resolve` flag is true, this method will then invoke the resolveClass(Class) method on the resulting `Class` object. Subclasses of `ClassLoader` are encouraged to override findClass(String), rather than this method. Unless overridden, this method synchronizes on the result of getClassLoadingLock method during the entire class loading process. throws: ClassNotFoundException If the class could not be found Parameters: `name` - The binary name of the class `resolve` - If `true` then resolve the class Returns: The resulting `Class` object

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class URLClassLoader` | `clearAssertionStatus, close, equals, findResource, findResources, getClass, getDefinedPackage, getDefinedPackages, getName, getParent, getPlatformClassLoader, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, getURLs, getUnnamedModule, hashCode, isRegisteredAsParallelCapable, loadClass, newInstance, newInstance, notify, notifyAll, resources, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### public RootLoader(ClassLoader parent)

      Constructs a `RootLoader` without classpath.

      Parameters:
        `parent` - the parent Loader

    - #### public RootLoader(URL[] urls, ClassLoader parent)

      Constructs a `RootLoader` with a parent loader and an array of URLs as its classpath.

    - #### public RootLoader(LoaderConfiguration lc)

      Constructs a `RootLoader` with a LoaderConfiguration object which holds the classpath.

  - ### Method Detail

    - #### public void addURL(URL url)

      Appends the specified URL to the list of URLs to search for classes and resources.

      If the URL specified is `null` or is already in the list of URLs, or if this loader is closed, then invoking this method has no effect.

      Parameters:
        `url` - the URL to be added to the search path of URLs

    - #### protected Class<?> findClass(String name)

      Finds and loads the class with the specified name from the URL search path. Any URLs referring to JAR files are loaded and opened as needed until the class is found.

      throws:
        ClassNotFoundException if the class could not be found, or if the loader is closed.
      throws:
        NullPointerException if `name` is `null`.
      Parameters:
        `name` - the name of the class
      Returns:
        the resulting class

    - #### public URL getResource(String name)

      Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code.

      The name of a resource is a '`/`'-separated path name that identifies the resource.

      Resources in named modules are subject to the encapsulation rules specified by Module.getResourceAsStream. Additionally, and except for the special case where the resource has a name ending with "`.class`", this method will only find resources in packages of named modules when the package is opened unconditionally (even if the caller of this method is in the same module as the resource).

      throws:
        NullPointerException If `name` is `null`
      revised:
        9
      Implementation Requirements:
        The default implementation will first search the parent class loader for the resource; if the parent is `null` the path of the class loader built into the virtual machine is searched. If not found, this method will invoke findResource(String) to find the resource.
      API Note:
        Where several modules are defined to the same class loader, and where more than one module contains a resource with the given name, then the ordering that modules are searched is not specified and may be very unpredictable. When overriding this method it is recommended that an implementation ensures that any delegation is consistent with the getResources(java.lang.String) getResources(String) method.
      Parameters:
        `name` - The resource name
      Returns:
        `URL` object for reading the resource; `null` if the resource could not be found, a `URL` could not be constructed to locate the resource, the resource is in a package that is not opened unconditionally, or access to the resource is denied by the security manager.
      Since:
        1.1

    - #### public Enumeration<URL> getResources(String name)

      Finds all the resources with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code.

      The name of a resource is a `/`-separated path name that identifies the resource.

      Resources in named modules are subject to the encapsulation rules specified by Module.getResourceAsStream. Additionally, and except for the special case where the resource has a name ending with "`.class`", this method will only find resources in packages of named modules when the package is opened unconditionally (even if the caller of this method is in the same module as the resource).

      throws:
        IOException If I/O errors occur
      throws:
        NullPointerException If `name` is `null`
      revised:
        9
      Implementation Requirements:
        The default implementation will first search the parent class loader for the resource; if the parent is `null` the path of the class loader built into the virtual machine is searched. It then invokes findResources(String) to find the resources with the name in this class loader. It returns an enumeration whose elements are the URLs found by searching the parent class loader followed by the elements found with `findResources`.
      API Note:
        Where several modules are defined to the same class loader, and where more than one module contains a resource with the given name, then the ordering is not specified and may be very unpredictable. When overriding this method it is recommended that an implementation ensures that any delegation is consistent with the getResource(java.lang.String) getResource(String) method. This should ensure that the first element returned by the Enumeration's `nextElement` method is the same resource that the `getResource(String)` method would return.
      Parameters:
        `name` - The resource name
      Returns:
        An enumeration of URL objects for the resource. If no resources could be found, the enumeration will be empty. Resources for which a `URL` cannot be constructed, are in a package that is not opened unconditionally, or access to the resource is denied by the security manager, are not returned in the enumeration.
      Since:
        1.2

      Collapses entries that resolve to the same canonical jar file so callers such as ServiceLoader don't see the same providers twice when the launcher's startup classpath and the `load` entries in `groovy-starter.conf` reference the same jar (GROOVY-11978).

    - #### protected Class<?> loadClass(String name, boolean resolve)

      Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:

      1. Invoke findLoadedClass(String) to check if the class has already been loaded.

      2. Invoke the loadClass method on the parent class loader. If the parent is `null` the class loader built into the virtual machine is used, instead.

      3. Invoke the findClass(String) method to find the class.

      If the class was found using the above steps, and the `resolve` flag is true, this method will then invoke the resolveClass(Class) method on the resulting `Class` object.

      Subclasses of `ClassLoader` are encouraged to override findClass(String), rather than this method.

      Unless overridden, this method synchronizes on the result of getClassLoadingLock method during the entire class loading process.

      throws:
        ClassNotFoundException If the class could not be found
      Parameters:
        `name` - The binary name of the class
        `resolve` - If `true` then resolve the class
      Returns:
        The resulting `Class` object