Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run maven compilation twice

Tags:

java

maven

ant

I'm in process of migrating ant project to maven and this project is quite unusual: it uses two compilation steps and code generation step between those compilation steps. The whole build process can be described as follows:

  1. Compile everything in src directory
  2. Run internal java tool, point java to the compiled classes and jars used to compile those classes. This tool generates code based on the compiled classes by using reflection.
  3. Compile generated classes and finally assemble a jar.

I found a few links that suggest to create a custom lifecycle but I've no idea where to start. If someone can point to similar project configuration that would be really great.

What would be the simplest way of achieving this with maven? I guess I should use ant maven plugin but I still don't understand how to make it compile sources twice and point it to the generated sources after first compilation step.

like image 941
Alex Avatar asked Jan 12 '23 09:01

Alex


1 Answers

OK, I finally figured out how to do that.

Basically I run compiler on different build phases so that compile happens on generate-sources phase, code is generated on process-sources phase and finally compiler makes final compilation on 'compile' phase.

Here is my configuration:

<build>
<plugins>
  <!-- Code generation, executed after the first compiler pass -->
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
      <execution>
        <id>generateCode</id>
        <phase>process-sources</phase>
        <goals>
          <goal>java</goal>
        </goals>
        <configuration>
          <classpathScope>test</classpathScope>
          <mainClass>my.code.Generator</mainClass>
          <arguments>
            <argument>-target</argument>
            <argument>${project.build.directory}/generated-sources/java</argument>
            <argument>-source</argument>
            <argument>my.code.generator.Configuration</argument>
          </arguments>
        </configuration>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
      <execution>
        <id>add-source</id>
        <phase>process-sources</phase>
        <goals>
          <goal>add-source</goal>
        </goals>
        <configuration>
          <sources>
            <source>${project.build.directory}/generated-sources/java</source>
          </sources>
        </configuration>
      </execution>
    </executions>
  </plugin>


  <!-- Custom compilation mode -->
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <executions>
      <execution>
        <id>default-compile</id>
        <phase>generate-sources</phase>
      </execution>
      <execution>
        <id>build-generated-code</id>
        <phase>compile</phase>
        <goals>
          <goal>compile</goal>
        </goals>
        <configuration>
          <generatedSourcesDirectory>${project.build.directory}/generated-sources/java</generatedSourcesDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

Hope this will be helpful for someone.

UPDATE You may probably notice that compiler unnecessarily compiles all the sources on final compiler pass. To fine tune your particular compiler pass you may want to use 'exclude'/'include' configuration for your project.

like image 55
Alex Avatar answered Jan 19 '23 07:01

Alex