有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

通过在Maven中运行项目的java类生成源代码

我正在将一个较大的Ant构建转换为Maven。作为Ant构建的一部分,我们有几个步骤,通过调用项目的一个类来创建Java类,简化为:

javac SomeGenerator.java
java  SomeGenerator  generated # generate classes in generated/
javac generated/*.java

我已经将每个生成器拆分为它自己的Maven模块,但是我遇到了无法运行生成器的问题,因为它还没有在generate-sources阶段编译

我试过类似的方法

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.1.1</version>
            <executions>
                <execution>
                    <id>generate-model</id>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <phase>generate-sources</phase>

                    <configuration>
                        <mainClass>DTOGenerator</mainClass>
                        <arguments>
                            <argument>${model.generated.dir}</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>

遗憾的是,由于上述原因,这项措施不起作用。将代码生成器拆分为两个项目,一个用于编译生成器,另一个用于生成DTO,这似乎有些过分

还有什么替代方案


使用Maven 2.2.1


共 (5) 个答案

  1. # 1 楼答案

    我们面临同样的问题。我们希望尽可能地尊重Maven的行为,对插件没有任何问题等等。。。和Maven战斗太贵了

    我们意识到生成代码的更新频率通常与我们手动编写的代码非常不同,因此分离代码对于构建具有非常好的性能特征。所以我们接受将生成的类作为手动编写的类的依赖项

    我们采用了下面的结构,与常规的maven配置相比,只做了一点小小的更改,即源目录中的更改

    父项目:世代

    我们为我们所有的世代创建了一个母项目

    • 如果它包含要编译的代码,则它具有JAR类型,否则为POM
    • 这里有我们的生成代码,在/src中
    • 它可以像往常一样在/target中编译
    • 它运行生成,每个生成器在/target的子目录中生成代码

    Note: if you want several generated results in the same jar, just put them in the same sub-directory.

    子jar项目:Generateds

    • 它是Generations项目的子目录

    • 它有一个JAR类型

    • 源目录指向父级目标中的子目录

      <sourceDirectory>../target/generated1</sourceDirectory>

    • 它通常在自己的/target目录中编译


    这种结构使我们能够:

    • 对标准的maven布局进行尽可能少的修改,因此每个maven命令和插件都能很好地工作
    • 如果你有几个发电机,就可以很好地扩展
    • 如果您想生成多个JAR,可以很好地进行扩展(我们有一个案例wsdl2java,其中一个生成器生成的代码应该拆分为多个JAR;每个子生成的项目都有相同的源目录,但将配置一个<includes>来仅处理一些类)
  2. # 2 楼答案

    您可以在GenerateSources阶段执行maven编译插件。只需在现有执行之前添加另一个执行,并对其进行配置,使其只拾取生成器的源代码

    或者将项目一分为二:使用单独的POM构建生成器,并将生成器库作为生成源的POM的依赖项包含在内

    就我个人而言,我会把这个项目分开。使生成文件更干净,更易于维护

  3. # 3 楼答案

    我不想有两个不同的项目,所以我尝试设置Maven,以便将生成的编译代码添加到最终的jar包中

    这是我使用的有效解决方案:

    • process-classes阶段(在compile阶段之后执行):
      • exec-maven-plugin用于执行能够在target/generated-sources/java文件夹中生成源文件的主类(在我的特定情况下,我使用Roaster library生成源代码)
      • build-helper-maven-plugin用于将生成的源添加到正确的位置
    • prepare-package阶段:
      • maven-compiler-plugin,以便检测更改并重新编译模块
      • maven-jar-plugin用于生成jar包

    这是我的pom。xml:

    <build>
        <plugins>
    
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                        <configuration>
                            <mainClass>com.example.MyClassWriter</mainClass>
                            <arguments>
                                <argument>${project.basedir}</argument>
                                <argument>${project.build.directory}</argument>
                            </arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.build.directory}/generated-sources/java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                    </execution>
                </executions>
            </plugin>
    
        </plugins>
    </build>
    
  4. # 5 楼答案

    为了在一个项目中实现这一点,有3个步骤:

    1. 编译生成器代码

      我们可以在generate-sources阶段使用maven-compiler-plugin来完成。您还可以排除其他源文件

    2. 运行生成器生成代码

      我们可以在process-sources阶段使用exec-maven-plugin来完成

    3. 编制项目

    以下是pom的关键部分。xml

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
        <executions>
            <execution>
                <id>compile-generator</id>
                <phase>generate-sources</phase>
                <goals>
                  <goal>compile</goal>
                </goals>
                <configuration>
                  <includes>
                    <include>source/file/of/generator/*.java</include>
                  </includes>
                  <excludes>
                    <exclude>other/source/files/*.java</exclude>
                  </excludes>
                </configuration>
            </execution>
        </executions>
      </plugin>   
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.6.0</version>
        <executions>
            <execution>
                <id>generate-codes</id>
                <goals>
                    <goal>java</goal>
                </goals>
                <phase>process-sources</phase>
                <configuration>
                    <mainClass>your.main.class.of.generator</mainClass>
                </configuration>
            </execution>
        </executions>
      </plugin>