Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Что такое Fat JAR (Uber JAR)
Fat JAR (также называется Uber JAR или Shaded JAR) — это JAR файл, который содержит не только скомпилированный код приложения, но и все его зависимости (библиотеки), упакованные вместе. Это позволяет запустить приложение с помощью одной команды: java -jar app.jar.
Сравнение: обычный JAR vs Fat JAR
Обычный JAR
myapp-1.0.jar
├── com/example/...
├── org/springframework/... ❌ НЕ включены
├── org/slf4j/... ❌ НЕ включены
└── META-INF/
└── MANIFEST.MF
Для запуска нужно:
java -cp "myapp-1.0.jar:lib/spring-*.jar:lib/slf4j-*.jar:..." com.example.Main
Fat JAR (Uber JAR)
myapp-1.0-fat.jar
├── com/example/...
├── org/springframework/...
├── org/slf4j/...
├── org/apache/...
└── ... все зависимости внутри
Для запуска:
java -jar myapp-1.0-fat.jar
Зачем нужен Fat JAR
1. Простота развёртывания
- Один файл вместо множества
- Не нужно собирать classpath
- Идеально для Docker контейнеров
2. Переносимость
# Скопировал файл и запустил — работает везде
cp myapp-1.0-fat.jar /path/to/server/
cd /path/to/server/
java -jar myapp-1.0-fat.jar
3. Microservices
# Dockerfile
FROM openjdk:11
COPY target/myservice-1.0-fat.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
4. Отсутствие конфликтов зависимостей
Все версии библиотек зафиксированы в одном файле
Создание Fat JAR: Maven
Способ 1: Maven Assembly Plugin (классический)
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>myapp-fat</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Сборка:
mvn clean assembly:assembly
# Результат: target/myapp-fat.jar
Способ 2: Maven Shade Plugin (рекомендуется)
Этот способ решает проблемы с конфликтами имён классов:
<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>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Способ 3: Spring Boot Maven Plugin (для Spring Boot)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.example.Application</mainClass>
</configuration>
</plugin>
</plugins>
Sборка:
mvn clean package
# Результат: target/myapp-1.0.jar (уже fat jar из коробки)
Создание Fat JAR: Gradle
version = '1.0'
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.0'
}
jar {
manifest {
attributes 'Main-Class': 'com.example.Main'
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Структура Fat JAR
$ unzip -l myapp-1.0-fat.jar | head -50
Archive: myapp-1.0-fat.jar
Length Date Time Name
--------- ---------- ----- ----
1234 2024-01-15 10:30 META-INF/MANIFEST.MF
5678 2024-01-15 10:30 META-INF/pom.xml
9012 2024-01-15 10:30 com/example/Main.class
3456 2024-01-15 10:30 com/example/App.class
15678 2024-01-15 10:30 org/springframework/core/... ← Зависимости
24567 2024-01-15 10:30 org/slf4j/...
...
Практический пример: простое приложение
// src/main/java/com/example/Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Приложение запущено!");
// Используем зависимость
ObjectMapper mapper = new ObjectMapper(); // Jackson
String json = mapper.writeValueAsString(new User("John", 30));
System.out.println(json);
}
static class User {
public String name;
public int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
}
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.0</version>
</dependency>
</dependencies>
Сборка и запуск:
mvn clean package
java -jar target/myapp-1.0.jar
# Выведет: {"name":"John","age":30}
Плюсы и минусы
Плюсы ✅
- Простота: Один JAR файл для развёртывания
- Портативность: Не нужно устанавливать зависимости
- Docker friendly: Идеально для контейнеризации
- Отсутствие конфликтов: Все версии зафиксированы
- Быстрое разворачивание: На сервере не нужно ничего конфигурировать
Минусы ❌
- Размер: Файл может быть очень большой (50-200MB)
- Медленный выход: Может занять время на загрузку всех классов
- Отладка: Сложнее отследить конфликты версий
- Обновление зависимостей: Нужно пересобирать весь JAR
Оптимизация размера
<!-- Исключить ненужные зависимости -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Запуск с параметрами
# С JVM параметрами
java -Xmx512m -Xms256m -jar myapp-1.0-fat.jar
# С программными параметрами
java -jar myapp-1.0-fat.jar --server.port=8080 --logging.level.root=DEBUG
# С переменными окружения
export APP_NAME="MyApp"
java -jar myapp-1.0-fat.jar
Альтернативы Fat JAR
- Modulith (Spring) — модульная архитектура
- Jlink + custom runtime — минимизированная JVM
- GraalVM Native Image — скомпилированный в машинный код
- Containerization (Docker) — всё в контейнере
Заключение
Fat JAR — это стандартный способ упаковки Java приложений для production. Он обеспечивает простоту развёртывания и отсутствие проблем с зависимостями. Идеально подходит для microservices, которые разворачиваются в Docker контейнерах.