3

I'm generating java sources with JCodeModel and now want to compile at runtime. But I don't want to write the Java files to disc before.

As far as I can see, the dynamic compiling is possible with javax.tools.JavaCompiler (see example) , but it looks like I need the source code for this.

Unfortunately I can't find a way to directly get the source code from a JDefinedClass. It seems as if I need to write a JDefinedClass to a File object on disc and read the source afterwards.

Is this really necessary or is there some workaround?

Morrandir
  • 595
  • 1
  • 4
  • 19
  • Maybe you should try Javassist or CGLIB? – hoaz Nov 28 '12 at 15:23
  • As far as I can see CGLIB is not longer maintained and it seems to be poorly documeted. In fact I can't find a simple example, where a HelloWorld class or something is generated. Javaassist doesn't seem to offer the possibility of generating source code, it's just for manipulating bytecode. I need the source code for some other reasons. – Morrandir Nov 29 '12 at 08:40
  • There is a sample implementation of `JavaFileObject` in the article you have provided. It is called `DynamicJavaSourceCodeObject` and it takes string as parameter. You don't need to write it to a file to compile. Just feed it to `JavaCompiler` – hoaz Nov 29 '12 at 14:12
  • Yeah, but how do I get the String from a JCodeModel? :) – Morrandir Nov 30 '12 at 09:31
  • 1
    Pass `SingleStreamCodeWriter` with `ByteArrayOutputStream` to `JCodeModel#build` method. Then convert byte array into string. – hoaz Nov 30 '12 at 14:28
  • @hoaz, I think you should promote your comment to a real answer so Morrandir can check it. I had the same question and this nailed the answer. – metasim Feb 06 '13 at 17:09

1 Answers1

3

You can use following code to avoid disk operations and write your code directly in memory using SingleStreamCodeWriter:

JCodeModel jCodeModel = createJCodeModel(); // create and prepare JCodeModel 
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CodeWriter codeWriter = new SingleStreamCodeWriter(baos);
jCodeModel.build(codeWriter);

String code = baos.toString(); // you can use toString(charset) if there are special characters in your code
hoaz
  • 9,883
  • 4
  • 42
  • 53
  • Thanks! Works like a charm, except from the first line being generated. It contains something like "------- full qualified class name ------". Can easily been filtered though. – Morrandir Feb 09 '13 at 21:40