Description
AWT support in GraalVM native images does not work on macOS (Darwin). The entire AWT library handling mechanism is explicitly excluded from macOS via platform annotations and early-return guards in the native-image builder code.
On Linux, native-image successfully:
- Copies JDK shared libraries (
libawt.so, libfontmanager.so, etc.) next to the binary
- Creates shim libraries (
libjvm.so, libjava.so) for symbol resolution
- Exports required JNI symbols via
JNIRegistrationAWTSupport
On macOS, all three of these steps are completely skipped:
This means any Java application using java.awt, java.awt.image, javax.imageio, or java.awt.Graphics2D cannot be compiled to a working native image on macOS.
Reproducer
// AwtTest.java
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
public class AwtTest {
public static void main(String[] args) throws Exception {
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.setColor(Color.RED);
g.fillRect(0, 0, 100, 100);
g.dispose();
ImageIO.write(img, "PNG", new File("test.png"));
System.out.println("Success: wrote test.png");
}
}
Steps to reproduce
# Compile
javac AwtTest.java
# Collect reachability metadata
java -agentlib:native-image-agent=config-output-dir=ni-config AwtTest
# Build native image
native-image --no-fallback -H:ConfigurationFileDirectories=ni-config -Djava.awt.headless=true AwtTest
# Run — fails with UnsatisfiedLinkError
./awttest
Expected behavior
On Linux, the same steps produce a working binary with libawt.so and related libraries copied next to the executable. The macOS build should produce equivalent artifacts (libawt.dylib, etc.) or statically link the AWT libraries.
Actual behavior
The build completes without errors but produces no AWT library artifacts. At runtime:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: /path/to/graalvm/lib/libawt.dylib
The binary tries to load libawt.dylib from the JDK's lib/ directory (baked in at build time), which:
Analysis
The static archive files needed for static linking do exist in GraalVM's JDK:
$GRAALVM_HOME/lib/static/darwin-aarch64/
├── libawt.a
├── libawt_lwawt.a
├── libfontmanager.a
├── libfreetype.a
├── libjavajpeg.a
├── liblcms.a
├── libmlib_image.a
└── libosxapp.a
And the JNILibraryInitializer already knows how to handle awt, fontmanager, lcms, javajpeg, and mlib_image as statically linked libraries. The infrastructure appears to be in place — it's just not wired up for macOS.
A custom Feature class cannot work around this because the required SVM APIs (NativeLibrarySupport, PlatformNativeLibrarySupport, NativeLibraries) are in the org.graalvm.nativeimage.builder module which does not export com.oracle.svm.core.jdk or com.oracle.svm.hosted.c to user code.
Environment
- GraalVM: Oracle GraalVM 25.0.2+10.1 (build 25.0.2+10-LTS-jvmci-b01)
- OS: macOS 15.4 (Darwin 25.3.0, arm64)
- Architecture: Apple Silicon (aarch64)
Related Issues
Description
AWT support in GraalVM native images does not work on macOS (Darwin). The entire AWT library handling mechanism is explicitly excluded from macOS via platform annotations and early-return guards in the native-image builder code.
On Linux, native-image successfully:
libawt.so,libfontmanager.so, etc.) next to the binarylibjvm.so,libjava.so) for symbol resolutionJNIRegistrationAWTSupportOn macOS, all three of these steps are completely skipped:
JNIRegistrationAWTSupportis annotated with@Platforms({Platform.WINDOWS.class, Platform.LINUX.class}), excluding Darwin entirelyJNIRegistrationSupport.afterImageWrite()hasif (isDarwin()) { return; }, which skips both library copying and shim creationThis means any Java application using
java.awt,java.awt.image,javax.imageio, orjava.awt.Graphics2Dcannot be compiled to a working native image on macOS.Reproducer
Steps to reproduce
Expected behavior
On Linux, the same steps produce a working binary with
libawt.soand related libraries copied next to the executable. The macOS build should produce equivalent artifacts (libawt.dylib, etc.) or statically link the AWT libraries.Actual behavior
The build completes without errors but produces no AWT library artifacts. At runtime:
The binary tries to load
libawt.dylibfrom the JDK'slib/directory (baked in at build time), which:libawt.dylib'sJNI_OnLoadcalls HotSpot-specific functions incompatible with SubstrateVM (see macOS Native Image libawt fails to load due to JNU_NewStringPlatform failure #8475)Analysis
The static archive files needed for static linking do exist in GraalVM's JDK:
And the
JNILibraryInitializeralready knows how to handleawt,fontmanager,lcms,javajpeg, andmlib_imageas statically linked libraries. The infrastructure appears to be in place — it's just not wired up for macOS.A custom
Featureclass cannot work around this because the required SVM APIs (NativeLibrarySupport,PlatformNativeLibrarySupport,NativeLibraries) are in theorg.graalvm.nativeimage.buildermodule which does not exportcom.oracle.svm.core.jdkorcom.oracle.svm.hosted.cto user code.Environment
Related Issues
libawtJNI_OnLoadfailure (same root cause, narrower scope)UnsatisfiedLinkError(Linux, open since 2020)