7

I am trying to distribute a Java application to OS X users. I am not using the Mac store - it is to be distributed through my own website. Whatever I try, OS X's Gatekeeper rejects the app.

Here's my method:

(1) Build the app as usual, get a JAR file

(2) Use appbundler as described here: https://docs.oracle.com/javase/7/docs/technotes/guides/jweb/packagingAppsForMac.html. This creates a .app around my JAR which runs nicely, and contains the JVM in the MyApp.app/Contents/PlugIns directory.

(3) Sign the app with my Developer certificate:

codesign -s 'Developer ID Application: MyCompany Ltd' --deep MyApp.app

...process completes successfully

(4) Verify that the .app will adhere to Gatekeeper's iron-fist laws:

spctl --assess --verbose=4 --type execute MyApp.app

...and the result I get back is:

MyApp.app: a sealed resource is missing or invalid

Doesn't seem very verbose to me! What could I be doing wrong? Or how can I get more information?

SO/Google searches around 'a sealed resource...' refer to signing frameworks (which I don't have) or suggest signing with the --force option (which I tried but doesn't work).

HughHughTeotl
  • 4,480
  • 2
  • 27
  • 41

1 Answers1

8

You can't use --deep. It sounds like the right option to use, since you also need to sign the embedded JRE, but it won't work. From Apple's docs:

Important: While the --deep option can be applied to a signing operation, this is not recommended. We recommend that you sign code inside out in individual stages (as Xcode does automatically). Signing with --deep is for emergency repairs and temporary adjustments only.

After a lot of hair-pulling, I cobbled this together from various tutorials. This one was the most helpful. Here was my final solution as an Ant script:

<!-- code sign -->
<exec executable="chmod">
    <arg line="a+w ${build.dir}/Mac/MyApp.app/Contents/PlugIns/jre"/>
</exec>

<apply executable="codesign"> <!-- note: this loops through the contents of dir -->
    <arg line="-f -s 'Developer ID Application: My Organization'"/>
    <fileset dir="${build.dir}/Mac/MyApp.app/Contents/PlugIns/jre" />
</apply>

<exec executable="codesign" dir="${build.dir}/Mac"> 
    <arg line="-f -s 'Developer ID Application: My Organization' MyApp.app/Contents/PlugIns/jre"/>
</exec>

<exec executable="codesign" dir="${build.dir}/Mac"> 
    <arg line="-f -s 'Developer ID Application: My Organization' MyApp.app/Contents/PlugIns/jre/Contents/_CodeSignature/CodeResources"/>
</exec>

<!-- also codesign anything else in _CodeSignature (see comments) -->

<exec executable="codesign" dir="${build.dir}/Mac">
    <arg line="-f -s 'Developer ID Application: My Organization' MyApp.app"/>
</exec>


<!-- verify codesign -->
<exec executable="codesign" dir="${build.dir}/Mac" failonerror="true">
    <arg line="-vv MyApp.app"/>
</exec>


<!-- verify gatekeeper -->
<exec executable="spctl" dir="${build.dir}/Mac" failonerror="true">
    <arg line="-vv --assess --type execute MyApp.app"/>
</exec>

Another thing to look out for is not to use the command-line zip to package your app after signing, because it will break the codesign of the app. You should package it using productbuild, PackageMaker, xip, or in a dmg.

martinez314
  • 11,512
  • 4
  • 29
  • 60
  • Many thanks for the response, really appreciated. Unfortunately this get as far as the verification (`codesign -vv MyApp.app` line) then dies with `[exec] MyApp.app: code object is not signed at all` / `[exec] In subcomponent: MyApp.app/Contents/PlugIns/jre/Contents/_CodeSignature/CodeDirectory`. Any ideas? – HughHughTeotl Nov 15 '14 at 11:15
  • 1
    @HughHughTeotl I don't get a `_CodeSignature/CodeDirectory` when I run it -- not sure what is causing the difference. You'll have to sign everything in `_CodeSignature`, so just add `_CodeSignature/CodeDirectory` to the list (and anything else in there). Also, be sure you are signing in OS X 10.9 or later. If you use an older version of OS X, the code signing will not work. – martinez314 Nov 15 '14 at 13:31
  • AWESOME! That seems to work. I will edit your answer with that small change so I can accept it (hope that's OK). Many many thanks. – HughHughTeotl Nov 15 '14 at 14:01
  • @HughHughTeotl Looks like the edit was rejected (not by me). I added a note about it to the answer. Thanks! – martinez314 Nov 15 '14 at 15:03