I am creating a JAVA desktop app for Mac computers, using jpackage to bundle the desired JRE into the app and finally shipping a .app to the customers.
With the new m1 apple arm silicon computers I do not want to create different apps for each processor architecture with the right JRE (intel & arm) but create one single universal binary app that launches the Intel JRE on Intel computers and the Arm JRE on Arm computers. I know this is possible somehow.
I tried to create two .apps and use the lipo tool from the mac command line, but this doesn't really work.
Any suggestions how to proceed?
So I followed this very detailed tutorial:
https://incenp.org/notes/2023/universal-java-app-on-macos.html
After some minor little changes it works perfectly on Intel (with Mac OS 11) and Apple chip (with Mac OS 14). I tried all three options but will use the last one with 2 threads.
I compiled the file on the machine with the older operating system.
Two small remarks: The function get_application_directory needs to be fixed a little bit:
static char * get_application_directory(char *buffer, uint32_t len)
{
char *last_slash = NULL;
int n = 2;
if ( ! _NSGetExecutablePath(buffer, &len) ) {
while ( n-- > 0 ) {
if ( (last_slash = strrchr(buffer, '/')) )
*last_slash = '\0';
}
}
return last_slash ? buffer : NULL;
}
and the reference of the jars on the classpath only work when I put every single jar file on the classpath and not use any wildcard *.
To debug you can always call this method that will print any exception the JVM is throwing:
void check_and_print_exception(JNIEnv *env) {
if ((*env)->ExceptionCheck(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
}