Executing bundled shell command in a hardened runtime application

code-signingjavanotarization

I have written a Java application which I want to distribute in form of a macOS application bundle. The application needs to execute a command line application which is also part of the bundle. The bundle is correctly signed (verified using the codesign command) and the hardened runtime is enabled.

I am able to run the application, but then the application fails to execute the bundled command line application.

The code used to execute the command line application:

Runtime.getRuntime().exec("/path/to/app/bundle/Contents/cli/myCommandLineApplication");

The code works fine when I sign the bundle without enabling the hardened runtime.
Once I enable the hardened runtime, I get the following exception:

Cannot run program "myCommandLineApplication": error=0, posix_spawn failed

What am I doing wrong? Is it even possible to spawn child processes from within a hardened runtime application?

The Java runtime I am using is AdoptOpenJDK (build 11.0.4+11).
The application is not sandboxed.
The entitlements I used when signing the bundle were

<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>

Best Answer

The issue was related to my build process itself, not the hardened runtime which I suspected. In fact, when I enabled the hardened runtime, also a launcher application was put into place inside the bundle which starts the main application using the bundled JRE.

As this is the AdoptOpenJDK I mentioned, it uses spawn for Runtime.exec which caused the issue. Once I added System.setProperty( "jdk.lang.Process.launchMechanism", "FORK"); to my main method, Runtime.exec was working just fine again afterwards, even with the hardened runtime enabled.