Hi,
I almost there with my snapification, looks like last problem to solve:
Snapified java 8 application doesn’t open requested file
minimal java to reproduce problem:
import java.awt.*;import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
Desktop.getDesktop().open(new File("existing filet")); }
}
file that should be opened by Document Viewer (Evince in my case) ~/snap/e-mikrofirma/common/AKMF/emikrofirma/temp_15_132099972430572.pdf (or any other in user home dir)
I know it works to get web links to open but I’m unsure if it has the same effect on files, my temptation is to say you might need to use a system call to xdg-open with the file location which should work fine but might require you to do a conditional to check if you’re in a snap environment in the Java itself.
Incidentally, xdg-open would work on web links too, so depending on where you’re deploying the app, you might just want to prefer it on Linux over Java’s own function anyway, since Java’s own function wouldn’t work reliably on say Arch Linux where GVFS isn’t a preinstalled package if they weren’t using the Snap.
Edit:
I’ve been looking further into this today. Adding GVFS adding it to the LD_LIBRARY_PATH has some influence if you’re using the GTK2 Snapcraft Desktop Helpers, but doesn’t seem to work with the GTK3 Snapcraft Extensions. This seems to be because Java checks for some GTK2 and I’m not exactly sure the interplay between the various Gnome components.
I would still overall recommend considering using xdg-open directly, in Snap, it’s wrapped around desktop portals and should be far more reliable in general for confined applications.
Unfortunatly the recipe doesn’t help and app modification isn’t an option
After adding GVFS I got an exception:
java.io.IOException: Failed to show URI:file:/home/myuser/snap/emikrofirma/common/AKMF/emikrofirma/temp_12_158094824738822.pdf
at sun.awt.X11.XDesktopPeer.launch(XDesktopPeer.java:123) ~[?:1.8.0_265]
at sun.awt.X11.XDesktopPeer.open(XDesktopPeer.java:86) ~[?:1.8.0_265]
at java.awt.Desktop.open(Desktop.java:269) ~[?:1.8.0_265]
at a.a.a.c.c.d.h.EPF$1.HZI(Unknown Source) [?:1.3.0.10]
at a.a.a.c.e.a.a.EVN.run(Unknown Source) [MicroLauncher.lib:1.3.0.10]
and I got this on start:
Gtk-Message: 23:20:43.953: Failed to load module "gail"
Gtk-Message: 23:20:43.953: Failed to load module "atk-bridge"
Gtk-Message: 23:20:43.983: Failed to load module "canberra-gtk-module"
If app modification isn’t an option, I think the options essentially become recompiling Java itself so you can patch the need for gnome_url_show, or using LD_PRELOAD with a custom .so designed to emulate gnome_url_show (and potentially the other GTK2 symbols) and pass it onto xdg-open.
From what I’ve seen older versions of Java have some ability to replace system classes that the newer versions don’t have, and whilst editing the apps bytecode itself is possible too, it’s not exactly elegant and only works on singular apps.
I can try dedicate some time soon into the LD_PRELOAD route since it effects me as well and presumably all Java snaps.
I wouldn’t worry about the Gtk-Messages at the end there, they’re common place in a lot of Snaps and are noise you can avoid worrying about in 99% of scenarios.
I’ve worked on the LD_PRELOAD route anyway and it works for me as long as you’re using GTK2 exclusively. From the error output above, this might be able to help you.
I’ve not been able to get this to work in GTK3 and think overall this is something better done at either the GVFS/GIO or Java level itself, but I can confirm that the example Java code above works with this patch setup.
TLDR: setting GTK_USE_PORTAL=1 in the environment will probably get your application to work.
The gnome_url_show function mentioned here ends up calling GTK’s gtk_show_uri, which in turn calls GIO’s g_app_info_launch_default_for_uri:
This uses the freedesktop.org mime-apps spec to determine what application to launch. Inside the snap sandbox there is no application registered to handle PDF files, so the open fails.
There is a way to get this to work though if we enable GTK/GLib’s xdg-desktop-portal support. This is not currently enabled by default for snap applications, but can be done by setting the GTK_USE_PORTAL environment variable. In this mode, if g_app_info_launch_default_for_uri cannot find a handler for the given file or URI, it will ask the xdg-desktop-portal D-Bus service to open the file on its behalf outside of the sandbox.
This of course requires that xdg-desktop-portal be installed on the user’s system, but that is fairly common these days.
I tried export GTK_USE_PORTAL=1 with Java 11, with both GTK2 Snapcraft Desktop Helpers, and GTK3 with the gnome-3-28 extension.
In GTK2 the flag has no effect as you’d probably expect. In GTK3, the variable has no percievable effect, but that’s because both with and without the variable, GTK2 and GTK3 conflicts happen in the terminal complaining their symbols can’t occupy the same address space.
If I had to guess, it’s as a result of upstream Java code here:
Is this something that you think is resolvable without recompiling Java? There’s no GTK2/GTK3 crossover outside the confinement, so my niave assumption is that the extension does something that interferes in this specific context, but I’m not knowledgable enough to say what.
The gnomevfs-2 library is an ancient GNOME 1.x library, which was obsolete in 2008. This is what preceded GIO/GVFS, so if you’re hitting that code path, something has gone terribly wrong.
It’s the GTK 2/3 code path that it should be hitting, in which case it’s the gtk_show_uri method that should matter. For both GTK 2 and GTK 3, these call through to GLib’s g_app_info_launch_default_for_uri:
One thing I notice from your YAML is that you include both the Snapcraft GLIB part and also the Gnome 3-34 extension. This is generally undefined behaviour and something that might introduce some subtle behavioural differences. This is because both the GLib helper and Gnome extension have a desktop-launch script, and you’re effectively calling it twice and potentially ambiguously to which actual one is being called. They’re designed to be used exclusively.
I can’t promise it’ll help anything here, but I would recommend removing the GLib part and the desktop-launch prefix in the command: line. You should hopefully not notice any major changes, but it might subtly change some behaviours including potentially what’s going on here. It’ll also likely give a speed boost of a second or two at launch.
The reason this works technically is because the Gnome extension will actually modify your YAML as it’s being interpretted, and calls desktop-launch itself prior to running the command anyway, via command-chain functionality.