Re: maven-compiler-plugin ignores Javac annotation processor error

2015-02-23 Thread Sébastien Lesaint
Hi Thomas,

Apparently, I failed a couple of times to make myself clear and did not run
my tests thoroughly enough.

1. Yes, you're right, from the command line, only javac 1.8 displays the
error message. Javac 1.7 does not display anything (being OpenJDK's or
Oracle's).
2. No, I have never seen a build with a warning. I was describing what I
was expecting from Maven. Also, turns out I had messed my env variables up
and was always running Maven with java 1.7. When running Maven with Java
1.8, the build does fail as you describe.

So, for the second bug, the conclusion is: run maven with Java 1.8 to get a
nice failing build and if a problem there was, it really was between the
chair and the keyboard.

Sorry for the bother, but I did learn quite a lot.

Thanks

Sébastien Lesaint

2015-02-23 10:28 GMT+01:00 Thomas Broyer t.bro...@gmail.com:

 On Mon Feb 23 2015 at 09:53:24 Sébastien Lesaint 
 sebastien.lesa...@gmail.com wrote:

  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 ?
 

 This is rather strange.

 When using OpenJDK 7, the build succeeds without actually compiling
 anything; and if I run javac manually with the options taken from mvn -X
 output, it also succeeds, without any warning about the missing processor
 (even when also passing -Xprefer:source -XprintProcessorInfo -XprintRounds
 and/or -verbose; with -XprintRounds we clearly see there's a problem
 though: only one round, with last round: false).

 When using OpenJDK 8 however, the build fails with a clear error:
 [ERROR] Failed to execute goal
 org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
 (default-compile) on project test: Compilation failure
 [ERROR] Bad service configuration file, or exception thrown while
 constructing Processor object: javax.annotation.processing.Processor:
 Provider foo.bar.BazProcessor not found

 So it looks like it could be a Javac bug that's been fixed in Java 8.

 I don't reproduce the same behavior as the one you describe though (build
 passing with warning). Tests conducted with Maven 3.0.5 and Maven 3.2.3 on
 Ubuntu 14.10 with the Ubuntu-provided OpenJDK versions, and default
 m-compiler-p version from the Maven super-pom.



Re: maven-compiler-plugin ignores Javac annotation processor error

2015-02-23 Thread Sébastien Lesaint
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 procnone/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 

Re: maven-compiler-plugin ignores Javac annotation processor error

2015-02-23 Thread Thomas Broyer
On Mon Feb 23 2015 at 09:53:24 Sébastien Lesaint 
sebastien.lesa...@gmail.com wrote:

 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 ?


This is rather strange.

When using OpenJDK 7, the build succeeds without actually compiling
anything; and if I run javac manually with the options taken from mvn -X
output, it also succeeds, without any warning about the missing processor
(even when also passing -Xprefer:source -XprintProcessorInfo -XprintRounds
and/or -verbose; with -XprintRounds we clearly see there's a problem
though: only one round, with last round: false).

When using OpenJDK 8 however, the build fails with a clear error:
[ERROR] Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
(default-compile) on project test: Compilation failure
[ERROR] Bad service configuration file, or exception thrown while
constructing Processor object: javax.annotation.processing.Processor:
Provider foo.bar.BazProcessor not found

So it looks like it could be a Javac bug that's been fixed in Java 8.

I don't reproduce the same behavior as the one you describe though (build
passing with warning). Tests conducted with Maven 3.0.5 and Maven 3.2.3 on
Ubuntu 14.10 with the Ubuntu-provided OpenJDK versions, and default
m-compiler-p version from the Maven super-pom.


Re: maven-compiler-plugin ignores Javac annotation processor error

2015-02-21 Thread Jeff MAURY
Sure this is not a Javac problem ?

Jeff

On Fri, Feb 20, 2015 at 9:09 PM, 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 procnone/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 procnone/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




-- 
Jeff MAURY


Legacy code often differs from its suggested alternative by actually
working and scaling.
 - Bjarne Stroustrup

http://www.jeffmaury.com
http://riadiscuss.jeffmaury.com
http://www.twitter.com/jeffmaury


Re: maven-compiler-plugin ignores Javac annotation processor error

2015-02-21 Thread Thomas Broyer
On Sat Feb 21 2015 at 10:12:23 Jeff MAURY jeffma...@jeffmaury.com wrote:

 Sure this is not a Javac problem ?


No it's not.
target/classes contains the
META-INF/services/javax.annotation.processing.Processor and it's put in the
classpath, and because there's no support for processorpath [1], javac
looks up annotation processors in the classpath; so it finds that file,
which references a class that you're about to compile, and tries to find
the class in the classpath, where it's obviously not.

This issue is actually known for YEARS:
https://jira.codehaus.org/browse/MCOMPILER-97

[1] https://jira.codehaus.org/browse/MCOMPILER-134


Re: maven-compiler-plugin ignores Javac annotation processor error

2015-02-21 Thread Thomas Broyer
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 procnone/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