Comments on jpackage (JEP 343)
mark.reinhold at oracle.com
mark.reinhold at oracle.com
Tue Sep 3 18:58:55 UTC 2019
I spent some time last week playing with the jpackage tool, using build
14-jpackage+1-35 from https://jdk.java.net/jpackage.
Overall, I can see that you’ve made good progress, but there’s still some
work to be done. I’ll start with high-level comments and questions, and
then comment on my experience using the tool on Debian and then macOS.
High-level comments/questions
- It’s good that you’re publishing EA builds, but I haven’t seen very
much feedback from those builds. It may be better to propose this as
an experimental feature when it’s ready to target. That would give
you the freedom to improve it incompatibly over one or two release
cycles before you commit to a final version.
- The tool still generates an image by default, rather than a package.
This will surprise many users, especially those who just want to do
something simple and straightforward. The least-surprising default
behavior would be to generate a package of the type most suitable for
the current platform. An option to generate just an image would be
fine, for those who want to tweak it before the actual packaging
step, but that shouldn’t be the default.
- Related to the previous point, I should only have to specify the
`--package-type` option if I want something other than the default
for the current platform.
- The tool assumes that the application being packaged will have a GUI.
This isn’t surprising, considering its heritage, but as a consequence
it always produces packages that perform GUI-specific actions, such
as installing icons and desktop-menu entries. If I’m just packaging
a command-line tool then these are unnecessary, and supporting them
can pull in lots of additional dependencies (e.g., a ton of Perl
scripts on Debian). Consider adding an option (`--gui`?) so that
the user can indicate when an application is to be installed for
graphical use.
- The `--output`/`-o` option is confusing. It doesn’t name the output
itself, but rather a directory into which the single item of output
will be placed. Typing `-o .` all the time is just annoying. It’d
be more logical to rename this option to `--dest`/`-d` and to make it
optional, with a default value of `.`.
- If my app is modular, and my main module has a version string, then
it’d be nice for that to be used as the package version unless a
specific version is specified on the command line.
- Terminology: For Linux we generally speak of “packages” rather than
“bundles.” Rename `--linux-bundle-name` to `--linux-package-name`.
- The `--temp-root` option could be shortened to `--temp`.
- Periods at the ends of error messages are unsightly and unnecessary.
We don’t use them in other JDK tools. Please remove them.
- It’d be nice to have an option that displays the programs being run
by the tool, in a form that can easily be cut-and-pasted into a
script for those who need to do a lot of customization. The current
verbose output shows (at least some of) this information, but in a
difficult-to-use format.
- What’s the rationale for copying the entire “input” directory as-is?
Why is its structure important? Couldn’t you just as well limit this
to a single directory full of JAR files?
Comments on Debian packaging
- On a Debian machine I tried to create a package for a trivial,
two-module application using the command
$ jpackage -o . --package-type deb -p lib -m org.openjdk.hello -n hello
which gave me the error message
Bundler DEB Installer skipped because of a configuration problem: java.lang.NullPointerException.
(Side note: This message is confusing since the tool is creating a
Debian package, not an “installer.”)
- On a hunch, I specified a main application class:
$ jpackage -o . --package-type deb -p lib -m org.openjdk.hello/org.openjdk.hello.Main -n hello
and that created `hello_1.0-1_amd64.deb`. It shouldn’t have been
necessary to specify a main class since the main module does have a
`ModuleMainClass` attribute in its module descriptor.
- The resulting package does not depend upon any others, i.e., the
`Depends:` line in its control file is empty. This can’t possibly be
right, since the embedded JDK depends on many system libraries for
proper operation (`libc`, `libfreetype`, `libpthread`, etc.).
- The resulting package would install into `/opt/hello`, as expected,
but the `/opt/hello/bin` directory would contain not just the `hello`
application launcher but also `hello.desktop`, `hello.png`, and
`libapplauncher.so`. These aren’t appropriate for a `bin` directory
and should be placed elsewhere, most likely `/opt/hello/lib`.
- The resulting package would install `/opt/hello/app` and
`/opt/hello/runtime` directories. These are not strictly forbidden
by the Linux FHS [1], but it’d be better to put both of them under
`/opt/hello/lib`, per convention.
- The resulting package does not contain the normal `java` launcher.
It’d be helpful to retain this (in `runtime/bin/java`, not in the
app’s `bin` directory) for diagnostic purposes. It’s not large.
- The resulting package would install the copyright file into
`/usr/share/doc/hello/copyright`, which is wrong -- a package that
installs into `/opt` should never touch anything under /usr [1]. This
file should be at `/opt/hello/share/doc/copyright`.
- I attempted to install the package on a fresh Ubuntu 18.04 machine:
# dpkg -i hello-1.0.deb
Selecting previously unselected package hello.
(Reading database ... 135670 files and directories currently installed.)
Preparing to unpack hello-1.0.deb ...
Unpacking hello (1.0) ...
Setting up hello (1.0) ...
Adding shortcut to the menu
/var/lib/dpkg/info/hello.postinst: 25: /var/lib/dpkg/info/hello.postinst: xdg-desktop-menu: not found
dpkg: error processing package hello (--install):
installed hello package post-installation script subprocess returned error exit status 127
Errors were encountered while processing:
hello
mr-dev # uname -a
Linux mr-dev 4.15.0-1018-oracle #20-Ubuntu SMP Wed Jul 3 06:46:12 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
mr-dev # cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
#
Apparently the package should depend upon `xdg-utils`, so that its
post-install script can find `xdg-desktop-menu`. Even better,
though, would be for this trivial non-graphical application not to
depend upon any desktop utilities, per my comment above.
- Installing the package succeeded despite the above error. I was
successfully able to run my trivial application. Yay!
- Then I tried to uninstall it:
mr-dev # dpkg --remove hello
(Reading database ... 135923 files and directories currently installed.)
Removing hello (1.0) ...
Removing shortcut
/var/lib/dpkg/info/hello.prerm: 25: /var/lib/dpkg/info/hello.prerm: xdg-desktop-menu: not found
dpkg: error processing package hello (--remove):
installed hello package pre-removal script subprocess returned error exit status 127
Errors were encountered while processing:
hello
mr-dev #
I installed `xdg-utils` by hand to get `xdg-desktop-menu`, but it still
didn’t work:
mr-dev # dpkg --remove hello
(Reading database ... 136878 files and directories currently installed.)
Removing hello (1.0) ...
Removing shortcut
xdg-desktop-menu: No writable system menu directory found.
dpkg: error processing package hello (--remove):
installed hello package pre-removal script subprocess returned error exit status 3
Errors were encountered while processing:
hello
mr-dev #
I eventually figured out how to create a fake writable system menu
directory and was then able to remove the package.
- The `--linux-deb-copyright` option is confusing. Its description
should mention that if this option is specified then the `--license`
option is, so far as I can tell, ignored.
- The `--identifier` option appears to have no use for Debian packages.
Perhaps this option should be package-type specific? Or at least its
description should mention that it’s irrelevant to Debian packages.
- I tried to create a package that would install into the `/usr`
hierarchy by adding `--install-dir /usr` to the above command line.
The resulting package would create a `/usr/hello` directory, with
`app`, `bin`, and `runtime` directories under that. That’s not
right. To install an application in the `/usr` hierarchy its command
should go into `/usr/bin`, and libraries and other files should go
into `/usr/lib/$APPNAME`, and documentation and copyright files
should go into `/usr/share/doc/$APPNAME`.
- Many of the above observations could also apply to RPM packages, but
I haven’t checked.
Comments on macOS packaging
(Warning: I’m not an expert macOS developer!)
- On a macOS machine (10.13.6) I tried to create a dmg package:
$ jpackage -o . --package-type dmg -p lib -m org.openjdk.hello/org.openjdk.hello.Main -n hello
which gave me the error message
Exec failed with code 1 command [[/usr/bin/SetFile, -c, icnC, /var/folders/mn/8nt00ldx7dqfrv55wk72mgq80000gr/T/jdk.jpackage9024163201922289964/images/hello/.VolumeIcon.icns] in unspecified directory output: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
although it exited with status 0 and did produce a valid `.dmg` file.
I suppose I’m missing some development tools? If so then please
document that dependency, and if possible issue a more helpful error
message that tells the user what they need to install.
- It’d be nice if the resulting `.dmg` file, when opened, were to show
an icon for the Applications folder and an arrow pointing to that
from the app icon, so that the user can drag it across. Almost all
`.dmg` files that I’ve seen do this.
- Mark
[1] https://www.debian.org/doc/packaging-manuals/fhs/fhs-3.0.html#optAddonApplicationSoftwarePackages
More information about the core-libs-dev
mailing list