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

Какой исполняемый файл можно получить после компиляции Java?

2.0 Middle🔥 141 комментариев
#Основы Java

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

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

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

Исполняемые файлы Java после компиляции

Этот вопрос проверяет понимание Java компиляции и дистрибуции. Ответ может показаться простым на первый взгляд, но он отражает эволюцию Java экосистемы.

Основной результат компиляции: .class файлы

Когда ты компилируешь Java код через javac:

$ javac HelloWorld.java
$ ls -la
HelloWorld.java    # Исходный файл
HelloWorld.class   # Скомпилированный bytecode

Важно: .class файлы — это НЕ исполняемые файлы в классическом смысле (как .exe на Windows или бинарники на Linux). Это bytecode (промежуточное представление), который выполняется JVM.

// Исходный код
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}

// После компиляции в HelloWorld.class
// Это bytecode (в hex формате):
// CA FE BA BE (magic number JVM)
// 00 34 (version 3.4)
// ... (инструкции JVM)

Как запустить .class файл?

$ java HelloWorld
# НЕ java HelloWorld.class!
# JVM находит HelloWorld.class в classpath и выполняет

Упаковка в JAR (Java Archive)

Для распределения используют JAR файлы — это ZIP архив с .class файлами:

$ jar cvf myapp.jar HelloWorld.class OtherClass.class
$ ls -la
myapp.jar

# Внутри JAR
$ unzip -l myapp.jar
HelloWorld.class
OtherClass.class
META-INF/MANIFEST.MF

Запуск JAR файла:

$ java -jar myapp.jar
# MANIFEST.MF должен содержать Main-Class
<!-- pom.xml (Maven) -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>HelloWorld</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

$ mvn package
$ java -jar target/myapp-1.0.jar

Варианты дистрибуции

1. Standalone JAR с зависимостями (Fat JAR / Uber JAR)

# Содержит все зависимости внутри
$ ls -la myapp-all.jar  # 50MB

# Внутри:
HelloWorld.class
spring-core-5.2.jar (распакован)
log4j-api-2.13.jar (распакован)
jackson-databind-2.11.jar (распакован)
...

$ java -jar myapp-all.jar  # Работает везде
<!-- Maven для Fat JAR -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>HelloWorld</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>myapp</finalName>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
        </execution>
    </executions>
</plugin>

2. Spring Boot JAR

Spring Boot создает специальный JAR формат с embedded сервером:

$ mvn spring-boot:build-image
$ ls target/
myapp-1.0.jar  # 45MB (содержит Tomcat, все зависимости)

$ java -jar myapp-1.0.jar
# Запустился веб-сервер на порту 8080
<!-- pom.xml с Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.0</version>
</parent>

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

$ mvn package
$ java -jar target/myapp-1.0.jar

3. WAR файл (Web Archive)

Для развертывания в приложение сервера (Tomcat, JBoss):

$ mvn package
$ ls target/
myapp-1.0.war

# Развертывание
$ cp target/myapp-1.0.war /opt/tomcat/webapps/
# Tomcat автоматически распакует и запустит
<!-- pom.xml для WAR -->
<packaging>war</packaging>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

4. EAR файл (Enterprise Archive)

Для Java EE приложений с модулями:

$ mvn package
$ ls target/
myapp-1.0.ear

# Внутри EAR:
myapp-web.war
myapp-ejb.jar
myapp-common.jar
meta-inf/application.xml

Современный подход: Native Image (GraalVM)

Можно скомпилировать Java в настоящий native бинарник:

# GraalVM native-image
$ native-image -cp target/myapp-1.0.jar HelloWorld
$ ls -la
helloworld  # Реальный исполняемый файл! (10-30MB)

$ ./helloworld
Hello  # Запустился за 50ms (vs 1-2 сек для JVM)

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

  • Очень быстрый старт (50ms vs 2-5 сек)
  • Меньший размер памяти
  • Можно запустить где угодно без Java

Недостатки:

  • Компиляция требует времени
  • Reflection нужно конфигурировать
<!-- Maven для GraalVM -->
<plugin>
    <groupId>org.graalvm.buildtools</groupId>
    <artifactId>native-maven-plugin</artifactId>
    <version>0.9.19</version>
</plugin>

$ mvn native:compile

Docker контейнеры

Типичное развертывание в production:

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

$ docker build -t myapp:1.0 .
$ docker run myapp:1.0

Сравнение всех форматов

ФорматРазмерЗапускГде использоватьПримечание
.classМалыйjava ClassNameDevelopmentЧерез classpath
JARСреднийjava -jarStandaloneНужен Main-Class
Fat JARБольшойjava -jarProductionВсе зависимости внутри
WARСреднийТомкатEnterpriseНужен сервер приложений
NativeОчень малый./appMicroservicesGraalVM требуется
Docker-docker runContainerizedОбраз с JVM + JAR

Исторически правильный ответ на вопрос

Ответ зависит от контекста:

После компиляции javac:
→ .class файлы (bytecode)

Для дистрибуции:
→ JAR файлы (архив .class файлов)
→ FAT JAR (JAR со всеми зависимостями)
→ WAR файлы (для веб-приложений)
→ EAR файлы (для enterprise приложений)
→ Native image (с GraalVM)

Для запуска:
→ JVM + .class файлы
→ JVM + JAR файл
→ Native бинарник (если скомпилировано через GraalVM)

Итог

Нет одного единственного ответа. Исполняемыми файлами в Java контексте могут быть:

  1. .class файлы (основной результат компиляции)
  2. JAR файлы (упакованные .class файлы)
  3. WAR файлы (веб-приложения)
  4. Native бинарники (GraalVM native-image)

Лучший ответ: Это зависит от того, как ты развертываешь приложение. В modern Java обычно это JAR файл, который запускается с java -jar.

Какой исполняемый файл можно получить после компиляции Java? | PrepBro