Как лучше скомпилировать Swing приложение с AOT?

Ссылка скопирована
1 ответ

Скажем... Вот этот код?

// Hello.java import javax.swing.*; public class Hello { public static void main (String [] args) { JOptionPane.showMessageDialog ( null, "Hello world", "Dialog", JOptionPane.PLAIN_MESSAGE ); } }
А вот моя попытка

~/Documents/Projects/Hello $ javac Hello.java ~/Documents/Projects/Hello $ ls Hello.class Hello.class ~/Documents/Projects/Hello $ native-image Hello hello ================================================================================ GraalVM Native Image: Generating 'hello' (executable)... ================================================================================ [1/8] Initializing... (4.8s @ 0.08GB) Java version: 24.0.2+11, vendor version: Oracle GraalVM 24.0.2+11.1 Graal compiler: optimization level: 2, target machine: armv8.1-a, PGO: ML-inferred C compiler: cc (apple, arm64, 17.0.0) Garbage collector: Serial GC (max heap size: 80% of RAM) 1 user-specific feature(s): - com.oracle.svm.thirdparty.gson.GsonFeature -------------------------------------------------------------------------------- Build resources: - 6.05GB of memory (75.6% of 8.00GB system memory, determined at start) - 8 thread(s) (100.0% of 8 available processor(s), determined at start) [2/8] Performing analysis... [******] (10.6s @ 0.57GB) 5,334 reachable types (75.2% of 7,094 total) 8,391 reachable fields (51.4% of 16,339 total) 29,730 reachable methods (52.6% of 56,478 total) 1,607 types, 11 fields, and 198 methods registered for reflection 59 types, 58 fields, and 53 methods registered for JNI access 4 native libraries: -framework Foundation, dl, pthread, z [3/8] Building universe... (1.7s @ 0.57GB) [4/8] Parsing methods... [**] (4.1s @ 0.65GB) [5/8] Inlining methods... [***] (0.8s @ 0.74GB) [6/8] Compiling methods... [*****] (26.9s @ 0.78GB) [7/8] Laying out methods... [**] (2.3s @ 0.89GB) [8/8] Creating image... [*] (1.8s @ 1.01GB) 14.40MB (56.68%) for code area: 15,560 compilation units 10.50MB (41.33%) for image heap: 153,800 objects and 55 resources 518.29kB ( 1.99%) for other data 25.41MB in total -------------------------------------------------------------------------------- Top 10 origins of code area: Top 10 object types in image heap: 6.24MB java.desktop 3.48MB byte[] for code metadata 5.33MB java.base 1.90MB byte[] for java.lang.String 2.27MB svm.jar (Native Image) 1.16MB java.lang.String 161.56kB java.logging 1004.72kB java.lang.Class 120.13kB com.oracle.svm.svm_enterprise 289.38kB byte[] for reflection metadata 69.91kB java.prefs 288.41kB byte[] for general heap data 30.61kB org.graalvm.nativeimage.base 250.03kB c.o.s.c.h.DynamicHubCompanion 22.43kB jdk.graal.compiler 241.34kB java.util.HashMap$Node 21.75kB org.graalvm.collections 219.95kB char[] 15.64kB jdk.internal.vm.ci 171.41kB byte[] for embedded resources 38.13kB for 6 more packages 1.55MB for 1212 more object types Use '--emit build-report' to create a report with more details. -------------------------------------------------------------------------------- Security report: - Binary includes Java deserialization. - Use '--enable-sbom' to assemble a Software Bill of Materials (SBOM). -------------------------------------------------------------------------------- Recommendations: PGO: Use Profile-Guided Optimizations ('--pgo') for improved throughput. AWT: Use the tracing agent to collect metadata for AWT. HEAP: Set max heap for improved and more predictable memory usage. CPU: Enable more CPU features with '-march=native' for improved performance. QBM: Use the quick build mode ('-Ob') to speed up builds during development. -------------------------------------------------------------------------------- 4.2s (7.7% of total time) in 1779 GCs | Peak RSS: 1.87GB | CPU load: 6.23 -------------------------------------------------------------------------------- Build artifacts: /Users/elisey/Documents/Projects/Hello/hello (executable) ================================================================================ Finished generating 'hello' in 53.9s. ~/Documents/Projects/Hello $ hello Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: awt | java.library.path = [.] at org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk.NativeLibraries.loadLibraryRelative(NativeLibraries.java:141) at java.base@24.0.2/java.lang.ClassLoader.loadLibrary(ClassLoader.java:100) at java.base@24.0.2/java.lang.Runtime.loadLibrary0(Runtime.java:822) at java.base@24.0.2/java.lang.System.loadLibrary(System.java:1663) at java.desktop@24.0.2/java.awt.Toolkit.loadLibraries(Toolkit.java:1293) at java.desktop@24.0.2/java.awt.Toolkit.initStatic(Toolkit.java:1318) at java.desktop@24.0.2/java.awt.Toolkit.<clinit>(Toolkit.java:1299) at java.desktop@24.0.2/java.awt.Component.<clinit>(Component.java:614) at java.base@24.0.2/java.lang.Class.ensureInitialized(DynamicHub.java:658) at java.base@24.0.2/java.lang.Class.ensureInitialized(DynamicHub.java:658) at java.base@24.0.2/java.lang.Class.ensureInitialized(DynamicHub.java:658) at Hello.main(Hello.java:9) at java.base@24.0.2/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Backend-редакция Ответ

Swing-приложение можно скомпилировать в native/AOT не любым Java-компилятором. Обычный javac создаёт bytecode, который запускается JVM. Для настоящего native binary чаще всего используют GraalVM Native Image. Но у Swing есть важное ограничение: AWT/Swing поддерживаются не во всех режимах и платформах одинаково, а нативная сборка GUI-приложений может потребовать дополнительных настроек.

Примерный путь с GraalVM:

javac Hello.java
native-image --enable-url-protocols=http,https Hello

javac Hello.java native-image --enable-url-protocols=http,https Hello

Но для Swing простого native-image часто недостаточно. Нужно использовать GraalVM, где поддержка AWT доступна для вашей платформы, и учитывать, что приложение всё равно зависит от системных GUI-библиотек.

Для вашего примера:

import javax.swing.*;
 
public class Hello {
    public static void main(String[] args) {
        JOptionPane.showMessageDialog(
            null,
            "Hello world",
            "Dialog",
            JOptionPane.PLAIN_MESSAGE
        );
    }
}

import javax.swing.*; public class Hello { public static void main(String[] args) { JOptionPane.showMessageDialog( null, "Hello world", "Dialog", JOptionPane.PLAIN_MESSAGE ); } }

Сначала проверьте обычную сборку:

javac Hello.java
java Hello

javac Hello.java java Hello

Потом пробуйте GraalVM Native Image. Если получите ошибки по AWT, reflection или unsupported features, это не проблема кода, а ограничение native-image для конкретной GUI-части.

Если цель - просто распространять приложение без установки Java пользователем, часто лучше использовать jpackage, а не AOT:

jpackage --input . --main-jar app.jar --main-class Hello --name HelloApp

jpackage --input . --main-jar app.jar --main-class Hello --name HelloApp

jpackage создаст установщик/пакет с bundled runtime. Размер будет больше, зато совместимость Swing будет намного выше. Для Swing я бы выбирал так: для эксперимента - GraalVM Native Image, для реального распространения - jpackage. Полный AOT для GUI на Java возможен, но не всегда экономит время и нервы.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно