jlink and jpackage not producing correct macOS packages

James Elliott james at deepsymmetry.org
Fri Feb 14 17:06:53 UTC 2020

I’d raised some issues earlier on this list about jpackage not being able to create packages that can successfully be notarized by Apple, which is now necessary for them to install and open when downloaded from the internet. My initial point was that jpackage needs to enable secure timestamps, the hardened runtime, and supply an entitlements.plist file which identifies a powerful set of entitlements the JVM needs in order to be able to compile and run arbitrary Java byte code.

I also opened a ticket with Apple to help get a better understanding of the problems, and I have learned there are many deeper ones.

But more fundamentally, the runtime bundle violates many Apple rules for structuring and signing code. I think this problem starts with jlink. Below I will quote the analysis from Apple Developer Technical Support. The person who researched this for me has generously offered to work with the OpenJDK teams responsible for jpackage and jlink in order to fix the problems at the source, so that they can generate correctly structures packages which are properly signed for notarization. So I am looking for help in identifying and contacting the people who can lead those efforts so I can put you all in touch.

Here are the details; Quinn is talking about an application image that was created by the version of jpackage in the release candidate of OpenJDK 14, without signing, and which I then tried to run `codesign --force --deep` requesting secure timestamps, the hardened runtime, and appropriate entitlements.plist myself. I can re-send the links to my build workflow and scripts if they would be helpful, but I think the problem is much deeper than that:

> Thanks for the info.  By an amazing coincidence, I just finished diagnosing almost exactly the same issue on behalf of another developer.
> The fundamental problem here is that the JDK is not following Apple’s nested code rules.  This results in confusion about what is and isn’t code, which results in code being signed as data, which is a /really/ bad idea.
> The specific cause of your notarisation failure is that the code `libjli.dylib` for won’t verify:
> % codesign -v "/Volumes/Beat Link Trigger/Beat Link Trigger.app/Contents/runtime/Contents/MacOS/libjli.dylib"
> /Volumes/Beat Link Trigger/Beat Link Trigger.app/Contents/runtime/Contents/MacOS/libjli.dylib: code has no resources but signature indicates they must be present
> Looking at the code signature reveals some interesting tidbits:
> % codesign -d -vvv "/Volumes/Beat Link Trigger/Beat Link Trigger.app/Contents/runtime/Contents/MacOS/libjli.dylib"
>> Format=bundle with Mach-O thin (x86_64)
>> Info.plist=not bound
>> Sealed Resources=none
> The code signature thinks that it’s part of a bundle, and yet it has no `Info.plist` entries or sealed resources.
> I’m not sure how it got into this state.  On the one hand, it seems that `/Volumes/Beat Link Trigger/Beat Link Trigger.app/Contents/runtime` was structured to resemble a bundle.  On the other hand, it’s doesn’t have an extension (which is typically a key factor in indicating that something is a bundle) and it’s missing its `runtime/Contents/_CodeSignature/CodeResources` file, which is what contains info about all the resources sealed in the bundle.
>                   *                   *                   *
> Looking at the overall structure of your app, it’s clearly /way/ out of spec when it comes to nested code.  There are lots of places where code is being signed as data, which is bad.  For example, `runtime/Contents/Home/bin/javac` is not in a nested code site within the `runtime` bundle, which in turn is not within a nested code site with then the main app, so the app’s reference to `javac` in `Beat Link Trigger.app/Contents/_CodeSignature/CodeResources` is a data reference, not a code reference.
> I encourage you to find all the code nested within your app, relocate it to a correct nested code site, and then adjust your code signing process accordingly.
> I realise that this can be a tricky task given that the cross-platform code you’re dealing with expects a particular layout on disk.  My general advice on this front is to place the code items in the correct place and then substitute a symlink in the location where the cross-platform code is expecting to find that code.  For more info on this, see the “Use Symlinks to Deal with Alien Structures” section of my “Signing a Mac Product For Distribution” post on DevForums.
> <https://forums.developer.apple.com/thread/128166 <https://forums.developer.apple.com/thread/128166>>

More information about the core-libs-dev mailing list