1、shade
也就是所说的fat jar,所有相关的类(含依赖)会被打进一个jar包
1.1、优点
- shade支持修剪不必要的依赖,不像assembly需要用户自己进行修剪,shade能过通过字节码分析自动修剪掉不必要的依赖
- 能够通过替换包名避免依赖冲突,如果一个项目中同时依赖了某个库的两个版本,比如spark程序中,自己的代码依赖okhttp3, spark本身的代码依赖okhttp2,此时除了重写自己的代码,更改依赖外,还可以通过shade解决依赖冲突。巧用maven-shade-plugin解决依赖冲突
1.2、缺点
- 不能打thin jar 即使shade能够修剪依赖,最终也只能将所有类打到一个jar包中
- 无法打包脚本,配置文件等
1.3、一般使用
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<!-- Do not copy the signatures in the META-INF folder.
Otherwise, this might cause SecurityExceptions when using the JAR. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<!--<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>demo.SocketWindowWC</mainClass>
</transformer>
</transformers>-->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
可以使用 relocations、filters、artifactSet(includes) 来解决jar冲突
2、assembly
2.1、优点
- thin jar 如果打fat jar,所有相关的类(含依赖)会被打进一个jar包,此时的问题是这个包除了比较大外,还失去了通过替换jar包更新程序的灵活性。assembly不会将依赖的jar包合并,仅仅是将它们放在一个压缩包中
- 打包脚本,配置文件等 assembly除了打包依赖外,还能include用户定义的目录或文件。如一般项目都会在bin目录中放启动脚本等
- 自定义依赖 assembly默认打包所有依赖的依赖,默认行为可能会打出很多jar包,可以手动include/exclude
2.2、缺点
手动依赖修剪assembly虽然可以通过定义include/exclude修剪依赖,但是需要用户明确自己的代码中用到了哪些,没用到哪些,否则如果该include没有include或被exclude了,那么很容易出No Class Found Exception
2.3、实例
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>*.yaml</exclude>
<exclude>*.xml</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>java-test</id>
<goals>
<!-- 只运行一次 -->
<goal>single</goal>
</goals>
<!-- 绑定到package生命周期 -->
<phase>package</phase>
<configuration>
<finalName>java-test</finalName>
<!-- 配置描述符文件 -->
<descriptors>
<descriptor>src/main/assembly/java-test.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
assembly/java-test.xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>java-test</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>java-test</baseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>*.properties</include>
</includes>
<outputDirectory>conf</outputDirectory>
</fileSet>
<fileSet>
<directory>${basedir}/src/main/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>libs</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
bin
jvm_args_env.sh
-Xms1g
-Xmx1g
-Xmn512m
-XX:+IgnoreUnrecognizedVMOptions
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-Xloggc:gc.log
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=dump.hprof
-Duser.timezone=${SPRING_JACKSON_TIME_ZONE}
start.sh
BIN_DIR=$(dirname $0)
JAVATEST_HOME=${JAVATEST_HOME:-$(cd $BIN_DIR/..; pwd)}
JVM_ARGS_ENV_FILE=${BIN_DIR}/jvm_args_env.sh
JVM_ARGS="-server"
if [ -f $JVM_ARGS_ENV_FILE ]; then
while read line
do
if [[ "$line" == -* ]]; then
JVM_ARGS="${JVM_ARGS} $line"
fi
done < $JVM_ARGS_ENV_FILE
fi
JAVA_OPTS=${JAVA_OPTS:-"${JVM_ARGS}"}
if [[ "$DOCKER" == "true" ]]; then
JAVA_OPTS="${JAVA_OPTS} -XX:-UseContainerSupport"
fi
echo "JAVA_HOME=${JAVA_HOME}"
echo "JAVA_OPTS=${JAVA_OPTS}"
$JAVA_HOME/bin/java $JAVA_OPTS \
-cp "$JAVATEST_HOME/conf":"$JAVATEST_HOME/libs/*" \
com.cestc.bigdata.java.JavaTask
程序
public class PropertyUtils {
private static Properties properties;
static {
try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties")) {
properties = new Properties();
properties.load(in);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getString(String key) {
return properties.getProperty(key);
}
}
public class JavaTask {
public static void main(String[] args) {
String name = PropertyUtils.getString("name");
Integer age = Integer.parseInt(PropertyUtils.getString("age"));
System.out.println("name : " + name + "; age :" + age);
}
}
resources/config.properties
name=zhangsan
age=20
打包测试mvn clean package
qiaozhanwei@qiaozhanweideMacBook-Pro target % sh bin/start.sh
JAVA_HOME=/Users/qiaozhanwei/Downloads/InstallProgram/jdk1.8.0_401.jdk/Contents/Home
JAVA_OPTS=-server -Xms1g -Xmx1g -Xmn512m -XX:+IgnoreUnrecognizedVMOptions -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:gc.log -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump.hprof
name : zhangsan; age :20
3、使用 maven-compiler-plugin 与 maven-shade-plugin 组合
maven-shade-plugin 主要用于生成 “uber JAR”(包含所有依赖的可执行 JAR 文件)并且提供重定位功能,避免类冲突
<build>
<plugins>
<!-- 编译插件:编译源代码 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 打包插件:生成包含依赖的 uber JAR -->
<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> <!-- 使用 shade 目标 -->
</goals>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom> <!-- 生成依赖精简的 POM 文件 -->
<archive>
<manifestEntries>
<Main-Class>com.example.MainClass</Main-Class> <!-- 主类 -->
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
构建过程:
1、编译阶段: 使用 maven-compiler-plugin 将 Java 源代码编译为字节码(.class 文件)。
2、打包阶段: 使用 maven-shade-plugin 将编译后的代码与所有依赖项一起打包成一个 “uber JAR” 文件,并且可以通过 createDependencyReducedPom 生成一个精简的 POM 文件以减少依赖管理问题。
生成的文件:
target/my-app-1.0-SNAPSHOT-shaded.jar(包含依赖的可执行 JAR 文件)
4、使用 maven-compiler-plugin 与 maven-assembly-plugin 组合
maven-assembly-plugin 也可以生成 “fat JAR”(包含所有依赖的可执行 JAR 文件),并且可以生成其他格式的压缩包如 ZIP、TAR 等
<build>
<plugins>
<!-- 编译插件:编译源代码 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 打包插件:生成包含依赖的 fat JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainClass</mainClass> <!-- 主类 -->
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef> <!-- 指定打包依赖的方式 -->
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase> <!-- 在打包阶段执行 -->
<goals>
<goal>single</goal> <!-- 使用 single 目标 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
构建过程
1、编译阶段: 使用 maven-compiler-plugin 将 Java 源代码编译为字节码。
2、打包阶段: 使用 maven-assembly-plugin 将编译好的代码及所有依赖项打包成一个 “fat JAR” 文件。
生成的文件:
target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar(包含依赖的可执行 JAR 文件)
5、maven-jar-plugin(非必须)
如果你使用了 maven-assembly-plugin 或 maven-shade-plugin 来生成包含所有依赖项的 “fat JAR” 或 “uber JAR”,这些插件本身可能会处理 JAR 文件的创建,并且 maven-jar-plugin 可以不需要单独配置
注意 : 如果要使用 -javaagent 提供 jar,需要使用它
- 主要功能: 用于创建标准的 JAR 文件。
- 用途: 打包项目的编译输出(类文件和资源)到一个 .jar 文件中。你可以定制 MANIFEST.MF 文件,指定入口点(Main-Class)或其他元数据。
- 常见场景:
1、生成普通的 JAR 文件。
2、为 JAR 文件添加元数据(例如 Main-Class 或 Premain-Class)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainClass</mainClass> <!-- 主类 -->
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
生成的文件:
target/my-app-1.0-SNAPSHOT.jar(标准的 JAR 文件)
如感兴趣,点赞加关注,谢谢!!!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。