Package net.sf.basedb.util
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 thegetInstance(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 theClass-Path
attribute in theMETA-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 theClass-Path
entry for the JAR file passed to thegetInstance(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 settingX-Delegate-First : true
in theMANIFEST.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) $
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) static class
JarClassLoader.JarClassLoaderProxy
A proxy class loader is typically needed when one extension depends on another extension.(package private) static class
JarClassLoader.JarInfo
-
Field Summary
Fields Modifier and Type Field Description private static HashMap<String,JarClassLoader>
classLoaders
A map of all loaded class loaders.private Map<String,List<File>>
classPath
Contains mappings from class names to the JAR file in which the class implementation can be found.private boolean
delegateFirst
If we should delegate to the parent class loader first.private Map<File,JarClassLoader.JarInfo>
jarFiles
For keeping track of jar files listed by Class-Path entry in the manifest file.private long
jarSize
The size of the JAR file.private long
jarTimeStamp
The timestamp of the JAR file.private static org.slf4j.Logger
log
private File
mainJarFile
The main JAR file to load classes from.private static int
MAX_PARENTS
private List<JarClassLoader.JarClassLoaderProxy>
proxyLoaders
Class loaders for extensions.
-
Constructor Summary
Constructors Modifier Constructor Description private
JarClassLoader(String jarPath)
Create a new JAR file class loader.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private void
addResources(Vector<URL> resources, Enumeration<URL> e)
private String
classNameToPath(String className)
Convert a class name to a file path.private Package
definePackage(String name, Manifest mf)
Define the package with the given name using information from a manifest for vendor, title and version.static boolean
exists(String jarPath)
Check if a class loader for the given JAR file exists.protected Class<?>
findClass(String name)
protected URL
findResource(String name)
protected Enumeration<URL>
findResources(String name)
boolean
getDelegateFirst()
If this class loader delegates to the parent class loader before or after trying to find the class by itself.static ClassLoader
getInstance(String jarPath)
Get a class loader for the specified JAR file.static ClassLoader
getInstance(String jarPath, boolean autoUnload)
Get a class loader for the specified JAR file, optionally unloading an the old one if the JAR file has been modified.URL
getResource(String name)
Enumeration<URL>
getResources(String name)
boolean
hasChanged(boolean checkSecondary)
Check if the JAR file this class loader loads is classes from has changed since this class loader was created.private boolean
isPackageDefined(String name)
protected Class<?>
loadClass(String name, boolean resolve)
private byte[]
loadClassData(File file, String name)
Load the byte[] of the given class.private Class<?>
loadClassInternal(ClassLoader loader, String name)
private void
loadJarFile(File file, boolean followClassPath)
Open the specified JAR file, list all entries and put them in theclassPath
mapping.static ClassLoader
newInstance(String jarPath)
Get a new class loader for the specified jar file.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.String
toString()
-
Methods inherited from class java.lang.ClassLoader
clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, definePackage, findClass, findLibrary, findLoadedClass, findResource, findSystemClass, getClassLoadingLock, getDefinedPackage, getDefinedPackages, getName, getPackage, getPackages, getParent, getPlatformClassLoader, getResourceAsStream, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, getUnnamedModule, isRegisteredAsParallelCapable, loadClass, registerAsParallelCapable, resolveClass, resources, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
-
-
-
-
Field Detail
-
log
private static final org.slf4j.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:
- Constant Field Values
-
-
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 loadedIOException
- 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 ifautoUnload
istrue
and the JAR file has changed since the existing class loader was created.- Parameters:
jarPath
- The path to a JAR fileautoUnload
- 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
-
findClass
protected Class<?> findClass(String name) throws ClassNotFoundException
- Overrides:
findClass
in classClassLoader
- Throws:
ClassNotFoundException
-
isPackageDefined
private boolean isPackageDefined(String name)
-
findResource
protected URL findResource(String name)
- Overrides:
findResource
in classClassLoader
-
findResources
protected Enumeration<URL> findResources(String name)
- Overrides:
findResources
in classClassLoader
-
loadClass
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
- Overrides:
loadClass
in classClassLoader
- Throws:
ClassNotFoundException
-
getResource
public URL getResource(String name)
- Overrides:
getResource
in classClassLoader
-
getResources
public Enumeration<URL> getResources(String name) throws IOException
- Overrides:
getResources
in classClassLoader
- 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 theclassPath
mapping.- Parameters:
file
- The JAR file to openfollowClassPath
- If the MANIFEST file should be checked for aClass-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 locatedname
- 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 packagemf
- 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)
-
-