Maven Compiler Plugin
  1. Maven Compiler Plugin
  2. MCOMPILER-157

Maven Compiler Plugin should add to compileSourceRoots for next plugins to consider as source directory for generated files

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.3.2
    • Fix Version/s: 3.2
    • Labels:
      None
    • Environment:
      Java 6
    • Flags:
      Patch

      Description

      Maven Compiler Plugin by relying on javac by default, on Java 6 platform includes annotation processors in it's processing, these in end could generate sources that are placed by default in target/generated-sources/annotations. The later should be added to compileSourceRoots so that next plugin in execution would consider those sources.

      Please, see the attached test case and consider the attached patch in the next release of maven-compiler-plugin.

      thanks,

      Zoran

      1. failing-test-example.zip
        10 kB
        Zoran Regvart
      2. maven-compiler-plugin-add-compileSourceRoots.patch
        2 kB
        Zoran Regvart
      3. maven-compiler-plugin-addToSourcePathAsWell.patch
        2 kB
        Gleb Frank
      4. test-case.zip
        8 kB
        Zoran Regvart
      5. TestCase2.zip
        8 kB
        Jérôme Verstrynge

        Issue Links

          Activity

          Hide
          Zoran Regvart added a comment - - edited

          One obvious workaround would be using build helper plugin to add the target/generated-sources/annotations to source path, like:

           
          <build>
              <plugins>
                <plugin>
                  <groupId>org.codehaus.mojo</groupId>
                  <artifactId>build-helper-maven-plugin</artifactId>
                  <version>1.7</version>
                  <executions>
                    <execution>
                      <id>add-source</id>
                      <phase>generate-sources</phase>
                      <goals>
                        <goal>add-source</goal>
                      </goals>
                      <configuration>
                        <sources>
                          <source>target/generated-sources/annotations</source>
                        </sources>
                      </configuration>
                    </execution>
                  </executions>
                </plugin>
              </plugins>
            </build>
          
          Show
          Zoran Regvart added a comment - - edited One obvious workaround would be using build helper plugin to add the target/generated-sources/annotations to source path, like: <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/generated-sources/annotations</source> </sources> </configuration> </execution> </executions> </plugin> </plugins> </build>
          Hide
          Jérôme Verstrynge added a comment -

          Hi, I have tried to above workaround, but it does not work.

          Here is the link to the StackOverflow question I created earlier today: http://stackoverflow.com/questions/6975298/generated-code-not-taken-into-account-in-maven-compile-process.

          Show
          Jérôme Verstrynge added a comment - Hi, I have tried to above workaround, but it does not work. Here is the link to the StackOverflow question I created earlier today: http://stackoverflow.com/questions/6975298/generated-code-not-taken-into-account-in-maven-compile-process .
          Hide
          Jérôme Verstrynge added a comment -

          To be more precise, when I apply the workaround to the provided test case, it works. Yet, in my application, it does not work. The only difference is that I generate a java file where only a .aj file is generated in the test case.

          Show
          Jérôme Verstrynge added a comment - To be more precise, when I apply the workaround to the provided test case, it works. Yet, in my application, it does not work. The only difference is that I generate a java file where only a .aj file is generated in the test case.
          Hide
          Jérôme Verstrynge added a comment -

          I have performed some tests and here are my results:

          i) I have checked-out maven-compiler-plugin from the 2.3.3 release locally
          ii) I have applied the patch provided by Zoran
          iii) I confirm that the issue he reported is solved with this patch (and it does not break existing tests)
          iv) However, when generating a java file instead of an aspectj file, the java file is not taken into account in the compiling process (it is not part of the generated .jar)

          I am posting another test case to illustrate my point. Keep in mind that I am new to annotation processing, so I may miss something obvious.

          Show
          Jérôme Verstrynge added a comment - I have performed some tests and here are my results: i) I have checked-out maven-compiler-plugin from the 2.3.3 release locally ii) I have applied the patch provided by Zoran iii) I confirm that the issue he reported is solved with this patch (and it does not break existing tests) iv) However, when generating a java file instead of an aspectj file, the java file is not taken into account in the compiling process (it is not part of the generated .jar) I am posting another test case to illustrate my point. Keep in mind that I am new to annotation processing, so I may miss something obvious.
          Hide
          Jérôme Verstrynge added a comment -

          Sorry, I meant 2.3.2 release.

          Show
          Jérôme Verstrynge added a comment - Sorry, I meant 2.3.2 release.
          Hide
          Gleb Frank added a comment -

          For that matter, why not also add the generated sources directory to the sourcepath as well, so that it gets compiled in the same run? The attached patch (maven-compiler-plugin-addToSourcePathAsWell.patch) builds on the original one to do that.

          Show
          Gleb Frank added a comment - For that matter, why not also add the generated sources directory to the sourcepath as well, so that it gets compiled in the same run? The attached patch (maven-compiler-plugin-addToSourcePathAsWell.patch) builds on the original one to do that.
          Hide
          Jesse Glick added a comment -

          maven-compiler-plugin-addToSourcePathAsWell.patch should not be necessary to my knowledge; 269-generated sources already get compiled in the same run.

          Show
          Jesse Glick added a comment - maven-compiler-plugin-addToSourcePathAsWell.patch should not be necessary to my knowledge; 269-generated sources already get compiled in the same run.
          Hide
          Martin Franklin added a comment -

          I managed to get this working using the helper plugin in combination with a second invocation of the compiler.

          Let compiler run normally and generate the annotation processor output.

          Then invoke the help plugin at the process-classes lifecycle stage, followed by the compiler again.

          Note that the order is important, so that the build-helper gets invoked before the compiler.

          <plugins>

          <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>build-helper-maven-plugin</artifactId>
          <version>1.7</version>
          <executions>
          <execution>
          <id>add-source</id>
          <phase>process-classes</phase>
          <goals>
          <goal>add-source</goal>
          </goals>
          <configuration>
          <sources>
          <source>target/generated-sources/annotations</source>
          </sources>
          </configuration>
          </execution>
          </executions>
          </plugin>
          <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <executions>
          <execution>
          <id>add-source</id>
          <phase>process-classes</phase>
          <goals>
          <goal>compile</goal>
          </goals>

          </execution>
          </executions>
          </plugin>
          </plugins>

          Show
          Martin Franklin added a comment - I managed to get this working using the helper plugin in combination with a second invocation of the compiler. Let compiler run normally and generate the annotation processor output. Then invoke the help plugin at the process-classes lifecycle stage, followed by the compiler again. Note that the order is important, so that the build-helper gets invoked before the compiler. <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>add-source</id> <phase>process-classes</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/generated-sources/annotations</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <executions> <execution> <id>add-source</id> <phase>process-classes</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> </plugins>
          Hide
          Martin Franklin added a comment -

          Should also state I upgraded to the compiler version 2.5.1 and am using maven 3.0.4

          Show
          Martin Franklin added a comment - Should also state I upgraded to the compiler version 2.5.1 and am using maven 3.0.4
          Hide
          Olivier Lamy (*$^¨%`£) added a comment -

          is there any way to have a failing test case ?

          Show
          Olivier Lamy (*$^¨%`£) added a comment - is there any way to have a failing test case ?
          Hide
          Zoran Regvart added a comment -

          Olivier, so the two projects that I'll upload are example of a failing situation. The awkwardly named compiler-plugin-simple-annotation-processor is an annotation processor that will generate a .txt file in the with the same directory structure as the annotated class, that is a class annotated with @SimpleAnnotation. The other project is compiler-plugin-annotation-test that has a compile dependency on the former, and a test that checks if the .txt file was indeed created.

          If you were to do it on command line using standard java tools you would first compile the sources with javac (including compiler-plugin-simple-annotation-processor.jar and junit.jar) at this point javac would detect the annotation processor and it would create the .txt file (in current directory if no -s option was given). Then you would use java org.junit.runner.JUnitCore org.apache.maven.plugin.AnnotationProcessorTest with classpath pointing to the output of javac (that would include the generated .txt file).

          With maven project directory structure and conventions, i.e. source output of annotation processors is target/generated-sources/[test-]annotations, and the fact that current maven compiler plugin does not forward the target/generated-sources/[test-]annotations to compileSourceRoots fails the test. The build helper workaround mentioned above helps, but I think that proper solution is for maven compiler plugin to include the sources it generated (via annotation processors) in classpath for other plugins to have.

          This is very similar to my original use case - in which I was generating resources (AspectJ inter type declarations) to be considered by the another plugin after maven compiler plugin (AspectJ maven plugin), that needs these generated resources in classpath. But I imagine that there are other use cases for this as well.

          I don't know it this is what you were thinking by a failing test, but I hope it helps.

          Zoran

          Show
          Zoran Regvart added a comment - Olivier, so the two projects that I'll upload are example of a failing situation. The awkwardly named compiler-plugin-simple-annotation-processor is an annotation processor that will generate a .txt file in the with the same directory structure as the annotated class, that is a class annotated with @SimpleAnnotation. The other project is compiler-plugin-annotation-test that has a compile dependency on the former, and a test that checks if the .txt file was indeed created. If you were to do it on command line using standard java tools you would first compile the sources with javac (including compiler-plugin-simple-annotation-processor.jar and junit.jar) at this point javac would detect the annotation processor and it would create the .txt file (in current directory if no -s option was given). Then you would use java org.junit.runner.JUnitCore org.apache.maven.plugin.AnnotationProcessorTest with classpath pointing to the output of javac (that would include the generated .txt file). With maven project directory structure and conventions, i.e. source output of annotation processors is target/generated-sources/ [test-] annotations, and the fact that current maven compiler plugin does not forward the target/generated-sources/ [test-] annotations to compileSourceRoots fails the test. The build helper workaround mentioned above helps, but I think that proper solution is for maven compiler plugin to include the sources it generated (via annotation processors) in classpath for other plugins to have. This is very similar to my original use case - in which I was generating resources (AspectJ inter type declarations) to be considered by the another plugin after maven compiler plugin (AspectJ maven plugin), that needs these generated resources in classpath. But I imagine that there are other use cases for this as well. I don't know it this is what you were thinking by a failing test, but I hope it helps. Zoran
          Hide
          Zoran Regvart added a comment -

          The failing test example

          Show
          Zoran Regvart added a comment - The failing test example
          Hide
          John Casey added a comment -

          adapted failing test case. It's now using a plugin to try to read the generated file from the annotation processor execution. It doesn't make sense that text files in the source roots would be accessible via the JUnit test classpath...

          Thanks for the patch and base test case!

          Show
          John Casey added a comment - adapted failing test case. It's now using a plugin to try to read the generated file from the annotation processor execution. It doesn't make sense that text files in the source roots would be accessible via the JUnit test classpath... Thanks for the patch and base test case!
          Hide
          Scott Carey added a comment -

          This seems to be the nexus of a lot of broken behavior related to annotation processing tools. Any chance it would be reverted? It simply appears to be the wrong thing to do. 'mvn clean compile' followed by 'mvn compile' breaks in most builds that have annotation processors that generate classes, from what appears to be this as the root cause.

          Adding a project's generated-sources/annotations to downstream projects classpath is probably ok, but adding it to itself appears flawed – that would imply that 'compile' and 'clean compile' are not expected to have the same input to the compile phase!.

          MCOMPILER-235, MCOMPILER-236

          Show
          Scott Carey added a comment - This seems to be the nexus of a lot of broken behavior related to annotation processing tools. Any chance it would be reverted? It simply appears to be the wrong thing to do. 'mvn clean compile' followed by 'mvn compile' breaks in most builds that have annotation processors that generate classes, from what appears to be this as the root cause. Adding a project's generated-sources/annotations to downstream projects classpath is probably ok, but adding it to itself appears flawed – that would imply that 'compile' and 'clean compile' are not expected to have the same input to the compile phase!. MCOMPILER-235 , MCOMPILER-236
          Hide
          Dawid Weiss added a comment -

          'mvn clean compile' followed by 'mvn compile' breaks in most builds that have annotation processors that generate classes, from what appears to be this as the root cause.

          Amen to that. It also happens with just about any JMH project.

          Show
          Dawid Weiss added a comment - 'mvn clean compile' followed by 'mvn compile' breaks in most builds that have annotation processors that generate classes, from what appears to be this as the root cause. Amen to that. It also happens with just about any JMH project.

            People

            • Assignee:
              John Casey
              Reporter:
              Zoran Regvart
            • Votes:
              7 Vote for this issue
              Watchers:
              15 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development