Hello, Thanks Thomas for your extensive answer. But you seemed to focus only on the first problem (which I had identified as potentially _not_ a bug).
What about the fact that m-compiler-p ignores the error returned by Javac and allows the build to continue ? Right now, I have a successful build (it's a demo, there is no test defined) and there is just nothing working. I would be far more comprehensive if the javac error was reported, the build failed and a quick google search would pop the workaround (either proc:none or use @AutoService) for that specific error. WDYT ? Thanks, Sébastien Lesaint 2015-02-21 13:14 GMT+01:00 Thomas Broyer <t.bro...@gmail.com>: > On Fri Feb 20 2015 at 21:11:14 Sébastien Lesaint < > sebastien.lesa...@gmail.com> wrote: > > > Hello, > > > > I have been into annotation processing a lot for the past year and a half > > and I am now going back to the basics so that I can share knowledge I > > gathered. > > > > Doing so, I stumbled upon, again, a problem I had meet very early, for > > which I had googled the solution, but this time I went deeper to figure > out > > what was really wrong. > > > > # the symptoms > > > > When writing an annotation processor and creating the associated > > service-discovery file > > "`META-INF/services/javax.annotation.processing.Processor" in a Maven > > module, one needs to disable annotation processing completely (using > > the <proc>none</proc> configuration option of the maven-compiler-plugin) > > otherwise the module compilation succeeds but not a single .class file is > > created. > > > > # how I investigated > > > > I compiled the module with the -X option, extracted the javac command > line > > and ran it by hand. I got the following compilation error: > > error: Bad service configuration file, or exception thrown while > > constructing Processor object: javax.annotation.processing.Processor: > > Provider com.foo.BarProcessor not found > > > > The thing is, the com.foo.BarProcessor is the very processor I am > compiling > > (and the single .java file of the module). > > > > # what I found > > > > I went through the maven logs, spent some time thinking about it and > > believe that we are facing one, maybe two bugs in the > > maven-compiler-plugin: > > > > 1. Maven copies resources from the "src/main/resources" directory to the > > "target/classes" directory > > 2. the maven-compiler-plugin builds up a javac command line that > specifies > > the "target/classes" directory as a member on the classpath with the > > argument "-classpath" (is that a bug ? there may be a good reason to do > so > > but in a basic jar module setup I can see any) > > > > This is because of m-compiler-p's attempt at incremental compilation. It > looks at all source files and if one doesn't have a corresponding *.class > file or is newer then it adds it to the list of source files to recompile. > Because those will likely reference other classes that might not have > changed, target/classes is included in the classpath so that the > already-compiled classes can be found. > > That said, incremental compilation is (was) kind-of broken, as it doesn't > track class dependencies and won't recompile those classes that reference > the classes that have changed. See > https://cwiki.apache.org/confluence/display/MAVEN/Incremental+Builds for > an > example. > If you ask me, m-compiler-p should just check whether "something" needs to > be recompiled (which in itself is already error-prone, for many reasons > [1]) and recompile everything. > Actually, m-compiler-p 3.1+ should apparently behave that way by deleting > all *.class files it had created in a previous run (unless you set > useIncrementalCompilation=false [2]), so it shouldn't need target/classes > to be part of the classpath, at least for this use-case of incremental > compilation, but still includes it anyway. > Takari has a new plugin (and lifecycle) that apparently does truly > incremental compilation [3], by tracking class dependencies (when using JDT > rather than javac). It'd still fail your use-case though IIUC, if it > supported annotation processing through JDT (I haven't looked at how it > handles incremental builds with javac). > > The other reason for target/classes to be in the classpath is so that > annotation processors could find resources (let's not debate here whether > it's a good idea or not). m-compiler-p developers can't seem to agree on > what should be done: should m-compiler-p use -sourcepath sometimes [4] or > always [5] ? Should target/classes be included in the sourcepath [6] ? > > [1] http://blog.ltgt.net/maven-is-broken-by-design/ (note: things have > changed a bit since I wrote this; e.g. incremental build in m-compiler-p > 3.1+, the Takari lifecycle, etc.) > [2] > > https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#useIncrementalCompilation > [3] http://takari.io/2014/10/16/incremental-compilation.html > [4] https://jira.codehaus.org/browse/MCOMPILER-26, > https://jira.codehaus.org/browse/MCOMPILER-174 > [5] https://jira.codehaus.org/browse/MCOMPILER-98 > [6] https://jira.codehaus.org/browse/MCOMPILER-122 > > 3. when run, javac finds a > > "META-INF/services/javax.annotation.processing.Processor" file in the > > classpath and looks for the specified processor "com.foo.BarProcessor " > > 4. obviously, this processor can not be found, javac reports an error and > > stops the compilation before it even started compiling anything (ence > not a > > single .class file in the target directory) > > 5. the error ("error: Bad service configuration file, or exception thrown > > while constructing Processor object: javax.annotation.processing. > > Processor: > > Provider com.foo.BarProcessorr not found") is ignored by the > > maven-compiler-plugin that considers the compilation successful and the > > maven build goes on (this is our big bug) > > > > # bonus > > > > Please note that this has pernicious side effects. > > > > Since the build is successful, the jar which is supposed to contain the > > processor is created but only with the resources which means that it > > contains the "META-INF/services/javax.annotation.processing.Processor" > > file. > > > > Now, any module or project which has this jar file as a dependency will > > produce 0 .class file. Their compilation classpath is "contaminated" > with a > > "META-INF/services/javax.annotation.processing.Processor which references > > an non existent processor. Javac will therefor fail with the "Bad service > > configuration file" and produces no .class file. > > > > # affected versions > > > > I tested this with Maven 3.1.1 & 3.2.5, maven-compiler-plugin 2.5, 3.1 > and > > 3.2 and Oracle JDK 6, 7 & 8 on a ubuntu 64 bits machine. But, according > to > > the various posts, stackoverflow entries, etc. all around the web which > > provide the <proc>none</proc> solution, it occurs on other setups. > > > > # conclusion > > > > I initially though I would file a bug in the maven-compiler-plugin JIRA > but > > it is unclear how I can create an account. > > > > It's a known bug, opened for YEARS: > https://jira.codehaus.org/browse/MCOMPILER-97 > > Note that a workaround might be to generate the > META-INF/services/javax.annotation.processor.Processor file using > annotation processing ;-) using either > com.google.auto.service:auto-service, > org.kohsuke.metainf-services:metainf-services, or org.immutables:metainf > (or anything similar) >