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 java.lang.class.forName("ClassName"); and the class’s newInstance( ) method.

Discussion

Suppose you are using Java as an extension language in a larger application and want customer developers to be able to write Java classes that can run in the context of your application. 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 available 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 will call 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?

$ javac 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 reasonable-sized set of application classes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.104.124