oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀

Home Page:https://www.graalvm.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

macOS: no awt in java.library.path

jkeys089 opened this issue · comments

ERROR: java.lang.UnsatisfiedLinkError: no awt in java.library.path when attempting to build a native image that depends on AWT on macOS.

Original issue reported at #2842

The parent issue has been resolved for both windows and linux but remains on macOS. Per @vjovanov, I'm creating a separate report to track this issue specifically for macOS since the parent issue has been closed.

You can follow instructions here in the meantime to use docker to build it and run it, and do a port forwarding so you can still access from the mac and continue development while this gets fixed. https://github.com/Karm/quarkus-quickstarts/blob/quarkus-awt/awt-graphics-rest-quickstart/src/main/docker/Dockerfile.native

I tried to compile a jetbrain compose app on Mac using the latest build GraalVM CE 22.0.0.2 and still have the same issue. The compilation was successful though. Any plans to fix this in the coming release?

Exception in thread "main" java.lang.UnsatisfiedLinkError: no awt in java.library.path
	at com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:132)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:47)
	at java.lang.Runtime.loadLibrary0(Runtime.java:818)
	at java.lang.System.loadLibrary(System.java:1989)
	at java.awt.Toolkit$2.run(Toolkit.java:1388)

@pejovica did the AWT for Windows so he can give a better estimate.

Is there any GraalVM-compatible way to read the clipboard on macOS since I cannot use java.awt.Toolkit ?

I am also experiencing this issue, and I hope it can be fixed

We plan to work on this in the near future using the same approach as we did for Windows (see #3084), so the main thing missing is support for dynamic linking of JDK libraries. Basically, we need the equivalent of #3085 but for macOS.

@pejovica One tricky problem with supporting AWT on Mac is that Cocoa requires the event loop (RunLoop in their lingo) to be started on the main thread. So JDK's libjli (Java Launch Interface) spawns another thread right away and runs JVM there, while parking the original thread in the run loop, i.e. does something like the following:

Main Thread                                        Spawned Thread
-----------                                        --------------
main() {
    if (!RunLoopStarted) {
        RunLoopStarted = true
        spawn new thread       ------------->      re-invoke main() here
        start RunLoop
    } else {
        // JVM startup routine
    }
}

I ported this logic to SVM some time ago. The result was a change to JavaMainWrapper which worked but was rather hack-like. If you are interested I can put up a PR with my changes for reference.

I also hit this issue today and would love to see it fixed. Do we have any rough idea of timings as to when it might be? Many thanks..

Were also experiencing this issue, hope this can be fixed soon.

Seeing this with 22.1.0

this issue still exists in the latest version.

in windows already resolved, right?
So in my opinion, it is easy to migrate the code to MacOS?

A major problem is that the whole AWT classes are missing. Even code which just needs some AWT classes, e.g., BufferedImage to do some offline image processing, can't be compiled with native-image. Such class usage is completely independent from the threading problem cited here. Even offline rendering into an image should not be affected as far as I know. But this is all impossible because the classes are just missing in the Mac.

@mipastgt indeed, i think i hit this by using java.awt.Color to parse a Hex color value.

@mipastgt Exactly this.

I was trying to compile a code that modifies and re-exports PDFs, requiring BufferedImage for raster images and Point2D for SVGs and vector fonts. Obviously my code is unable to compile to native executable. Never thought that the macOS version would lack such basic functionality.

That are exactly the problems that I had in mind. Many software makes use of AWT classes without actually trying to run an AWT application and thus cannot be compiled on the Mac.

FYI, Graalvm team recently announced its Community Roadmap. In its Native +Compiler tab, there's one ticket for improved AWT support, though unfortunately it's not prioritized for upcoming releases just yet.

As previously discussed, some of the classes in awt are in widespread use (e.g., BufferedImage or Point2D) for both raster and vector graphics. It'd be great if this part of the awt can be fixed first, but it seems unlikely to happen.

Bellsoft is providing that support already now.
https://bell-sw.com/announcements/2022/08/05/liberica-native-image-kit-22-2-0-and-21-3-3-builds-are-out/
See: Enhanced AWT/Swing support

Bellsoft is providing that support already now. https://bell-sw.com/announcements/2022/08/05/liberica-native-image-kit-22-2-0-and-21-3-3-builds-are-out/ See: Enhanced AWT/Swing support

@mipastgt They have no download option for ARM (M1) though...

Hope to see this resolved soon 🙂

They do have ARM support already. Have a look here: https://bell-sw.com/pages/downloads/native-image-kit/#/nik-22-17 There are tabs for x86 and arm.

@mipastgt You're absolutely right, don't know how I missed that. Must've been looking at the NIK 21 downloads.

@pejovica Just checking in here - is this issue blocked by #4921?

Still present in latest dev version of OpenJDK/LabJDK+GraalVM which does include a similar patch for linux (graalvm#487 (comment)) - I'm posting this so that debugging is easier for you.

I am seeing this on iOS as well on latest community edition of graalvm.

I just wanted to compile to native image a simple Swing application, so I followed https://www.graalvm.org/22.2/reference-manual/native-image/guides/use-native-image-maven-plugin/ guide and hit the exact same issue:

Exception in thread "main" java.lang.UnsatisfiedLinkError: No awt in java.library.path
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:136)
	at java.base@21/java.lang.ClassLoader.loadLibrary(ClassLoader.java:106)

with:

$ java -version
openjdk version "21" 2023-09-19
OpenJDK Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)
OpenJDK 64-Bit Server VM GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15, mixed mode, sharing)

Basically it seems it's impossible to get any Swing app compiled to native image as it heavily relies on java.awt.* (something as basic as java.awt.EventQueue or java.awt.Toolkit!)

Same issue with java 21 (graalvm edition), spring boot 3 and Gradle :(

After trying several Graals I was glad I stumbled upon this thread. I can confirm that the Bellsoft Liberica NIK 23..1.1 (OpenJDK 21) works for me (creating ASCIIArt).

After trying several Graals I was glad I stumbled upon this thread. I can confirm that the Bellsoft Liberica NIK 23..1.1 (OpenJDK 21) works for me (creating ASCIIArt).

I've tried using Bellsoft Liberica NIK on MacOS ARM, and it worked fine.

I'm just curious, I know that Bellsoft is a paid offering. Roughly how much does it cost, and how do they bill? Per end CPU? Per native build? Something else? Thanks.

Bellsoft Liberica NIK can be used freely. You only have to pay if you want support for it. https://bell-sw.com/support/#pricing

Oh, that's great to hear. Thanks for the quick reply! I have been blocked using vanilla Graal for a while and now will give Bellsoft a spin to see if it gets me unblocked. I'm assuming the metadata I recorded earlier via Graal works for the latter as well. (Reflection, JNI usage, etc.).

the bell-sw's native-image is working!
Does anyone know why? bell-sw rewrite and compile the native-image?

They did not rewrite it but added some missing parts and provide their own modified build of native-image and the supporting libs.

For me it is not, I'm using the last version Liberika 21.0.2, 23.1.2.r21-nik

java.lang.UnsatisfiedLinkError: No awt in java.library.path
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:136) ~[na:na]
	at java.base@21.0.1/java.lang.ClassLoader.loadLibrary(ClassLoader.java:106) ~[com.luvcard.card.CardApiApplication:na]
	at java.base@21.0.1/java.lang.Runtime.loadLibrary0(Runtime.java:916) ~[na:na]
	at java.base@21.0.1/java.lang.System.loadLibrary(System.java:2059) ~[na:na]
	at java.desktop@21.0.1/java.awt.image.ColorModel$1.run(ColorModel.java:211) ~[na:na]
	at java.desktop@21.0.1/java.awt.image.ColorModel$1.run(ColorModel.java:209) ~[na:na]
	at java.base@21.0.1/java.security.AccessController.executePrivileged(AccessController.java:129) ~[na:na]
	at java.base@21.0.1/java.security.AccessController.doPrivileged(AccessController.java:319) ~[na:na]
	at java.desktop@21.0.1/java.awt.image.ColorModel.loadLibraries(ColorModel.java:208) ~[com.luvcard.card.CardApiApplication:na]
	at java.desktop@21.0.1/java.awt.image.ColorModel.<clinit>(ColorModel.java:221) ~[com.luvcard.card.CardApiApplication:na]
	at java.desktop@21.0.1/java.awt.image.BufferedImage.<clinit>(BufferedImage.java:286) ~[com.luvcard.card.CardApiApplication:na]
	at com.google.zxing.client.j2se.MatrixToImageWriter.toBufferedImage(MatrixToImageWriter.java:63) ~[na:na]
	at com.google.zxing.client.j2se.MatrixToImageWriter.toBufferedImage(MatrixToImageWriter.java:50) ~[na:na]

Dear graalvm team, do you have any updates/plans regarding this issue? Thanks for letting us know.

By analysing the reports it looks like Bellsoft are linking awt statically. Why can't the graalvm team use a similar approach as Bellsoft? at least for now just to unblock a lot of users.