I have a simple .txt file which has pure Java code inside it like
public class C {
public static void main(String[] args ) {
System.out.println("This is executed");
}
}
The file is named C.txt. Now I want to write Java code that will read the code in C.txt and will compile and run the read code as a pure Java file. Note, I can easily rename C.txt to C.java and compile and run the code manually. However, this is not my intention. I want to read the .txt file as is and execute the code directly. Is this possible somehow?
Open the notepad and write a Java program into it. Save the Java program by using the class name followed by . java extension. Open the CMD, type the commands and run the Java program.
You can use the javax.tools api form Java 6 to compile the code on the fly. However since your extension is illegal it will complain with a error: C.txt Class names are only accepted if annotation processing is explicitly requested.
To get around this (as mentioned in the comments) you must first load the code into a String and then execute it:
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyCompiler2 {
public static void main(String[] args) throws Exception {
String program = "";
try {
BufferedReader in = new BufferedReader(new FileReader("C.txt"));
String str;
while ((str = in.readLine()) != null) {
program += str;
}
in.close();
} catch (IOException e) {
}
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
Iterable<? extends JavaFileObject> fileObjects;
fileObjects = getJavaSourceFromString(program);
compiler.getTask(null, null, null, null, null, fileObjects).call();
Class<?> clazz = Class.forName("C");
Method m = clazz.getMethod("main", new Class[]{String[].class});
Object[] _args = new Object[]{new String[0]};
m.invoke(null, _args);
}
static Iterable<JavaSourceFromString> getJavaSourceFromString(String code) {
final JavaSourceFromString jsfs;
jsfs = new JavaSourceFromString("code", code);
return new Iterable<JavaSourceFromString>() {
public Iterator<JavaSourceFromString> iterator() {
return new Iterator<JavaSourceFromString>() {
boolean isNext = true;
public boolean hasNext() {
return isNext;
}
public JavaSourceFromString next() {
if (!isNext)
throw new NoSuchElementException();
isNext = false;
return jsfs;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
}
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
Notice how you need to explicitly provide the method and class name in order for reflection to execute your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With