Specifying order of annotation processors

2019-01-14 02:27发布

问题:

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.

回答1:

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.



回答2:

Ideally the order shouldn't matter. Annotation processors should only create files - whenever a file is created, another processing round starts and other processor 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).



回答3:

It is possible to specify the order of annotation processors in javac using the -processor flag. However, I didn't get the compile even with this parameter set. I suspect that dagger looks at the source code directly, or that the annotation processor API schedules the annotation processor in the same round and the modifications by lombok are not propagated.

I think the most robust solution now is to use delombok to force the order.

Disclosure: I am a Lombok developer.