Question

I am trying to edit a class file and make it available to the JVM at runtime. Is that possible, how can I do it?

For example:

main() {
    for (int i=0;i<10;i++) {
        NewClass.method();
        //ask user if to continue..
    }
}

public class NewClass() {
    static void method() {
        sysout("hi");
    }
}

When this loop is executing, I want to change the file NewClass() and load it in the JVM, so that it prints "bye".

Here is the complete code:

try {
    for (int iCount = 0; iCount < 10; iCount++) {
        BufferedReader br = new BufferedReader(new InputStreamReader(
                System.in));
        System.out.print("Enter which method:");
        int i = Integer.parseInt(br.readLine());
        System.out.println(i);
        if (i == 1) {
            Called.calledMethod1();
        } else {
            Called.calledMethod2();
        }
    }
} catch (NumberFormatException nfe) {
    System.err.println("Invalid Format!");
}

I want to run the main method of one class, and while it is running I want to refer to another class, edit it, and refer the 2nd class's same method and get different output.

I don't want to:

  1. stop the jvm
  2. edit the code
  3. run the code again.

I want to

  1. edit the code at run time, and get the changes reflected immediately.
Was it helpful?

Solution

You have to use Java reflection. Using reflection,

  1. you load dynamically a class at runtime using Class forName method.
  2. Using invoke method on the instance of Class you got,you can call any static method you want giving it's name.

If your class is fixed at design time, you just skeep the first point. Some code:

...

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter which class:");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
className=br.readLine()
int results = compiler.run(null, null, null, className+".java");
if(results == 0){

    Class clazz = Class.forName(className+".class");
    System.out.print("Compiled successfully.Enter which method:");
    Object returnValue=clazz.getMethod(br.readLine()).invoke(null);
}
...

But beware of security issues: the code above let anyone to execute each static method of each class accessible at runtime. If security is one of your concern, it's better if you first validate the input received from console and test that they match one of the class methods you whant to make available via console.

EDIT:

I better understand your question after I read your comment. In order to compile a class at runtime if you are targeting Java 6, you could use Java Compiler object. I have edit the code to include JavaCompiler usage.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top