Reputation: 21
How can I run the compiled code (.class
) java from the java code itself?
I'm doing a kind of providing service like compiling and running java code on server side and giving output to the end user.
Can anyone suggest an approach that will accomplish this?
import java.io.*;
public class demo {
public static void main(String args[]) throws IOException, InterruptedException {
int result;
try {
System.out.println("command output:");
Process proc = Runtime.getRuntime().exec("java -cp . demoh");
InputStream in = proc.getInputStream();
result = proc.waitFor();
BufferedInputStream buffer = new BufferedInputStream(proc.getInputStream());
BufferedReader commandOutput = new BufferedReader(new InputStreamReader(buffer));
System.out.print(commandOutput);
String line = null;
try {
while ((line = commandOutput.readLine()) != null) {
System.out.print(line);
System.out.println("command output: " + line);
}//end while
commandOutput.close();
} catch (IOException e) {
//log and/or handle it
}
} catch (IOException e) {
System.err.println("IOException raised: " + e.getMessage());
}
}
}
Upvotes: 1
Views: 5006
Reputation: 62439
If you have the .class
files somewhere on disk, simply spawn a new process and run the java command like you would from a command line:
Process p = Runtime.getRuntime().exec("java <java class file>");
After some testing around, the following code worked for me:
public static void main(String args[]) throws IOException, InterruptedException {
int result;
try {
System.out.println("command output:");
Process proc = Runtime.getRuntime().exec("java -cp . Test");
InputStream errin = proc.getErrorStream();
InputStream in = proc.getInputStream();
BufferedReader errorOutput = new BufferedReader(new InputStreamReader(errin));
BufferedReader output = new BufferedReader(new InputStreamReader(in));
String line1 = null;
String line2 = null;
try {
while ((line1 = errorOutput.readLine()) != null ||
(line2 = output.readLine()) != null) {
if(line1 != null) System.out.print(line1);
if(line2 != null) System.out.print(line2);
}//end while
errorOutput.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}//end catc
result = proc.waitFor();
} catch (IOException e) {
System.err.println("IOException raised: " + e.getMessage());
}
}
Note two things here:
Upvotes: 1
Reputation: 51
Here's a sample app that will compile the Java source file, load the class, instantiate an instance, and print out the toString() of the class HelloWorld. I believe you'll need tools.jar on the classpath. The sample code expects the source file in the src folder. The src folder is required on the classpath since the .class file will get generated there by default.
For more control of the Java Compiler, read up on the javax.tools package.
package sourcerunner;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class SourceRunner {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(System.in, System.out, System.err, "src/sourcerunner/HelloWorld.java");
TimeUnit.SECONDS.sleep(1L);
Class<?> cls = Class.forName("sourcerunner.HelloWorld");
Object instance = cls.newInstance();
System.out.println(instance);
}
}
And here's the HelloWorld class:
package sourcerunner;
public class HelloWorld {
@Override
public String toString() {
return "Hello Java Compiler World.";
}
}
The above code is insanely insecure. Once you understand the code, modify it to use a new ClassLoader to load and instantiate the class. Make sure the ClassLoader has minimal permissions.
Upvotes: 0
Reputation: 1
One of the options is to create an instance of the class using the class loader. The class loader can take your class as a byte array and then you can create an instance of it and run it. See this method in the JDK docs.
Upvotes: 0
Reputation: 24084
Try
Process process = Runtime.getRuntime().exec("java " + filePath); // without .class
Scanner output = new Scanner(process.getInputStream());
while (output.hasNext) {
String token = output.next();
...
}
Upvotes: 0
Reputation: 12453
There are still a lot of building/compiling tools, i.e. Ant or Maven, you can check before you write your own.
Upvotes: 0