JavaRush /Blog Java /Random-VI /Nghỉ giải lao #148. Cách biến bất kỳ chương trình Java nà...

Nghỉ giải lao #148. Cách biến bất kỳ chương trình Java nào thành tệp EXE độc lập

Xuất bản trong nhóm
Nguồn: McCue.dev Hôm nay bạn sẽ tìm hiểu cách tạo một tệp EXE thực thi từ một chương trình Java để chạy trên hệ điều hành Windows. Nghỉ giải lao #148.  Cách biến bất kỳ chương trình Java nào thành tệp EXE độc lập - 1Nhấp đúp để khởi chạy là một trong những cách dễ dàng nhất để mở chương trình. Nếu người mà bạn muốn cho xem ứng dụng của mình đã cài đặt đúng phiên bản Java, họ có thể bấm đúp vào tệp jar để chạy nó. Nếu nó chưa cài đặt Java, có nhiều cách để tạo trình cài đặt có thể thực thi được, chẳng hạn như jpackage . Sau đó, để chạy mã bạn chỉ cần nhấp vào trình cài đặt này. Bạn cũng có thể sử dụng Hình ảnh gốc để biến mã thành tệp thực thi mà không yêu cầu cài đặt bổ sung. Trong bài viết này, chúng tôi sẽ tập trung vào một cách tiếp cận khá đơn giản, phù hợp với mọi ứng dụng, bất kể bạn đưa vào những phần phụ thuộc nào hoặc bạn sử dụng tính năng JVM nào. Mã sẽ được thảo luận hôm nay có thể được tìm thấy trong kho GitHub và các tệp thực thi của chương trình được đăng ở đây .

Ngăn xếp được sử dụng

Java 9+

java --version jlink --version

Maven

mvn --version

NodeJS

npx --version

Bước 1: Biên dịch và đóng gói mã của bạn vào một cái lọ

Chương trình cơ bản này sẽ tạo một cửa sổ đơn giản có văn bản mà bạn có thể thay đổi bằng cách nhấp vào một trong các nút trong giao diện.
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);
    }
}
Nghỉ giải lao #148.  Cách biến bất kỳ chương trình Java nào thành tệp EXE độc lập - 2Mục tiêu của chúng tôi bây giờ là đóng gói mã cùng với các phần phụ thuộc của nó vào một cái lọ. Tệp JAR là tệp lưu trữ ZIP thông thường có ít cấu trúc bổ sung. Đối với dự án Maven , cấu hình sẽ như thế này.
<?xml version="1.0" mã hóa="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>ví dụ</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> <dependency> <dependency> <groupId> org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.9</version> </dependency> </dependency> <build> <plugins> <plugin> <groupId>org.apache .maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <phase>gói</phase> <goals> <goal> shade</goal> </goals> <configuration> <transformers> <transformer performance="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>example.Main</Main- Lớp> <Build-Number>1.0</Build-Number> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </dự án>
Ở đây, plugin “bóng râm” sẽ xử lý việc bao gồm mã từ tất cả các phần phụ thuộc của bạn vào jar. Trong trường hợp này, phần phụ thuộc bên ngoài duy nhất là org.apache.commons/commons-text .
gói sạch mvn
Sau đó, chúng tôi sẽ di chuyển tệp jar này sang một thư mục target/ mới , nơi nó sẽ được tách biệt khỏi các tệp khác.
mkdir build mv target/javaexe-1.0.jar build

Bước 2: Tạo Môi trường chạy thi hành Java (JRE)

Để chạy tệp jar mà chúng ta đã tạo, chúng ta cần liên kết nó với môi trường thời gian chạy Java. Đối với điều này, chúng tôi sẽ sử dụng jlink . Vì hệ sinh thái Java không sử dụng các mô-đun nên có thể bạn chưa từng nghe đến chúng hoặc chưa từng sử dụng jlink. Nói tóm lại, jlink có thể tạo ra “hình ảnh thực thi tùy chỉnh”. Ví dụ: bạn đang tạo một máy chủ web. Bạn không cần AWT hoặc Swing, vì vậy việc đưa chúng vào mã của bạn sẽ không cần thiết. Với jlink, bạn có thể tạo một JRE hoàn toàn không bao gồm mô-đun java.desktop . Hệ thống này hoạt động tốt nhất nếu ứng dụng của bạn và tất cả các phần phụ thuộc của nó bao gồm các tệp module-info.java đã biên dịch , cho jlink biết chính xác những mô-đun nào bạn muốn đưa vào. Bạn cũng có thể xác định thủ công danh sách các mô-đun cần thiết bằng cách sử dụng jdeps . Và ngay cả khi không có dự án mô-đun, chúng tôi vẫn có thể sao chép cài đặt Java của mình vào một thư mục một cách hiệu quả bằng cách sử dụng jlink.
jlink --add-modules ALL-MODULE-PATH --output build/runtime
Việc bao gồm từng mô-đun riêng lẻ sẽ đảm bảo rằng các thư viện như org.apache.commons/commons-text sẽ hoạt động như dự định. Chúng ta chỉ cần tìm ra mô-đun nào chúng ta cần.

Bước 3: Kết hợp Jar và JRE thành file thực thi

Có một tệp jar chứa mã và tất cả các phần phụ thuộc của nó, cũng như JRE, tất cả những gì còn lại là kết hợp chúng. Để làm điều này chúng ta cần làm như sau:
  1. Nén thư mục chứa JRE và jar của ứng dụng của bạn.
  2. Đính kèm tập lệnh sơ khai vào đầu tệp zip này, tập lệnh này sẽ trích xuất dữ liệu vào một thư mục tạm thời và chạy mã.
Có một thư viện JavaScript cho cái này được gọi là caxa . Mục đích của nó là biến các dự án NodeJS thành các tệp thực thi và nó cũng có thể đóng gói mọi cài đặt NodeJS trên hệ thống. May mắn thay, bạn có thể bỏ qua bước này bằng cách chỉ định cờ --no-include-node .
npx caxa \ --input build \ --output application \ --no-include-node \ -- ​​​ "{{caxa}}/runtime/bin/java" "-jar" "{{caxa}}/javaexe -1.0 .jar"
Điều này sẽ tạo ra một tập tin thực thi có tên là “ứng dụng”. Nếu bạn đang tạo nó cho Windows, thì bạn cần chỉ định “application.exe”. Khi tệp thực thi chạy, {{caxa}} sẽ được thay thế bằng thư mục tạm thời nơi tệp zip được triển khai. Xin lưu ý rằng khi tạo tệp thực thi, các cơ chế như ký mã và cập nhật tự động cũng được sử dụng. Tuy nhiên, những điều này đòi hỏi phải nghiên cứu sâu hơn, khó có thể gói gọn trong một ấn phẩm.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION