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

holgip5t  于 5个月前  发布在  Java
关注(0)|答案(6)|浏览(78)

我正在将一个较大的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.

n1bvdmb6

n1bvdmb61#

您可以在generate-sources阶段执行maven-compile-plugin。只需在现有执行之前添加另一个执行并配置它,以便它只为生成器拾取源代码。
或者将项目一分为二:使用单独的POM构建生成器,并将生成器库作为生成源代码的POM的依赖项。
就我个人而言,我会拆分项目。保持构建文件更干净,更容易维护。

p1iqtdky

p1iqtdky2#

我不想有两个不同的项目,所以我尝试设置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用于生产罐 Package

这是我的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>

字符串

jtoj6r0c

jtoj6r0c3#

为了在一个项目中做到这一点,有三个步骤:
1.编译生成器代码
我们可以在generate-sources阶段使用maven-compiler-plugin来完成。您也可以排除其他源文件。
1.运行generator生成代码
我们可以在process-sources阶段使用exec-maven-plugin
1.编译项目
下面是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>

字符串

kxxlusnw

kxxlusnw4#

我们面临着同样的问题。我们希望尽可能地尊重Maven的行为,不存在插件等问题...与Maven战斗太昂贵了!
我们意识到生成的代码的更新频率通常与我们手动编写的代码有很大的不同,所以分离代码对构建有很好的性能特征。所以我们接受将生成的类作为手动编写的依赖。
我们采用了下面的结构,与常规maven配置相比只有一个小小的变化,即源目录的变化。

父项目:Generations

我们为我们所有几代人创建了一个父项目。

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

注意:如果你想在同一个jar中生成多个结果,只需将它们放在同一个子目录中。

jar子项目:Generateds

  • 这是世代计划的一部分。
  • 它有一个反式的。
  • 源目录指向父目录目标中的子目录。

第一个月

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

这种结构使我们能够:

  • 尽可能少的修改标准maven布局,所以每个maven命令和插件都能很好的工作。
  • 如果你有几个发电机,
  • 如果你想生成多个jar,可以很好地伸缩(我们有一个例子wsdl 2 java,其中一个生成器生成的代码应该被分成几个jar;每个子生成的项目都有相同的源目录,但是会配置一个<includes>来处理一些类)。
xwbd5t1u

xwbd5t1u5#

我在这里发布了一个最小的工作设置https://github.com/baloise/inlinesourcecodegenerator它使用构建助手编译器和exec插件,并在同一个项目中的所有代码。

llmtgqce

llmtgqce6#

下面是一个最小的、注解良好的pom.xml,它允许在同一个项目中生成代码,同时确保之后正确清理:

<build>
        <plugins>
            <!-- Compile XyzGenerator.java to XyzGenerator.class -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <executions>
                    <execution>
                        <id>code-generator</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>com/project/codegen/XyzGenerator.java</include>
                            </includes>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- Execute XyzGenerator.class to generate Xyz.Java -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <id>code-generator</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                        <configuration>
                            <classpathScope>compile</classpathScope>
                            <mainClass>com.project.codegen.CodeGenerator</mainClass>
                            <commandlineArgs>target/codegen/com/project/</commandlineArgs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- Include the path to Xyz.java for compilation -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.5.0</version>
                <executions>
                    <execution>
                        <id>code-generator</id>
                        <phase>process-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>target/codegen</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <!-- Package the application in a JAR file -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>default-jar</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                        <configuration>
                            <excludes>
                                <!-- Exclude the XyzGenerator.class file from the JAR -->
                                <exclude>com/project/codegen/*.*</exclude>
                                <exclude>com/project/codegen</exclude>
                            </excludes>
                            <archive>
                                <manifest>
                                    <!-- Add the name of main class -->
                                    <addClasspath>true</addClasspath>
                                    <mainClass>com.project.Main</mainClass>
                                </manifest>
                            </archive>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

字符串
XyzGenerator.java文件中的CodeGenerator类中的main函数将输出目录作为第一个命令行参数;在上面,这是在<commandlineArgs>标记中传递的。
文件结构为:

src
'- main
   '- java
      '- com
         '- project
            '- Main.class
            '- codegen
               '- XyzGenerator.java
target
'- codegen
   '- com
      '- project

相关问题