SpringBoot项目关于Maven打包问题
本文所有问题以及解决方案都以 IDEA 开发工具为基础。
Maven 打包缺少资源文件
一般出现这种问题的常见原因有三种:
第一种,项目中的resources文件没有标记为资源根目录。
第二种,pom文件缺少指定配置文件路径的相关配置。
第三种,绝对路径和相对路径问题(重点)。
项目中的resources文件没有标记为资源根目录
先说说第一种的情况,如图1-1就是SpringBoot项目中的resources文件没有被标记为资源根目录的样子,这个时候resources文件下的配置文件是不会生效的,也就是不会被SpringBoot自动扫描到的。
解决办法,选中resources文件鼠标右键,选择Mark Directory as
-> Resources Root
将目录标记为资源根目录就可以了,标记完以后就像如图1-2一样。
也可以通过File
->Porject Structure
打开项目结构窗口,选择Modules
的Sources
模块进行标记,如图1-3。
pom文件缺少指定配置文件路径的相关配置
第二种情况出现的原因是和pom文件有关,通过上面我们已经把resorces标记为资源根目录了,如果打包资源文件还有问题的话,可以在pom文件增加如下配置:
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
但是一般情况下把资源文件放在默认的src/main/resources
目录下是不会有问题的,需不需要写上面配置跟一下三种情况有关:
- 编译和打包:对于编译和打包,默认情况下,Maven会处理
src/main/resources
目录下的所有资源文件。所以,如果你的资源文件都在这个目录下,并且你没有使用到过滤功能,那么移除这段配置很可能不会影响到你的项目。 - 资源过滤:然而,如果你使用了资源过滤功能(例如,在资源文件中使用了${property}形式的占位符,并在pom.xml中定义了这些属性的值),那么移除这段配置后,资源过滤将不再发生,这可能会影响到你的项目。
- 非默认资源目录:如果你的资源文件不在
src/main/resources
目录下,或者你有额外的资源目录,那么你需要这段配置来指定这些目录,否则Maven将不会处理这些目录中的文件。
绝对路径和相对路径问题
如果以上配置都检查无误后,使用Maven打包时仍然缺少资源文件,就很有可能是第三种原因导致的。如图1-4和图1-5可以看一下他们的区别,如果你的配置和图1-4一致,那么恭喜你,你会发现你使用Idea工具启动项目时,target/classes
目录下是存在资源文件的,但是一旦使用Maven进行打包,资源文件就不见了。如果你的配置和图1-5一致,就不会有问题,这就是因为绝对路径和相对路径导致的。图1-4的写法属于绝对路径,图1-5属于相对路径。
下面讲一下以上两种写法的区别:
对于 <directory>src/main/resources</directory>
:
- 这是相对于POM文件的相对路径,它指向项目中的 src/main/resources 目录。这是Maven的默认资源目录,通常包含应用程序的配置文件、属性文件等。
对于 <directory>/src/main/resources</directory>
:
- 这是从文件系统的根目录开始的绝对路径。它指向文件系统中的 /src/main/resources 目录,而不是项目目录中的 src/main/resources。
使用第二种写法(即从根目录开始的路径,如 /src/main/resources)在Maven打包时可能会出现以下问题:
- 路径错误:由于这是从文件系统的根目录开始的绝对路径,如果POM文件不在预期的位置,Maven可能无法找到资源目录,导致构建失败。
- 不可移植性:与先前的例子一样,使用绝对路径会降低项目的可移植性,因为它可能在不同的操作系统或文件系统中表现不同。
- 默认配置覆盖:Maven有默认的资源目录配置,通常指向src/main/resources。如果你使用绝对路径,可能会覆盖这些默认配置,导致混淆或不必要的复杂性。
这里再补充一下相对路径和绝对路径的区别:
- 路径的起点:相对路径是从当前文件所在的位置开始的路径,它是相对于当前文件的路径。而绝对路径是从文件系统的根目录开始的完整路径,它不依赖于当前文件的位置。
- 路径的表示方式:相对路径使用相对于当前文件或目录的路径来表示,它通常是相对于当前工作目录或当前文件的路径。相对路径更简洁,因为它只需要指定从当前位置到目标文件的路径。而绝对路径提供完整的从根目录到目标文件的路径,因此它通常更长。
以下是相对路径和绝对路径的例子:
- 绝对路径例子:在文件系统中,绝对路径可能类似于C:\Users\Username\Documents\file.txt。在网络中,绝对路径可以是完整的URL,例如http://www.example.com/path/to/file.html。
- 相对路径例子:如果当前文件是file.txt,并且在同一目录下有一个名为image.jpg的文件,那么相对路径可能是./image.jpg。如果image.jpg在上一级目录中,则相对路径可能是…/image.jpg。
SpringBoot 引入第三方jar包问题
一般SpringBoot项目都是使用Mavne或者Gradle工具进行依赖管理(这里以Maven为基础演示),但是也有特殊的情况需要使用不存在坐标的第三方依赖,这个时候可能会在项目中的resources目录下新建一个lib目录引入第三方依赖进行管理。
但是这种方式可能会延伸出一种问题,当我们使用Maven进行打包的时候怎么让Maven找到它们呢?下面就围绕这个问题寻找答案。
通过pom文件指向resources/lib
目录下的第三方依赖
如果项目中需要使用不属于Maven管理第三方依赖时,将依赖放进resource/lib
目录的同时还需要在pom文件中添加如下配置:
<!-- 你需要将<groupId>、<artifactId>和<version>替换为第三方依赖的实际信息。<scope>元素设置为system,表示这是一个系统级别的依赖。
<systemPath>元素指定了依赖文件的路径,${project.basedir}代表项目的根目录。 -->
<dependency>
<groupId>com.tpaic</groupId>
<artifactId>auto-client</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/auto-client.jar</systemPath>
</dependency>
图2-1是放第三方依赖的位置。
按照上述步骤添加完以后,该依赖已经被添加到项目中了。但是,当使用Maven进行打包,会发现手动导入的第三方依赖没有打包进去,如果这个时候运行打包后的jar文件,肯定会抛异常。
解决办法就是在pom文件中添加下面配置:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 加载所有 system 的依赖 -->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
<includeSystemScope>true</includeSystemScope>
关键配置就是这段代码,添加完以后再进行打包,就会发现第三方依赖被加载进去了。<includeSystemScope>
配置主要用于确定system作用域的依赖是否被包含在某些Maven操作中,比如创建WAR文件或者JAR文件。当这个配置设置为true时,system作用域的依赖会被包含进来;设置为false时,则不会。在Maven中,依赖可以有不同的作用域,例如compile、runtime、test、provided、system等。每个作用域都有不同的含义和用途。其中,system作用域的依赖通常是你需要从本地文件系统或其他非Maven仓库的位置引入的依赖。
通过命令将第三方依赖添加到Maven仓库
- 首先打开电脑终端
- 输入下面命令(前提是已经配置了maven的环境变量):
mvn install:install-file -DgroupId=com.fjc -DartifactId=toolUtil -Dversion=1.0.1 -Dpackaging=jar -Dfile=D:\fanjunchao\ToolUtil.jar
参数说明:
- -DgroupId:表示 jar 对应的 groupId
- -DartifactId::表示 jar 对应的 artifactId
- -Dversion::表示 jar 对应的 version
- -Dfile: 表示 jar 的位置 D:\fanjunchao\ToolUtil.jar
下面就是执行成功了:
最后在 pom.xml 引入我们的对应坐标就可以了:
<dependency>
<groupId>com.fjc</groupId>
<artifactId>toolUtil</artifactId>
<version>1.0.1</version>
</dependency>