Aspectj and Lombok mutually exclusive?

2,918 views
Skip to first unread message

Eric B

unread,
Sep 18, 2014, 12:03:01 AM9/18/14
to project...@googlegroups.com
As a follow up to my previous post, I dug around and saw an ancient post where AJDT was the culprit. So I disabled aspectj and now Lombok generate things properly.

But I want/need to use AspectJ in my project. Does that mean I cannot use Lombok? Is there any way to make the two play nicely together?

I presume it is because aspectj uses ajc as a compiler and not javac, but I wouldn't know what to look at further then that. Can Lombok even be made to work with ajc?

Thanks,

Eric

Fabrizio Giudici

unread,
Sep 18, 2014, 3:30:00 AM9/18/14
to project...@googlegroups.com, Eric B
The problem is probable the one I described here:

https://weblogs.java.net/blog/fabriziogiudici/archive/2011/07/19/making-lombok-aspectj-and-maven-co-exist

AspectJ by default works on the sources, calling the compiler by itself
and then operating on the byte code. The workaround is to switch it to
another operating mode, that is leaving the compiler alone and having
Aspectj to work on the byte code produced by it.

If you're using Ant, you should be able to find the solution there. If you
use Maven, the solution for Maven in the blog post is quite old, and in
the meantime the Maven plugin bug has been fixed. You might wnat to look
at the solution in the profile

it.tidalwave-aspectj-springaop-v1

in this super POM

https://bitbucket.org/tidalwave/thesefoolishthings-superpom-src/src/65d85b8086ec87fb09ad64ab8221a1174a2dbd88/pom.xml?at=2.15

Actually, the latter thing is the solution I'm currently working. It works
by forcing AspectJ to ignore the position of sources (see <!-- Prevent ajc
from finding sources -->), so it switches working on the bytecode.

Let me know if this works for you.

--
Fabrizio Giudici - Java Architect @ Tidalwave s.a.s.
"We make Java work. Everywhere."
http://tidalwave.it/fabrizio/blog - fabrizio...@tidalwave.it

Eric B

unread,
Sep 18, 2014, 10:48:09 AM9/18/14
to Fabrizio Giudici, project...@googlegroups.com
On Thu, Sep 18, 2014 at 3:29 AM, Fabrizio Giudici <Fabrizio...@tidalwave.it> wrote:


The problem is probable the one I described here:

        https://weblogs.java.net/blog/fabriziogiudici/archive/2011/07/19/making-lombok-aspectj-and-maven-co-exist

AspectJ by default works on the sources, calling the compiler by itself and then operating on the byte code. The workaround is to switch it to another operating mode, that is leaving the compiler alone and having Aspectj to work on the byte code produced by it.

If you're using Ant, you should be able to find the solution there. If you use Maven, the solution for Maven in the blog post is quite old, and in the meantime the Maven plugin bug has been fixed. You might wnat to look at the solution in the profile

        it.tidalwave-aspectj-springaop-v1

in this super POM

        https://bitbucket.org/tidalwave/thesefoolishthings-superpom-src/src/65d85b8086ec87fb09ad64ab8221a1174a2dbd88/pom.xml?at=2.15

Actually, the latter thing is the solution I'm currently working. It works by forcing AspectJ to ignore the position of sources (see <!-- Prevent ajc from finding sources -->), so it switches working on the bytecode.

Let me know if this works for you.

Thanks - so you confirmed my suspicions about ajc and javac.  However, by using your technique, do you not run into a race condition, where the sources must be complete such that javac can compile everything first?  This is find for simple aspects that just do crosscuts around methods/etc, but for any project that uses ITDs (inter type declaration) to add members or interfaces to classes, javac will fail, won't it?

For example, if you use an ITD that declares a bunch of additional variables and methods to a ClassA, and ClassB relies on those methods, compilation of ClassB should fail if ajc hasn't been run.  So if ClassB then has Lombok annotations, javac won't be able to generate any byte code until ClassA is properly weaved by ajc.

I haven't actually run any tests - this is just off the top of my head - but it seems like a logical conclusion that you run into a race condition like this, where javac needs to rely on ajc, but ajc will wipe out any Lombok annotations.

Thanks,

Eric

Fabrizio Giudici

unread,
Sep 18, 2014, 11:34:36 AM9/18/14
to Eric B, project...@googlegroups.com
On Thu, 18 Sep 2014 16:47:47 +0200, Eric B <eben...@gmail.com> wrote:

> Thanks - so you confirmed my suspicions about ajc and javac. However, by
> using your technique, do you not run into a race condition, where the
> sources must be complete such that javac can compile everything first?
> This is find for simple aspects that just do crosscuts around
> methods/etc,
> but for any project that uses ITDs (inter type declaration) to add
> members
> or interfaces to classes, javac will fail, won't it?

I have done some limited development in this area (see below an example),
as most of my work with aspects is by means of Java annotated code (e.g.
@Around in Spring), but it seems to reliably work (apart from some
problems when I also upgraded to JDK 8, there were a few bugs in the early
AspectJ support for it, that disappeared when they released the final
bits). I don't push these things to extreme stuff, thus my understanding
is limited to some cases; anyway my understanding in this case is that ajc
is completely capable to do everything in bytecode. My Hudson builds and
re-tests everything at midnight (even when there are no changes), so a lot
of compilations were succesfull without traces of races.

If you want to quickly try it, it's available at
http://bitbucket.org/tidalwave/thesefoolishthings-src - the project is a
kitchen sink, the module containing that file is SpringMessageBus. Maven
required.



package it.tidalwave.messagebus.impl.spring;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;
import it.tidalwave.messagebus.annotation.SimpleMessageSubscriber;

public aspect SpringSimpleMessageSubscriberAspect
{
//
// This aspect works by making the target bean implement
InitializingBean and DisposableBean and introducing
// an implementation that delegates the required subscribe/unsubscribe
semantics to
// SpringSimpleMessageSubscriberSupport
//
static interface MessageBusHelperAware extends InitializingBean,
DisposableBean
{
}

declare parents:
@SimpleMessageSubscriber * implements MessageBusHelperAware;

public SpringSimpleMessageSubscriberSupport
MessageBusHelperAware.support =
new SpringSimpleMessageSubscriberSupport(this);

public void MessageBusHelperAware.afterPropertiesSet()
{
support.subscribeAll();
}

public void MessageBusHelperAware.destroy()
{
support.unsubscribeAll();

Eric B

unread,
Sep 18, 2014, 2:25:15 PM9/18/14
to Fabrizio Giudici, project...@googlegroups.com
I've been trying to understand your maven setup and am a little confused.  You point the aspectj compiler to use your woven-classes directory as its source, but don't you also need to point it to your .aj files as well?  Won't just the javac output .class files end up in the woven-classes folder?

I'm a little confused as to how/why this setup is actually weaving in your AJ aspects.

Thanks,

Eric

Fabrizio Giudici

unread,
Sep 18, 2014, 4:51:01 PM9/18/14
to Eric B, project...@googlegroups.com
On Thu, 18 Sep 2014 20:24:53 +0200, Eric B <eben...@gmail.com> wrote:

> I've been trying to understand your maven setup and am a little confused.
> You point the aspectj compiler to use your woven-classes directory as
> its
> source, but don't you also need to point it to your .aj files as well?
> Won't just the javac output .class files end up in the woven-classes
> folder?
>
> I'm a little confused as to how/why this setup is actually weaving in
> your
> AJ aspects.

The simpler way to understand how it works is to try it :-) that's why I
pointed you to the whole project.

Howver not everything that is needed is in the superpom. Projects that
also have *.aj files also have this in their poms:

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<aspectLibraries>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
</aspectLibraries>
<sources>
<source>
<basedir>${basedir}/src/main/java</basedir>
<includes>
<include>**/*.aj</include>
</includes>
</source>
</sources>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>

Basically:

1. javac has been reconfigured to compile bytecode to the unwoven-classes
directory. Here they have the Lombok-generated code as well.
2. ajc by default doesn't see the java source files, so it understands it
has to read bytecode from the unwoven-classes directory, weave it and put
woven bytecode into the regular classes directory.
3. if there are *.aj files, the specific module pom such as the fragment
above specify sources, but the include element only includes *.aj. So it
still doesn't see *.java and point #2 still works.

I think it could be cleaned up. *.aj sources could go in a src/main/aspect
directory (but my problem is that NetBeans in this case doesn't see the
new folder - it would require to add a source folder with the
build-helper-maven-plugin, but I'm unsure this is smarter). The
configuration for including *.aj files probably can go up in the superpom,
but I don't have checked whether ajc complains if the directory is empty.
Probably this could be part of a different profile that gets enabled only
when the src/main/aspect directory exists.

Eric B

unread,
Sep 19, 2014, 11:21:59 AM9/19/14
to Fabrizio Giudici, project...@googlegroups.com
Can't believe I forgot to check the actual project pom!  Thanks for pointing out the obvious. :)

So I finally got the configuration working, but as I suspect, or feared, ITDs will not work.  If any java file relies on fields/members/etc of injected code, javac will fail (since those fields have not yet been woven in) and the build will break.  I wonder if I could use delombok, but I presume that delombok must be able to compile the code as well.

I've been trying to hack around with the lombok sources a little to make them run with ajc, but I'm struggling to understand how they work.

So, it still appears that proper/full AJ support cannot be had with Lombok in its current state.  Which is a royal shame given how great it seems to be.

Thanks,

Eric

Fabrizio Giudici

unread,
Sep 19, 2014, 12:16:27 PM9/19/14
to Eric B, project...@googlegroups.com
On Fri, 19 Sep 2014 17:21:37 +0200, Eric B <eben...@gmail.com> wrote:

> Can't believe I forgot to check the actual project pom! Thanks for
> pointing out the obvious. :)
>
> So I finally got the configuration working, but as I suspect, or feared,
> ITDs will not work. If any java file relies on fields/members/etc of

Ok, I now understand what you mean in your first post. Yes, if the Java
code relies on them, the thing doesn't work. My example has got a field
injection, but the new field is only used by the aspect. That's why there
are no problems.

> in its current state. Which is a royal shame given how great it seems to
> be.

The problem is that Lombok is an innovation outside the original scope of
annotations. I think we should lobby a lot to have Oracle and other
partners to recognize it's a useful tool and provide explicit support for
it.

Eric B

unread,
Sep 19, 2014, 2:59:36 PM9/19/14
to Fabrizio Giudici, project...@googlegroups.com
There might be an ugly hack-around to first generate delombok source and then ajc the sources.  But the problem with that is 
a) It generates a lot of warnings when it encounters "errors" in the java code
b) I cannot figure out a way to do this incrementally from the editor such that I have continued real-time compilation warnings/errors that are displayed.

So while that might work for a build system, it is not effective for me to develop.

I guess I'll have to stick with Roo (sigh) until I can get some more feedback from the Lombok devs how to try to resolve this.

Eric

Martin Grajcar

unread,
Sep 19, 2014, 9:31:00 PM9/19/14
to project...@googlegroups.com, Eric B
On Fri, Sep 19, 2014 at 6:16 PM, Fabrizio Giudici <Fabrizio...@tidalwave.it> wrote:
The problem is that Lombok is an innovation outside the original scope of annotations. I think we should lobby a lot to have Oracle and other partners to recognize it's a useful tool and provide explicit support for it.

I disagree. Nearly everything what Lombok does should be part of Java. I really can't understand why I should write constructors or withers, or similar boilerplate. It's 2014. For Oracle it should be pretty easy to add such features, it's no breaking change, bears no risks, and keeps Java feels the same (except for the verbosity).

OTOH it would be nice to let annotation processing extend the existing class, so that new features could be easily implemented. One possible way would be to simply replace the source class by the APT-generated one.

I might be repeating myself, but I actually find Lombok way more useful than the JDK 9 functional stuff. It's not that fancy, but saves more lines.

Fabrizio Giudici

unread,
Sep 20, 2014, 3:11:58 AM9/20/14
to project...@googlegroups.com, Martin Grajcar, Eric B
On Sat, 20 Sep 2014 03:30:58 +0200, Martin Grajcar <maaar...@gmail.com>
wrote:

> On Fri, Sep 19, 2014 at 6:16 PM, Fabrizio Giudici <
> Fabrizio...@tidalwave.it> wrote:
>
>> The problem is that Lombok is an innovation outside the original scope
>> of
>> annotations. I think we should lobby a lot to have Oracle and other
>> partners to recognize it's a useful tool and provide explicit support
>> for
>> it.
>
>
> I disagree. Nearly everything what Lombok does should be part of Java. I

But it isn't, right? The process of evolving Java is unavoidable
bureaucratic and slow and unavoidably doesn't satisfy a lot of people
because it must produce a single Java. OTOH with Lombok one can choose how
to extend the language (not counting what you say below, that a further
enhancement might make really easy for everybody to design his own
annotations). That's why I see a reason for Lombok even in the long time.

> really can't understand why I should write constructors or withers, or
> similar boilerplate. It's 2014. For Oracle it should be pretty easy to
> add
> such features, it's no breaking change, bears no risks, and keeps Java
> feels the same (except for the verbosity).
>
> OTOH it would be nice to let annotation processing extend the existing
> class, so that new features could be easily implemented. One possible way
> would be to simply replace the source class by the APT-generated one.
>
> I might be repeating myself, but I actually find Lombok way more useful
> than the JDK 9 functional stuff. It's not that fancy, but saves more
> lines.
>


Martin Grajcar

unread,
Sep 21, 2014, 12:48:41 AM9/21/14
to Fabrizio Giudici, project...@googlegroups.com, Eric B
On Sat, Sep 20, 2014 at 9:11 AM, Fabrizio Giudici <Fabrizio...@tidalwave.it> wrote:
The problem is that Lombok is an innovation outside the original scope of
annotations. I think we should lobby a lot to have Oracle and other
partners to recognize it's a useful tool and provide explicit support for
it.


I disagree. Nearly everything what Lombok does should be part of Java. I

But it isn't, right? The process of evolving Java is unavoidable bureaucratic and slow and unavoidably doesn't satisfy a lot of people because it must produce a single Java.

Yes.. this can explain quite some conservatism. But it can't explain everything. Between the two last notable improvements (generics and closures) there lie 10 years. OK, there were ARM and multicatch and string-switch in JDK 7, and whatever, but who cares?
 
OTOH with Lombok one can choose how to extend the language (not counting what you say below, that a further enhancement might make really easy for everybody to design his own annotations). That's why I see a reason for Lombok even in the long time.

Given the blazing speed of Oracle, Lombok will be needed as long as Java itself (*). Designing own annotation would be nice, but it'd lead to some big language split, which is a bad thing. That's another reason for including the basics in the core language ASAP.

(*) I hope, it won't take long till some new language takes over. I guess, a lot of people would like something very similar and very compatible, just cleaner and better (unfortunately, Scala seems to be too ~%#+#>, while the others haven't gone very far yet).

The thing above is not swearing, it's a "key-weighted key-labeled directed edge" operator in a Scala graph library.

Marco Servetto

unread,
Sep 21, 2014, 4:07:29 AM9/21/14
to project...@googlegroups.com, Fabrizio Giudici, Eric B
---------------
>>Designing own annotation would be nice, but it'd lead to some big language split...
>>(*) I hope, it won't take long till some new language takes over....
---------
I'm a lecturer in Victoria University of Wellington and I'm in the
process of designing a java-like programming language that should
offer good support for lombok-like annotation/class decorators...
If someone is interested, I'm happy do discuss about it!
> cleaner and better (unfortunately, Scala seems to be too *~%#+#>*, while
> the others haven't gone very far yet).
>
> The thing above is not swearing, it's a "key-weighted key-labeled directed
> edge" operator in a Scala graph library.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Project Lombok" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to project-lombo...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

Fabrizio Giudici

unread,
Sep 21, 2014, 4:26:35 AM9/21/14
to Martin Grajcar, project...@googlegroups.com, Eric B
On Sun, 21 Sep 2014 06:48:40 +0200, Martin Grajcar <maaar...@gmail.com>
wrote:

> itself (*). Designing own annotation would be nice, but it'd lead to some
> big language split, which is a bad thing.

I think that languages supporting operator overloading, such as C++ or
Scala, are more prone to a "language split" phenomenon. I don't think that
this is a serious problem with Lombok.

Martin Grajcar

unread,
Sep 22, 2014, 12:41:29 AM9/22/14
to project...@googlegroups.com
Hi Marco,

On Sun, Sep 21, 2014 at 10:07 AM, Marco Servetto <marco.s...@gmail.com> wrote:
I'm a lecturer in Victoria University of Wellington and I'm in the
process of designing a java-like programming language that should
offer good support for lombok-like annotation/class decorators...
If someone is interested, I'm happy do discuss about it!

I'm not designing anything, but I really like discussing interesting things and this is surely one of them. Can you point me to some information about your project?

Martin.
Reply all
Reply to author
Forward
0 new messages