javapoet syntax example

Which framework to generate source code ?


I have been recently writings to convert code in Java. This is a technical post to compare some frameworks to generate java code.


How to generate java code ?

It exists several solutions that I would classify in three categories.

  • using a template engine
  • using an AST/ to code framework
  • others

Each solution has it drawbacks and strengths.

Template engine

Well with a template engine like Velocity or JET, you basically can write anything you want.

You won’t be constrained by an API and you may also generate syntaxic invalid files.

The main drawback is that you can’t write in a one shot your implementation. You will have to  store your template in your resources, write a code to access it before generating your code.

Depending of the template engine, it can be a real pain.

public class HelloVelocity {
 public static void main(String[] args) {
// Boring code to initialize the template engine
 VelocityEngine ve = new VelocityEngine();
 ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
 ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());

 // Try to find the code template
 Template t = ve.getTemplate("codeTemplate.vm");
 VelocityContext ctx = new VelocityContext();
 // Initialize the context.
 ctx.put("name", "velocity");
 ctx.put("date", (new Date()).toString());
 List temp = new ArrayList();
 ctx.put("list", temp);
 StringWriter sw = new StringWriter();
 // Finally render
 t.merge(ctx, sw);

Using an AST/ to source generator

I will present you an interesting framework based on JDT Java compiler.

This framework is called Roaster, is open- and hosted on Github.

This is a maven library which provides a fluent API to generate java classes. Here an example:

final JavaClassSource javaClass = Roaster.create(JavaClassSource.class);


javaClass.addProperty(Integer.class, "id").setMutable(false);
javaClass.addProperty(String.class, "firstName");
javaClass.addProperty("String", "lastName");

  .setBody("this.id = id;")
  .addParameter(Integer.class, "id");

Where the framework differs, is that it relies on JDT. The code (parsed or created programmatically is associated to a JDT Dom Tree). Basically we are using the Eclipse functionalities to build the Java source code and unparse it.

Therefore, an hybrid approach can be chosen mixing parsing and programmation to produce your code.

JavaClassSource javaClass =
  Roaster.parse(JavaClassSource.class, "public class SomeClass {}");
  .setBody("System.out.println(\"Hello World\");")
  .addParameter("java.lang.String[]", "args");

The main drawback of this solution is that I did not find any way to insert invalid java code (aka a plain String) into my class structure. The string is parsed by JDT and if its invalid, it throws an exception. Since I potentially have some invalid structures in Beanshell to be converted as Java, I have been blocked without solution.

Other frameworks

I want to present an outsider : JavaPoet.

This framework hosted on Github is half-way between a template engine and an AST generation framework,

JavaPoet is offering a nice Fluent interface to produce your Java code.

All things are easy to understand and manipulate : structures, flow control statements, types.

MethodSpec main = MethodSpec.methodBuilder("main")
    .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
    .addParameter(String[].class, "args")
    .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")

TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
    .addModifiers(Modifier.PUBLIC, Modifier.FINAL)

JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)


I have been using it in several projects and it’s possible to inject plain Strings directly inside a valid structure. Rather efficient (it generates the package folder structure for you), it has a main drawback, you cannot declare your own imports (at the exception of the static ones).

Therefore if  you are building your code using a mix of  Fluent blocks and String templates, you will be soon short of imports to have a perfectly compiling code.

And you know what, they don’t want to add the feature grr :



Sylvain Leroy

Senior Software Quality Manager and Solution Architect in Switzerland, I have previously created my own company, Tocea, in Software Quality Assurance. Now I am offering my knowledge and services in a small IT Consulting company : Byoskill and a website www.byoskill.com Currently living in Lausanne (CH)

View all posts by Sylvain Leroy →
Exit mobile version