public class JarClassLoader extends ClassLoader
The top JAR and nested JARs are included in the classpath and searched for the class or resource to load. The nested JARs could be located in any directories or subdirectories in a parent JAR.
All directories or subdirectories in the top JAR and nested JARs are included in the library path and searched for a native library. For example, the library "Native.dll" could be in the JAR root directory as "Native.dll" or in any directory as "lib/Native.dll" or "abc/xyz/Native.dll".
This class delegates class loading to the parent class loader and successfully loads classes, native libraries and resources when it works not in a JAR environment.
Create a Launcher
class to use this class loader and start its
main() method to start your application com.mycompany.MyApp
public class MyAppLauncher {
public static void main(String[] args) {
JarClassLoader jcl = new JarClassLoader();
try {
jcl.invokeMain("com.mycompany.MyApp", args);
} catch (Throwable e) {
e.printStackTrace();
}
} // main()
} // class MyAppLauncher
An application could be started in two different environments:
1. Application is started from an exploded JAR with dependent resources
locations defined in a classpath. Command line to start the application could
point to the main class e.g. MyApp.main()
or to the
MyAppLauncher.main()
class (see example above). The application
behavior in both cases is identical. Application started with
MyApp.main()
uses system class loader and resources loaded from
a file system. Application started with MyAppLauncher.main()
uses JarClassLoader
which transparently passes class loading to
the system class loader.
2. Application is started from a JAR with dependent JARs and other resources
inside the main JAR. Application must be started with
MyAppLauncher.main()
and JarClassLoader
will load
MyApp.main()
and required resources from the main JAR.
Use VM parameters in the command line for logging settings (examples):
-DJarClassLoader.logger=[filename]
for logging into the
file. The default is console.-DJarClassLoader.logger.level=INFO
for logging level. The
default level is ERROR. See also JarClassLoader.LogLevel
.-DJarClassLoader.logger.area=CLASS,RESOURCE
for logging
area. The default area is ALL. See also JarClassLoader.LogArea
. Multiple logging
areas could be specified with ',' delimiter.
Known issues: some temporary files created by class loader are not deleted on
application exit because JVM does not close handles to them. See details in
shutdown()
.
See also discussion "How load library from jar file?" http://discuss.develop.com /archives/wa.exe?A2=ind0302&L=advanced-java&D=0&P=4549 Unfortunately, the native method java.lang.ClassLoader$NativeLibrary.unload() is package accessed in a package accessed inner class. Moreover, it's called from finalizer. This does not allow releasing the native library handle and delete the temporary library file. Option to explore: use JNI function UnregisterNatives(). See also native code in ...\jdk\src\share\native\java\lang\ClassLoader.class
Modifier and Type | Class and Description |
---|---|
static class |
JarClassLoader.LogArea |
static class |
JarClassLoader.LogLevel |
Modifier and Type | Field and Description |
---|---|
static String |
KEY_LOGGER
VM parameter key to turn on logging to file or console.
|
static String |
KEY_LOGGER_AREA
VM parameter key to define log area.
|
static String |
KEY_LOGGER_LEVEL
VM parameter key to define log level.
|
static String |
TMP_SUB_DIRECTORY
Sub directory name for temporary files.
|
Constructor and Description |
---|
JarClassLoader()
Default constructor.
|
JarClassLoader(ClassLoader parent)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
protected String |
findLibrary(String sLib) |
protected URL |
findResource(String sName) |
Enumeration<URL> |
findResources(String sName) |
String |
getManifestMainClass()
Returns the name of the jar file main class, or null if no "Main-Class"
manifest attributes was defined.
|
void |
invokeMain(String sClass,
String[] args)
Invokes main() method on class with provided parameters.
|
boolean |
isLaunchedFromJar()
Checks how the application was loaded: from JAR or file system.
|
protected Class<?> |
loadClass(String sClassName,
boolean bResolve)
Class loader JavaDoc encourages overriding findClass(String) in derived
class rather than overriding this method.
|
clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, definePackage, findClass, findLoadedClass, findSystemClass, getClassLoadingLock, getPackage, getPackages, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, registerAsParallelCapable, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
public static final String KEY_LOGGER
public static final String KEY_LOGGER_LEVEL
JarClassLoader.LogLevel
. Default value is LogLevel#OFF
.public static final String KEY_LOGGER_AREA
JarClassLoader.LogArea
. Default value is JarClassLoader.LogArea.ALL
. Multiple areas
could be specified with ',' delimiter (no spaces!).public static final String TMP_SUB_DIRECTORY
JarClassLoader extracts all JARs and native libraries into temporary files and makes the best attempt to clean these files on exit.
The sub directory is created in the directory defined in a system property "java.io.tmpdir". Verify the content of this directory periodically and empty it if required. Temporary files could accumulate there if application was killed.
public JarClassLoader()
public JarClassLoader(ClassLoader parent)
parent
- class loader parent.public boolean isLaunchedFromJar()
public String getManifestMainClass()
public void invokeMain(String sClass, String[] args) throws Throwable
sClass
- class name in form "MyClass" for default package or
"com.abc.MyClass" for class in some packageargs
- arguments for the main() method or null.Throwable
- wrapper for many exceptions thrown while
(1) main() method lookup: ClassNotFoundException, SecurityException, NoSuchMethodException
(2) main() method launch: IllegalArgumentException, IllegalAccessException (disabled)
(3) Actual cause of InvocationTargetException
See ://java.sun.com/developer/Books/javaprogramming
/JAR/api/jarclassloader.html
and ://java.sun.com/developer
/Books/javaprogramming/JAR/api/example
-1dot2/JarClassLoader.java
protected Class<?> loadClass(String sClassName, boolean bResolve) throws ClassNotFoundException
loadClass
in class ClassLoader
ClassNotFoundException
protected URL findResource(String sName)
findResource
in class ClassLoader
ClassLoader.findResource(java.lang.String)
public Enumeration<URL> findResources(String sName) throws IOException
findResources
in class ClassLoader
URL
objects for
the resourcesIOException
ClassLoader.findResources(java.lang.String)
protected String findLibrary(String sLib)
findLibrary
in class ClassLoader
ClassLoader.findLibrary(java.lang.String)
Copyright © 2013. All Rights Reserved.