Hardened runtime and JavaVMMBS

I’m posting this here in case anyone else has this problem.

We had a problem with our new release no longer correctly launching the JavaVM.
The Java call from Xojo failed on Catalina after code signing with hardened runtime (MBS Java Plugin).

dim javaVm as new JavaVMMBS(JavaVMMBS.JNI_VERSION_1_4, options, true)

This failed in the constructor
It’s a Hard crash on Catalina (the program just gets dumped from memory), so there’s no log.
(Try Catch does not help)

What worked:
When debugging it worked.

After building it worked.

When code signing the following way it worked:

codesign -s  "Developer ID Application: XXXX" JavaCheck.app --deep --force

What failed:
When code signing with hardened runtime the following way it failed:

codesign -s  "Developer ID Application: XXXX" JavaCheck.app --deep --force --options runtime

The problem:
I added Xojo2DMG (https://www.jo-tools.ch/xojo/xojo2dmg/) to the test code (to be able to codesign for debugging) and added the following:

Dim strDylib As String = "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib" dim sd as SoftDeclareMBS sd=new SoftDeclareMBS if sd.LoadDylib(strDylib) then bJavaFound = True end if

This gave an error loading the dylib

[code]dlopen(/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib, 2):
no suitable image found.

Did find:
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib:
code signature in (/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib)

not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned?
Code has to be at least ad-hoc signed.

/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib: stat() failed with errno=60[/code]

So it looks like the Java Libraries aren’t signed (see for instance https://bugs.eclipse.org/bugs/show_bug.cgi?id=558570#c4)

The solution:

The solution is to set com.apple.security.cs.disable-library-validation to true so that the validation of the dylib doesn’t happen.

Add the following to the entitlements

<key>com.apple.security.cs.disable-library-validation</key> <true/>

Then sign again in the following way:

codesign -s  "Developer ID Application: XXXX" JavaCheck.app --deep --force --options runtime --entitlements ./entitlements.plist

After this the JavaVMMBS constructor works again.

Thanks for posting this.

I keep repeating myself when I mention here and there that I recommend to CodeSign with Hardened Runtime each and every DebugRun :slight_smile:
That’s how one notices these kind of issues immediately, and not only when building (or worse: distributing) a release build.

[quote=490003:@Dirk Cleenwerck]Dim strDylib As String = "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib"
The solution is to set com.apple.security.cs.disable-library-validation to true so that the validation of the dylib doesn’t happen.[/quote]
Yup. Hardened Runtime needs that Entitlement: Disable Library Validation Entitlement if you’re going to load frameworks, plug-ins, or libraries unless they’re either signed by Apple or signed with the same team ID as the app. While bundled within your app, you can always codesign those with your certificate. But obviously not when you’re loading them from outside your app.

Just for reference - here is Apple’s Documentation: Disable Library Validation Entitlement
And the full list of Entitlements: Hardened Runtime