Class JarClassLoader

java.lang.Object
java.lang.ClassLoader
net.sf.basedb.util.JarClassLoader

public final class JarClassLoader extends ClassLoader
A class loader implementation that loads classes from JAR files. Each JAR file requires a separate instance of this class. Use the getInstance(String) method to get an existing or create a new instance for a specific JAR file. If the classes in the JAR file requires other classes in another JAR file to work, the paths to those JAR files must be listed in the Class-Path attribute in the META-INF/MANIFEST.MF file. For example:
Manifest-Version: 1.0
Class-Path: OtherJarPlugin.jar
If more than one JAR is needed separate them with one or more spaces. Note! It is only the Class-Path entry for the JAR file passed to the getInstance(String) method that is checked. The manifest file is not checked for the other JARs.

This class loader will by default first look in the specified JAR files for a class or resource and only if not found delegate to the parent class loader. This behaviour can be changed by calling setDelegateFirst(boolean) or by setting X-Delegate-First : true in the MANIFEST.MF file in the main JAR file.

Version:
2.0
Author:
Nicklas
Last modified
$Date: 2019-05-22 09:56:58 +0200 (ons, 22 maj 2019) $
  • Field Details

    • log

      private static final Logger log
    • classLoaders

      private static final HashMap<String,JarClassLoader> classLoaders
      A map of all loaded class loaders.
    • mainJarFile

      private final File mainJarFile
      The main JAR file to load classes from.
    • classPath

      private final Map<String,List<File>> classPath
      Contains mappings from class names to the JAR file in which the class implementation can be found.
    • delegateFirst

      private boolean delegateFirst
      If we should delegate to the parent class loader first.
    • jarFiles

      private final Map<File,JarClassLoader.JarInfo> jarFiles
      For keeping track of jar files listed by Class-Path entry in the manifest file.
    • proxyLoaders

      private final List<JarClassLoader.JarClassLoaderProxy> proxyLoaders
      Class loaders for extensions.
    • jarTimeStamp

      private final long jarTimeStamp
      The timestamp of the JAR file.
    • jarSize

      private final long jarSize
      The size of the JAR file.
    • MAX_PARENTS

      private static final int MAX_PARENTS
      See Also:
  • Constructor Details

    • JarClassLoader

      private JarClassLoader(String jarPath) throws IOException
      Create a new JAR file class loader.
      Parameters:
      jarPath - The path to the JAR file
      Throws:
      InvalidDataException - If the JAR file can't be loaded
      IOException - If there is another IO-related error
  • Method Details

    • getInstance

      public static final ClassLoader getInstance(String jarPath) throws IOException
      Get a class loader for the specified JAR file. If a class loader for the specified file already exists, that class loader is returned, otherwise a new class loader is created.
      Parameters:
      jarPath - The path to a JAR file
      Returns:
      A class loader
      Throws:
      IOException - If the jar file can't be loaded
    • getInstance

      public static final ClassLoader getInstance(String jarPath, boolean autoUnload) throws IOException
      Get a class loader for the specified JAR file, optionally unloading an the old one if the JAR file has been modified. A new class loader is created if no class loader exists or if autoUnload is true and the JAR file has changed since the existing class loader was created.
      Parameters:
      jarPath - The path to a JAR file
      autoUnload - If TRUE the old class loaded will automatically be unloaded if the JAR file or any one it depends on (listed in the Class-Path attribute in the manifest file) has been modified (if the timestamp and/or size) is different
      Returns:
      A class loader
      Throws:
      IOException - If the jar file can't be loaded
      Since:
      2.4
    • newInstance

      public static final ClassLoader newInstance(String jarPath) throws IOException
      Get a new class loader for the specified jar file.
      Parameters:
      jarPath - The path to the jar file
      Returns:
      A class loader object
      Throws:
      IOException - If the jar file can't be loaded
    • exists

      public static final boolean exists(String jarPath)
      Check if a class loader for the given JAR file exists.
      Parameters:
      jarPath - The path to the JAR file
      Returns:
      TRUE if a class loader exists, FALSE otherwise
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • findClass

      protected Class<?> findClass(String name) throws ClassNotFoundException
      Overrides:
      findClass in class ClassLoader
      Throws:
      ClassNotFoundException
    • isPackageDefined

      private boolean isPackageDefined(String name)
    • findResource

      protected URL findResource(String name)
      Overrides:
      findResource in class ClassLoader
    • findResources

      protected Enumeration<URL> findResources(String name)
      Overrides:
      findResources in class ClassLoader
    • loadClass

      protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
      Overrides:
      loadClass in class ClassLoader
      Throws:
      ClassNotFoundException
    • getResource

      public URL getResource(String name)
      Overrides:
      getResource in class ClassLoader
    • getResources

      public Enumeration<URL> getResources(String name) throws IOException
      Overrides:
      getResources in class ClassLoader
      Throws:
      IOException
    • setDelegateFirst

      public void setDelegateFirst(boolean delegateFirst)
      If the class loader should delegate to the parent class loader before trying to find the class by it's own.
      Parameters:
      delegateFirst - TRUE to delegate to parent first, FALSE to only delegate if the class is not found
      Since:
      2.13
    • getDelegateFirst

      public boolean getDelegateFirst()
      If this class loader delegates to the parent class loader before or after trying to find the class by itself.
      Since:
      2.13
    • hasChanged

      public boolean hasChanged(boolean checkSecondary)
      Check if the JAR file this class loader loads is classes from has changed since this class loader was created.
      Parameters:
      checkSecondary - TRUE to also check secondary JAR files listed in the Class-Path entry of the manifest file
      Since:
      2.8
    • classNameToPath

      private String classNameToPath(String className)
      Convert a class name to a file path. Ie. replace dots with slahses and add .class to the end: net.sf.basedb.util.JarClassLoader -> net/sf/basedb/util/JarClassLoader.class
    • loadJarFile

      private void loadJarFile(File file, boolean followClassPath) throws IOException
      Open the specified JAR file, list all entries and put them in the classPath mapping.
      Parameters:
      file - The JAR file to open
      followClassPath - If the MANIFEST file should be checked for a Class-Path entry that lists other JAR files that also should be checked.
      Throws:
      IOException - If there is an error reading the JAR files
    • loadClassData

      private byte[] loadClassData(File file, String name) throws ClassNotFoundException
      Load the byte[] of the given class.
      Parameters:
      file - The JAR file in which the class implmentation is located
      name - The name of the class using regular naming convention, ie. net.sf.basedb.util.JarClassLoader
      Throws:
      ClassNotFoundException - If the class can't be loaded
    • definePackage

      private Package definePackage(String name, Manifest mf)
      Define the package with the given name using information from a manifest for vendor, title and version. The package should not already exist.
      Parameters:
      name - The name of the package
      mf - An optional manifest
      Returns:
      A package
      Since:
      2.16
    • loadClassInternal

      private Class<?> loadClassInternal(ClassLoader loader, String name)
    • addResources

      private void addResources(Vector<URL> resources, Enumeration<URL> e)