【问题标题】:Maven child module in parent pom as dependency父 pom 中的 Maven 子模块作为依赖项
【发布时间】:2020-02-24 22:34:34
【问题描述】:

我正在尝试创建一个包含多个模块的 maven spring-boot 项目。我创建了一个包装类型为 pom 的父模块和许多包装类型为 jar 的子模块。

所以我父母的 pom.xml 看起来像:

<groupId>Creator</groupId>
    <artifactId>DPAI</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>starter</module>
        <module>DatabaseApi</module>
        ...
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

其中一个子模块:starter 仅包含使用 @SpringBootApplicatoion 注释的起始类,并且在其 pom.xml 中有一个包含其他子工件的部分,例如:

    <parent>
        <artifactId>DPAI</artifactId>        
        <groupId>Creator</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

<artifactId>starter</artifactId>
<packaging>jar</packaging>

 <dependencies>
        <dependency>
            <groupId>Creator</groupId>
            <artifactId>DatabaseApi</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
...
    </dependencies>

所以我正在尝试进行一些重构并将 Main.class 和所有依赖项移动到我父母的 pom 中,但它不会编译错误并显示我的依赖项引用自身的消息。

在我看来,问题在于我的父 pom 包含带有它自己的子模块的部分。该子模块的父级是同一个 pom,我尝试在其中添加描述的依赖项

【问题讨论】:

  • 错误内容是什么?
  • 构建无法读取 1 个项目 -> [帮助 1] 项目 Creator:DatabaseApi:1.0-SNAPSHOT (D:\Workspaces\Creator\DatabaseApi\pom.xml) 有 1 个错误“依赖项”。依赖。 Creator:DatabaseApi:1.0-SNAPSHOT' for Creator:DatabaseApi:1.0-SNAPSHOT 正在引用自身。 @Creator:DPAI:1.0-SNAPSHOT,D:\Creator\DPAI\pom.xml,第 29 行,第 21 列
  • 您的应用程序是做什么的?它是否提供任何 REST Web 服务?还是一些网络前端?
  • Rest webservices,做一些统计计算——在不同的子模块中提供不同的场景(目的是在其他应用程序中也使用该数学模型)。将结果保存在 DB 中,同时从 DB 中获取一些参数。

标签: java spring-boot maven


【解决方案1】:

parent.pom 不能包含任何 java 代码,只能包含 Maven 细节,例如见:https://howtodoinjava.com/maven/maven-parent-child-pom-example/#parent-content

也许可以告诉我们,您想要实现什么。

【讨论】:

  • 我只想删除启动模块 - 它只是依赖收集器和运行应用程序,所以我试图将 java 代码添加到我的父模块。更重要的是,当我刚刚在父模块中创建 @SpringBootApplication 类时,应用程序启动了,但是 spring 上下文没有看到来自其他模块的任何 bean
  • 那么你为什么想要一个多模块项目呢? DatabaseApi 中有什么?您的其余业务逻辑在哪里?
  • 其余的业务逻辑在其他模块中——我在这里粘贴的时候跳过了。 DatabaseAPI 是一个用于数据库通信的模块,它位于单独的模块中,可以为其他应用程序导入该 jar。
  • 这是正确答案。父模块不能包含 Java 代码。
【解决方案2】:

在一个 Maven 多模块项目中,您通常有一个父 Pom(带有打包 Pom)和多个处于同一级别的模块,因为您已经设置了项目。 首先构建不依赖于您的代码的模块,依赖模块:在您的父 Pom 中,将模块的顺序更改为

<modules>
    <module>DatabaseApi</module>
    <module>starter</module>
    ...
</modules>

【讨论】:

  • 不,重点是,我想删除 starter,因为它只包含 Main.class 和其他模块的 部分。我正在尝试将 Main.class 和 部分移动到我的父 pom。
  • 这不是 Maven 的工作方式。每个 Maven 项目都会产生一个工件。要构建你的 starter 并定义它的依赖项,你需要一个 Pom for a jar。要构建整个项目,您需要一个带有打包 Pom 的父 Pom,它会生成有关如何构建所有内容(Pom 本身)的描述。
  • 没错,所以我正在尝试删除其中一个子模块 - 启动器并将其移动到父模块。更重要的是,当我刚刚在父模块中创建 @SpringBootApplication 类时,应用程序启动了,但是 spring 上下文没有看到来自其他模块的任何 bean
  • 你应该重新考虑你的架构......我会说你有一个主应用程序,它是可执行的,然后是其他模块,它们提供库样式代码作为依赖项。
  • 事实上,我只是想将@SpringBootApplication 类移动到我的父级 - pompacking 模块。现在,我想这是不可能的。
【解决方案3】:

所以我正在尝试进行一些重构并移动 Main.class 和所有 对我父母的 pom 的依赖

我认为这是不可能的。您的父 pom 实际上是 pom 类型,这意味着您实际上不应该在其中包含任何 java 代码。它旨在保存子模块中使用的 jar 版本。您可以将其与 spring-boot-parent 模块相关联。当我们在 spring boot 项目中声明 spring-boot-parent 模块时,您将项目添加为 spring-boot-parent 的子项。父级将管理您所有依赖项的版本。

我认为最好的方法是在 spring-boot 模块中维护所有与服务相关的代码。过滤器、控制器等其他东西,比如你的 jdbc,集成层可以在其他子模块中维护,然后将 spring 模块称为类似于你的示例的 jar 引用。

【讨论】:

    【解决方案4】:

    所以我正在尝试进行一些重构并移动 Main.class 和所有 对我父母的 pom 的依赖,

    我不确定 Maven 是否会在父 POM 本身中支持以下内容:

     <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>DatabaseApi</artifactId>
            <version>${project.version}</version>
        </dependency>
    ...
    </dependencies>
    

    但可以肯定的是,它不会支持带有 pom-packaging 的模块中的 Java 类(例如父模块或多模块模块)。编译器:编译目标等是not bound to any phase for pom-packaging by default。换句话说:默认情况下,Maven 不会为 pom-modules 编译 Java 类。

    我的建议: 将 SpringBootApplication 保存在基于 Java 的模块中。对于 Spring MVC/WebFlux 应用程序,我通常创建一个“-web”模块:

    • SpringBootApplication
    • 网络服务控制器
    • http/ 网络过滤器
    • 全局配置,例如:security、swagger、async
    • application.yml
    • ...

    这也是我配置 Spring Boot 插件以创建可执行 JAR 的模块。

    【讨论】:

    • “我不能 100% 确定 Maven 是否会在父 POM 本身中支持类似以下内容”它不起作用。我可以像在单个模块应用程序中一样将@SpringBootApplication 类放在父模块中吗?
    • @Gajek:正如我所说:POM 项目中没有代码。也许你可以手动绑定一些 Maven 目标,但确实不推荐。
    • 当我刚刚在我的父模块中创建 @SpringBootApplication 类时,应用程序启动了,但是 spring 上下文没有看到来自其他模块的任何 bean。单模块应用呢,pom打包模块里有java文件?
    • @Gajek:你检查了我提供的链接吗?默认情况下,compiler:compile 目标等不绑定到 pom 打包的任何阶段。换句话说:Maven 默认不为 pom-modules 编译 Java 类。
    • @Gajek 在单个 Java 模块应用程序中,您不使用 pom 打包,而是使用 jar/war/ear/ejb/bundle 或其他一些基于 Java 的打包。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 2012-07-19
    相关资源
    最近更新 更多