X

Sundararajan's Weblog

  • Java
    June 14, 2006

"Dynamic source" code in Java applications

Guest Author

I came across "Add dynamic Java code to your application".
In this (nice) article, the author discusses how to use Java compiler (javac) to generate bytecode on-the-fly and load the same using a ClassLoader. This is done to extend an application dynamically - for example, an application can check for file timestamp of .java source file and recompile/reload as needed. In the article, author proposes designing around interfaces - a Java interface used by "static" portion of the application and the implementation of the same could be dynamically generated and loaded.

With Mustang (Java SE 6), it is easy to load "dynamic" code. I'll discuss three different ways in this blog entry. In the discussion, we will implement java.lang.Runnable interface by "dynamic" code.

  1. You can use javax.script
    API and the JavaScript engine bundled with JRE.

    // method to load Runnable implementation from a script file
    public Runnable load(String file) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    // get JavaScript engine instance
    ScriptEngine engine = manager.getEngineByName("JavaScript");
    // open the file and evaluate the code.
    // File is expected to contain a Runnable implementation
    FileReader reader = new FileReader(file);
    return (Runnable) engine.eval(reader);
    }

    The JavaScript file may contain code like

    new java.lang.Runnable() {
    run: function() { print("hello world"); }
    }

    More details on JavaScript-to-Java "communication" is
    http://www.mozilla.org/rhino/ScriptingJava.html
  2. What if you don't like to implement the interface in JavaScript and you want to use Java. What can you do? You can use the same idea discussed in the article -- but, with Mustang, you can use the standard Java Compiler API (JSR-199) instead of using non-standard com.sun.\* compiler Main class.
  3. What if you want an easier way? ["Compiler API is not for me - I am a Mort neither an Elvis nor an Einstein!"]. You can download javax.script compliant script engine for the Java programming language from http://scripting.dev.java.net

    // method to load Runnable implementation from a Java file
    public Runnable load(String file) throws Exception {
    ScriptEngineManager manager = new ScriptEngineManager();
    // get JavaScript engine instance
    ScriptEngine engine = manager.getEngineByName("java");
    // open the Java source file and evaluate the code.
    // File is expected to contain a Runnable implementation
    FileReader reader = new FileReader(file);
    // when we evaluate a Java class, "Java" script engine
    // executes the main method and returns the Class object
    // of the "main" class from the Java source
    Class clazz = (Class) engine.eval(reader);
    // create a new instance of the Runnable (assumes that
    // the interface implementor class has a public no-arg
    // constructor
    return (Runnable) clazz.newInstance();
    }

    Your (dynamically loaded) Java file may contain something like:

    public class DynamicRunnable implements Runnable {
    public void run() {
    System.out.println("hello (dynamic) world!");
    }
    // dummy main method for "eval"
    public static void main(String[] args) {}
    }

Join the discussion

Comments ( 1 )
  • Torsten Curdt Thursday, June 15, 2006
    4. or go jci which supports all sorts of compilers. It provides pre-mustang support for what jsr199 aims at. As member of the EG I will of course make sure jsr199 compilers will be supported as well.
    http://jakarta.apache.org/commons/sandbox/jci/
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.