Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specifying order of annotation processors

I'm trying to run Dagger 2 as well as Lombok on my Java project. Lombok has to run first, of course, but whether it actually does seems to be up to chance. At first I suspected I could specify the order by the respective position of the library jars in the class path, but that order evidently gets ignored.

Is there a way to specify the order for them to run somehow, or do I simply have to live with not being able to combine two APs ?

I have produced an SSCCE test case.

A simple git clone & mvn compile is enough to demonstrate the issue - if you comment line 18 and uncomment lines 20-21 in App.java, it will compile, even though the Lombok notation in line 18 creates an identical constructor. The problem is that Lombok seems to run after Dagger.

like image 815
Torque Avatar asked Mar 22 '15 11:03

Torque


People also ask

Does order of annotations matter spring?

In almost all cases the answer is No, the order has no effect. But in fact it is a bit more complicated. Considering annotations that are processed by annotation processors, it was already stated in the other answers that it more depends on the order in which the processors run.

What is an annotation processor?

Annotation processing is a tool built into javac for scanning and processing annotations at compile time. It can create new source files; however, it can't modify existing ones. It's done in rounds. The first round starts when the compilation reaches the pre-compile phase.

How does annotation processing work?

The annotation processing is done in multiple rounds. Each round starts with the compiler searching for the annotations in the source files and choosing the annotation processors suited for these annotations. Each annotation processor, in turn, is called on the corresponding sources.


2 Answers

After a lot of research and having talked to one of the Lombok developers, it turns out that because javac does class loading based on hashCode(), the order of annotation processors running in this scenario is essentially random, and what's worse, random between multiple runs. There currently does not seem to be a solution to this issue.

I went with the lombok-maven plugin and delomboking the whole thing, which isn't perfect and somewhat hacky, but at least produces a working result. In hopes that it may aid future googlers coming here, I commited the working version to the repo.

like image 169
Torque Avatar answered Sep 27 '22 23:09

Torque


Ideally the order shouldn't matter. Annotation processors should only create files - whenever a file is created, another processing round starts and other processors have the chance again to do their thing with the new file. In this case the order doesn't really matter, so I don't think there is an official way to force an order of processors. The problem is that the Lombok processor manipulates existing files instead of creating new ones, which it is not supposed to do. Some compilers might have an option for ordering processors or use the order in which processors are loaded or appear in the command line arguments, but that will depend on the compiler's implementation.

You could try looking at Daggers and Lombok's build process and see which processors are invoked there. Then explicitly set up those processors in your maven build in the correct order and test different compilers and see if any of them run them in this order.

If necessary, you could split the compilation process and run Lombok with -proc:only first and after that another compilation step without Lombok and without overriding the manipulated files (if that is possible, I never tried that).

like image 25
kapex Avatar answered Sep 27 '22 23:09

kapex