5

I have wrote some code to compile a Java source code. It then produces the .class file. The problem is how do I run it?

For example, I am ok with the name of the program and class being set, I've used prog p = new prog(), in this case, however, the class file does not yet exist until I compile it. Not really sure what to do. Can someone give me an advice?

btw, the class looks like this:

public void compile{
  JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();  
  int compilationResult = compiler.run(null, null, null, fileToCompile);  
}

public void run(){
  Prog prog = new Prog();
  prog.run();
}
tshepang
  • 12,111
  • 21
  • 91
  • 136
gerky
  • 6,267
  • 11
  • 55
  • 82

3 Answers3

5

If you just want to run it, you could launch a java process using Runtime.exec or ProcessBuilder. These will create a seperate java process to run your java program. This is more likely what you want. You can essentially do the equivelant of:

>java someClass

from within your application. This link may help.

If you want to actually load the classfile and use it in your current application, I think something along the lines of this, or dynamically loading Java Classes ought to help. Basically (directly from the link, slightly modified):

public class MainClass {

  public static void main(String[] args){

    ClassLoader classLoader = MainClass.class.getClassLoader();

    try {
        Class aClass = classLoader.loadClass("MyClass");
        System.out.println("aClass.getName() = " + aClass.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}

Once you loaded the class, you have a Class object, and you can create an instance of the class represented by aClass by calling aClass.newInstance(), which is like

MyClass newObj = new MyClass()

Or you can use any of the other methods the Class object exposes.

As pointed out by davmac, the code sample above presumes that the code you're loading is on your applications classpath. If the class files you want to run are not in your classpath, you might want to look into URLClassLoader

Zach L
  • 16,072
  • 4
  • 38
  • 39
  • Good answer, though the sample code only handles the case where the compiler output is put on the current class path (or at least, a path which the current classloader looks in). – davmac Feb 11 '11 at 03:29
  • May I just ask, how can I run a method of MyClass using this method? pretty lost here – gerky Feb 11 '11 at 03:58
  • @user536770 I now added how you can use it. You can get an instance of MyClass through `aClass.newInstance` and use methods on the instance returned or use `aClass.getMethod` – Zach L Feb 11 '11 at 04:02
  • thanks for explaining it clearly, I have tested the exact codes above with a simple class with a main method. The .class file is in the same folder as the program i'm coding. I was expecting it to execute the main, but it doesn't. Am I missing something? – gerky Feb 11 '11 at 04:37
  • @user536770 No, it won't. In that cause, you'll probably want to use something like `Runtime.getRuntime().exec("java yourClassNameHere")`, or to use the class-loading solution, call `aClass.getMethod("main").invoke(null, new String[0])` – Zach L Feb 11 '11 at 04:43
  • thanks a lot, you've been a big help. I have a last question though. Suppose I am calling a function run() w/ no param, do i use aClass.getMethod("run").invoke(null)? – gerky Feb 11 '11 at 05:04
  • @user536770 If `run` is a static function, yes. If `run` is an instance function (i.e. it isn't labeled with `static`), you'll need to pass to `invoke` first an instance of MyClass, like: `aClass.getMethod("run").invoke(aClass.newInstance())` – Zach L Feb 11 '11 at 05:07
  • thanks a lot! problem solved. You're a genius zach. really learned a lot from here, got a long way to go myslf – gerky Feb 11 '11 at 05:10
  • @user536770 aw, shucks, I don't know about *that*. Just keep on practicing, learning, and trying, and you'll grow in no time :-). – Zach L Feb 11 '11 at 05:15
3

Load it by URLClassLoader.

File root = new File("/java"); // The package root.
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("test.Test", true, classLoader); // Assuming package test and class Test.
Object instance = cls.newInstance();
// ...

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

You need to create a classloader (a URLClassLoader will probably be fine) which will load the just-compiled class file. (So for a URLClassLoader, the compilation output path should be one of the URLs).

Then, load the compiled class using the classloader, and execute it using reflection.

Class c = cl.loadClass("ClassName");

... etc.

davmac
  • 20,150
  • 1
  • 40
  • 68