Languages/Java2013.04.17 11:51

JAR file can be dynamically loaded from a running Java program. The dynamic loading is relatively easy. 


public class JarLoader {


@SuppressWarnings("unchecked")

private static Class<OFController> loadJar(String path) {

if ( !path.endsWith(".jar") ) {

// this is not a jar file.

return null;

}

String basename = Basename.get(path, "jar");

File file = new File(path);

if ( file.exists() ) {

ClassLoader loader;

try {

loader = URLClassLoader.newInstance(

new URL[] { file.toURI().toURL() },

JarLoader.class.getClassLoader()

);

return (Class<OFController>)
                                    Class.forName( basename, true, loader );

} catch (MalformedURLException e1) {

return null;

} catch (ClassNotFoundException e) {

Logger.stderr("basename " + basename + " is not found");

e.printStackTrace();

return null;

}

}

return null;

}


public static OFController getController(String path, int num_of_instances) {

Class<OFController> ctrl = loadJar(path);

if ( ctrl == null ) {

return null;

}

try { 

Constructor<OFController> constructor = 

ctrl.getConstructor(new Class[]{ int.class });

return constructor.newInstance( num_of_instances );

} catch (NoSuchMethodException e) {

Logger.stderr("Cannot find constructor for " + path);

return null;

} catch (SecurityException e) {

Logger.stderr("You are not authorized to open " + path);

return null;

} catch (InstantiationException e) {

Logger.stderr("Cannot instantiate controller from the given jar "
                                          + path);

return null;

} catch (IllegalAccessException e) {

Logger.stderr("You are not authorized to access constructor for "
                                           + path);

return null;

} catch (IllegalArgumentException e) {

Logger.stderr("You have passed wrong argument to " + path);

return null;

} catch (InvocationTargetException e) {

Logger.stderr("Wrong invocation target for " + path);

return null;

}

}

}


Above code is from a working system. Basically, all you need to look is the URLClassLoader, loadJar method, and codes  that actually call the constructor of the loaded class. 




In implementing this class, We have used a utiliy class called 'Basename'. As we set the name of the Jar file to the complete path of the class including package name (for example, xxx.yyy.SimpleClass), the class 'Basename' is critical in extracting the class name that would be instantiated. 


public class Basename {

public static String get(String path, String extension) {

String[] delimited = path.split("/");

String filename = delimited[ delimited.length - 1 ];

return filename.substring(0, filename.lastIndexOf("." + extension));

}

}


May the force of JAR files be with you!


저작자 표시 비영리 변경 금지
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^