GWT and Lombok

130 views
Skip to first unread message

Wil Johnson

unread,
Aug 3, 2009, 11:55:10 AM8/3/09
to Project Lombok
First off, let me say that I'm in love with Lombok. Great work guys!

I spent some time this weekend playing around with writing an
extension to Lombok to support GWT. I'm running into a few obstacles,
so I thought I would post what I've done so far and see if any of you
had any ideas. I know Reinier is a fellow GWT junkie. :)

I created a GWT generator, and a marker interface called Generatable.
This way your class would look something like:

public @Data class Foo implements Generatable {
private int count;
private String name;
}


The problem I ran into is that deferred binding generators don't have
access to the original source, just the interface definition. So, my
next workaround was to have the generator output something like this:

public class FooImpl extends Foo {
public int getCount() {
return this.count;
}
public void setCount(int count) {
this.count = count;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}

For this to work, though, the fields must be declared as protected,
instead of private. Not exactly the cleanest solution. Another
possible solution might be to move the handling of the Lombok
annotations earlier up in the compile process. There's a precompile
phase in GWT that generates an AST, but I wasn't able to find much in
the way of documentation on extending this.

Any ideas?

Reinier Zwitserloot

unread,
Aug 3, 2009, 1:04:48 PM8/3/09
to Project Lombok
GWT, Javadoc, and PMD are three tools that work directly on java
source that have a sizable community behind it, and don't really run
off of javac v1.6 internals (javadoc sort of does, but with many
caveats).

We were planning on solving all three of those via a 'delombok' tool -
which turns your java code into java code sans javac. You can then
modify your GWT build and test scripts to FIRST run the delombok tool,
copying all your sources over to a temporary directory, and then run
GWT on that temporary directory. delombok should be very very fast, so
even for tools that are continuous rebuild aware such as GWT, it's
just a matter of rerunning delombok. Because of GWT, we were planning
on having delombok offer a 'continuous' feature, where it'll keep
running continuously, watching for changes to any of the source files,
immediately delomboking them and saving them to the temp dir.

I don't think you'll have to mess with generators or, in fact,
anything GWT specific if delombok were to exist.

If you want to help out with this, that would be great! Javac has a
decent API that includes the ability to keep comments around, and
running toString on any AST note produces (not very readable, but
correct) java source code. You can check this out via the
@lombok.core.PrintAST(printContent=true) annotation, which will dump
the AST (post-lombok transformations) of the annotated item to
standard output.

It should simply be a matter of firing up javac, with a parameter to
explicitly load lombok.jar as an annotation processor, then turning
all relevant files into ASTs (which, due to having lombok.jar as
annotation processor, will automatically run lombok and thus de-lombok
everything), and then saving the toString() of each JCCompilationUnit
to a temp dir. You may also have to put in some extra effort to take
the annotations out (lombok doesn't remove its own annotations, though
all those annotations are source-level only) - though I think the GWT
compiler will just ignore them. Continuous mode is a bit more
problematic; real support for watching a directory tree for changes is
slated for java7. So, I guess you'd just run a thread that checks
every ~200 msec or so.

It's one of the plans for the next milestone release.

Wil Johnson

unread,
Aug 3, 2009, 4:27:19 PM8/3/09
to Project Lombok
This sounds great, and I would definitely be interested in helping
out.

I am curious about how well this would work with tools that wrap the
GWT compiler, such as the Google Eclipse plugin, or the Cypal plugin.
After a quick peek, it does look like the Google Eclipse plugin will
let you specify an alternate source path when running hosted mode, but
I haven't tried it yet.

Let me know when you're ready to start on the delombok tool. In
addition, if there are any other issues or enhancements you want to
task out, I'd be willing to try my hand at it. I didn't see anything
in the issues list on the Google Code site.

If you're taking suggestions, how about a @Mapped annotation for
dynamic property access? This would be handy once the GWT support is
available through delombok, since it would allow some lightweight
reflection that we don't have in GWT by default.

public @Data @Mapped class Foo {
int count;
String name;
}


Foo f = new Foo();
f.set("count", 1);
f.set("name", "Joe");

Something like this could probably be easily bundled into the design
work to be done for Property support.

Reinier Zwitserloot

unread,
Aug 3, 2009, 6:24:06 PM8/3/09
to Project Lombok
There's a LOT of work to be done on sussing out a good API for the
property support first. So many different requirements - but going
overboard and doing all of them will probably result in a horribly
over-engineered, complicated mess, so we'll have to pick and choose
which use cases are sufficiently important, or come up with some novel
tricks to allow for all of them without overcomplicating things.

Roel is on vacation, and I have built up a bit of a backlog for my job
during the release sprint for lombok, so we're taking it easy for the
next 3 weeks. But, we'll get cracking on these things after that,
promise :)

You can fork the lombok release via github and work on whatever you
like. I can then rather easily pull your changes into the main
repository, or just to my own machine to play around with what you've
built, so if you feel like working on it, go right ahead. The delombok
thing in particular would be great. I don't really use javadoc that
much, I don't use PMD, and I don't currently maintain any websites
that run on GWT anymore, so while I think delombok is a great plan,
I'm not nearly as motivated as it's not something I actually need at
the moment.

v6ak

unread,
Aug 4, 2009, 2:13:21 AM8/4/09
to Project Lombok
Delombok can do:
1) compile java
2) decompile java
3) combine original and decompiled code (It is neccessary to keep
comments) - it's good to add generated methods only
4) generate additional comments (JavaDoc for Geters and Setters)
I think that Eclipse uses a Sun's tool to analyze java *source*. It
can be useful for delombok.
Delombok should be intergated with jdoc generation in Eclipse, I
think.

Reinier Zwitserloot

unread,
Aug 4, 2009, 7:40:46 AM8/4/09
to Project Lombok
Nono, delombok can only turn something like:

public class Foo {
private @Getter int x;
}

into:

public class Foo {
private int x;
public int getX() {
return x;
}
}


with both files being called Foo.java.

So, it can NOT compile java code (after all, if you want to compile
lombok-contained javac, just run javac!)

It can't decompile java code. At some point we'd like to make a tool
that can turn JAVA source (not class files) into shorter java source
with lombok annotations, but that would either way not fall under
'delombok', that would be a different tool.

Eclipse does not use Sun anything.

Matías Costa

unread,
Aug 6, 2009, 7:25:22 PM8/6/09
to Project Lombok
Hello, I am in the same situation as you. I do not use the GWT
generator facility. I just scan and generate the code using templates
iwht velocity inspired by the gears orm:

http://gwtsandbox.com/?q=node/34

But I write it to disk because I need the code server side. The
generated code includes named property suport -- <X> getProperty
(String) / <X> setProperty(String, X) for seamless integration with
GXT and some other goodies and classes specific to my project. We use
it also as a king of AOP injector and django.

On Aug 3, 5:55 pm, Wil Johnson <wil.john...@gmail.com> wrote:
>
> I created a GWT generator, and a marker interface called Generatable.
> This way your class would look something like:
>
> public @Data class Foo implements Generatable {
>     private int count;
>     private String name;
>
> }
>
> The problem I ran into is that deferred binding generators don't have
> access to the original source, just the interface definition.  So, my
> next workaround was to have the generator output something like this:
>
> public class FooImpl extends Foo {
>     public int getCount() {
>         return this.count;
>     }
>     public void setCount(int count) {
>         this.count = count;
>     }
>     public String getName() {
>         return this.name;
>     }
>     public void setName(String name) {
>         this.name = name;
>     }
>
> }
>
> For this to work, though, the fields must be declared as protected,
> instead of private.  Not exactly the cleanest solution.

I do not care for the protected thing. My real problem is
inheritance....

For a class A we generate A', but if B extends A, the generated B'
extends... B? then anything taking an A' can't take a B'!. The
solution is making B ineriting A'. That's a real mess.


 Another
> possible solution might be to move the handling of the Lombok
> annotations earlier up in the compile process.  There's a precompile
> phase in GWT that generates an AST, but I wasn't able to find much in
> the way of documentation on extending this.
>
> Any ideas?

Mixup A and the generated code in A', see:

class A {
@Property
private String name;
@ChangesState
public void doStuff() {

}
}


Matías Costa

unread,
Aug 6, 2009, 7:43:37 PM8/6/09
to Project Lombok
Oops, I pressed tab to indent and when I noticed it didn't work I
pressed space four times... sorry, it's 1:27 AM here.

Let me continue with the simple example please:

package something.client.beans;


class A {
@Property
private String name;

@Touch("name")
public void sanitize() {
name = Utils.trim(name);
name = Utils.capitalize(name);
}
}

---------------------- Generated code ------------------
package something.client.superBeans;
class A' {
private String name;

public String getName() // getter code ommited
public String setName(String _name) // setter code ommited

public void sanitize() {
// pre-injected code
String _name = name;

name = Utils.trim(name);
name = Utils.capitalize(name);

// post-injected code
fireEvent(new PropertyChangeEvent("name", _name, name));
}
}

Can lombok help with this? looks like no, but... may be the nice
lombok author can point me where to look -- far from here you
crazy-metaprogrammer fool:)

Reinier Zwitserloot

unread,
Aug 9, 2009, 9:27:52 AM8/9/09
to Project Lombok
That design would never make it into standard lombok because it's not
thread safe.

You can do this via the real @Property support which is planned (see
the 'I like its simplicity thread'). You COULD roll something like
this yourself, though, as we're speaking of GWT, the delombok tool
would have to exist for it to be useful for you.
Reply all
Reply to author
Forward
0 new messages