How can I compile java code from an arbitrary string (in memory) in Java 5 and Java 6, load it and run a specific method on it (predefined)?
Before you flame this, I
You might want to check out Janino as well.
From their website:
Janino is a compiler that reads a JavaTM expression, block, class body, source file or a set of source files, and generates JavaTM bytecode that is loaded and executed directly. Janino is not intended to be a development tool, but an embedded compiler for run-time compilation purposes, e.g. expression evaluators or "server pages" engines like JSP.
http://www.janino.net/
Im currently using it in a pretty large mission critical project and it works just fine
If you're not completely tied to compiling, solutions like Beanshell, groovy and the other scripting languages are easily embedded (in-fact, java has built-in support for plugging in a scripting language so your code doesn't even know what language the script is written in)
Beanshell should run any 100% java code IIRC, and I believe Groovy can run most java code--possibly all.
Run inside a web container like Tomcat and first generate a JSP page, and then invoke it.
This also allow you to get rid of the old class definitions by simply overwriting the JSP page instead of having your classloader slowly run full.
Is the "in-memory" requirement due to speed or due to not changing the code base?
JCI looks fine. This code snippet should be your base:
JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");
MemoryResourceReader mrr = new MemoryResourceReader();
mrr.add("resource name string", yourJavaSourceString.getBytes());
MemoryResourceStore mrs = new MemoryResourceStore();
CompilationResult result = compiler.compile(sources, mrr, mrs);
// don't need the result, unless you care for errors/warnings
// the class should have been compiled to your destination dir
Any reason this should not work?
MemoryResourceStore
to send the compiled class output to memory, like requested.
Also, setting javac
settings, like classpath in your case, can be done via setCustomArguments(String[] pCustomArguments) in JavacJavaCompilerSettings
class.
Javassist might interest you
ECJ Eclipse Java Compiler
Eclipse provides and uses its own compiler that is not javac
Compile a source file
$ java -jar ecj-3.5.2.jar HelloWorld.java