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 start your class
com.mycompany.MyApp main() method to start your application
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();
}
}
}
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.
The launcher class for the Java applet is very similar to application launcher.
public class MyAppletLauncher extends JApplet {
private JarClassLoader jcl;
@Override
public void init() {
jcl = new JarClassLoader();
try {
jcl.initApplet("com.mycompany.MyApplet", this);
} catch (Throwable e) {
e.printStackTrace();
}
}
@Override
public void start() {
jcl.startApplet();
}
@Override
public void stop() {
jcl.stopApplet();
}
@Override
public void destroy() {
jcl.destroyApplet();
}
}
The applet launcher class could have both main() and applet
related methods for UI class which could be started as an application or
an applet. This technique is very convenient to develop an applet and test
it as an application.
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? 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 |
|---|---|
void |
destroyApplet()
Call this method to destroy the applet from your launcher class
MyAppletLauncher.destroy() method. |
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 |
initApplet(String sClass,
JApplet appletParent)
Call this method to initialize an applet from your launcher class
MyAppletLauncher.init() method. |
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.
|
void |
startApplet()
Call this method to start the applet from your launcher class
MyAppletLauncher.start() method. |
void |
stopApplet()
Call this method to stop the applet from your launcher class
MyAppletLauncher.stop() 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, setSignerspublic static final String KEY_LOGGER
public static final String KEY_LOGGER_LEVEL
JarClassLoader.LogLevel.
Default value is JarClassLoader.LogLevel.ERROR.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
public void initApplet(String sClass, JApplet appletParent) throws Throwable
MyAppletLauncher.init() method.sClass - class name in form "MyClass" for default package
or "com.abc.MyClass" for class in some packageappletParent - parent applet from a launcher.Throwable - wrapper for many exceptions thrown while applet
instantiation and calling init() method.public void startApplet()
MyAppletLauncher.start() method.public void stopApplet()
MyAppletLauncher.stop() method.public void destroyApplet()
MyAppletLauncher.destroy() method.protected Class<?> loadClass(String sClassName, boolean bResolve) throws ClassNotFoundException
loadClass in class ClassLoaderClassNotFoundExceptionprotected URL findResource(String sName)
findResource in class ClassLoaderClassLoader.findResource(java.lang.String)public Enumeration<URL> findResources(String sName) throws IOException
findResources in class ClassLoaderURL objects for
the resourcesIOExceptionClassLoader.findResources(java.lang.String)protected String findLibrary(String sLib)
findLibrary in class ClassLoaderClassLoader.findLibrary(java.lang.String)Copyright © 2018. All rights reserved.