views:

2896

answers:

2

I want to run the maven compiler plugin in a different phase and with different sourceDirectories and destinationDirectories such that code from directories other than src/main/java and src/test/java can be used.

I thought the solution would look something like the below, where the phase I was linking it to was pre-integration-test. However the properties for testSourceDirectory and testOutputDirectory don't seem to be specified in this way as they are in the section of the POM.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>

  <executions>
    <execution>
      <id>compile mytests</id>
      <goals>
        <goal>testCompile</goal>
      </goals>
      <phase>pre-integration-test</phase>
      <configuration>
        <testSourceDirectory>${basedir}/src/inttest/java</testSourceDirectory>
        <testOutputDirectory>${basedir}/target/inttest-classes</testOutputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Is there a way to get this plug-in to compile different directories in different phases without affecting its default operation?

+2  A: 

The source directories are set outside the compiler-plugin inside the <build> element, so this won't work.

You can use the build-helper-maven-plugin's add-source and add-test-source to specify additional source directories for your integration tests, but this will not remove the existing source dirs.

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <id>add-it-source</id>
        <phase>pre-integration-test</phase>
        <goals>
          <goal>add-source</goal>
        </goals>
        <configuration>
          <sources>
            <source>${basedir}/src/inttest/java</source>
          </sources>
        </configuration>
      </execution>
    </executions>
  </plugin>

If you bind the add-test-source goal to run just before the testCompile goal, your integration tests will be included. Note you want them to be output to target/test-classes so the surefire plugin will find them.

To handle removal of the standard test sources, I wrote a small plugin to modify the model to remove existing testSource locations before adding the ones for integration tests.

Rich Seller
+1  A: 

After more research it is apparent this is not actually possible in Maven 2 in the way I want, a hack of some form is necessary to introduce integration tests. While you can add additional directories (as suggested by Rich Seller) there is no plugin to remove the other sources or to compile a directory separately from the main compilation.

The best solution I have found for adding integration tests is to first use the build helper plugin to add the directory inttest directory to be compiled as tests.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
     <execution>
      <id>add-test-source</id>
      <phase>generate-sources</phase>
      <goals>
       <goal>add-test-source</goal>
      </goals>
      <configuration>
       <sources>
        <source>src/inttest/java</source>
       </sources>
      </configuration>
     </execution>
    </executions>
</plugin>

Now in order to get the integration tests to execute on the integration-test phase you need to use excludes and includes to manipulate when they get run as below. This allow any custom parameters you might want (in my case an agent being added via argline).

<plugin>
<groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
    <excludes>
        <exclude>**/itest/**</exclude>
    </excludes>
    </configuration>
<executions>
 <execution>
  <id>inttests</id>
  <goals>
   <goal>test</goal>
  </goals>
  <phase>integration-test</phase>
  <configuration>
   <excludes><exclude>none</exclude></excludes>
   <includes>
    <include>**/itest/**/*Test.java</include>
   </includes>
  </configuration>
 </execution>
</executions>
</plugin>
Paul Keeble
Alas this does not work correctly either. In seems that if you use this cobertura:cobertura integration-test then Maven runs the unit tests with coverage, then the tests themselves and then finally runs the integration tests, and for some reason ignores the excludes but takes account of the includes.
Paul Keeble