Yes our application is self contained (executables, derby database,
log files, etc) with the .app
bundle, which we can distribute the
entire application with only dealing with a single .app
bundled
file.
That’s fine if you consider the database to be read only, for example, if you want it to act as a template for each new user who runs your app. Where you get into trouble is if you modify that database in place. That will break the seal on your app’s code signature and bad things will ensue.
This architecture has worked prior to macOS Catalina with no issues …
That you’ve noticed (-:
Are you saying with the newer macOSes, it does not support this type
of "legacy" architecture … ?
No. I’m saying that this architecture hasn’t been supported since the original Macintosh, all the way back in 1984. The nature of unsupported things is that sometimes they work and sometimes they don’t.
If so, can you point me to an Apple architectural best practice
documentation so I have some guidance on bundling an application using
a derby database and logging system?
What, you mean like:
(-:
Seriously though, I’m struggling to find a modern reference that definitively states that you must not write to your own app bundle on the Mac. That’s partly because the standard documentation style focuses on what you should do rather than what you shouldn’t. You only find this sort of info when you get to DTS-authored documents, like QA1662 Why can’t I save data to my application’s bundle when running on the device?, and those tend to focus on iOS where the OS absolutely prevents self-modifying apps.
QA1662 contains a link to File System Programming Guide, which has a lot of good advice about where to store your app’s data.
Again, this code worked prior to macOS Catalina, but I infer with the
newer macOS security model (e.g. MAC restriction), it has now turned
what worked before into a bug which is a null pointer exception.
OK, there’s three parts to this:
-
The new MAC feature will generate file system errors in specific situations where they previously did not occur.
-
Having said that, file system errors are a fact of life and you need to handle them correctly. For example, a file system error could just as easily have been caused by the volume running out of space, or the user changing the permissions on a directory, or an actual disk error.
-
File system errors are reported by the relevant file system API. They will not generate a null pointer exception automatically [1]. The fact that your code is throwing a null pointer exception suggests that it mishandles file system errors in general, and you’re now only noticing because of the MAC change.
Is there a coding technique best practice I should use to become
compliant with this new MAC restriction?
Again, this is not a new requirement. Your code should handle file system errors cleanly, regardless of their source.
As to how you do that, the goal is not to crash with a null pointer exception but rather present the user with an error alert telling them what’s gone wrong. How you do that really depends on how your code is structured, and that’s tied to your app architecture, including its third-party runtime, and thus not something that I can advise you on.
If you can boil this down to a specific Apple API, I can help you understand how to catch the errors that it generates but, honestly, I don’t think that you’ll need help with that part of this problem.
So run.sh
is another "legacy" architecture technique and should be
replaced with a native executable?
Yes.
And this is a new requirement. Historically macOS expected the main executable to be a native executable but using a script had no negative consequences. The advent of TCC means that this is no longer a good option. You should work with your third-party runtime vendor to see how best to adapt to this change.
Does that three part remedy sound right?
Yes.
I recommend that you start with the main executable change because I believe that fixing that will cause TCC to correctly display its MAC alert. At that point clicking Allow should let your app work, so you’ll only see the crash if you click Deny.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] This is logically impossible. Null pointer exceptions are a Java thing and Apple’s OSes have no built-in Java support.