Найти в Дзене
От Джуна до Лида (IT Jobs)

Как превратить любую Java программу в автономный EXE-файл

В данной статье вы узнаете, как создать из Java-программы исполняемый EXE-файл для запуска в операционной системе Windows Двойной щелчок для запуска — один из самых простых способов открыть программу. Если у человека, которому вы хотите показать свое приложение, уже установлена ​​правильная версия Java, для запуска он может дважды щелкнуть файл jar. Если же у него не установлена ​​Java, то есть способы создать исполняемый установщик, такой как jpackage. После этого для запуска кода нужно лишь нажать на этот установщик. Также можно использовать Native Image, чтобы превратить код в исполняемый файл, который не требует какой-либо дополнительной установки. В этой статье мы сосредоточимся на довольно простом подходе, который работает для любого приложения, независимо от того, какие зависимости вы включаете или какие функции JVM используете. Код, о котором сегодня пойдет речь, можно найти в репозитории GitHub, а исполняемые файлы с программой выложены здесь. Используемый стек Java 9+ java -
Оглавление

В данной статье вы узнаете, как создать из Java-программы исполняемый EXE-файл для запуска в операционной системе Windows

Двойной щелчок для запуска — один из самых простых способов открыть программу. Если у человека, которому вы хотите показать свое приложение, уже установлена ​​правильная версия Java, для запуска он может дважды щелкнуть файл jar. Если же у него не установлена ​​Java, то есть способы создать исполняемый установщик, такой как jpackage. После этого для запуска кода нужно лишь нажать на этот установщик. Также можно использовать Native Image, чтобы превратить код в исполняемый файл, который не требует какой-либо дополнительной установки.

В этой статье мы сосредоточимся на довольно простом подходе, который работает для любого приложения, независимо от того, какие зависимости вы включаете или какие функции JVM используете.

Код, о котором сегодня пойдет речь, можно найти в репозитории GitHub, а исполняемые файлы с программой выложены здесь.

Используемый стек

Java 9+

java --version

jlink --version

Maven

mvn --version

NodeJS

npx --version

Шаг 1. Скомпилируйте и упакуйте свой код в jar

Эта базовая программа создаст простое окно с текстом, который вы можете менять, нажимая на одну из кнопок в интерфейсе.

Эта базовая программа создаст простое окно с текстом, который вы можете менять, нажимая на одну из кнопок в интерфейсе.

package example;

import org.apache.commons.text.WordUtils;

import javax.swing.*;
import java.awt.*;

public class Main {
public static void main(String[] args) {
var label = new JLabel("Hello, World!");
label.setFont(new Font("Serif", Font.PLAIN, 72));

var uppercaseButton = new JButton("Uppercase");
uppercaseButton.addActionListener(e ->
label.setText(WordUtils.capitalize(label.getText()))
);

var lowercaseButton = new JButton("lowercase");
lowercaseButton.addActionListener(e ->
label.setText(WordUtils.uncapitalize(label.getText()))
);

var panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(label);
panel.add(uppercaseButton);
panel.add(lowercaseButton);

var frame = new JFrame("Basic Program");
frame.add(panel);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}

Сейчас наша цель состоит в том, чтобы упаковать код вместе с его зависимостями в jar. JAR-файлы — это обычные ZIP-архивы с небольшой дополнительной структурой.

Для проекта Maven конфигурация будет выглядеть следующим образом.

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>example</groupId>

<artifactId>javaexe</artifactId>

<version>1.0</version>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<maven.compiler.source>18</maven.compiler.source>

<maven.compiler.target>18</maven.compiler.target>

</properties>

<dependencies>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-text</artifactId>

<version>1.9</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-shade-plugin</artifactId>

<version>2.4.3</version>

<executions>

<execution>

<phase>package</phase>

<goals>

<goal>shade</goal>

</goals>

<configuration>

<transformers>

<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">

<manifestEntries>

<Main-Class>example.Main</Main-Class>

<Build-Number>1.0</Build-Number>

</manifestEntries>

</transformer>

</transformers>

</configuration>

</execution>

</executions>

</plugin>

</plugins>

</build>

</project>

Здесь плагин “shade” будет обрабатывать включение кода из всех ваших зависимостей в jar. В данном случае единственной внешней зависимостью является org.apache.commons/commons-text.

mvn clean package

Затем мы переместим этот jar-файл в новый каталог target/, где он будет отделен от других файлов.

mkdir build

mv target/javaexe-1.0.jar build

Шаг 2. Создайте среду выполнения Java (Java Runtime Environment, JRE)

Чтобы запустить уже созданный нами jar-файл, нужно связать его со средой выполнения Java. Для этого мы будем использовать jlink.

Поскольку в экосистеме Java не используются модули, то вы, скорее всего, не слышали о них и не использовали jlink.

Короче говоря, jlink может создавать “настраиваемые исполняемые образы”. Например, вы делаете веб-сервер. Вам не нужны AWT или Swing, поэтому включать их в код будет лишним. С помощью jlink вы можете создать JRE, которая вообще не включает модуль java.desktop.

Эта система работает лучше всего, если ваше приложение и все его зависимости включают скомпилированные файлы module-info.java, которые дают jlink точную информацию, какие модули вы хотите включить. Вы также можете вручную определить список необходимых модулей, используя jdeps.

И даже без модульного проекта мы можем эффективно клонировать нашу инсталляцию Java в каталог с помощью jlink.

jlink --add-modules ALL-MODULE-PATH --output build/runtime

Включение каждого модуля по отдельности дает уверенность в том, что такие библиотеки как org.apache.commons/commons-text будут работать именно так, как задумано. Нужно лишь выяснить, какие модули нам требуются.

Шаг 3. Объедините Jar и JRE в исполняемый файл

Имея jar-файл, содержащий код и все его зависимости, а также JRE, остается только объединить их. Для этого нам нужно выполнить следующие действия:

  1. Заархивируйте каталог, содержащий JRE и jar вашего приложения.
  2. Прикрепите сценарий-заглушку (stub script) к верхней части этого zip-файла, который извлечет данные во временный каталог и запустит код.
  3. Для этого существует библиотека JavaScript, которая называется caxa. Ее цель — превращать проекты NodeJS в исполняемые файлы, она также может объединять любые установки NodeJS в системе. К счастью, этот шаг можно пропустить, указав флаг --no-include-node.

npx caxa \

--input build \

--output application \

--no-include-node \

-- "{{caxa}}/runtime/bin/java" "-jar" "{{caxa}}/javaexe-1.0.jar"

Это создаст исполняемый файл с именем “application”. Если вы создаете его для Windows, то нужно указать “application.exe”. Когда исполняемый файл запускается, {{caxa}} будет заменен на временный каталог, в котором был развернут zip-файл.

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

#it #java #exe #code