Running MicroOS as my daily on the work laptop is quite the experience. Nothing ever breaks but at the same time there is very little that can. This is because the apps I need are not packaged. Sad.

Over time I have packaged what I need but one of them took some time. VisualVM is a GUI to troubleshoot your Java processes, as it requires the Java SDK and Java SRE at runtime I was not sure how to package it.

Development tools and libraries are available at build time but applications are not shipped with them. Turns out that it was easy but almost undocumented so here we are. I will give bits and pieces of the manifest I made and explain what parts where necessary to have access to the Java SDK and Java JRE at runtime so that others may do the same.

The Flatpak build process is isolated in a sandbox and this means that we have access to almost nothing. What we need to build the app must be brough into the sandbox. This is where the sdk image comes in. The sdk image is a file-system with lots of development tools that can be used by flatpak at build times. The problem for us is that it does not have /all the tools/.

The sdk image does not provide a Java SDK and Java JRE so you cannot build your Java applications as is. The sanctioned way to do build a Java app is to use a sdk image extension. Following is the incantation to use the openjdk extension.

sdk-extensions:
  - org.freedesktop.Sdk.Extension.openjdk

The extension provides the (Java) tools and libraries we need at build time but we also want them available at runtime. As this is a sensible use-case the publishers of the sdk extension have included a script to install everything in the final artifact that we produce. Following is the incanation to do so.

modules:
  - name: install-openjdk
    buildsystem: simple
    build-commands:
      - /usr/lib/sdk/openjdk/install.sh

Now tools like javac will be available both at build time and runtime. Everything we need will be copied in the /app directory. If the packaged app requires the tools we can point it there and everything will work as expected.

Following is the manifest that I have used to package VisualVM.

id: io.github.visualvm
branch: '2.1.10'
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
sdk-extensions:
  - org.freedesktop.Sdk.Extension.openjdk
finish-args:
  # setup JRE and JDK path
  - --env=PATH=/app/jre/bin:/usr/bin
  # X11 + XShm access
  - --share=ipc
  - --socket=x11
  # GPU acceleration if needed
  - --device=dri
  # Needs to talk to the network:
  - --share=network
  - --persist=.visualvm
command: /app/visualvm/bin/visualvm
modules:
  - name: install-openjdk
    buildsystem: simple
    build-commands:
      - /usr/lib/sdk/openjdk/install.sh
  - name: install-visualvm
    sources:
      - type: archive
        url: 'https://github.com/oracle/visualvm/releases/download/2.1.10/visualvm_2110.zip'
        archive-type: 'zip'
        sha256: 87850af9e9873c690cbb76056627e73dfbfd1e1d95279a9031722a85ac36d999
    buildsystem: simple
    build-commands:
      - mkdir -p ${FLATPAK_DEST}/visualvm
      - cp -ar * ${FLATPAK_DEST}/visualvm
    build-options:
      strip: true # debugedit craps otherwise
  - name: install-desktop-app
    sources:
      - type: file
        path: io.github.visualvm.desktop
    buildsystem: simple
    build-commands:
      - install -D --target-directory=${FLATPAK_DEST}/share/applications -m444 ${FLATPAK_ID}.desktop