Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile java source from String without writing to file [duplicate]

Tags:

java

Here I have found some good example:

// Prepare source somehow.
String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\"); } }";

// Save source in .java file.
File root = new File("/java"); // On Windows running on C:\, this is C:\java.
File sourceFile = new File(root, "test/Test.java");
sourceFile.getParentFile().mkdirs();
new FileWriter(sourceFile).append(source).close();

// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());

// Load and instantiate compiled class.
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("test.Test", true, classLoader); // Should print "hello".
Object instance = cls.newInstance(); // Should print "world".
System.out.println(instance); // Should print "test.Test@hashcode".

Question: Is it possible to achieve exactly the same thing without writing to a file?

@Edit: To be more exact: I know how to compile from string (overloading JavaFileObject). But after doing this, I have no idea how to load the class. I probably missed the output-write part, but this also a thing I would like not to do.

@Edit2 For anyone interested, I created this small project to implement discussed feature: https://github.com/Krever/JIMCy

like image 391
Krever Avatar asked May 14 '14 19:05

Krever


Video Answer


1 Answers

OK, so here is an example of using JavaCompiler to compile from a String input. this file is the core of it.

In this file, I load the class which is compiled. You will notice that I also detect the package and classname using regexes.


As to the output, if you want to do that in memory, it appears that you can do so if you implement your own JavaFileManager; however I have never tried that!

Note that you can debug what happens quite easily by extending ForwardingJavaFileManager

like image 190
fge Avatar answered Oct 12 '22 21:10

fge