Class 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-03-12 07:53:27 +0100 (tis, 12 mars 2019) $
    • Field Detail

      • log

        private static final org.slf4j.Logger log
      • 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.
      • jarTimeStamp

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

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

      • 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 Detail

      • 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
      • 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