«No main manifest attribute»: почему Java не видит точку входа в JAR и как это исправить

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: знакомство с ошибкой, которая пугает новичков

Вы написали программу на 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:

  1. Откройте File → Project Structure (или нажмите Ctrl+Alt+Shift+S).
  2. Перейдите в раздел Artifacts → нажмите + → JAR → From modules with dependencies.
  3. В поле Main Class нажмите на иконку папки и выберите ваш класс с методом main.
  4. Убедитесь, что выбрана опция extract to the target JAR (чтобы все зависимости упаковались внутрь).
  5. Нажмите OK, затем Apply.
  6. Соберите артефакт: Build → Build Artifacts → Build.

Готово! Ваш JAR-файл появится в папке out/artifacts/. Попробуйте запустить его двойным щелчком или через java -jar.

Что делать, если ошибка всё ещё появляется?

Вы проверили манифест, пересобрали JAR — а ошибка никуда не делась? Вот чек-лист для диагностики:

  • Проверьте содержимое JAR: jar tf YourFile.jar. Вы должны увидеть папку

Блоги

Рекомендаций по книгам