如何打一个FatJar(uber-jar)

FatJar也就叫做UberJar,是一种可执行的Jar包(Executable Jar)。FatJar和普通的jar不同在于它包含了依赖的jar包。

1. maven-jar-plugin

例子

<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.yourcompay.Demo</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
  1. 首先使用maven-dependency-plugin把依赖全部copy到outputDirectory中,为了将包打到一个jar中,需要把outputDirectory配置到classes/lib中
  2. 使用maven-jar-plugin指定MainClass和classpath,需要注意的是classpathPrefix必须是${project.build.finalName}/lib路径
  3. 执行命令
java -jar ./target/demo.jar

注意:采用maven-jar-plugin方式有个缺点,demo.jar不能移动到其他路径下面执行java -jar命令,因为demo.jar依赖放在了lib/目录下

解决方法有点复杂,首先用maven-dependency-plugin把依赖copy到${project.build.directory}/classes/lib,然后需要自定义jar加载的classloader,真复杂...

2. maven-assembly-plugin

maven-assembly-plugin是一个强大的打包工具,除了jar包还能打zip、tar.gz、tar.bz2等类型的包,描述文件放在assembly.xml中

如何用assembly打一个FatJar,使用预定义格式jar-with-dependencies打包

实际上

<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.yourcompany.Demo</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

执行命令make clean package,得到demo-jar-with-dependencies.jar,这时我们就可以使用java -jar命令了

注意:预定义格式jar-with-dependencies实际上只有基本的FatJar打包功能,背后集成是maven-shade-plugin。下一节就讲shade-plugin

3. maven-shade-plugin

3.1 一个简单的例子

maven-shade-plugin将goal shade:shade绑定到maven的package阶段

<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

执行命令maven package在target目录下生成一个demo.jar

3.2 设置MainClass创建一个可执行的Jar包

<build>
<finalName>demo</finalName>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.yourcompany.Demo</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

执行mvn package命令生成一个demo.jar,执行demo.jar

java -jar ./target/demo.jar

3.2.1 Resource Transformers

  1. AppendingTransformer 增加一个文件到resource
  2. XmlAppendingTransformer 增加一个xml到resource
  3. ManifestResourceTransformer 设置MANIFEST

3.3 使用include/exclude指定需要打包的jar

在configuration元素下增加includes和excludes节点

<configuration>
<artifactSet>
<includes>
<include>org.apache.commons:commons-langs</include>
</includes>
<excludes>
<exclude>com.alibaba:fastjson</exclude>
</excludes>
</artifactSet>
</configuration>

3.4 使用filter过滤jar包中的类或者资源

在configuration元素下增加filters节点

<configuration>
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>junit/framework/**</include>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
<exclude>org/junit/runners/**</exclude>
</excludes>
</filter>
</filters>
</configuration>

3.5 maven-shade-plugin 自动将所有不使用的类全部排除掉

<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>

如何打一个FatJar(uber-jar)的更多相关文章

  1. 关于 maven 打包直接运行的 fat jar (uber jar) 时需要包含本地文件系统第三方 jar 文件的问题

    关于maven打包fat jar (uber jar) 时需要包含本地文件系统第三方jar文件的问题,今天折腾了一整天.最后还是用了spring boot来做.下面是几篇关于打包的有参考价值的文章,以 ...

  2. Java - 在控制台中执行一个可执行jar

    1.Maven打包一个可执行jar: <build> <plugins> <plugin> <groupId>org.apache.maven.plug ...

  3. Spring Boot 怎么打一个可执行 Jar 包?

    传统的 Java 应用程序都需要打一个 war 包,并到到 Tomcat webapps 目录下运行. Java 支持打 Jar 包,但没有提供一个标准的方式在一个 Jar 包内再加载嵌入别的 Jar ...

  4. Maven- 使用Maven构建一个可执行jar

    How to Create an Executable JAR with Maven 1.最重要的是使用jar类型,<packaging>jar</packaging>.当然不 ...

  5. 发布一个自己的jar包给全球人使用

    目录 项目准备 sonatype 注册 申请sonatype工单 gpg配置 项目配置 依赖oss-parent 自定义配置 pom配置 全局settings配置 发布 验证 maven 项目对于我们 ...

  6. 8.5打包libgdx为一个桌面程序(jar包)

    简陋的地图编辑终于做好了,于是要开始制作地图了,想导出为一个windows下可用的程序,让熟人代做地图,然后找人问了下打包流程,其实跟普通java打包为jar没什么区别,记录如下: 导出类型选第三个 ...

  7. 记一个 protobuf 的 jar 包冲突

    尝试使用 spark 以 bulkload 的方式写 HBase 时,遇到一个问题,错误堆栈如下 19/02/02 09:00:43 ERROR Utils: Aborting task java.l ...

  8. JAR-使用JAVA命令编译打包一个可执行jar包

    一.开发一个演示项目 项目源代码开发 项目名称叫jar-package-example(其实只是一个文件夹, 用以将演示的所有文件夹和文件存放在其中, 没啥其它作用), 为了方便, 后文统一叫jar- ...

  9. 如何向hadoop集群定时提交一个jar作业?

    除了使用Hive,Pig来执行一个MapReduce任务,不需要专门的把项目打成jar包,提交执行,或者定时执行,因为Hive,Pig这些开源框架已经,帮我们自动打包上传了. 而有些时候,我们自己手写 ...

随机推荐

  1. VS 2017 Git failed with a fatal error的解决办法

    前几天,满怀欣喜的从VS2015更新到了VS2017,经过这几天的试用,整体来说感觉还是挺不错的.昨天推送项目到远程服务器的时候,发现出现了推送失败的错误,错误如图: 按照提示,我看到输出窗口的输入内 ...

  2. XMLHttpRequest API 使用指南

    一.实例化 XMLHttpRequest 对象 使用 Ajax API 的第一件事情就是实例化 XMLHttpRequest 对象. var xhr = new XMLHttpRequest(); 二 ...

  3. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  4. Rookey.Frame v1.0极速开发平台稳定版发布

    Rookey.Frame v1.0经过一年时间的修改及沉淀,稳定版终于问世了,此版本经过上线系统验证,各个功能点都经过终端用户验证并持续优化,主要优化以下几个方面: 1.性能较原来提升3倍之多 2.修 ...

  5. 从Chrome源码看JS Array的实现

    .aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } .crayon-line spa ...

  6. Cookie中文乱码问题

    页面一登录,页面二保存用户信息,放入Cookies里. 但是Cookies放入中文会引起编码问题,如报错“Control character in cookie value, consider BAS ...

  7. jdk动态代理与cglib代理、spring aop代理实现原理

    原创声明:本博客来源与本人另一博客[http://blog.csdn.net/liaohaojian/article/details/63683317]原创作品,绝非他处摘取 代理(proxy)的定义 ...

  8. 浅谈C#数组(二)

    六.枚举集合 在foreach语句中使用枚举,可以迭代集合中的元素,且无需知道集合中元素的个数.foreach语句使用一个枚举器.foreach会调用实现了IEnumerable接口的集合类中的Get ...

  9. iOS原生地图与高德地图的使用

    原生地图 1.什么是LBS LBS: 基于位置的服务 Location Based Service 实际应用:大众点评,陌陌,微信,美团等需要用到地图或定位的App 2.定位方式 1.GPS定位 2. ...

  10. 【转载】stm32之看门口介绍

    今天在学习mpu6050的时候,发现程序出现了看门狗的程序,其实这个在学习51的时候就应该了解的,但是我并没有去了解.导致现在学习32,其实就是在补之前的51. 首先,我想把文章最后一句放到开始写出来 ...