Введение: знакомство с ошибкой, которая пугает новичков
Вы написали программу на Java, скомпилировали её, упаковали в JAR-файл и с гордостью пытаетесь запустить двойным щелчком мыши — но вместо окна приложения видите чёрное окно терминала с пугающей надписью: Can't execute jar- file: "no main manifest attribute". Знакомо? Если нет — считайте, что вам повезло (пока).
Эта ошибка — одна из самых популярных на Stack Overflow. Только представьте: тысячи разработчиков, от студентов до опытных инженеров, хотя бы раз в жизни сталкивались с тем, что их JAR-файл «отказывается» запускаться. Почему так происходит? Дело в том, что Java — это не просто «запакуй и запускай». Виртуальная машина должна чётко знать: какой класс содержит точку входа? Без этой информации JAR-файл остаётся обычным архивом, а не исполняемой программой.
В этой статье мы разберёмся, что такое манифест, как он связан с точкой входа, и — самое главное — как сделать так, чтобы ваш JAR-файл запускался без ошибок. Мы пойдём от простого к сложному: от ручной сборки в командной строке до настройки IDE. Поехали!
Что такое манифест и зачем он нужен?
Каждый JAR-файл (Java Archive) внутри содержит папку META-INF, а в ней — файл MANIFEST.MF. Это не просто технический артефакт, а самая настоящая «инструкция по эксплуатации» для виртуальной машины Java.
Представьте себе книгу без оглавления. Вы знаете, что в ней есть главы, но не знаете, с какой страницы начинать чтение. Примерно то же самое происходит с JAR-файлом без указания главного класса. Виртуальная машина видит множество классов, но не знает, какой из них содержит метод public static void main(String[] args).
Типичный файл MANIFEST.MF выглядит так:
Manifest-Version: 1.0
Created-By: 17.0.2 (Oracle Corporation)
Main-Class: com.example.Main
Самая важная строка здесь — Main-Class. Она указывает полное имя класса (с пакетом), который Java должна запустить. Если этой строки нет или она указана неверно — вы получаете ту самую ошибку «no main manifest attribute».
Почему манифест может быть пустым или некорректным?
- Ручная сборка через
jar— если вы не указали флаг-eили не создали свой манифест. - Сборка в IDE без настройки — некоторые среды разработки (особенно старые версии) не добавляют
Main-Classавтоматически. - Оплошность при именовании — например, вы написали
mainс маленькой буквы или забыли указать пакет. - Кодировка и форматирование — в манифесте важна каждая пустая строка в конце файла.
Как создать исполняемый JAR-файл: три способа
Способ 1. Командная строка (ручной контроль)
Этот метод даёт полное понимание процесса. Допустим, у нас есть простой класс HelloWorld.java:
package com.example;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Привет, мир! JAR работает!");
}
}
Шаг 1. Компилируем класс
javac -d . HelloWorld.java
Флаг -d . создаёт структуру пакетов (com/example/HelloWorld.class).
Шаг 2. Создаём манифест вручную
Создаём файл MANIFEST.MF (например, в блокноте) со следующим содержимым:
Manifest-Version: 1.0
Main-Class: com.example.HelloWorld
Важно: после последней строки обязательно должна быть пустая строка! Без неё JAR-файл может не прочитать манифест.
Шаг 3. Создаём JAR
jar cfm HelloWorld.jar MANIFEST.MF com/example/HelloWorld.class
Флаг c — создать архив, f — указать имя файла, m — использовать наш манифест.
Шаг 4. Запускаем
java -jar HelloWorld.jar
Если всё сделано правильно, вы увидите: Привет, мир! JAR работает!
Способ 2. Упрощённая команда (без ручного манифеста)
Начиная с Java 7, можно не создавать отдельный файл манифеста. Вместо этого используйте флаг -e (entry point):
jar cfe HelloWorld.jar com.example.HelloWorld com/example/HelloWorld.class
Флаг e автоматически добавит строку Main-Class в манифест. Этот способ проще и меньше шансов ошибиться с форматированием.
Способ 3. Сборка в IntelliJ IDEA (для ленивых и занятых)
Большинство современных Java-разработчиков используют IDE. Вот как создать исполняемый JAR в IntelliJ IDEA:
- Откройте File → Project Structure (или нажмите
Ctrl+Alt+Shift+S). - Перейдите в раздел Artifacts → нажмите + → JAR → From modules with dependencies.
- В поле Main Class нажмите на иконку папки и выберите ваш класс с методом
main. - Убедитесь, что выбрана опция extract to the target JAR (чтобы все зависимости упаковались внутрь).
- Нажмите OK, затем Apply.
- Соберите артефакт: Build → Build Artifacts → Build.
Готово! Ваш JAR-файл появится в папке out/artifacts/. Попробуйте запустить его двойным щелчком или через java -jar.
Что делать, если ошибка всё ещё появляется?
Вы проверили манифест, пересобрали JAR — а ошибка никуда не делась? Вот чек-лист для диагностики:
- Проверьте содержимое JAR:
jar tf YourFile.jar. Вы должны увидеть папку