Remapping .local/share/applicationname to inside the snap

Hi there,

I’m trying to snap OpenRefine and have found solutions to most issues so far (e.g. the dangling symlink warning when using default-jre, by removing the symlinks afterwards), but struggle with this now: The application uses the folder $HOME/local/share/openrefine as temporary storage, and I would want to map this inside the $SNAP_DATA directory. It seems this doesn’t work with the layouts feature, because paths under /home are not supported. Is there another way to fix this?

Link to snapcraft.yaml

Snaps modify the $HOME variable by default, but some apps will look at /etc/passwd directly to get a value for the home directory. The usual fix for this is to try the snapcraft-preload library.

However in the case of Java, I’d first recommend trying to pass -Duser.home="${SNAP_DATA}" to your java parameter. If you can’t pass it directly, set it as an environment variable, e.g:

environment:
      _JAVA_OPTIONS: -Duser.home="${SNAP_DATA}"

Regarding the dangling symlink, you possibly fix it in a different way to processing it manually; try adding ca-certificates-java to your build-packages, it’s a rather unique case that this will actually effect the runtime environment (by replacing the symlink with the actual content it points to, rather than having to remove it).

Thanks! Your suggestion with the certificates, worked perfectly. But on the directory problem, I now get this error:

java.io.FileNotFoundException: /var/snap/openrefine/x1/.local/share/openrefine/workspace.temp.json (No such file or directory)

This happens after these messages:

Creating new workspace directory /var/snap/openrefine/x1/.local/share/openrefine (291ms)
FAILED to create new workspace directory /var/snap/openrefine/x1/.local/share/openrefine (1ms)

Maybe because the openrefine folder path wasn’t created beforehand?

Also is there a solution to using the Java Desktop Integration to open a Browser window?

Java Desktop class not supported on this platform. Please open %s in your browser Sorry, some error prevented us from launching the browser for you.

My guess that using the Gnome Extension may fix it, but this would be a huge inclusion, for a technically “non-desktop” app.

$SNAP_DATA is owned by root, it’s usually used if the application is a system daemon. While you can use it to also store data that might be sharable by all users on the system, my guess here is you likely actually meant $SNAP_USER_DATA (which would point to $HOME/snap/...). If you did genuinely mean $SNAP_DATA, you’d have to set up the permissions on the folder properly in advance (via hooks, such as the install hook).

I do personally have a fix for the web browser issue with Java applications, though I don’t think there’s a standardised approach for it. In Flathub, they rebuild the entire JVM to incorporate a patch for it. Personally, I take advantage of the Java Modules system to replace the class file that’s responsible for the Linux integration so that it works better with Snaps.

Take a look here and download the patch + source (Java’s GPL, sorry, I’d very much recommend bundling both in your snap just to satisfy the license requirements). It’s very important that the class file in compiled/java.desktop/sun/awt/X11 stays in a folder with the path of compiled/java.desktop/sun/awt/X11, it’s how Java is going to know what to replace. Also, this is built for Ubuntu’s OpenJDK 11 (default-jre on core20), I have’t tested if it’d work on different Java versions.

Once it’s in your snap image, you can make Java use it with --patch-module java.desktop=$SNAP/java-patches/compiled/java.desktop (so basically, it’s important that java.desktop is part of the path, but the leading path doesn’t matter).

The advantage of doing it with the module system is that if there’s any patches to Java in the future, you don’t have to recompile Java everytime, just rebuild your snap and the patch should keep going.

The Gnome Extensions wouldn’t have fixed this issue, but you could still consider using them anyway. You can eliminate a lot of the bloat they add with a cleanup part, which would look something like

cleanup:
    plugin: nil
    build-snaps:
      - core20
      - gnome-3-38-2004
    override-prime: |
      set -eux
      for snap in "core20" "gnome-3-38-2004"; do
          cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \;
      done
    after: [my_part_1, my_part_2, etc]

This way you benefit from the advantages of the extension yet eliminate the majority of the downside of the file size inflation. ( Admiteddly the benefits might not be great for what’s effectively a browser based environment )

1 Like

You were 100% correct about $SNAP_USER_DATA, thanks! I’m gonna try your suggestion about the java desktop integration, but will mark the original question as resolved. Your answers were insightful and a great explanation!

Thanks again for your answer, but while I tried looking at your runescape snap for how you integrate Java desktop, I still didn’t quite where you use the patch command etc. Do you have any hints where I should put that? Maybe as part of the env in the snapcraft.yaml file? The original code also falls back automatically to xdg-open, is there a way to use that to open the browser?

Also I can’t seem to get the .desktop file to work, at least it doesn’t show up in the applications folders…

Link to snap folder.

It’s this the final line here.

Given the complexity of the init script, it’s likely still easier for you to also append this to the _JAVA_OPTIONS environment variable you’re currently using, possibly:

_JAVA_OPTIONS: -Duser.home="${SNAP_USER_DATA}" --patch-module java.desktop=$SNAP/java-patches/compiled/java.desktop

Looking at Openrefine’s code, if the JVM claims it can open links, then it never attempts to use the fallback; so what’s likely happening is that the JVM does claim that it can open the link, but fails to actually do it. Openrefine then doesn’t try using xdg-open at all, if it did, it’d actually work! I can’t see a fix for this that doesn’t involve changing Openrefines code (custom logic when the $SNAP variable is set), swapping out the JVM, or patching it with the module patch.

I can’t see a problem with your .desktop file at first glance, so I’d propose testing to make sure other snaps can set desktop files properly, just to ensure this isn’t an issue with e.g your environment variables being misconfigured and not picking up .desktop files made by snaps generally.

Looking at commit cf7decde you pushed earlier, you probably don’t want to include the xdg-utils stage-packages.

xdg-open is provided in the base snap, it’s a wrapper around snapctl. The version of xdg-open your pulling from the repos is the normal implementation and it won’t work in snaps. Depending on the relative priorities in the $PATH variable, you’re either just bundling unnecessary packages for no gain, or the normal implementation will override the version in the base snap and break things.

Best to just not include it if you’ve no other need :slight_smile: