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. Nhấ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);
}
}
Mụ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:- Nén thư mục chứa JRE và jar của ứng dụng của bạn.
- Đí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ã.
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.
GO TO FULL VERSION