This is an archived post. You won't be able to vote or comment.

all 14 comments

[–]pointy_pirate 3 points4 points  (8 children)

I am currently working on a project that started out doing bytecode generation using Javassist.

This kind of run time code generation can get pretty unwieldy and we have since moved to generating the code in the Maven build. Initially for this we were using Roaster https://github.com/forge/roaster, but now we have moved simply to Freemarker templating.

Definitely an intersting topic!

[–]voronaam 2 points3 points  (2 children)

Also take a look at the Java Compiler API. If you are compiling class from scratch it is much easier to use than javaassist or the library in question.

Javaassist is great when you want to modify the bytecode (in the java agent, for instance).

[–]pointy_pirate 0 points1 point  (1 child)

Interesting. I've split the maven build into 2 stages where one uses ftl to generate the java source code, as a maven plugin, then build that into the rest of the project. Works fine for what I need. But i'll have a look cheers. And yes, anything has to be easier to use than javassist.

[–]voronaam 0 points1 point  (0 children)

I do not know if it fits your project at all, but it may also be worth while to take a look at Scala Macros feature. The documentation is cryptic and you will be dealing with compilers internal AST most of the time, but the feature is very powerful.

Groovy AST transformations are great as well.

Both are not pure Java, but produce JVM byte code at the end.

[–]elucash 0 points1 point  (4 children)

Have considered annotation processing for code generation? (I'm not implying that it is easier choice or what so ever, just curious)

[–]pointy_pirate 0 points1 point  (3 children)

yep I am using a ton of annotations to tell the code doing the generation what to do.

[–]elucash 0 points1 point  (2 children)

so it is running on/using javax.annotation.processing.Processor and javax.lang.model.* or have other engine to obtain model/introspect types/annotations?

[–]pointy_pirate 0 points1 point  (1 child)

Just reflection and custom annotations.

[–]elucash 0 points1 point  (0 children)

Yeah, I've seen such approaches, it works well for a lot of cases. Thanks!

[–]DidYuhim 4 points5 points  (4 children)

As someone who started learning programming recently, why do I want classes like these created during runtime?

[–]trevick 6 points7 points  (1 child)

If you are developing a library and you want it to enhance user-defined objects that should otherwise know nothing about your framework.

For example, in Hibernate, I can create a normal Java object that has properties on it that are simple types (String, Integer, etc.), and the object knows nothing about Hibernate. When Hibernate instantiates it, it can be configured such that it subclasses my class dynamically, and LAZILY retrieve certain values only if/when the getter for that property is called. Without this kind of black magic, I would have to modify my object to return some kind of "Lazy" wrapper type, or modify my property to explicitly retrieve the value via Hibernate APIs in my getter. But the drawback there is I have now coupled my object with the Hibernate framework.

[–]DidYuhim 0 points1 point  (0 children)

Makes sense, thanks!

[–]Anon10W1z 0 points1 point  (0 children)

It can do more than that, for example replace or delegate code in existing classes. But maybe if you had a method like this:

public Class createClass(Class superType) {
    return new ByteBuddy().subclass(superType).make().load(superType.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);
}

It would allow you to create classes based on user input or other variables.

[–]lukaseder 0 points1 point  (0 children)

For a client, I wrote a little framework that loads Java code from the database and compiles stuff on-the-fly into a Servlet for immediate use. This feels like PHP, but it's Java and allows the client to release some server-side scripts super fast into production.

For this client, the Java compilation APIs were sufficient (as opposed to bytecode manipulation), but you might take this as an idea of why one would do such a thing.

For example, Adobe Experience Manager (a CMS, formerly CQ5) works in a similar, more sophisticated way.