Java项目的定制构建生命周期

Java项目的定制构建生命周期,java,maven,gradle,ivy,Java,Maven,Gradle,Ivy,在一个Maven项目中,我面临着一种奇怪的依赖循环:有两个Maven模块,其中一个是检测Java字节码,同时使用在另一个模块中定义的断言(用于单元测试),而另一个模块又应该由第一个模块检测 所以,这不仅仅是一个循环,它是一个循环,分布在maven阶段之间。我没有通过重组Maven模块来解决这个问题,我怀疑在这种情况下这是可能的 此问题的假设解决方案可能是以以下方式重新组织生成生命周期: 编译第一个模块的源代码 编译第二个模块的源代码 使用第一个模块的等级为第二个模块安装仪表 测试第一个和第二个模

在一个Maven项目中,我面临着一种奇怪的依赖循环:有两个Maven模块,其中一个是检测Java字节码,同时使用在另一个模块中定义的断言(用于单元测试),而另一个模块又应该由第一个模块检测

所以,这不仅仅是一个循环,它是一个循环,分布在maven阶段之间。我没有通过重组Maven模块来解决这个问题,我怀疑在这种情况下这是可能的

此问题的假设解决方案可能是以以下方式重新组织生成生命周期:

  • 编译第一个模块的源代码
  • 编译第二个模块的源代码
  • 使用第一个模块的等级为第二个模块安装仪表
  • 测试第一个和第二个模块
  • 打包
  • 安装/部署它们
  • 我怀疑Maven是为这种黑客设计的。其他工具呢?可以用葛兰朵或常春藤来做吗?或者可能在Maven中通过某个插件实现?或者问题是典型的,并且有更直接的解决方案


    PS:请不要建议在单独的模块中列出常见的依赖项。如果它这么简单,我就不会在这里了。

    在我看来,你应该在Gradle上完成这项任务,特别是它的多项目构建。Gradle允许从任何构建脚本访问多项目构建的任何项目中的任务。因此,您应该在子项目中定义您需要的任务,并从根项目中以您想要的任何顺序调用它们。

    Gradle提案非常好,但由于内部障碍,不适用于我的情况

    对于Maven,我不得不承认,在我的例子中,将插装代码和测试断言分离到模块是不可能的:它们在构建时过于耦合。因此,我没有在构建时尝试将它们分开,而是在构建后设法将它们分开

    注意这个解决方案并不是很好的解决方法:如果您试图分离的类实际上正在相互使用,那么在运行时可能会出现类加载异常。此外,在分离的JAR之间不会有任何可传递的解决方案-Maven会将它们视为完全独立的

    因此,我通过遵循以下步骤序列,成功地将插装代码和测试断言分离为两个jar工件:

  • 让它们都在一个Maven模块中
  • 像往常一样,在模块的
    构建
    阶段进行编译和插装,并在
    测试
    阶段进行测试。这不再是问题,因为此阶段的所有必要内容都位于模块中
  • package
    阶段,配置maven-jar-plugin以使用有限的类文件集收集其他工件

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
                <execution>
                    <id>jar-api</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <classifier>api</classifier>
                        <includes>
                            <include>com/example/api/**</include>
                        </includes>
                    </configuration>
                </execution>
                <execution>
                    <id>jar-codegen</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <classifier>codegen</classifier>
                        <skipIfEmpty>false</skipIfEmpty>
                        <includes>
                            <include>oo/example/codegen/**</include>
                        </includes>
                    </configuration>
                </execution>
                <execution>
                    <id>jar-tests</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                    <configuration>
                        <skipIfEmpty>false</skipIfEmpty>
                        <classifier>tests</classifier>
                        <includes>
                            <include>com/example/tests/**</include>
                        </includes>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    
    
    org.apache.maven.plugins
    maven jar插件
    jarapi
    罐子
    应用程序编程接口
    com/example/api/**
    jar代码发生器
    罐子
    编码基因
    假的
    oo/example/codegen/**
    震击试验
    罐子
    假的
    测验
    com/示例/测试/**
    
  • install
    阶段,这些附加工件将与组装的模块一起安装到本地存储库中

  • 我在这里看到的最好的解决方案是添加一个具有公共依赖项的独立模块,比如test-utils。不幸的是,在这种特殊情况下,它不是选项。根据定义,假设该语句是不可伪造的:“插装代码使用断言进行测试,断言应该由该代码插装”。它们之间没有共同的依赖关系。它们只在特定阶段相互接触。我完全知道这句话本身听起来很臭,但这是事实。由于该周期涉及许多Maven阶段,我认为打破它的唯一方法是重新组织阶段,而不是依赖关系。单元测试应该与您正在测试的类位于同一个模块中,这意味着在第一个模块内运行测试…而不是在第一个模块外运行测试…问题是您使用的是哪种工具?是的,一个单独的解决方案是按照前面的建议定义公共DEP。说到测试,不是项目之外的测试,而是它们的断言。但这与问题无关。同样,我知道在Maven中解决依赖循环的典型方法。我的问题不是关于这个,说到插装,它只是验证了一些关于Java字节码的假设,并为符合这个假设的类生成equals和hashCode。它在启用它的项目(maven插件)的流程类阶段工作。除此之外,与问题无关。