我听说人们说他们创建了一个胖 JAR 并部署它。它们实际上是什么意思?
6 回答
fat jar 是 jar,它包含来自所有库的类,您的项目依赖于这些库,当然还有当前项目的类。
在不同的构建系统中,胖 jar 的创建方式不同,例如,在 Gradle 中,可以使用(指令)创建它:
task fatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'com.example.Main'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
在 Maven 中,它是这样做的(在设置常规 jar 之后):
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
<plugin>
<groupid>org.dstovall</groupid>
<artifactid>onejar-maven-plugin</artifactid>
<version>1.4.4</version>
<executions>
<execution>
<configuration>
<onejarversion>0.97</onejarversion>
<classifier>onejar</classifier>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
不同的名称只是打包 Java 应用程序的方式。
Skinny – 仅包含您在代码编辑器中真正输入的位,没有其他内容。
Thin – 包含上述所有内容以及应用程序对您的应用程序的直接依赖项(数据库驱动程序、实用程序库等)。
Hollow – Thin 的倒数 – 仅包含运行您的应用程序所需的位,但不包含应用程序本身。基本上是一个预打包的“应用程序服务器”,您可以稍后将应用程序部署到该服务器,其风格与传统 Java EE 应用程序服务器相同,但有重要区别。
Fat/Uber –包含你自己写的部分加上你的应用程序的直接依赖项加上“独立”运行你的应用程序所需的部分。
资料来源:Dzone 文章
Fat jar 或 uber jar 是一个 jar,它包含所有项目类文件和资源以及它的所有依赖项。有不同的方法可以达到这种效果:
- 依赖项的 jar 被复制到主 jar 中,然后使用特殊的类加载器(onejar,spring-boot-plugin:repackage)加载
- 依赖项的 jar 在主 jar 层次结构的顶部提取(maven-assembly-plugin 及其 jar-with-dependencies 程序集)
- 依赖项的 jar 在主 jar 层次结构的顶部被解包,并且它们的包被重命名(带有 shade 目标的 maven-shade-plugin)
下面的示例程序集插件配置jar-with-dependencies:
<project>
...
<build>
...
<plugins>
<plugin>
<!-- NOTE: We don't need a groupId specification because the group is
org.apache.maven.plugins ...which is assumed by default.
-->
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<classifier
</configuration>
...
</project>
更详细的解释:imagej.net 上的 Uber-JAR
在可执行 jar 的情况下,考虑胖 jar 的另一种方法是您可以通过调用执行:
java -jar myFatLibrary.jar
不需要-cp
/ --classpath
,甚至不需要双击 jar 图标。
胖 jar 只包含与经典 jar 相同的类 + 来自所有运行时依赖项的类。
使用 Jeka ( https://jeka.dev ),您可以通过编程方式实现它:
JkPathTreeSet.of(Paths.get("classes")).andZips(
Paths.get("bouncycastle-pgp-152.jar"),
Paths.get("classgraph-4.8.41.jar"),
Paths.get("ivy-2.4.0.jar")
).zipTo(Paths.get("fat.jar"));
或者只是通过参数化 Java 插件:
javaPlugin.getProject().getMaker().defineMainArtifactAsFatJar(true);
在 Java 空间中,应用程序及其依赖项通常被打包为单个分发存档中的单独 JAR。这仍然会发生,但是现在有另一种常见的方法:将依赖项的类和资源直接放入应用程序 JAR 中,创建所谓的 uber 或 fat JAR。
uberJar
这是文件中任务的演示 build.gradle
:
task uberJar(type: Jar) {
archiveClassifier = 'uber'
from sourceSets.main.output
dependsOn configurations.runtimeClasspath
from {
configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }
}
}
在这种情况下,我们将获取项目的运行时依赖项configurations.runtimeClasspath.files
——并使用该方法包装每个 JAR 文件zipTree()
。结果是 ZIP 文件树的集合,其内容与应用程序类一起复制到 uber JAR 中。