Recipe 25.3 Loading and Instantiating a Class Dynamically


Problem

You want to load classes dynamically, just like browsers load your applets and web servers load your servlets.

Solution

Use class.forName("ClassName"); and the class's newInstance( ) method.

Discussion

Suppose you are writing a Java application and want other developers to be able to extend your application by writing Java classes that run in the context of your application. In other words, these developers are, in essence, using Java as an extension language, in the same way that Applets are an extension of a web browser. You would probably want to define a small set of methods that these extension programs would have and that you could call for such purposes as initialization, operation, and termination. The best way to do this is, of course, to publish a given, possibly abstract, class that provides those methods and get the developers to subclass from it. Sound familiar? It should. This is just how web browsers such as Netscape allow the deployment of applets.

We'll leave the thornier issues of security and of loading a class file over a network socket for now, and assume that the user can install the classes into the application directory or into a directory that appears in CLASSPATH at the time the program is run. First, let's define our class. We'll call it Cooklet (see Example 25-4) to avoid infringing on the overused word applet. And we'll initially take the easiest path from ingredients to cookies before we complicate it.

Example 25-4. Cooklet.java
/** A simple class, just to provide the list of methods that   * users need to provide to be usable in our application.  * Note that the class is abstract so you must subclass it,  * but the methods are non-abstract so you don't have to provide  * dummy versions if you don't need a particular functionality.  */ public abstract class Cooklet {     /** The initialization method. The Cookie application will      * call you here (AFTER calling your no-argument constructor)      * to allow you to initialize your code      */     public void initialize( ) {     }     /** The work method. The cookie application will call you      * here when it is time for you to start cooking.      */     public void work( ) {     }     /** The termination method. The cookie application will call you      * here when it is time for you to stop cooking and shut down      * in an orderly fashion.      */     public void terminate( ) {     } }

Now, since we'll be baking, err, making this available to other people, we'll probably want to cook up a demonstration version too; see Example 25-5.

Example 25-5. DemoCooklet.java
public class DemoCooklet extends Cooklet {     public void work( ) {         System.out.println("I am busy baking cookies.");     }     public void terminate( ) {         System.out.println("I am shutting down my ovens now.");     } }

But how does our application use it? Once we have the name of the user's class, we need to create a Class object for that class. This can be done easily using the static method Class.forName( ) . Then we can create an instance of it using the Class object's newInstance( ) method; this calls the class's no-argument constructor. Then we simply cast the newly constructed object to our Cooklet class, and we can call its methods! It actually takes longer to describe this code than to look at the code, so let's do that now; see Example 25-6.

Example 25-6. Cookies.java
/**  * This is the part of the Cookies application that loads  * the user-defined subclass.  */ public class Cookies {     public static void main(String[] argv) {         System.out.println("Cookies Application Version 0.0");         Cooklet cooklet = null;         String cookletClassName = argv[0];         try {             Class cookletClass = Class.forName(cookletClassName);             Object cookletObject = cookletClass.newInstance( );             cooklet = (Cooklet)cookletObject;         } catch (Exception e) {             System.err.println("Error " + cookletClassName + e);         }         cooklet.initialize( );         cooklet.work( );         cooklet.terminate( );     } }

And if we run it?

$ java  Cookies DemoCooklet Cookies Application Version 0.0 I am busy baking cookies. I am shutting down my ovens now. $

Of course, this version has rather limited error handling. But you already know how to fix that. Your ClassLoader can also place classes into a package by constructing a Package object; you should do this if loading any medium-sized set of application classes.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net