Java dynamic class loading issue
Resource:
The thread to discuss how to add (only) jar files into JVM just like it is added in classpath during start up.
http://forum.java.sun.com/thread.jspa?threadID=300557&start=0&tstart=0
This link talks about how to dynamically plug in/out jar files (the best way)
http://java.sun.com/products/jndi/tutorial/beyond/misc/index.html
A more detailed white paper is available at
http://www.javageeks.com/Papers/ClassForName/index.html
Quoted abstract:
Abstract:
Dynamic loading of Java classes at runtime provides tremendous flexibility in the development of enterprise systems. It provides for the basis of "application servers", and allows even simpler, lighter-weight systems to accomplish some of the same ends. Within Java, dynamic loading is typically achieved by calling the forName method on the class java.lang.Class; however, when Class.forName is naively called from within an Extension, strange errors can occur. This paper describes why those errors occur, and how Java2 provides two facilities, one a modification to the forName syntax, and the other, called the "Thread context ClassLoader", to avoid them. This paper assumes you are passingly familiar with Java Reflection, and have at least a general idea of what Java ClassLoaders are and how they are used within Java code.
Keywords:Java ClassLoaders Extensions Threads
Following is the core code for invokeMethod
public ReturnValue invokeMethod(
String moduleName, String className, String methodName, Object[] methodParams)
{
//!!!!!check moduleName/className/methodName, undone
ClassLoader prevCl = Thread.currentThread().getContextClassLoader();
ReturnValue retVal = new ReturnValue();
retVal.success = false;
try {
File cwd = new File (workDir);
System.out.println("current work dir: "+cwd.getCanonicalPath());
String fileSeparator = System.getProperty("file.separator");
String xsharpCodePackageLocation = cwd.getCanonicalPath()+fileSeparator+moduleName+".jar";
File xsharpJar = new File(xsharpCodePackageLocation);
File implJar = new File(implAssemblyLocation);
// add .jar to class loader
URL[] urls = new URL[1];
urls[0]=xsharpJar.toURL();
ClassLoader urlCl = URLClassLoader.newInstance(urls,prevCl);
Thread.currentThread().setContextClassLoader(urlCl);
Class thisClass = Class.forName(moduleName+"."+className,true,urlCl);
Object iClass = thisClass.newInstance();
Method m[] = thisClass.getDeclaredMethods();
for (int i=0; i<m.length;i++)
{
if (methodName.equals(m[i].getName()))
{
m[i].setAccessible(true);
retVal.result = m[i].invoke(iClass, methodParams);
retVal.success = true;
}
}
}
catch (Exception e) {
retVal.info = e.toString();
}finally
{
Thread.currentThread().setContextClassLoader(prevCl);
}
return retVal;
}