← Назад к вопросам

Что такое make jar, not war?

2.0 Middle🔥 181 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Make JAR, Not WAR

Make JAR, Not WAR (Jar, а не War) — это архитектурный подход в разработке Java-приложений, пропагандируемый Spring Boot. Это означает: создавайте standalone JAR-файлы вместо традиционных WAR-файлов для развёртывания веб-приложений.

Различие между JAR и WAR

WAR (Web Application Archive) — это архивный формат для веб-приложений, разработанный для запуска внутри сервера приложений (Application Server).

  • Требует запущенного сервера приложений (Tomcat, Jetty, JBoss, WebSphere)
  • Структура: WEB-INF/lib/, WEB-INF/classes/, WEB-INF/web.xml
  • Старый подход (J2EE era)

JAR (Java Archive) — универсальный архивный формат для Java-приложений, упакованный как standalone исполняемый файл.

  • Содержит встроенный сервер приложений (например, Tomcat)
  • Запускается как обычное Java-приложение: java -jar application.jar
  • Современный подход (Spring Boot era)

Традиционный подход: WAR

<!-- pom.xml -->
<packaging>war</packaging>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- Scope: provided, т.е. не включается в WAR -->
    <scope>provided</scope>
</dependency>

Проблемы:

1. Нужен отдельный Application Server
2. Сложное развёртывание (copy war -> restart server)
3. Проблемы совместимости между версиями Tomcat и приложением
4. Невозможно легко запустить локально
5. Медленное развёртывание

Современный подход: JAR с Spring Boot

<!-- pom.xml -->
<packaging>jar</packaging>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- Scope: compile, включается в JAR -->
</dependency>

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

Преимущества:

1. Независимый standalone файл
2. Простой запуск: java -jar app.jar
3. Встроенный Tomcat (версия контролируется разработчиком)
4. Легко запустить локально для разработки
5. Контейнеризация (Docker) становится простой
6. Микросервисная архитектура

Структура Spring Boot JAR

app.jar
├── BOOT-INF/
│   ├── classes/               (скомпилированный код)
│   │   └── application.properties
│   ├── lib/                   (зависимости)
│   │   ├── spring-core-*.jar
│   │   ├── tomcat-embed-*.jar
│   │   └── ...
│   └── classpath.idx
├── org/
│   └── springframework/
│       └── boot/               (Spring Boot loader)
├── META-INF/
│   ├── MANIFEST.MF
│   └── spring.factories
└── (другие служебные файлы)

Пример Spring Boot приложения

// Application.java - главный класс
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// REST Controller
@RestController
@RequestMapping("/api")
public class HelloController {
    
    @GetMapping("/hello")
    public Map<String, String> hello() {
        return Map.of("message", "Hello from Spring Boot JAR!");
    }
}

Сборка и запуск:

mvn clean package           # Создаёт target/app-1.0.0.jar
java -jar target/app-1.0.0.jar  # Запуск приложения

Встроенные серверы в Spring Boot

Tomcat (по умолчанию):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- Автоматически включает Tomcat -->
</dependency>

Jetty:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

Undertow:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

Docker с JAR

FROM openjdk:17
COPY target/app-1.0.0.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

Сборка и запуск:

docker build -t my-app .
docker run -p 8080:8080 my-app

Конфигурация через application.properties

# application.properties
server.port=8080
server.servlet.context-path=/api
spring.application.name=my-app

# Database
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret

Запуск с переопределением параметров:

java -jar app.jar --server.port=9090 --spring.datasource.url=jdbc:mysql://prod-db:3306/db

Когда используют WAR сегодня

  • Legacy приложения, требующие specific версии Application Server
  • Корпоративные требования, привязанные к конкретному серверу
  • Развёртывание на managed hosting (например, AWS Elastic Beanstalk)

Когда используют JAR (Spring Boot)

  • Новые проекты и микросервисы
  • Cloud-native приложения (AWS, GCP, Azure)
  • Docker/Kubernetes развёртывание
  • Разработка и тестирование (быстрый запуск)
  • DevOps культура (CI/CD pipelines)

Make JAR, Not WAR — это рекомендация Spring Boot создателей для более гибкого, современного и облачного подхода к разработке Java-приложений.