Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8286122

[macos]: App bundle cannot upload to Mac App Store due to info.plist embedded in java exe

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      b24
    • CPU:
      generic
    • OS:
      os_x

      Description

      A DESCRIPTION OF THE PROBLEM :
      I am attempting to upload an update of our app to the Mac App Store.

      Our app is a Java Swing app and I am using OpenJDK 17 and the jpackage tool to generate an app bundle for upload.
      https://docs.oracle.com/en/java/javase/17/docs/specs/man/jpackage.html
      NOTE: I have also tried JDK 18. I have not tried earlier versions of the JDK as they do not include all app store options in the jpackage tool.

      The pkg file produced by jpackage passes verification using the Transporter app (with one warning: ITMS-90889), however when I deliver the pkg using Transporter I receive the following error email:

      Dear Developer,
      We identified one or more issues with a recent delivery for your app, "APP_NAME" APP_VERSION. Please correct the following issues, then upload again.
      ITMS-90511: CFBundleIdentifier Collision - The Info.plist CFBundleIdentifier value 'net.java.openjdk.java' of 'java' is already in use by another application.
      ...


      I have done much searching on the internet to try and fix this issue.

      I've determined that the issue is being caused by the bundled java executable - it contains its own Info.plist with the CFBundleIdentifier 'net.java.openjdk.java' and this has been uploaded by someone else previously.
      Apple do not allow the same bundle identifier that someone else has previously used.

      Some articles indicate this can be fixed by using codesign --removesignature and re-signing the executable with my own Mac developer certificate and entitlements file.
      The jpackage process appears to be doing this:
      [15:37:04.534] Command [PID: 47885]:
          /usr/bin/codesign --remove-signature /path/to/APP_NAME.app/Contents/runtime/Contents/Home/bin/java
      [15:37:04.534] Returned: 0
      [15:37:05.063] Command [PID: 47886]:
          /usr/bin/codesign --timestamp --options runtime -s 3rd Party Mac Developer Application: CERTIFICATE_NAME --prefix UNIQUE_PREFIX -vvvv --entitlements /path/to/APP_NAME.entitlements /path/to/APP_NAME.app/Contents/runtime/Contents/Home/bin/java
      [15:37:05.064] Output:
          /path/to/APP_NAME.app/Contents/runtime/Contents/Home/bin/java: signed Mach-O thin (x86_64) [net.java.openjdk.java]
      [15:37:05.064] Returned: 0

      Other articles, some quite old, suggest editing the java executable with a hex editor and replacing 'net.java.openjdk.java' with a unique value of the same length.
      I tried this and it resulted in the java executable no longer functioning:
      Killed: 9


      I raised this issue with Apple Developer technical support and they investigated the issue and sent a reply which I have included below.

      Any help you could provide with this issue would be greatly appreciated.




      Email reply from DTS tech support:

      Looking at your app I was able to get to the bottom of this issue. Consider the error message in your original email:

      ITMS-90511: CFBundleIdentifier Collision - The Info.plist
      CFBundleIdentifier value 'net.java.openjdk.java' of 'java' is already in use by another application.

      I’ve dealt with this message before, and it has a long and interesting history. The Mac App Store prevents two developers from submitting executables with the same bundle identifier. This is an important security check: We don’t want app A impersonating app B.

      This check applies to all executables, not just the app’s main executable. Historically the Mac App Store ingestion process had bugs that caused it to apply to other types of code, like frameworks and bundles. When I first saw this incident I was worried that these bugs had come back.

      However, that’s not the case. Let’s look at the main executables in your app:

      % find APP_NAME.app -type f -print0 | xargs -0 file | grep "Mach-O.*executable"
      APP_NAME.app/Contents/MacOS/APP_NAME: Mach-O 64-bit executable x86_64
      APP_NAME.app/Contents/runtime/Contents/Home/bin/java: Mach-O 64-bit executable x86_64
      APP_NAME.app/Contents/runtime/Contents/Home/bin/keytool: Mach-O 64-bit executable x86_64
      APP_NAME.app/Contents/runtime/Contents/Home/lib/jspawnhelper: Mach-O 64-bit executable x86_64

      Based on the error message it’s obvious we need to focus on the `java` executable. However, it’s placed in a location that doesn’t have a corresponding `Info.plist` file:

      % find APP_NAME.app -name "Info.plist"
      APP_NAME.app/Contents/Info.plist
      APP_NAME.app/Contents/runtime/Contents/Info.plist

      The first file here applies to your entire app and the second file applies to the Java runtime package as a whole. Moreover, neither of these have a bundle ID that matches the error message:

      % plutil -extract CFBundleIdentifier raw -o - "APP_NAME.app/Contents/Info.plist"
      UNIQUE.BUNDLE.ID
      % plutil -extract CFBundleIdentifier raw -o - "APP_NAME.app/Contents/runtime/Contents/Info.plist"
      com.oracle.java.com.UNIQUE.BUNDLE.ID

      So where is this bundle ID coming from?

      * * *

      Some further spelunking reveals the issue. Consider this:

      % otool -s __TEXT __info_plist -v APP_NAME.app/Contents/runtime/Contents/Home/bin/java

      <dict>
      <key>CFBundleIdentifier</key>
      <string>net.java.openjdk.java</string>

      </dict>
      </plist>

      This is an obscure corner case in the macOS bundle story: A standalone tool, like `java`, which isn’t in a bundle structure, and thus can’t have a standalone `Info.plist` file, can put its information property list in a `__TEXT` / `__info_plist` section within its executable. And it seems that the folks who created your Java runtime did just that.

      Given that, the Mac App Store error is valid: You are trying to submit an executable whose bundle ID matches some existing app.

      To get around this check you’ll need to give `java` a new bundle ID. That’s not easy to do. This `__TEXT` / `__info_plist` section is set up by a linker option (see `-sectcreate` in <x-man-page://1/ld&gt;) and there’s no good way to modify it after the fact [1].

      At this point my advice is that you escalate this with your Java runtime vendor. I suspect that they’ve added this information property list to get around a TCC check — the only other interesting property in there is `NSMicrophoneUsageDescription` — and they probably didn’t notice this Mac App Store submission issue. There’s a couple of ways they could resolve this [2] but it’s really their issue to resolve.

      If they need help with this they should absolutely open their own DTS tech support incident; I’d be happy to help them in that context.

      <https://developer.apple.com/support/technical/>

      Share and Enjoy
      --
      Quinn “The Eskimo!”
      Apple Developer Relations, Developer Technical Support, Core OS/Hardware
      <http://www.apple.com/developer/>

      [1] And by “good” I mean “Using a standard tool supplied by Apple.” The Mach-O file format is reasonably well documented and thus you could build a custom tool to do that, but even that’s not easy. There are a couple of problems:

      * The new information property list may be larger than the previous one.

      * The `__info_plist` section can appear anywhere in the `__TEXT` segment.

      If you increase the size of the section then subsequent sections need to move up to accommodate it and, depending on which sections you have to move, that might require other cross-section links to be fixed up. Yergh!

      [2] The ones that spring to mind are:

      * Package the `java` executable in a standard bundle, replacing `runtime/Contents/Home/bin/java` with a symlink to that.

      * Add an `__info_plist` section with a bunch of padding and then build a tool to update the bundle ID in that section, taking advantage of that padding to avoid the need to move subsequent sections in the `__TEXT` segment.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Build a simple java swing application on Mac OSX using the jpackage tool.

      Upload to the Mac App Store.

      Receive the ITMS-90511 CFBundleIdentifier Collision error via email.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Mac App Store accepts the uploaded application without any CFBundleIdentifier Collision errors.
      ACTUAL -
      e identified one or more issues with a recent delivery for your app, "APP_NAME" APP_VERSION. Please correct the following issues, then upload again.
      ITMS-90511: CFBundleIdentifier Collision - The Info.plist CFBundleIdentifier value 'net.java.openjdk.java' of 'java' is already in use by another application.


      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              Assignee:
              almatvee Alexander Matveev
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: