У любого компилируемого приложения есть два состояния. Первое – исходный код для разработки. Второе – скомпилированная программа, готовая для запуска. Причем программа запускается не там где она компилируется, ее сначала нужно доставить либо на сервер, либо на компьютер тому, кто ее запустит.
Компиляция => Доставка по месту назначения => Запуск
Доставлять программу куда-либо удобно только если она состоит из одного файла. Поэтому создатели Java разработали специальный формат архива JAR (Java ARchive). Он позволяет взять любые файлы и упаковать их в один сжатый файл. Упаковка происходит в два этапа:
Компиляция
Сначала нужно выполнить компиляцию. Причем таким образом, чтобы готовые файлы лежали отдельно от исходного кода. Исходный код скрывается, если это не открытый проект. У компилятора есть опция -d
, которая задает директорию, куда надо сложить готовые файлы.
# Два файла из прошлого урока
# Внутри io/hexlet
javac One.java Two.java -d build
Компилятор создаст директорию build и сложит туда готовые файлы. Сделает это с учетом пакетов:
# Показывает структуру директории
tree build
build
└── io
└── hexlet
├── One.class
└── Two.class
Проверим что все работает:
# Внутри директории build
java io.hexlet.One
Java for Brave
Упаковка
Теперь упакуем содержимое директории build в jar файл. Первым шагом создадим файл манифеста manifest.MF, который нужен для правильного запуска jar на исполнение. В этом файле указывается входная точка в программу. Сам файл проще всего положить внутрь директории build иначе придется указывать classpath.
tree build
build
├── io
│ └── hexlet
│ ├── One.class
│ └── Two.class
└── manifest.MF
Ниже содержимое файла. Справа указывается полное имя класса включая пакет. Обратите внимание на пустую строку в конце. Если ее не добавить, то возникнет ошибка.
Main-Class: io.hexlet.One
Следующим шагом запустим упаковку:
# Запускаем внутри директории build,
# поэтому в конце команды точка (текущая директория)
# Опции:
# c – создать новый файл
# v - подробный вывод
# f – имя выходного jar файла
# m – имя файла манифеста (или путь до него)
jar -cvfm build.jar manifest.MF .
added manifest
adding: manifest.MF(in = 39) (out= 41)(deflated -5%)
adding: io/(in = 0) (out= 0)(stored 0%)
adding: io/hexlet/(in = 0) (out= 0)(stored 0%)
adding: io/hexlet/(in = 0) (out= 0)(stored 0%)
adding: io/hexlet/Two.class(in = 415) (out= 292)(deflated 29%)
adding: io/hexlet/One.class(in = 332) (out= 242)(deflated 27%)
На выходе получился архив:
tree build
build
├── build.jar # вот он
├── io
│ └── hexlet
│ ├── One.class
│ └── Two.class
└── manifest.MF
Внутри архива лежит директория io. Сейчас там только байткод (файлы с расширением class), но может быть все, что угодно, например картинки, шрифты или любые другие файлы, нужные для работы приложения.
JAR можно запускать напрямую, поэтому сразу проверим как работает наша программа:
java -jar build.jar
Java for Brave
Самостоятельная работа
- Упакуйте программу в проекте в JAR-архив
- Запустите получившийся архив на исполнение и убедитесь, что программа работает
- Добавьте все изменения на гитхаб
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.