A Java API to generate Java source files

Viewed 56138

I'm looking for a framework to generate Java source files.

Something like the following API:

X clazz = Something.createClass("package name", "class name");
clazz.addSuperInterface("interface name");
clazz.addMethod("method name", returnType, argumentTypes, ...);

File targetDir = ...;
clazz.generate(targetDir);

Then, a java source file should be found in a sub-directory of the target directory.

Does anyone know such a framework?


EDIT:

  1. I really need the source files.
  2. I also would like to fill out the code of the methods.
  3. I'm looking for a high-level abstraction, not direct bytecode manipulation/generation.
  4. I also need the "structure of the class" in a tree of objects.
  5. The problem domain is general: to generate a large amount of very different classes, without a "common structure".

SOLUTIONS
I have posted 2 answers based in your answers... with CodeModel and with Eclipse JDT.

I have used CodeModel in my solution, :-)

15 Answers

Sun provides an API called CodeModel for generating Java source files using an API. It's not the easiest thing to get information on, but it's there and it works extremely well.

The easiest way to get hold of it is as part of the JAXB 2 RI - the XJC schema-to-java generator uses CodeModel to generate its java source, and it's part of the XJC jars. You can use it just for the CodeModel.

Grab it from http://codemodel.java.net/

Solution found with CodeModel
Thanks, skaffman.

For example, with this code:

JCodeModel cm = new JCodeModel();
JDefinedClass dc = cm._class("foo.Bar");
JMethod m = dc.method(0, int.class, "foo");
m.body()._return(JExpr.lit(5));

File file = new File("./target/classes");
file.mkdirs();
cm.build(file);

I can get this output:

package foo;
public class Bar {
    int foo() {
        return  5;
    }
}

Solution found with Eclipse JDT's AST
Thanks, Giles.

For example, with this code:

AST ast = AST.newAST(AST.JLS3);
CompilationUnit cu = ast.newCompilationUnit();

PackageDeclaration p1 = ast.newPackageDeclaration();
p1.setName(ast.newSimpleName("foo"));
cu.setPackage(p1);

ImportDeclaration id = ast.newImportDeclaration();
id.setName(ast.newName(new String[] { "java", "util", "Set" }));
cu.imports().add(id);

TypeDeclaration td = ast.newTypeDeclaration();
td.setName(ast.newSimpleName("Foo"));
TypeParameter tp = ast.newTypeParameter();
tp.setName(ast.newSimpleName("X"));
td.typeParameters().add(tp);
cu.types().add(td);

MethodDeclaration md = ast.newMethodDeclaration();
td.bodyDeclarations().add(md);

Block block = ast.newBlock();
md.setBody(block);

MethodInvocation mi = ast.newMethodInvocation();
mi.setName(ast.newSimpleName("x"));

ExpressionStatement e = ast.newExpressionStatement(mi);
block.statements().add(e);

System.out.println(cu);

I can get this output:

package foo;
import java.util.Set;
class Foo<X> {
  void MISSING(){
    x();
  }
}

Another alternative is Eclipse JDT's AST which is good if you need to rewrite arbitrary Java source code rather than just generate source code. (and I believe it can be used independently from eclipse).

The Eclipse JET project can be used to do source generation. I don't think it's API is exactly like the one you described, but every time I've heard of a project doing Java source generation they've used JET or a homegrown tool.

Don't know of a library, but a generic template engine might be all you need. There are a bunch of them, I personally have had good experience with FreeMarker

If you REALLY need the source, I don't know of anything that generates source. You can however use ASM or CGLIB to directly create the .class files.

You might be able to generate source from these, but I've only used them to generate bytecode.

I was doing it myself for a mock generator tool. It's a very simple task, even if you need to follow Sun formatting guidelines. I bet you'd finish the code that does it faster then you found something that fits your goal on the Internet.

You've basically outlined the API yourself. Just fill it with the actual code now!

Related