Я слышал, как люди говорят, что они создают толстый JAR и разворачивают его. Что они на самом деле имеют в виду?
Что такое толстый JAR?
Ответ 1
Жирная фляга - это банка, содержащая классы из всех библиотек, от которых зависит ваш проект, и, конечно, классы текущего проекта.
В разных системах сборки жирный фрейм создается по-разному, например, в 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 это делается таким образом (после настройки обычной банки):
<pluginrepositories>
<pluginrepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginrepository>
</pluginrepositories>
<!-- ... -->
<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>
Ответ 2
Fat jar или uber jar - это банка, содержащая все файлы и ресурсы класса проекта, упакованные вместе со всеми ее зависимостями. Существуют разные способы достижения такого эффекта:
- Флажки
- dependations копируются в основную банку, а затем загружаются с помощью специального загрузчика классов (onejar)
- баги зависимостей извлекаются в верхней части главной иерархии jar (сборка maven-assembly-plugin с сборкой jar-with-dependencies, 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>
Ответ 3
В случае исполняемого флага другой способ думать о толстой банке - это тот, который вы можете выполнить, вызвав:
java -jar myFatLibrary.jar
без необходимости -cp
/--classpath
или даже дважды щелкнуть значок баннера.
Ответ 4
Различные названия - это просто способы упаковки Java-приложений.
Тощий - содержит ТОЛЬКО биты, которые вы буквально вводите в редактор кода, и НИЧЕГО больше.
Тонкий - содержит все вышеперечисленное, а также прямые зависимости приложений от вашего приложения (драйверы БД, служебные библиотеки и т.д.).
Пустота - Инверсия тонкого - Содержит только биты, необходимые для запуска вашего приложения, но НЕ содержит самого приложения. По сути, это предварительно упакованный "сервер приложений", на котором вы можете позднее развернуть свое приложение в том же стиле, что и традиционные серверы приложений Java EE, но с существенными отличиями.
Fat/Uber - содержит бит, который вы буквально пишете себе, плюс прямые зависимости вашего приложения, плюс биты, необходимые для запуска вашего приложения "самостоятельно".
Источник: Статья из Dzone
Ответ 5
Толстый 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);
Ответ 6
В пространстве Java приложения и их зависимости обычно упаковывались как отдельные JAR файлы в одном архиве распространения. Это все еще происходит, но есть и другой распространенный подход: размещение классов и ресурсов зависимостей непосредственно в JAR приложения, создание так называемого UAR или жирного 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 файлов, содержимое которых копируется в UAR JAR вместе с классами приложения.