【问题标题】:Run maven compilation twice运行两次maven编译
【发布时间】:2014-07-11 19:29:23
【问题描述】:

我正在将 ant 项目迁移到 maven,这个项目很不寻常:它使用两个编译步骤和这些编译步骤之间的代码生成步骤。整个构建过程可以描述如下:

  1. 编译src目录下的所有东西
  2. 运行内部 java 工具,将 java 指向已编译的类和用于编译这些类的 jar。该工具使用反射基于编译的类生成代码。
  3. 编译生成的类,最后组装一个 jar。

我找到了一些建议创建自定义生命周期的链接,但我不知道从哪里开始。 如果有人能指出类似的项目配置,那就太好了。

用 maven 实现这一目标的最简单方法是什么? 我想我应该使用 ant maven 插件,但我仍然不明白如何让它编译两次源并在第一个编译步骤后将其指向生成的源。

【问题讨论】:

  • 我希望你能从 Maven 中获得一些好处,以换取这种头痛。
  • 我真正想从 maven 获得的唯一东西是它的依赖管理。现代 maven 也能够进行并行构建。
  • 可能值得关注 Ivy 的依赖管理。对于具有异常构建流程的现有 Ant 项目,Ant+Ivy 可能是比直接迁移到 Maven 更简单的迁移路径。无论如何,祝您迁移顺利!
  • 感谢 Ivy 的指点,但我必须坚持使用 maven,因为许多其他项目已经使用了它。如果有人感兴趣——目前我决定坚持使用多模块项目配置——这不是一个理想的解决方案,但它看起来是一种简单的方法来做我想做的事。虽然我仍然没有放弃为 maven 找到一个干净、更好的解决方案的希望。

标签: java maven ant


【解决方案1】:

好的,我终于想通了。

基本上我在不同的构建阶段运行编译器,以便在生成源阶段进行编译,在进程源阶段生成代码,最后编译器在“编译”阶段进行最终编译。

这是我的配置:

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

希望这对某人有所帮助。

更新 您可能会注意到编译器不必要地编译了最终编译器传递的所有源代码。要微调您的特定编译器通道,您可能需要为您的项目使用“排除”/“包含”配置。

【讨论】:

  • 这段代码指定了默认的generatedSourcesDirectory,这是多余的。小尼特。无论如何,非常有用的例子。
  • 注意 default-compile 既神奇又需要。
  • 感谢@AlicePurcell,这是为我解决问题的关键。
【解决方案2】:

Example: Configuring compile to run twice

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.5</source>
    <target>1.5</target>
  </configuration>
  <executions>
    <execution>
      <id>default-compile</id>
      <configuration>
        <excludes>
          <exclude>**/cli/*</exclude>
        </excludes>
      </configuration>
    </execution>
    <execution>
      <id>build-java14-cli</id>
      <phase>compile</phase>
      <goals>
        <goal>compile</goal>
      </goals>
      <configuration>
        <source>1.3</source>
        <target>1.3</target>
        <includes>
          <include>**/cli/*</include>
        </includes>
      </configuration>
    </execution>
  </executions>
</plugin>

根据您的需要调整此配置

【讨论】:

  • 这似乎非常接近我的需要,但我没有看到在给定编译步骤之间嵌入代码生成步骤的简单方法。可能我错过了一些非常基本的 maven 功能,但在我看来,在另一个插件中引用另一个插件的执行阶段是不可能的,是吗?
【解决方案3】:

我建议您最好创建两个单独的 Maven 项目。将(静态)Java 源代码放入第一个项目。将动态的东西放到第二个项目中,并添加对第一个项目的引用:

<dependency>
  <groupId>org.yourgroup</groupId>
  <artifactId>sub-module-1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</dependency>

现在,构建并安装第一个项目:

mvn install

之后,您应该能够构建第二个项目。

【讨论】:

  • 我想过,但这对我来说似乎太过分了,而且有点混乱。生成的代码并不大,并且与原始包中的源密切相关。所以,如果可能的话,我会保留一个项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多