How do I get the output from a java program?
I need to write some code that could help me get the output of the program.
I have in this Java file MainClass.java
that I am compiling simple code that prints "OK"
.
How can I get this output back, and even if there is an error, I need to take it too.
This is my code that compiles and creates a file .class
.
File sourceFile = new File("C:\\Projet_Interne\\webProject\\NewFolder\\MainClass.java");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int compilationResult = compiler.run(null, null, null,sourceFile.getPath());
int result = compiler.run(System.in,System.out,System.err,sourceFile.getPath());
System.out.println("Compile result code = " + result);
if(compilationResult == 0){
System.out.println("Compilation is successful");
}else{
System.out.println("Compilation Failed");
}
StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, Locale.getDefault(), null);
stdFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File("C:\\Projet_Interne\\webProject\\NewFolder")));
source to share
You can use DiagnosticCollector
which will allow you to collect diagnostic information about the compilation process, you can find more details from the JavaDocs
For example...
File helloWorldJava = new File(...);
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
// This sets up the class path that the compiler will use.
// I've added the .jar file that contains the DoStuff interface within in it...
List<String> optionList = new ArrayList<String>();
optionList.add("-classpath");
optionList.add(System.getProperty("java.class.path"));
Iterable<? extends JavaFileObject> compilationUnit
= fileManager.getJavaFileObjectsFromFiles(Arrays.asList(helloWorldJava));
JavaCompiler.CompilationTask task = compiler.getTask(
null,
fileManager,
diagnostics,
optionList,
null,
compilationUnit);
if (task.call()) {
System.out.println("Yipe");
} else {
// Opps compile failed...
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
System.out.format("Error on line %d in %s%n",
diagnostic.getLineNumber(),
diagnostic.getSource().toUri());
}
}
fileManager.close();
Once compiled, you have two options, you can use a custom classloader to load the class and execute it, which will use your current stdout ...
// Create a new custom class loader, pointing to the directory that contains the compiled
// classes, this should point to the top of the package structure!
URLClassLoader classLoader = new URLClassLoader(new URL[]{new File("./").toURI().toURL()});
// Load the class from the classloader by name....
Class<?> loadedClass = classLoader.loadClass("testcompile.HelloWorld");
// Create a new instance...
Object obj = loadedClass.newInstance();
// Santity check
if (obj instanceof DoStuff) {
// Cast to the DoStuff interface
DoStuff stuffToDo = (DoStuff)obj;
// Run it baby
stuffToDo.doStuff();
}
Or use ProcessBuilder
to execute another Java process ...
ProcessBuilder pb = new ProcessBuilder("java", "HelloWorld");
pb.directory(new File("src"));
pb.redirectError();
Process p = pb.start();
InputStreamConsumer.consume(p.getInputStream());
p.waitFor();
For reference, InputStreamConsumer
....
public static class InputStreamConsumer implements Runnable {
private InputStream is;
public InputStreamConsumer(InputStream is) {
this.is = is;
}
public InputStream getInputStream() {
return is;
}
public static void consume(InputStream is) {
InputStreamConsumer consumer = new InputStreamConsumer(is);
Thread t = new Thread(consumer);
t.start();
}
@Override
public void run() {
InputStream is = getInputStream();
int in = -1;
try {
while ((in = is.read()) != -1) {
System.out.print((char)in);
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
This is described in more detail in:
source to share