Wednesday, May 19, 2010

Loading Classes from Jars in an Applet

Here are the rules as far as I can gather:
1) First consider the dependencies. If you want to load a class from a jar that has dependencies on other jars that are essential to the applet, then you want to put the jar that contains the class to load in the archive attribute of the applet tag. The applet essential jars will already be defined there so the class jar can access the code in the applet jars through the class loader of the applet. If you do that, all the jars will be downloaded to the browser at the start. If you want to load a class from a jar that does not have dependencies on jars required by the applet, then you can use a URLClassLoader to load the jar and access the class that way.

2) If you are loading from a dependent jar, you can use Class.forName to find the class but you can only use newInstance() on the resulting class if the constructor of the class that you wish to load has no parameters. If you want to instantiate a class where the constructor has parameters you need to find the constructor first. For example, consider a constructor that takes one String parameter:


// get the name of the class to load from the applet parameters
// this should be in the form: .
// for example: atlas_seaquest.SeaQuest
String sApp = this.getParameter("app_class");
// get the class for the class name
Class cls = Class.forName(sApp);
// find the constructor that takes a String parameter
// (other constructors may be found in the same way)


Constructor con = cls.getConstructor(new Class[] {String.class});
// instantiate the object using the constructor with a parameter
// in this case a user code was passed to the class constructor
// the resulting object was of type AtlasAbstractApplication.
// This will vary depending on the object you wish to instantiate.
AtlasAbstractApplication app = (AtlasAbstractApplication)con.newInstance(sUser);
// now use the object as usual...


3) If you want to instantiate a class that does not have dependencies on jars that are specific to the applet then you can use a URL loader to find the jar and load the class from that jar. This will download the jar (in theory) at runtime when the class is called. If you use this method you do not have to include the independent jar in the archive attribute of the applet tag. For example:


//Get a url to the location of your jar
String sJar = "myjarname.jar";
URL jarfile = new URL(this.getCodeBase().toString()+ sJar);
// Create a class loader to load the class from the jar

URLClassLoader cl = URLClassLoader.newInstance(new URL[] {jarfile});
// Get a reference to the class
String sApp = this.getParameter("app_class");
// get the class for the class name
Class cls = cl.loadClass(sApp);
// use cls.newInstance() or the above constructor method to
// create your object.