文档章节

一次多模块 Spring Boot 项目 mvn package 失败的解决经验

傅易
 傅易
发布于 2017/01/16 03:26
字数 975
阅读 9057
收藏 29

第一次使用多模块来组织项目代码,算是练手,却一波三折。

使用多模块的项目并不难,只需要在项目的 pom.xml 里声明其他模块(module)的路径,并依赖其它项目的 Maven 包即可。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <artifactId>B</artifactId>
    <groupId>demo</groupId>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>../A</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>demo</groupId>
            <artifactId>A</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

我们将 B 项目这种处在依赖链末端的项目称为终端项目。我们在终端项目里可以惯常地执行 mvn compilemvn package 毫无问题。

如果我们没有指定相应的模块路径,就需要在 A 项目里执行 mvn install 将其发布到本地仓库,否则 B 项目将会因为无法找到 A 包而报错,无法编译。

显然 mvn install 是一种很“重”的操作,它不够干净,而给每个依赖了其他模块的项目添加模块路径重复了很多不必要的代码。此时我们寄希望于使用父子项目的模式,按照官方文档 Guide to Working with Multiple Modules 搭建出被称为 Reactor(反应堆)的项目结构:

./path/to/parent/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>

    <groupId>demo</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>./path/to/A</module>
        <module>./path/to/B</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>demo</groupId>
                <artifactId>A</artifactId>
                <version>${project.version}</version>
            </dependency>
            <dependency>
                <groupId>demo</groupId>
                <artifactId>B</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

./path/to/A/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>parent</artifactId>
        <groupId>demo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>A</artifactId>
</project>

./path/to/B/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>parent</artifactId>
        <groupId>demo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>B</artifactId>

    <dependencies>
        <dependency>
            <groupId>demo</groupId>
            <artifactId>A</artifactId>
        </dependency>
    </dependencies>
</project>

此时项目的构建要稍费心思。

简单的在终端项目里使用 mvn compile 编译是不行的,因为找不到其他模块的 Maven 包。这时我们可以使用 mvn install 的老办法,也可以使用 -am--also-make 参数使 Maven 构建被依赖的包。

在 parent 包下使用 mvn compile -ammvn compile -pl B -am 的作用是一致的(-pl 参数的作用是指定编译模块)。因为 Maven 会分析依赖树并找到可行的顺序来构建。

当我将多模块项目应用于 Spring Boot 框架的时候,使用 IDE 编译、运行都没问题,但执行 mvn package 却发生了问题。明明被依赖包的 class 和 jar 包都输出了,却报错找不到被依赖的包。

百思不得其解,竟然发现 mvn compilemvn package 可行!令人迷醉。细心查看 Maven 构建过程,发现被依赖的包执行了 spring-boot-maven-plugin:repackage 目标,这嫌疑很大。

最终在 StackOverflow 找到了解决方案:

我们不应该给 parent 项目添加 spring-boot-maven-plugin 构建插件,而应该给终端项目使用,因为这个插件的 repackage 目标会处理 jar 包,导致依赖它的模块无法使用它。在 parent 项目中使用它会导致每个子项目都执行了该目标,进而出现编译失败。

仅此记录,希望能够减少大家的 debug 时间,祝大家生活愉快。

© 著作权归作者所有

傅易
粉丝 28
博文 110
码字总数 68632
作品 0
海淀
后端工程师
私信 提问
加载中

评论(5)

liujiduo
liujiduo
解决了,多谢!
lzxianren
lzxianren
<configuration>
<classifier>exec</classifier>
</configuration>

增加上面的配置可以打包两个,一个原始包,一个执行包。
https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/repackage-classifier.html
jack_jones
jack_jones

引用来自“傅易君”的评论

引用来自“jack_jones”的评论

我也是这么配置的,parent下面有几个module,b-module依赖于a-module,在b-module里执行package,提示找不到a-module的jar文件

@jack_jones 因为 b-module 里没有配置 a-module 的模块路径,这个路径在 parent 里配置了,所以你能从 parent 项目 mvn package -pl 实现你的目标。
用pl就可以了,3q
傅易
傅易 博主

引用来自“jack_jones”的评论

我也是这么配置的,parent下面有几个module,b-module依赖于a-module,在b-module里执行package,提示找不到a-module的jar文件

@jack_jones 因为 b-module 里没有配置 a-module 的模块路径,这个路径在 parent 里配置了,所以你能从 parent 项目 mvn package -pl 实现你的目标。
jack_jones
jack_jones
我也是这么配置的,parent下面有几个module,b-module依赖于a-module,在b-module里执行package,提示找不到a-module的jar文件
springboot|解决:mvn多模块下filter配置替换

问题:之前的mvn多模块项目,我会在parent模块下,创建几个filter配置文件,以实现不同环境不同配置。但是在搭建springboot的mvn多模块框架时,配置文件始终替换不了。 原因:仔细看springb...

云胜886
2018/07/31
0
0
springboot分离打包并部署到centos的服务脚本编写

maven构建的springboot项目打包很方便,但是如果项目是多模块的,依赖的第三方jar包可能比较多时,最终打包的jar包会很大,甚至超过100M,这对于版本迭代频率比较高的情况是比较浪费时间的,...

陈俊凯
03/09
121
0
SpringBoot2系列教程(二)maven项目包 (特别完整!)

前言:相信很多朋友都会遇到一些maven打包失败的问题,这里我把我自己再打包过程中遇到的问题都分享出来,希望能帮到大家。 本教程大概内容如下: 1. 依赖传递失效问题解决方案 注意父类继承...

fantj666
2018/03/08
0
0
SpringCloud多模块记一次maven打包报错

前言:微服务多模块开发经常会有公共的基础类库被引用,maven打包引入依赖一直无效 一、模块:demo-user需要引入demo-common,一直提示找不到程序包 二、原因:spring-boot-maven-plugin插件...

WALK_MAN
2018/11/18
418
0
开发笔记20 | 多模块工程部署

在上面的配置窗口中,我们注意到有一个"Before launch: "的模块,这个模块是添加运行配置前的任务的(譬如执行mvn打包任务),其中有几个操作: 这几个操作从左到右分别为: 增加任务 去除任...

银时
2018/12/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
14
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
15
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部