Could not load library libgtk-4.so.1 #324

Closed
opened 2026-01-20 02:45:54 +01:00 by OutCraft-Mods · 10 comments
OutCraft-Mods commented 2026-01-20 02:45:54 +01:00 (Migrated from github.com)

I'm trying to run the example in https://java-gi.org/usage/, but I'm getting the following exception:

Exception in thread "main" java.lang.ExceptionInInitializerError
	at org.gnome.gtk.Application.<clinit>(Application.java:133)
	at com.example.GtkGuiTest.<init>(GtkGuiTest.java:23)
	at com.example.GtkGuiTest.main(GtkGuiTest.java:11)
Caused by: org.javagi.interop.InteropException: Could not load library libgtk-4.so.1
	at org.javagi.interop.LibLoad.loadLibrary(LibLoad.java:156)
	at org.javagi.interop.Interop.loadLibrary(Interop.java:71)
	at org.gnome.gtk.Gtk.<clinit>(Gtk.java:742)
	... 3 more
	Suppressed: java.lang.IllegalArgumentException: Cannot open library: libgtk-4.so.1
		at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:348)
		at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:299)
		at org.javagi.interop.LibLoad.loadLibrary(LibLoad.java:161)
		... 5 more
	Suppressed: java.lang.IllegalArgumentException: Cannot open library: /home/<stuff_here>/_libs/libgtk-4.so.1
		at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:348)
		at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:333)
		at org.javagi.interop.LibLoad.loadLibrary(LibLoad.java:195)
		... 5 more

I'm using -Djava.library.path=/home/<stuff_here>/_libs and the folder _libs contains libgtk-4.so.1.
I can even successfully read its contents using this code:

Path path = Path.of("/home/<stuff_here>/_libs/libgtk-4.so.1");
try {
	System.out.println(Arrays.toString(Files.readAllBytes(path)));
} catch (Exception e) {
	throw new RuntimeException(e);
}

correctly outputs 10908688 bytes, and libgtk-4.so.1 is 10,9 MB.

What might be my issue?

I'm trying to run the example in https://java-gi.org/usage/, but I'm getting the following exception: ``` Exception in thread "main" java.lang.ExceptionInInitializerError at org.gnome.gtk.Application.<clinit>(Application.java:133) at com.example.GtkGuiTest.<init>(GtkGuiTest.java:23) at com.example.GtkGuiTest.main(GtkGuiTest.java:11) Caused by: org.javagi.interop.InteropException: Could not load library libgtk-4.so.1 at org.javagi.interop.LibLoad.loadLibrary(LibLoad.java:156) at org.javagi.interop.Interop.loadLibrary(Interop.java:71) at org.gnome.gtk.Gtk.<clinit>(Gtk.java:742) ... 3 more Suppressed: java.lang.IllegalArgumentException: Cannot open library: libgtk-4.so.1 at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:348) at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:299) at org.javagi.interop.LibLoad.loadLibrary(LibLoad.java:161) ... 5 more Suppressed: java.lang.IllegalArgumentException: Cannot open library: /home/<stuff_here>/_libs/libgtk-4.so.1 at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:348) at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:333) at org.javagi.interop.LibLoad.loadLibrary(LibLoad.java:195) ... 5 more ``` I'm using `-Djava.library.path=/home/<stuff_here>/_libs` and the folder `_libs` contains `libgtk-4.so.1`. I can even successfully read its contents using this code: ```java Path path = Path.of("/home/<stuff_here>/_libs/libgtk-4.so.1"); try { System.out.println(Arrays.toString(Files.readAllBytes(path))); } catch (Exception e) { throw new RuntimeException(e); } ``` correctly outputs `10908688` bytes, and `libgtk-4.so.1` is 10,9 MB. What might be my issue?
jwharm commented 2026-01-20 20:06:02 +01:00 (Migrated from github.com)

Thank you for trying out Java-GI!

Gtk is much more than just the file libgtk-4.so.1. How did you install Gtk in this location? If you just copied this file, it will not work.

If you’re sure that Gtk is installed correctly (for example, gtk4-demo runs fine), then try running your app with the environment variable LD_DEBUG=libs set. It will print detailed logging from the dynamic linker that will help you find the cause.

Thank you for trying out Java-GI! Gtk is much more than just the file `libgtk-4.so.1`. How did you install Gtk in this location? If you just copied this file, it will not work. If you’re sure that Gtk is installed correctly (for example, `gtk4-demo` runs fine), then try running your app with the environment variable `LD_DEBUG=libs` set. It will print detailed logging from the dynamic linker that will help you find the cause.
OutCraft-Mods commented 2026-01-20 22:48:32 +01:00 (Migrated from github.com)

My IDE is installed via flatpak and doesn't have access to /usr/lib64, so I copied the folder to a location the IDE can access (_libs).
What files does Java-GI need to work?

My IDE is installed via flatpak and doesn't have access to `/usr/lib64`, so I copied the folder to a location the IDE can access (`_libs`). What files does Java-GI need to work?
OutCraft-Mods commented 2026-01-20 22:50:55 +01:00 (Migrated from github.com)

Also, I just want to mention that I know a lot about Java but absolutely nothing about system libraries, so sorry if that question seems stupid

Also, I just want to mention that I know a lot about Java but absolutely nothing about system libraries, so sorry if that question seems stupid
jwharm commented 2026-01-21 08:04:17 +01:00 (Migrated from github.com)

That's never going to work. GTK is far too complicated to get it working by manually copying files.
I am afraid you will have to install the IDE in another way.

That's never going to work. GTK is far too complicated to get it working by manually copying files. I am afraid you will have to install the IDE in another way.
OutCraft-Mods commented 2026-01-21 20:01:11 +01:00 (Migrated from github.com)

How exactly does it work when an app bundles gtk? Doesn't it include the .so files and could I do something similar to that?

How exactly does it work when an app bundles gtk? Doesn't it include the `.so` files and could I do something similar to that?
jwharm commented 2026-01-21 20:33:28 +01:00 (Migrated from github.com)

It's not really necessary to bundle Gtk on most Linux systems, because it's usually preinstalled. A flatpak app would use the GNOME runtime; you can see how that works in combination with java-gi in here. You can edit that project in a flatpak-installed IDE, but you can't run it from the IDE. (As a workaround, you could build and run the flatpak every time, but it's not a nice workflow.)

On Windows, all Gtk libraries and executables, including its dependencies, can be installed in one place, so it's relatively easy to bundle it. You can download the necessary files here.

I'm not sure about how this all works on macOS.

My advice is to build your app in an IDE that can use your system's Gtk libraries, so you can build and run your app directly from the IDE. Alternatively, you can install the IDE and Gtk in a Distrobox container; that's what I do.
For distribution, you can use the app-template I linked above, to create a flatpak based on the GNOME runtime.

It's not really necessary to bundle Gtk on most Linux systems, because it's usually preinstalled. A flatpak app would use the GNOME runtime; you can see how that works in combination with java-gi in [here](https://github.com/jwharm/java-gi-app-template). You can edit that project in a flatpak-installed IDE, but you can't run it from the IDE. (As a workaround, you could build and run the flatpak every time, but it's not a nice workflow.) On Windows, all Gtk libraries and executables, including its dependencies, can be installed in one place, so it's relatively easy to bundle it. You can download the necessary files [here](https://github.com/jwharm/java-gi/releases/tag/libraries). I'm not sure about how this all works on macOS. My advice is to build your app in an IDE that can use your system's Gtk libraries, so you can build and run your app directly from the IDE. Alternatively, you can install the IDE and Gtk in a Distrobox container; that's what I do. For distribution, you can use the app-template I linked above, to create a flatpak based on the GNOME runtime.
OutCraft-Mods commented 2026-01-21 23:25:24 +01:00 (Migrated from github.com)

Thanks for all the useful information!

I've solved the problem by letting my IDE talk to org.freedesktop.Flatpak and using this gradle task I made:

tasks.register<Exec>("runWithFlatpakSpawn") {
    dependsOn(tasks.build)

    group = "application"
    description = "Runs the application using Flatpak spawn."

    val javaPath = "path/to/jdk";
    val mainClass = "com.example.GradleGtkTest" // Replace with your main class

    var classpath = configurations.runtimeClasspath.get().joinToString(":") {
        it.absolutePath.replace("/.gradle/", "/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/")
    }

    classpath = rootProject.layout.buildDirectory.get().dir("classes/java/main").toString() + ":" + classpath;

    commandLine(
        "flatpak-spawn",
        "--host",
        "$javaPath/bin/java",
        "--enable-native-access=ALL-UNNAMED",
        "-classpath",
        classpath,
        mainClass
    )
}

Using this I can spawn java outside of the sandbox, while retaining all the benefits of a sandboxed IDE. It's probably not the best solution, but it works. I'll also make sure to look at your template for creating Flatpak apps.

Thanks for all the help!

Thanks for all the useful information! I've solved the problem by letting my IDE talk to `org.freedesktop.Flatpak` and using this gradle task I made: ```kotlin tasks.register<Exec>("runWithFlatpakSpawn") { dependsOn(tasks.build) group = "application" description = "Runs the application using Flatpak spawn." val javaPath = "path/to/jdk"; val mainClass = "com.example.GradleGtkTest" // Replace with your main class var classpath = configurations.runtimeClasspath.get().joinToString(":") { it.absolutePath.replace("/.gradle/", "/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/") } classpath = rootProject.layout.buildDirectory.get().dir("classes/java/main").toString() + ":" + classpath; commandLine( "flatpak-spawn", "--host", "$javaPath/bin/java", "--enable-native-access=ALL-UNNAMED", "-classpath", classpath, mainClass ) } ``` Using this I can spawn java outside of the sandbox, while retaining all the benefits of a sandboxed IDE. It's probably not the best solution, but it works. I'll also make sure to look at your template for creating Flatpak apps. Thanks for all the help!
Ombrelin commented 2026-02-09 21:17:23 +01:00 (Migrated from github.com)

Hi @OutCraft-Mods,
I'm in the same situation as you, and I tried to adapt your solution to my setup, but I struggle. Currently, I have successfully enabled access to flatpak-spawn, and my JDK, but it's not finding my main class.

I suspect it's because of the following line not correctly configured for my setup :

        it.absolutePath.replace("/.gradle/", "/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/")

Could you elaborate on how you came up with it, so I can maybe adapt it to my setup which might be a bit different ?

Thanks a lot in advance 🙏

Hi @OutCraft-Mods, I'm in the same situation as you, and I tried to adapt your solution to my setup, but I struggle. Currently, I have successfully enabled access to flatpak-spawn, and my JDK, but it's not finding my main class. I suspect it's because of the following line not correctly configured for my setup : ``` it.absolutePath.replace("/.gradle/", "/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/") ``` Could you elaborate on how you came up with it, so I can maybe adapt it to my setup which might be a bit different ? Thanks a lot in advance 🙏
OutCraft-Mods commented 2026-02-09 21:24:17 +01:00 (Migrated from github.com)

Hi Ombrelin, if you're getting issues with this line, you should check where your .gradle directory is located. My IDE saves it in ~/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/, so I'm replacing the path with it.

Do you know where your gradle directory is stored? If not, I'd recommend simply searching for "gradle" from your home directory.

I hope I could help!

Hi Ombrelin, if you're getting issues with this line, you should check where your `.gradle` directory is located. My IDE saves it in `~/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/`, so I'm replacing the path with it. Do you know where your gradle directory is stored? If not, I'd recommend simply searching for "gradle" from your home directory. I hope I could help!
Ombrelin commented 2026-02-13 10:31:12 +01:00 (Migrated from github.com)

Hi @OutCraft-Mods , thanks a lot for your answer.
Indeed I have no ~/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/, I just get a ~/.gradle when running the search you suggest, which I'm not sure is the right directory 🤔 because it doesn't feel related to my flatpak IntelliJ (I have a /home/arsene/.var/app/com.jetbrains.IntelliJ-IDEA-Community though, but it contains no .gradle)

Hi @OutCraft-Mods , thanks a lot for your answer. Indeed I have no `~/.var/app/com.jetbrains.IntelliJ-IDEA-Community/.gradle/`, I just get a `~/.gradle` when running the search you suggest, which I'm not sure is the right directory 🤔 because it doesn't feel related to my flatpak IntelliJ (I have a `/home/arsene/.var/app/com.jetbrains.IntelliJ-IDEA-Community` though, but it contains no `.gradle`)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
java-gi/java-gi#324
No description provided.