Maven学习笔记

标签: Maven 分类: Java 创建时间:2020-05-23 05:27:13 更新时间:2024-11-15 10:49:43

1.外部jar打包

将lib打包进jar,直接在build的resource节点下增加 resources 节点就可以了。

(1)将lib放到项目路径中,如果是子模块,最好就是放到子模块的 src 路径下,然后配置build。
(2)使用springboot的应用,需要在 spring-boot-maven-plugin 插件的地方,配置 includeSystemScope 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<dependencies>
<dependency>
<groupId>dingding</groupId>
<artifactId>dingding</artifactId>
<scope>system</scope>
<version>1.2.0</version>
<systemPath>${project.basedir}/lib/zwdd-sdk-java-1.2.0.jar</systemPath>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>

<resources>
<resource>
<directory>lib</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</resources>
</build>

参考文章:
1.maven将lib打包进jar 使用了maven-assembly-plugin 插件,这个插件我还没有用会
2.Maven引用自定义jar包,并且在打包时包含自定义jar包 与plugins标签平级添加resources标签就可以指定资源打包路径了,不需要其他的插件
3.Maven项目依赖外部jar进行打包的两种方式 1.使用开发工具引入。2.引入jar包路径。如果是 springboot 项目,还需要加入true配置
4.JEECGBOOT打包发布后提示jar不存在 在主项目下的pom文件中增加以下配置,把scope为system的依赖同样打到jar包中去。有些情况例如“三.”中的插件在子项目pom文件中引入的,打包时提示找不到主类。解决方案可尝试使用mainClass指向子项目的启动类
5.Maven内置属性及使用

问题

(1) 识别不了 ${project.basedir} 路径
我遇到一个奇葩的问题,就是死活识别不了 ${project.basedir} 路径,更加奇怪的就是,我在其他的项目中,用同样的方法引入,结果就是完全没有问题。

【尝试方法】
(1)我尝试了删除缓存重新启动,结果不行。
(2)添加了 resource 节点,也不行。
(3)因为是springboot应用,我还配置了 includeSystemScope 属性,结果也是不行。

1
2
3
4
5
6
7
8
9
10
11
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>

【解决方法】
问题产生的原因,就是我在子模块中写了 ${project.basedir} 变量,其实这是不对的。我应该在父模块的pom.xml中引入 ${project.basedir} 路径,而不是在子模块中编写。project 是 pom.xml 的根节点, project.basedir 就是pom文件所在的目录。

~~如果非要在子模块中编写的话,那就是使用 parent.basedir 进行替换,${parent.basedir}/lib/zwdd-sdk-java-1.2.0.jar~~

1
2
3
4
5
6
<dependency>
<groupId>dingding</groupId>
<artifactId>dingding</artifactId>
<scope>system</scope>
<version>1.2.0</version>
</dependency>

打包时出现:must specify an absolute path but is ${parent.basedir}/lib/zwdd-sdk-java-1.2.0.jar ,就需要将lib放到和pom.xml同一级,然后使用 ${project.basedir} 进行替换。

再接下去,就是解决这个lib打包进程序中的事情了。因为是单独的模块,这个也是子模块的pom.xml,无法打包进主模块。

这个其实不是问题,是我自己看错了,我把 zwdd-sdk-java-1.2.0.jar 写成了 dingding,最后打包进jar里面的就成了 dingding-1.2.0.jar,而不是 zwdd-sdk-java-1.2.0.jar,如果我要写成 zwdd-sdk-java 最后就是打包到了 zwdd-sdk-java 了。

1
2
3
4
5
6
7
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>zwdd-sdk-java</artifactId>
<scope>system</scope>
<version>1.2.0</version>
<systemPath>${project.basedir}/lib/zwdd-sdk-java-1.2.0.jar</systemPath>
</dependency>
参考文章:
1maven scope范围注释了但是不生效 通过设置 Modules 进行修改。
2.Maven引入本地jar包无法使用的解决方法 true 这行代码 表示不执行测试用例,也不编译测试用例类.加入这行代码 跳过测试用例.jar包就能正常引用了.
3.maven使用本地jar以及pom文件中${project.basedir} project 是 pom.xml 的根节点, project.basedir 就是pom文件所在的目录。
4.How do I include tools.jar in my dependencies?
5.‘dependencies.dependency.systemPath‘ for ::jar must specify an absolute path but is 1.写死绝对路径。2.在settings.xml中配置变量,配置好绝对路径,然后使用这个变量。3.如文中把lib/k3cloud-webapi-sdk8.0.4.jar与当前pom.xml放在同一级,然后用${project.basedir}/lib/k3cloud-webapi-sdk8.0.4.jar
6.Finding the root directory of a multi module Maven reactor project
7.查找多模块Maven反应器项目的根目录 这是上面的中文版本,尝试从根pom继承一个自定义属性,但是,当我尝试在模块POM中使用${myproject.root}时,${basedir}将解析为模块的basedir。
8.Maven引用外部依赖包${pom.basedir} 注意打包的时候要在spring-boot-maven-plugin中加入includeSystemScope为true,这样maven在install的时候才会打包进去

2.profile使用

不同的环境,使用不同的配置文件。

(1) pom.xml中增加profiles

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<profiles>
<profile>
<id>test</id>
<!--默认启动-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>

<properties>
<!-- default Spring profiles -->
<spring.profiles.active>test</spring.profiles.active>
</properties>
</profile>
<profile>
<id>pro</id>
<!--默认启动-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>

<properties>
<!-- default Spring profiles -->
<spring.profiles.active>pro</spring.profiles.active>
</properties>
</profile>

</profiles>

(2) resource中增加不同的配置文件

1
2
application-test.yml 
application-pro.yml

(3) 修改pom.xml中的build节点的resource配置

1
2
3
4
5
6
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

(4) yml文件中,启用mvn配置
可以使用 @ 符号引用profile配置中定义的 spring.profiles.active 定义的变量

1
2
3
spring:
profiles:
active: @spring.profiles.active@

(5) idea中刷新下依赖
这一步就是说要要执行一下子 mvn clean install 命令,我直接就是在idea中的Maven中刷新了一下,不知道有没有作用,我觉得其实省略这一步也没有什么问题。如果在启动debug的时候,总是找不到设置的默认的profile,可以打开右侧的maven,更新一下配置,然后选中自己需要启动的maven配置进行debug。

(6) 指定打包的环境
在进行打包的使用,使用-P参加进行环境的打包,-Ppro就是打包pro环境

1
mvn clean package -Ppro

(7) 不同的环境生成不同的jar包名称
主要的思路就是在每一个profile下的properties,自定义一个标签,比如,在配置时引用这个标签,比如:web-${fname}

(8) 同时生成不同的jar包
就是说有很多的环境,如何能同时生成各个不同环境的不同的jar包呢?

问题

(1) Caused by: org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character ‘@’ that cannot start any token
在yml中引入mvn配置时,启动报错。

1
2
3
spring:
profiles:
active: @spring.profiles.active@

【解决方法】
在build下的resources的resource节点中,增加filtering配置

1
2
3
4
5
6
<resources>
<resource>
<directory>src/main/resources</directory> 1
<filtering>true</filtering>
</resource>
</resources>
参考文章:
1.org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token found character ‘@‘ t 尝试 maven reimport ,问题解决。
2.解决 ‘@’ that cannot start any token. (Do not use @ for indentation) 增加 filtering,这里还讲了原因。
3.application.yml使用maven配置报错:while scanning for the next token found character ‘@‘ that cannot start a 在maven加上如下配置filtering,(修改配置后记住mvn clean install一下) 我没有进行mvn clean install 这一步。

(2) Property ‘spring.profiles.active’ imported from location ‘class path resource [bootstrap-dev.yml]’ is invalid in a profile specific resource [origin: class path resource [bootstrap-dev.yml]

【解决】
主要就是在boostrap.yml中指定了 spring.profiles.active,在boostrap-dev.yml中重复指定了 spring.profiles.active

3.单独构建子模块

在一个大的工程中,有一个子模块,需要单独打包,如何操作呢? 多数文章中都写了使用-pl等参数进行单独模块的打包。

1
2
3
4
5
6
7
8
9
10
11
12
13
# -pl, --projects
# Build specified reactor projects instead of all projects
# -am, --also-make
# If project list is specified, also build projects required by the list
# -amd, --also-make-dependents
# If project list is specified, also build projects that depend on projects on the list


## 单独构建模块jsoft-web,同时会构建jsoft-web模块依赖的其他模块
mvn install -pl jsoft-web -am

## 单独构建模块jsoft-common,同时构建依赖模块jsoft-common的其他模块
mvn install -pl jsoft-common -am -amd
参考文章:
1.SpringBoot+Maven多模块项目(创建、依赖、打包可执行jar包部署测试)完整流程 注意:build内容也需要做替换,因为默认的spring-boot-maven-plugin这种方式,等到后期打包的时候他会一直提示你,你引入的依赖不存在
2.geekidea/spring-boot-assembly 这里还配置了其他的多个插件,比如 maven-jar-plugin、spring-boot-maven-plugin
3.Maven单独构建多模块项目中的单个模块 就是上面的内容

4.多模块打包

我编写了多个微服务,在微服务moduleB中,我用依赖的形式将moduleA引入进来了,这样可以在moduleB中使用moduleA的部分类定义,但是在父工程的pom.xml中执行打包的时候,出现了问题,说是 “程序包不存在,找不到符号”。

【原因】
spring-boot-maven-plugin打包出来的jar是不可依赖的

【解决】
在需要被依赖的模块的pom.xml的build中,增加configuration配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<!--主要是在原先的配置的基础上增加了这个-->
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>

关于classifier配置为exec,我认为可能是这个样子的,原先的不带exec后缀的文件,被用来作为依赖进行使用,后面的生成的这个exec才是实际需要执行的jar包。

后来我又尝试使用assembly打包,其实也是打包成了一个重命名的jar包,我本来就是想要用一个名字替代的,结果不行了,总要打包成两个jar包,一个用来依赖,一个用来执行(jar-with-dependencies)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<!--增加一下配置,可以实现mvn package时直接生成可执行jar包-->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>com.proheng.system.PhSystemApplication</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>

算了,就用 classifier 吧,不折腾了。

参考文章:
1.maven父子工程—子模块相互依赖打包时所遇到的问题:依赖的程序包找不到 这个和我的情况时一样的,抽取出了base模块作为公共模块,Module A和Module B都引入了公共模块。这里说明了原因:默认打包出来的jar是不可依赖的。
2.maven 多模块 相互依赖 打jar包流程及注意事项 这里通过安装的方式解决
3.关于maven项目多模块的打包问题的血泪经历(必看)
4.运行 jar 出现”中没有主清单属性”
5.记-maven 多模块项目运行正常但是打包提示被依赖模块类找不到的问题 父工程和基础模块使用maven-compiler-plugin插件打包,web模块因为需要打成可执行jar,再使用spring-boot-maven-plugin打包。
6.spring-boot-maven-plugin:打依赖包 不使用spring-boot-maven-plugin打包。三种方式:1.将spring-boot-maven-plugin注释掉;2.将spring-boot-maven-plugin的repackage目标跳过,即设置skip为true;3.使用命令行跳过spring-boot-maven-plugin的repackage;
7.使用maven-assembly-plugin制作可执行jar包 可以使用assembly进行打包,当然也是重名了了可运行的jar包了。

5.resource文件打包

在打包resource文件的时候,如果配置了 resources 节点,那么就会覆盖默认的打包文件路径,如果要把静态资源也进行打包,需要重新注明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<build>
<resources>
<resource>
<directory>${project.basedir}/lib</directory>
<targetPath>BOOT-INF/lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
<!--必要时也需要添加这个地方-->
<resource>
<directory>${project.basedir}/src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.ftl</include>
</includes>
</resource>
</resources>
</build>
参考文章:
1.关于maven打包时, 资源文件没有被打包进来的问题 maven默认会将资源目录下的资源文件进行打包,而如果在pom.xml中配置了resources标签,则默认的资源打包策略就被覆盖掉了,只会打包resources标签中配置的资源文件,解决方案呢?当然有,手动将src/main/resources也添加到配置就可以了。按如下的pom.xml配置,maven打包时,既能包含src/main/java下的XML文件,也能包含资源目录(src/main/resources)下面的资源文件。

6.阿里云Maven仓库

(1) 修改maven安装目录 conf/settings.xml文件,在标签中添加 mirror 子节点

1
2
3
4
5
6
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>

(2) 修改Idea,File->settings,找到Maven配置,选择使用 maven 安装目录的 settings.xml

参考文章:
【1】.Intellij IDEA配置Maven(内置Maven和修改本地仓库地址和阿里云中央仓库)
【2】.将maven源改为国内阿里云镜像
【3】.Maven 镜像
【3】.Maven之阿里云镜像仓库配置 全局配置可以添加阿里云的镜像到maven的setting.xml配置中,这样就不需要每次在pom中,添加镜像仓库的配置,在mirrors节点下面添加子节点:nexus-aliyuncentralNexus aliyunhttp://maven.

7.子模块的配置文件打包

在主模块的application.yml配置中,引入了子模块的配置文件,但是执行打包之后,却发现找不到自模块的配置文件,也就是说子模块的配置文件没有打包进去。

1
2
3
spring:
config:
import: classpath:application-drone-prod.yml

【解决方案】
这个问题暂时不是问题,我以为没有打包,实际上打包了。

子模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<build>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
<resource>
<directory>${project.basedir}/src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.json</include>
<include>**/*.html</include>
</includes>
</resource>
</resources>
</build>

主模块

1
2
3
4
5
6
7
8
9
10
11
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>

8.多模块打包之后没有生成jar包

我下载了大疆的后端系统源码,但是打包之后,没有生成 相应的 jar包,虽然各个子模块已经生成了jar,但是主模块就是没有jar包。这里可以看到已经生成了三个jar包,实际上找不到这个 cloud-api-sample 1.9.0。

【尝试方案】
我尝试使用了 maven-shade-plugin 结果总是不行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<build>
<plugins>
<!-- 此插件必须放在父 POM 中 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!--
设置将依赖整合到一个自定义名称的 JAR 包。
如果不设置此项,依赖将整合到 Maven 无插件时的默认 JAR 包,并生成一个前缀为 original- 的无依赖 JAR 包
-->
<shadedArtifactAttached>true</shadedArtifactAttached>
<!-- 设置生成的 JAR 包后缀名 -->
<shadedClassifierName>jar</shadedClassifierName>
<!-- 设置程序运行入口 -->
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.openmap.drone.Application</mainClass>
</transformer>
</transformers>
<!-- 设置 JAR 包输出目录 -->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

【解决方案】
注解父模块的 pom.xml 中的 打包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

改为在启动模块的 pom.xml 中添加如下代码,比如启动类所在的模块 sample 模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
参考文章:
【1】.将 Maven 中的多模块项目只打成一个 JAR 包 方法 1:使用插件 maven-assembly-plugin;方法 2:使用插件 maven-shade-plugin
【2】.maven 将多模块项目打成一个jar包(多个jar包合成一个) springboot项目可以使用 spring-boot-maven-plugin 插件,会自动帮我们完成项目打包。非springboot项目,可以使用 maven-assembly-plugin 。
【3】.springboot打包没有可执行的jar?打包成功jar没有将依赖打包入jar。
【4】.spring boot maven打包可执行jar包缺少依赖包的问题 pom中必须配置spring-boot-maven-plugin插件,而且必须指定需要执行的目标构建。请避免直接使用mvn repackage命令,因为repackage依赖原生maven的package命令,直接执行repackage无法获取依赖,会导致打包失败。
【5】.spring-boot-maven-plugin
【6】.maven打包运行时没有主清单属性,找不到xxx.jar,以及修改maven打包的项目名

8.@profile.name@无效

在 application.yml 配置通过 profile 进行启动不同的配置,总是无法生效。尝试使用 ${profile.name} 也不行。

1
2
3
spring:
profiles:
active: '@profile.name@'

【解决方案】
这里 filtering 一定要配置为 true,否则不生效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<build>
<finalName>drone-control</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
参考文章:
【1】.maven profile动态选择配置文件 这里注意一个参数true,一定要设置成true.这样才会用对应env目录下的配置文件覆盖原来的。
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。