Maven 打包方式探究
参考资料:
Maven打包可执行jar包方法大全(史上最全)_AllenLeungX的博客-CSDN博客_maven打包可执行jar包
测试仓库:
代码浏览 - maven-package-demo - Maven-Example - caozicheng (coding.net)
方法零:maven-jar-plugin
什么插件都不添加,就用默认的配置,直接mvn package,从信息来看,maven使用的默认打包插件是maven-jar-plugin
[INFO] Building maven-package-demo 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-package-demo ---
[INFO] Deleting /Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-package-demo ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-package-demo ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-package-demo ---
[INFO] Not copying test resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-package-demo ---
[INFO] Not compiling test sources
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-package-demo ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-package-demo ---
[INFO] Building jar: /Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/Test.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.518 s
[INFO] Finished at: 2022-08-10T10:51:50+08:00
[INFO] ------------------------------------------------------------------------
这生成出来的,实际上是一个没有指定mainClass,也没有指定classpath的包,关于怎么执行,看“问题二”,当然实际生产时不可能这么做,直接看下面的方法吧。
方法一:使用maven-jar-plugin
和maven-dependency-plugin
maven-jar-plugin
配合maven-dependency-plugin
把所依赖的jar包copy到指定目录
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!--是否在manifest文件中添加classpath。默认为false。如果为true,则会在manifest文件中添加classpath,这样在启动的时候就不用再手动指定classpath-->
<addClasspath>true</addClasspath>
<!--所依赖jar包所在的文件夹-->
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
com.test.Main
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!--outputDirectory指定了要将所依赖的jar包copy到哪个目录。要与maven-jar-plugin中的classpathPrefix一致。-->
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
查看生成jar包中的MANIFEST.MF文件,classpath被指定为libs
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: caozicheng
Class-Path: libs/slf4j-api-1.7.36.jar libs/log4j-slf4j-impl-2.17.2.jar
libs/log4j-api-2.17.2.jar libs/log4j-core-2.17.2.jar libs/junit-4.12
.jar libs/hamcrest-core-1.3.jar
Created-By: Apache Maven 3.8.4
Build-Jdk: 1.8.0_202
Main-Class: com.test.Main
最终打包目录结果是,自己写的Class在jar包中,所依赖的jar包在libs目录中:
├── myClass.jar
├── lib
│ ├── dependence1.jar
│ ├── dependence2.jar
优点
- 有诸多配置项,很自由,每个步骤都可控。
- 不同项目使用不同版本的依赖,也方便分离管理。
缺点
- 打成的最终jar包中没有所依赖的jar包。依赖跟自己的代码不在一个jar包中。部署或者移动的时候,要考虑到多个文件,比较麻烦
方法二:使用maven-assembly-plugin
(推荐)
作用:将自己项目中的代码和资源(包含了所有依赖包)打成一个jar包。
打包后会在target目录下生成一个xxx-jar-with-dependencies.jar文件,这个文件不但包含了自己项目中的代码和资源,还包含了所有依赖包的内容。所以可以直接通过java -jar来运行。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.test.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!--下面是为了使用 mvn package命令,如果不加则使用mvn assembly-->
<executions>
<execution>
<id>make-assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
优点
-
所有的东西都打到一个jar包中,出问题的可能大大减少。
缺点 -
配置项少,包比较大,不自由。
方法三:使用maven-shade-plugin
跟maven-assembly-plugin
类似,都可以将所有的东西都打包到一个jar包中。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.test.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
优点
- 功能同
maven-assembly-plugin
,可配置项更多。
缺点
- 配置起来太麻烦。
问题一:classpath 和 jar
经常碰到的问题,IDE中运行完全正常,打包出来就一堆问题。
其实就是两个问题指定mainClass和classpath。
以IDEA为例运行,Run中可以看到,IDEA是将在命令中指定了mainClass和classpath,所以,我们想要简单的通过 java -jar xx.jar
就成功运行,自然需要配置得当。
/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=55200:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8/Contents/Home/jre/lib/rt.jar:/Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/classes:/Users/caozicheng/.m2/repository/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar:/Users/caozicheng/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.17.2/log4j-slf4j-impl-2.17.2.jar:/Users/caozicheng/.m2/repository/org/apache/logging/log4j/log4j-api/2.17.2/log4j-api-2.17.2.jar:/Users/caozicheng/.m2/repository/org/apache/logging/log4j/log4j-core/2.17.2/log4j-core-2.17.2.jar:/Users/caozicheng/.m2/repository/junit/junit/4.12/junit-4.12.jar:/Users/caozicheng/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar com.test.Main
不推荐手动设置classpath,会污染整个系统环境,而且在使用了如maven的包管理软件后,classpath也会更复杂。详见 classpath和jar - 廖雪峰的官方网站 (liaoxuefeng.com)
问题二:打包时不指定classpath,怎么才能 work?
首先,maven-jar-plugin的作用是打不含依赖的jar包,可以配置mainClass,(不指定classpath,测试下如何在执行jar包时手动指定classpath)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>
com.test.Main
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
这时候直接运行生成的jar包,会找不到依赖所在的路径。
(base) caozicheng@caozichengdeAir maven-package % java -jar target/Test.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at com.test.Main.<clinit>(Main.java:8)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
看jar包中的MANIFEST.MF文件,确实classpath是空的
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: caozicheng
Created-By: Apache Maven 3.8.4
Build-Jdk: 1.8.0_202
Main-Class: com.test.Main
首先尝试了java -classpath lib/*.jar -jar ABCD.jar,但是并不能work,搜索发现如下。
众所周知,如果采用java -classpath,可以允许用户指定其他的Jar包或者class文件的位置。
比如java -classpath lib/*.jar ABC.class
但是如果采用了-jar参数,-classpath的功能就会被屏蔽。java的加载器会旨在指定的jar文件里面寻找需要的类。比如
java -classpath lib/*.jar -jar ABCD.jar,我们的本意是要运行ABCD.jar文件里面的main函数类,而且这个类依赖lib目录下的那些jar文件,着用的结果就会导致类似下面的错误
Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/poi/ss/usermodel/Workbook、
无论你怎么设置classpath,都不会work。
然后尝试,手动更改jar包中的MANIFEST.MF文件
修改已经打好的jar包中的配置文件 https://www.cnblogs.com/qingtian-jlj/p/13265094.html
最后没成功,不瞎折腾了,老老实实用上面的方法。
Error: Invalid or corrupt jarfile target/Test.jar
问题三:配置了多个打包插件会怎么样?
上述方法一、二、三同时使用会如何?build 标签如下
<build>
<finalName>Test</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!--是否在manifest文件中添加classpath。默认为false。如果为true,则会在manifest文件中添加classpath,这样在启动的时候就不用再手动指定classpath-->
<addClasspath>true</addClasspath>
<!--所依赖jar包所在的文件夹-->
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
com.test.Main
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!--outputDirectory指定了要将所依赖的jar包copy到哪个目录。要与maven-jar-plugin中的classpathPrefix一致。-->
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.test.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<!--下面是为了使用 mvn package命令,如果不加则使用mvn assembly-->
<executions>
<execution>
<id>make-assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.test.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
首先,从结果来看,各自插件打包名称不同,不会“冲突”,打出来的包都能work
但是会有一些warning,比如maven-shade-plugin打出来的包(大概就是重复引入依赖了)
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/maven-package-demo-1.0-SNAPSHOT-shaded.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/libs/log4j-slf4j-impl-2.17.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
从打包信息来看:
- 实测,插件执行的先后顺序,与声明顺序无关,推测应该是根据插件的功能,由maven来决定。
- 推测,生成jar包的过程,是先在临时文件夹中写入配置,再package成jar包。
- 虽然是上一个插件的jar包生成出来之后,才会开始执行下一个插件,但是推测临时文件夹并没有删除,而是“继承”了上一个插件的内容去修改,所以第一个插件maven-jar-plugin可以正常执行,而maven-assembly-plugin执行时,会发现文件已存在就skipping(这个skipping显然是插件面对这种情况的应对策略),最后一个maven-shade-plugin写入时明显还进行了写入,出现了warning(所以,maven-shade-plugin打出来的包执行会有warning)
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-package-demo ---
[INFO] Building jar: /Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/Test.jar
[INFO]
[INFO] --- maven-assembly-plugin:2.2-beta-5:single (make-assemble) @ maven-package-demo ---
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] org/ already added, skipping
[INFO] org/slf4j/ already added, skipping
[INFO] META-INF/maven/ already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] org/ already added, skipping
[INFO] org/apache/ already added, skipping
[INFO] org/apache/logging/ already added, skipping
[INFO] META-INF/maven/ already added, skipping
[INFO] META-INF/maven/org.apache.logging.log4j/ already added, skipping
[INFO] META-INF/LICENSE already added, skipping
[INFO] META-INF/DEPENDENCIES already added, skipping
[INFO] META-INF/NOTICE already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] org/ already added, skipping
[INFO] org/apache/ already added, skipping
[INFO] org/apache/logging/ already added, skipping
[INFO] org/apache/logging/log4j/ already added, skipping
[INFO] META-INF/versions/ already added, skipping
[INFO] META-INF/versions/9/ already added, skipping
[INFO] META-INF/versions/9/org/ already added, skipping
[INFO] META-INF/versions/9/org/apache/ already added, skipping
[INFO] META-INF/versions/9/org/apache/logging/ already added, skipping
[INFO] META-INF/versions/9/org/apache/logging/log4j/ already added, skipping
[INFO] META-INF/services/ already added, skipping
[INFO] META-INF/maven/ already added, skipping
[INFO] META-INF/maven/org.apache.logging.log4j/ already added, skipping
[INFO] META-INF/NOTICE already added, skipping
[INFO] META-INF/DEPENDENCIES already added, skipping
[INFO] META-INF/LICENSE already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] org/ already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] org/ already added, skipping
[INFO] Building jar: /Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/target/Test-jar-with-dependencies.jar
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] org/ already added, skipping
[INFO] org/slf4j/ already added, skipping
[INFO] META-INF/maven/ already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] org/ already added, skipping
[INFO] org/apache/ already added, skipping
[INFO] org/apache/logging/ already added, skipping
[INFO] META-INF/maven/ already added, skipping
[INFO] META-INF/maven/org.apache.logging.log4j/ already added, skipping
[INFO] META-INF/LICENSE already added, skipping
[INFO] META-INF/DEPENDENCIES already added, skipping
[INFO] META-INF/NOTICE already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] org/ already added, skipping
[INFO] org/apache/ already added, skipping
[INFO] org/apache/logging/ already added, skipping
[INFO] org/apache/logging/log4j/ already added, skipping
[INFO] META-INF/versions/ already added, skipping
[INFO] META-INF/versions/9/ already added, skipping
[INFO] META-INF/versions/9/org/ already added, skipping
[INFO] META-INF/versions/9/org/apache/ already added, skipping
[INFO] META-INF/versions/9/org/apache/logging/ already added, skipping
[INFO] META-INF/versions/9/org/apache/logging/log4j/ already added, skipping
[INFO] META-INF/services/ already added, skipping
[INFO] META-INF/maven/ already added, skipping
[INFO] META-INF/maven/org.apache.logging.log4j/ already added, skipping
[INFO] META-INF/NOTICE already added, skipping
[INFO] META-INF/DEPENDENCIES already added, skipping
[INFO] META-INF/LICENSE already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] org/ already added, skipping
[INFO] META-INF/ already added, skipping
[INFO] META-INF/MANIFEST.MF already added, skipping
[INFO] org/ already added, skipping
[INFO]
[INFO] --- maven-shade-plugin:3.3.0:shade (default) @ maven-package-demo ---
[INFO] Including org.slf4j:slf4j-api:jar:1.7.36 in the shaded jar.
[INFO] Including org.apache.logging.log4j:log4j-slf4j-impl:jar:2.17.2 in the shaded jar.
[INFO] Including org.apache.logging.log4j:log4j-api:jar:2.17.2 in the shaded jar.
[INFO] Including org.apache.logging.log4j:log4j-core:jar:2.17.2 in the shaded jar.
[INFO] Including junit:junit:jar:4.12 in the shaded jar.
[INFO] Including org.hamcrest:hamcrest-core:jar:1.3 in the shaded jar.
[INFO] Dependency-reduced POM written at: /Users/caozicheng/Library/CloudStorage/OneDrive-stu.suda.edu.cn/repository/java/maven-package/dependency-reduced-pom.xml
[WARNING] Test.jar, hamcrest-core-1.3.jar, junit-4.12.jar, log4j-api-2.17.2.jar, log4j-core-2.17.2.jar, log4j-slf4j-impl-2.17.2.jar, slf4j-api-1.7.36.jar define 1 overlapping resource:
[WARNING] - META-INF/MANIFEST.MF
[WARNING] log4j-api-2.17.2.jar, log4j-core-2.17.2.jar, log4j-slf4j-impl-2.17.2.jar define 3 overlapping resources:
[WARNING] - META-INF/DEPENDENCIES
[WARNING] - META-INF/LICENSE
[WARNING] - META-INF/NOTICE
[WARNING] maven-shade-plugin has detected that some class files are
[WARNING] present in two or more JARs. When this happens, only one
[WARNING] single version of the class is copied to the uber jar.
[WARNING] Usually this is not harmful and you can skip these warnings,
[WARNING] otherwise try to manually exclude artifacts based on
[WARNING] mvn dependency:tree -Ddetail=true and the above output.
[WARNING] See https://maven.apache.org/plugins/maven-shade-plugin/
[INFO] Attaching shaded artifact.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.218 s
[INFO] Finished at: 2022-08-10T11:08:39+08:00
[INFO] ------------------------------------------------------------------------
问题四:三种项目打包方式——jar,war,pom的区别
<groupId>org.example</groupId>
<artifactId>maven-package-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
jar:默认的打包方式,打包成jar用作jar包使用,本文所探讨的内容。
war:打包成war,发布在服务器上,如网站或服务。用户可以通过浏览器直接访问,或者是通过发布服务被别的工程调用,一般配合SpringBoot等框架使用。
pom:用在父级工程或聚合工程中,用来做jar包的版本控制,必须指明这个聚合工程的打包方式为pom,例如leyou,创建12个model分别为,关于多模块打包:代码浏览 - maven-multi-module - Maven-Example - caozicheng (coding.net)