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)
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.

So, I am using this mailing list to reach to the experts and the developer
to get accurate feedback on the matter.

Thanks in advance,

Sébastien Lesaint

Reply via email to