Both app and pkg are notarized; app opens fine but pkg encounters javascript error

I have an app built using python with pyinstaller. I was able to successfully get the app notarized and open it on my computer as well as a different one (OS 11.6.1).

I can also get the pkg successfully notarized, but when I attempt to launch it on my own computer (or a different one), an error box immediately appears stating "There was an error reading the package" along with "JavaScriptError."

I looked at the log file corresponding to the notarization, and I saw no error messages or warnings. Neither "java" nor "javascript" appear anywhere.

This was not a problem for me a couple weeks ago when using a slightly different version of my program. Is there a different log file of some type, associated with javascript, that might shed light on the problem?

Update: I did just try to check whether package passed the gatekeeper test by typing

spctl -a '/Users/..../application.pkg'

at the terminal, which returned "rejected"

This is more of an installer issue than a notarisation issue. The installer uses JavaScript internally.

How are you building your installer package? Using productbuild? Or some other Apple tool? Or a third-party tool?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I'm building my installer package using productbuild at the command line. After I code sign the app, I type

productbuild --sign 'Developer ID Installer: My Name (XXXXXX7RBW)' --component /Users/fishbacp/Desktop/dist/My\ App.app /Applications /Users/fishbacp/Desktop\ My\ App_unsigned.pkg

The \ is just to force the space in the app and pkg names. Perhaps I should place the path names within quotation marks instead?

I then sign the package:

productsign --sign 'Developer ID Installer: My Name (XXXXXX7RBW)' /Users/fishbacp/Desktop/My\ App_unsigned.pkg /Users/fishbacp/Desktop/My\ App.pkg

If you are building the pkg with --sign, then your package is signed. You don't need to sign again. However, you should include the "--timestamp" option. You also have to make sure that the underlying app is properly signed with the hardened runtime and timestamp options.

@nk_kennedy: Thanks for your suggestion. Unfortunately, unless I misunderstood your directions, I wasn't able to resolve my problem.

I added the --timestamp option to my product build. As for my code signing the app, I did this using the following:

codesign -f -o runtime -v --deep --timestamp --entitlements /Users/fishbacp/Desktop/entitlements.plist -s "Developer ID Application: My Name (XXXXXX7RBW)" /Users/fishbacp/Desktop/dist/My\ App.app

I assume that -o runtime is what ensures the code signing is done with a hardened run time?

As for my entitlements.plist, I discovered a while back that I needed to use this (for reasons I don't understand) to get the app running since my .app was built using pyinstaller. The relevant line from it is as follows:

<plist version="1.0"> <dict> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> </dict> </plist>

As long as I've seen notarization problems, I've seen Apple developer support engineers say not to use "--deep". Here is a canonical example from two years ago.

Maybe just work on one problem at a time. Does your package install anything other than this app? If it doesn't, then you don't need an installer package.

Otherwise, these kinds of problems are endemic to PyInstaller. I recommend you complain to the people making PyInstaller.

There are two “installers” in play here: PyInstaller, which creates a Mac app from Python code, and the Apple Installer, which creates an installer package from files. These should be independent, meaning that the content of your app shouldn’t affect the ability of productbuild to package it or the Installer to install it. However, the evidence here suggests that’s not the case.

I’m going to recommend that you run a test to tease these apart:

  1. Using Xcode, create a new project from one of the built-in templates.

  2. Use Product > Archive to create an Xcode archive for that.

  3. Using the Xcode organiser, export that using Distribute App > Developer ID > Export.

  4. Wrap that in an installer package as you’re currently doing.

Does the resulting installer package exhibit the problem?


Some minor nits:

productbuild --sign 'Developer ID Installer: My Name (XXXXXX7RBW)' …

productsign --sign 'Developer ID Installer: My Name (XXXXXX7RBW)' …

This is redundant. If you sign at the productbuild stage, you don’t need to sign it again.

codesign -f -o runtime -v --deep

Don’t use --deep. nk_kennedy has already pointed you to my --deep Considered Harmful post, which explains why.

Rather, sign each code item separately, from the inside out. See:

However, neither of these points explain your installer error.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for your suggestions. I'll be honest that I really have no experience using Xcode and have been developing all my apps from Python and Pyinstaller. Before I dive into learning Xcode in an attempt to "tease" the two installers (Pyinstaller and Apple Installer) as you suggest, perhaps I should ask the following, which I think is really at the heart of my misunderstanding.

My app is a small "toy example" called Determinant Calculator.app, and I'll assume it's stored on my desktop in a directory named dist

I found from my notarization log that, without including --deep in my code-sign, many items were not being signed with valid time-stamped signatures. A couple listed examples were

"Determinant Calculator.app/Contents/MacOS/libtcl8.6.dylib"

"Determinant_Calculator.pkg/Determinant%20Calculator.pkg Contents/Payload/Applications/Determinant Calculator.app/Contents/MacOS/QtQml"

All messages involved dynamic libraries or various directories, whose names began with Qt.

I understand from the "inside out" approach, which is what I was trying to avoid by using --deep, that I need for these to be signed separately, before I sign the application itself. For example, I just code-signed the above dylib using

codesign -f -o runtime -v --timestamp --entitlements /Users/fishbacp/Desktop/determinants/entitlements.plist -s "Developer ID Application: My Name (XXXXXX7RBW)" "/Users/fishbacp/Desktop/dist/Determinant Calculator.app/Contents/MacOS/libtcl8.6.dylib"

For the QtQml, I used

codesign -f -o runtime -v --timestamp --entitlements /Users/fishbacp/Desktop/determinants/entitlements.plist -s "Developer ID Application: My Name (XXXXXX7RBW)" "/Users/fishbacp/Desktop/dist/Determinant Calculator.app/Contents/MacOS/QtQml" 

Question 1: Is my understanding correct that all such items need to be signed separately before signing the application?

Question 2: Is it possible to write a shortcut that will automate the process if I give it the list of all directories in the notarization log? If there is such a shortcut, can you point me to a link where I could find such an example? (Or is this just a matter of me writing a shell script?)

Thanks for all your help.

A proper macOS app should use frameworks instead of dylibs, and they should be in the Frameworks folder. Plus, macOS already has tcl built into the operating system. I don't know why you would need another one, unless maybe PyInstaller absolutely requires some new feature in TCL 8.6 that doesn't exist in TCL 8.5.

It is a bigger question of why anyone in 2022 would even be concerned about incompatibilities with minor version differences in TCL to begin with. According to Wikipedia, "The Tcl programming language was created in the spring of 1988 by John Ousterhout while working at the University of California, Berkeley. Originally 'born out of frustration'...".

Do you feel yourself to be "unfrustrated" at this point?

Why not just bite the bullet and starting writing real apps with Xcode? Why spend so much of your time and effort because somebody else royally screwed something up? I can guarantee that you'll get far more use and mileage about of SwiftUI running on both iOS and macOS that you will out of TCL, Python, and Qt.

Is my understanding correct that all such items need to be signed separately before signing the application?

Yes, although some of the details in what you posted are wrong. For example, signing a library, like libtcl8.6.dylib, with entitlements is always wrong. Entitlements are only effective on a main executable. Normally signing a library with entitlements is benign but in some cases it can cause problems.

Is it possible to write a shortcut that will automate the process if I give it the list of all directories in the notarization log?

Automating this is standard procedure. How you go about implementing that automation is kinda up to you. Personally I probably wouldn’t start from the notarisation log.

Or is this just a matter of me writing a shell script?

That’s what most folks do.

Keep in mind that there’s a reason why we haven’t ‘fixed’ --deep: It’s not possible to implement this in a fully general way without external knowledge about your program. For example, some executables within your program might need one set of entitlements while others might need a completely different set, and you can’t tell that by looking at, say, the executables themselves, a notarisation log, or whatever.

The other problem with --deep is the bundle structure. That flag requires that your app follow the rules in Placing Content in a Bundle. If you don’t follow those rules exactly, -deep will misbehave. And my experience is that a a lot of third-party tooling ignores those rules [1].


nk_kennedy wrote:

A proper macOS app should use frameworks instead of dylibs

That’s not true. Standalone dynamic libraries work just fine on macOS [2]. There’s nothing improper about them.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] My Embedding Nonstandard Code Structures in a Bundle is an attempt to point folks in the right direction here.

[2] They are not, however, supported an iOS and its descendents (except for the Swift runtime libraries, which are a special case).

Both app and pkg are notarized; app opens fine but pkg encounters javascript error
 
 
Q