JavaRush /Java Blog /Random-KO /커피 브레이크 #148. Java 프로그램을 독립형 EXE 파일로 변환하는 방법

커피 브레이크 #148. Java 프로그램을 독립형 EXE 파일로 변환하는 방법

Random-KO 그룹에 게시되었습니다
출처: Mccue.dev 오늘은 Windows 운영 체제에서 실행하기 위해 Java 프로그램에서 실행 가능한 EXE 파일을 만드는 방법을 배우게 됩니다. 커피 브레이크 #148.  Java 프로그램을 독립 실행형 EXE 파일로 변환하는 방법 - 1두 번 클릭하여 실행하는 것은 프로그램을 여는 가장 쉬운 방법 중 하나입니다. 애플리케이션을 보여주려는 사람이 이미 올바른 버전의 Java를 설치한 경우 jar 파일을 두 번 클릭하여 실행할 수 있습니다. Java가 설치되어 있지 않은 경우 jpackage 와 같은 실행 가능한 설치 프로그램을 만드는 방법이 있습니다 . 그런 다음 코드를 실행하려면 이 설치 프로그램을 클릭하기만 하면 됩니다. 네이티브 이미지를 사용하여 코드를 추가 설치가 필요 없는 실행 파일로 변환 할 수도 있습니다 . 이 기사에서는 포함하는 종속성이나 사용하는 JVM 기능에 관계없이 모든 애플리케이션에 작동하는 매우 간단한 접근 방식에 중점을 둘 것입니다. 오늘 논의할 코드는 GitHub 저장소 에서 찾을 수 있으며 , 프로그램과 함께 실행 가능한 파일은 여기에 게시되어 있습니다 .

사용된 스택

자바 9+

자바 --버전 jlink --버전

메이븐

mvn --버전

NodeJS

npx --버전

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);
    }
}
커피 브레이크 #148.  Java 프로그램을 독립 실행형 EXE 파일로 변환하는 방법 - 2이제 우리의 목표는 종속성과 함께 코드를 jar로 패키징하는 것입니다. JAR 파일은 추가 구조가 거의 없는 일반 ZIP 아카이브입니다. Maven 프로젝트 의 경우 구성은 다음과 같습니다.
<?xml version="1.0" 인코딩="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> <종속성> <종속성> <groupId> org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.9</version> </dependent> </dependent> <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> 그늘</goal> </goals> <configuration> <transformers> <transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>example.Main</Main- 클래스> <빌드 번호>1.0</빌드 번호> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </프로젝트>
여기서 "shade" 플러그인은 모든 종속성의 코드를 jar에 포함하는 작업을 처리합니다. 이 경우 유일한 외부 종속성은 org.apache.commons/commons-text 입니다 .
mvn 클린 패키지
그런 다음 이 jar 파일을 다른 파일과 분리될 새 target/ 디렉터리 로 이동합니다 .
mkdir 빌드 mv target/javaexe-1.0.jar 빌드

2단계: JRE(Java Runtime Environment) 생성

이미 생성한 jar 파일을 실행하려면 해당 파일을 Java 런타임 환경에 연결해야 합니다. 이를 위해 우리는 jlink를 사용할 것입니다 . Java 생태계에서는 모듈을 사용하지 않으므로 모듈에 대해 들어본 적도 없고 jlink를 사용해 본 적도 없을 것입니다. 즉, jlink는 "사용자 정의 실행 가능 이미지"를 만들 수 있습니다. 예를 들어, 웹 서버를 만들고 있습니다. AWT 또는 Swing이 필요하지 않으므로 코드에 포함하는 것은 중복됩니다. jlink를 사용하면 java.desktop 모듈을 전혀 포함하지 않는 JRE를 생성할 수 있습니다 . 이 시스템은 애플리케이션과 모든 종속성이 컴파일된 module-info.java 파일을 포함하는 경우 가장 잘 작동합니다 . 이 파일은 포함하려는 모듈을 jlink에 정확하게 알려줍니다. jdeps를 사용하여 필수 모듈 목록을 수동으로 정의할 수도 있습니다 . 그리고 모듈식 프로젝트가 없더라도 jlink를 사용하여 Java 설치를 디렉토리에 효과적으로 복제할 수 있습니다.
jlink --추가 모듈 ALL-MODULE-PATH --출력 빌드/런타임
각 모듈을 개별적으로 포함하면 org.apache.commons/commons-text 와 같은 라이브러리가 의도한 대로 작동하도록 보장됩니다. 우리는 어떤 모듈이 필요한지 알아내기만 하면 됩니다.

3단계: Jar와 JRE를 실행 파일로 결합

코드와 모든 종속성, 그리고 JRE가 포함된 jar 파일이 있으면 이를 결합하는 것만 남아 있습니다. 이렇게 하려면 다음을 수행해야 합니다.
  1. 애플리케이션의 JRE 및 jar이 포함된 디렉토리를 압축합니다.
  2. 이 zip 파일 상단에 스텁 스크립트를 첨부하면 임시 디렉터리에 데이터가 추출되고 코드가 실행됩니다.
이를 위한 caxa 라는 JavaScript 라이브러리가 있습니다 . 그 목적은 NodeJS 프로젝트를 실행 파일로 바꾸는 것이며, 시스템에 설치된 모든 NodeJS를 번들로 묶을 수도 있습니다. 다행히 --no-include-node 플래그를 지정하여 이 단계를 건너뛸 수 있습니다 .
npx caxa \ --input 빌드 \ --output 애플리케이션 \ --no-include-node \ -- ​​​​"{{caxa}}/runtime/bin/java" "-jar" "{{caxa}}/javaexe -1.0 .jar"
그러면 "application"이라는 실행 파일이 생성됩니다. Windows용으로 생성하는 경우 "application.exe"를 지정해야 합니다. 실행 파일이 실행되면 {{caxa}}는 zip 파일이 배포된 임시 디렉터리로 대체됩니다. 실행 파일을 생성할 때 코드 서명 및 자동 업데이트와 같은 메커니즘도 사용된다는 점에 유의하세요. 그러나 이러한 것들은 더 깊은 연구가 필요하며, 이는 하나의 출판물에 담기 어렵습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION