OpenJFX app crashing because of Prism pipeline

My snap I’m developing is crashing on start due to what I think is the Prism pipeline trying to initialize graphics. I’m not sure what I’m missing so I’m posting my snapcraft.yaml and error output. Am I missing a interface? How should I try and debug the error? The snap works fine when installed with --devmode.

name: bisq-desktop
base: core18
version: 0.9.3
summary: Peer-to-peer exchange to trade various curriencies for bitcoin
description: |
  Cross-platform desktop application that allows users to trade national currency (dollars, euros, etc) for bitcoin without relying on centralized exchanges
confinement: strict
grade: stable
icon: icon.png

plugs:
  personal-files:
    write: [ $HOME/.local/share/Bisq, $HOME/.openjfx/cache/11 ]

apps:
  bisq-desktop:
    command: desktop-launch "$SNAP/opt/bisq/bin/bisq-desktop"
    plugs:
      - network
      - network-bind
      - desktop
      - desktop-legacy
      - x11
      - wayland
      - opengl
      - home
      - personal-files
    desktop: usr/share/applications/bisq.desktop
    environment:
      JAVA_HOME: "$SNAP/usr/lib/jvm/java-11-openjdk-amd64"

parts:
  bisq:
    plugin: gradle
    override-build: |
      ./gradlew build

      # Install executable.
      install -d "${SNAPCRAFT_PART_INSTALL}/opt/bisq"
      cp -r desktop/build/app/* "${SNAPCRAFT_PART_INSTALL}/opt/bisq"

      # Install desktop launcher icon
      install -Dm644 desktop/package/linux/icon.png "${SNAPCRAFT_PART_INSTALL}/usr/share/pixmaps/bisq.png"

    source: https://github.com/bisq-network/bisq-desktop.git
    source-tag: v0.9.3
    build-packages: [openjdk-11-jdk]
    stage-packages: [openjdk-11-jre]
    after: [desktop-gtk3]

  # Install desktop launcher
  desktop-file:
    plugin: dump
    source: .
    organize:
      'bisq.desktop': usr/share/applications/bisq.desktop
    after:
      - bisq

  desktop-gtk3:
    source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
    source-subdir: gtk
    plugin: make
    make-parameters: ["FLAVOR=gtk3"]
    build-packages:
      - libgtk-3-dev
    stage-packages:
      - libxkbcommon0  # XKB_CONFIG_ROOT
      - ttf-ubuntu-font-family
      - dmz-cursor-theme
      - light-themes
      - adwaita-icon-theme
      - gnome-themes-standard
      - shared-mime-info
      - libgtk-3-0
      - libgdk-pixbuf2.0-0
      - libglib2.0-bin
      - libgtk-3-bin
      - unity-gtk3-module
      - libappindicator3-1
      - locales-all
      - xdg-user-dirs
      - ibus-gtk3
      - libibus-1.0-5

# vim:tabstop=2 shiftwidth=2 expandtab

Error output:

Loading library prism_es2 from resource failed: java.lang.UnsatisfiedLinkError: /home/david/.openjfx/cache/11/libprism_es2.so: /home/david/.openjfx/cache/11/libprism_es2.so: failed to map segment from shared object
java.lang.UnsatisfiedLinkError: /home/david/.openjfx/cache/11/libprism_es2.so: /home/david/.openjfx/cache/11/libprism_es2.so: failed to map segment from shared object
	at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
	at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2424)
	at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2481)
	at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2678)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2611)
	at java.base/java.lang.Runtime.load0(Runtime.java:814)
	at java.base/java.lang.System.load(System.java:1838)
	at com.sun.glass.utils.NativeLibLoader.installLibraryFromResource(NativeLibLoader.java:205)
	at com.sun.glass.utils.NativeLibLoader.loadLibraryFromResource(NativeLibLoader.java:185)
	at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:157)
	at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:52)
	at com.sun.prism.es2.ES2Pipeline.lambda$static$0(ES2Pipeline.java:68)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at com.sun.prism.es2.ES2Pipeline.<clinit>(ES2Pipeline.java:50)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:291)
	at com.sun.prism.GraphicsPipeline.createPipeline(GraphicsPipeline.java:187)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:91)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
	at java.base/java.lang.Thread.run(Thread.java:844)
Loading library prism_sw from resource failed: java.lang.UnsatisfiedLinkError: /home/david/.openjfx/cache/11/libprism_sw.so: /home/david/.openjfx/cache/11/libprism_sw.so: failed to map segment from shared object
java.lang.UnsatisfiedLinkError: /home/david/.openjfx/cache/11/libprism_sw.so: /home/david/.openjfx/cache/11/libprism_sw.so: failed to map segment from shared object
	at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
	at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2424)
	at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2481)
	at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2678)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2611)
	at java.base/java.lang.Runtime.load0(Runtime.java:814)
	at java.base/java.lang.System.load(System.java:1838)
	at com.sun.glass.utils.NativeLibLoader.installLibraryFromResource(NativeLibLoader.java:205)
	at com.sun.glass.utils.NativeLibLoader.loadLibraryFromResource(NativeLibLoader.java:185)
	at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:157)
	at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:52)
	at com.sun.prism.sw.SWPipeline.lambda$static$0(SWPipeline.java:42)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at com.sun.prism.sw.SWPipeline.<clinit>(SWPipeline.java:41)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:291)
	at com.sun.prism.GraphicsPipeline.createPipeline(GraphicsPipeline.java:187)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:91)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
	at java.base/java.lang.Thread.run(Thread.java:844)
Graphics Device initialization failed for :  es2, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
	at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
	at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:222)
	at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
	at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
	at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
	at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
	at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
	at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
	... 1 more
Exception in thread "main" java.lang.RuntimeException: No toolkit found
	at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
	at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
	at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
	at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
	at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
	at java.base/java.lang.Thread.run(Thread.java:844)

It was suggested on ##java IRC that the ~/.openjfx/cache/11 directory needs to allow exec flag but it might be set to noexec now due to apparmor. Is there a way to allow exec for home directory files or can I move the OpenJFX cache out of home?

I changed the HOME for the Java application with the JAVA_TOOL_OPTIONS environment variable. The application was looking for user.home which I changed to the $SNAP_USER_COMMON directory.

    environment:
      JAVA_HOME: "$SNAP/usr/lib/jvm/java-11-openjdk-amd64"
      JAVA_TOOL_OPTIONS: "-Duser.home=$SNAP_USER_COMMON"

This solves the issue because JavaFX wants to put some files in a hidden . directory but AppArmour is preventing it. Even with personal-files interface the files are not executable so JavaFX fails unless the files are put under a expected Snap data directory.