Bundling a Java Application with Flatpak

This tutorial will walk you through bundling a pre-built Java application using Flatpak. Many Java applications ship a pre-built tarball with the Java dependencies included, and this tutorial will step through an example of taking such a tarball and creating a Flatpak application from it.

To complete this tutorial, it is necessary to have flatpak and flatpak-builder installed on your system. See getting Flatpak for details on installing Flatpak on your system.

Get the Application Tarball

The application that we are going to bundle with Flatpak is Sweethome3D -- an application that lets you map a plan of the interior of your house so you can design and then view your design plans in 3D. Sweethome3D ships a prebuilt tarball that contains all the Java dependencies it requires, as well as the pre-built binary.

The first step is to download the Sweethome3D tarball, and extract it to your working directory:

$ wget http://downloads.sourceforge.net/project/sweethome3d/SweetHome3D/SweetHome3D-5.2/SweetHome3D-5.2-linux-x64.tgz
$ tar xvf SweetHome3D-5.2-linux-x64.tgz

Install the Flatpak Freedesktop SDK and runtime

Every Flatpak application is required to specify a runtime that provides the core dependencies when the application is run. A Flatpak SDK is used just by you, the developer when building and bundling the application. See the Developer page for further details on how the runtimes and SDKs work.

For this example of bundling up Sweethome3D, we are going to use the Freedesktop SDK and runtime. The Freedesktop SDK and runtime are available in from the GNOME SDK repository. If you haven't previously set up this repository, you need to download the GPG key, then enable the repository:

$ wget https://sdk.gnome.org/keys/gnome-sdk.gpg
$ flatpak remote-add --gpg-import=gnome-sdk.gpg gnome https://sdk.gnome.org/repo/

You now have enabled a new Flatpak repo called gnome. Next, install version 1.4 of the Freedesktop SDK and runtime from your newly enabled gnome repository:

$ flatpak install gnome org.freedesktop.Platform 1.4
$ flatpak install gnome org.freedesktop.Sdk 1.4

Create the Flatpak application

Next up, we are going to create the Flatpak application that we are going to bundle Sweethome3D into. Use the following command to create the Flatpak application with the unique name com.sweethome3d.App, using the Freedesktop runtime and SDK:

$ flatpak build-init sweethome3d-flatpak com.sweethome3d.App org.freedesktop.Sdk org.freedesktop.Platform 1.4

This creates a default empty Flatpak application called com.sweethome3d.App in a new the directory sweethome3d-flatpak.

Move the tarball contents into the Flatpak sandbox

The flatpak build command lets you run commands within your newly created Flatpak sandbox. First we use flatpak build to create a bin/ and a SweetHome3D/ directory in the /app/ directory within the sweethome3d-flatpak sandbox:

$ flatpak build sweethome3d-flatpak mkdir -p /app/SweetHome3D
$ flatpak build sweethome3d-flatpak mkdir -p /app/bin

At this point, we can also run ls inside the build sandbox to see the results of the above two commands:

$ flatpak build sweethome3d-flatpak ls /app/

Next, move the contents of the tarball we extracted in the '''Get the Application Tarball''' step above into the /app/Sweethome3D/ directory in the sandbox:

$ flatpak build sweethome3d-flatpak cp -ra SweetHome3D-5.2/* /app/SweetHome3D

Finally, make a symbolic link for the Sweethome3D binary in /app/SweetHome3D/SweetHome3D to the /app/bin/ directory in the sandbox.

$ flatpak build sweethome3d-flatpak ln -s /app/SweetHome3D/SweetHome3D /app/bin

Adding a Desktop entry, AppData, and an icon

One thing you will notice about Sweethome3D is that the application does not ship a Desktop file, AppData file or application icon in the tarball. Including a desktop file will make the application show up in the menus of a Linux desktop, so a user can launch the application directly from their desktop environment (rather than having to run a terminal command). AppData files provide extra information about an application that Desktop environments can use to populate software installers (e.g. gnome-software and apper).

creating and getting the files and icon

Create a new file in your working directory called com.sweethome3d.App.desktop and populate it with a simple desktop entry for Sweethome3D:

[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=SweetHome 3D
Comment=Draw the plan of your home or office, test furniture layouts and view the results in 3D
Exec=SweetHome3D
Icon=com.sweethome3d.App.png
Terminal=false

Next, create another new file called com.sweethome3d.App.appdata.xml in your working directory, and populate it with an AppData file for SweetHome3D:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2013 First Lastname <your@email.com> -->
<component type="desktop">
 <id>com.sweethome3d.App.desktop</id>
 <metadata_license>CC0-1.0</metadata_license>
 <project_license>GPL-2.0</project_license>
 <name>SweetHome 3D</name>
 <summary>Draw the plan of your home or office, test furniture layouts and view the results in 3D</summary>
 <description>
  <p>
   Use SweetHome 3D to map out a plan of your house and plan the layout
   and colors of floors, walls and furniture.
  </p>
  <p>Example list:</p>
  <ul>
   <li>First item</li>
   <li>Second item</li>
  </ul>
  <p>
  This is another paragraph of information about SweetHome 3D and the Many
  things that you can use it for
  </p>
 </description>
 <screenshots>
  <screenshot type="default">
   <image>http://www.sweethome3d.com/images/gallery/SweetHome3DExample10-FlatWithMezzanine-VirtualVisit.jpg</image>
   <caption>The main window showing the application in action</caption>
  </screenshot>
 </screenshots>
 <url type="homepage">http://http://www.sweethome3d.com/</url>
</component>

The sweethome 3D tarball also does not ship with an icon included, so we need to download it from their upstream source control:

$ wget http://sweethome3d.cvs.sourceforge.net/viewvc/sweethome3d/SweetHome3D/src/com/eteks/sweethome3d/viewcontroller/resources/help/images/applicationIcon.png

Place them in the sandbox

Now you have the 3 files in your working directory, we can place them in the appropriate locations in the build sandbox.

First, create the directory for the desktop file, and move the file from your working directory, to the build sandbox:

$ flatpak build sweethome3d-flatpak mkdir -p /app/share/applications/
$ flatpak build sweethome3d-flatpak cp com.sweethome3d.App.desktop /app/share/applications/

Then do the same for the icon, being sure to rename it to com.sweethome3d.App.png

$ flatpak build sweethome3d-flatpak mkdir -p /app/share/icons/hicolor/128x128/apps/
$ flatpak build sweethome3d-flatpak cp applicationIcon.png /app/share/icons/hicolor/128x128/apps/com.sweethome3d.App.png

Create the /app/share/appdata/ directory in the sandbox, and copy the appdata file over:

$ flatpak build sweethome3d-flatpak mkdir -p /app/share/appdata/
$ flatpak build sweethome3d-flatpak cp com.sweethome3d.App.appdata.xml /app/share/appdata/

After adding the AppData file, use the following command to generate the Appstream files:

$ flatpak build sweethome3d-flatpak appstream-compose --prefix=/app --origin=flatpak --basename=com.sweethome3d.App  com.sweethome3d.App

This reads the desktop file, the icon and the appdata file and produces appstream files in /app/share/app-info/. Note that this step is done automatically if you are automating your build process with Flatpak-builder

Finalize the build

Next, we finalize the build of the Flatpak application. In this step, we tell Flatpak what the sandboxed application should have access to outside of the sandbox, and the name of the executable. In this Sweethome3D example, Sweethome3D needs access to the network, and to X11 (since it is a GUI application):

$ flatpak build-finish sweethome3d-flatpak --persist=.java --share=ipc --socket=x11 --share=network --command=SweetHome3D

Export the repo, and test out the application

Your SweetHome3D Flatpak application is now complete. The next step is to export it into a local repository so we can install it and try it out. First, export the Flatpak application with:

$ flatpak build-export repo sweethome3d-flatpak
This creates a repo/ directory that contains your new repo with the SweetHome3D application in it.

Next, we need to add this to Flatpak as a "remote" repo, similar to what you did earlier for the SDK repo:

$ flatpak --user remote-add --no-gpg-verify sweethome-repo repo

Finally install the application from the newly linked repo, and run it:

$ flatpak --user install sweethome-repo com.sweethome3d.App
$ flatpak run com.sweethome3d.App

Also check the Application menus on your desktop environment, an entry for SweetHome 3D should now be visible in the menus, using the icon for SweetHome too.

Automating this process with flatpak-builder

The above steps have walked you through generating a Flatpak application using a series of manual steps. If you need to automate this process, there the Flatpak-builder tool that lets you specify all the details of your Flatpak application, and will download and build the application automatically.

First, in a clean working directory from the steps above, create a new file called com.sweethome3d.App.json with the following contents:

{
  "app-id": "com.sweethome3d.App",
  "runtime": "org.freedesktop.Platform",
  "runtime-version": "1.4",
  "sdk": "org.freedesktop.Sdk",
  "command": "SweetHome3D",
  "finish-args": [
      "--persist=.java",
      "--share=ipc", "--socket=x11",
      "--share=network"
  ],
  "modules": [
      {
          "name": "sweethome",
          "no-autogen": true,
          "sources" : [
              {
                  "type": "archive",
                  "url": "http://downloads.sourceforge.net/project/sweethome3d/SweetHome3D/SweetHome3D-5.2/SweetHome3D-5.2-linux-x64.tgz",
                  "sha256": "c963afe9111e7b557cbdb99678926e5767c30928aa9565878f0d0b132151d69e"
              },
              {
                  "type": "file",
                  "path": "sweethome-Makefile",
                  "dest-filename": "Makefile"
              }
          ]
      }
  ]
}

You also need a simple Makefile to do the steps of placing the files in the tarball into the proper locations in the /app/ directory in the sandbox. Create a new file called sweethome-Makefile and add the following contents:

all:
      true
install:
      mkdir -p /app/SweetHome3D /app/bin
      cp -ra * /app/SweetHome3D
      ln -s /app/SweetHome3D/SweetHome3D /app/bin

Now, with these two files created, running the following command will download the tarball, extract it, move the files into the correct locations, finalize the build, and export the repo:

$ flatpak-builder --repo=repo sweethome3d-flatpak com.sweethome3d.App.json

Finally, enable the new repo as we did before, then install and run the application:

$ flatpak --user remote-add --no-gpg-verify sweethome-repo2 repo
$ flatpak --user install sweethome-repo2 com.sweethome3d.App
$ flatpak run com.sweethome3d.App