Skip to content

Exported Application broken in 4.0 beta 1 on macOS when using P2D or P3D #249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
processing-bot opened this issue Aug 10, 2021 · 25 comments
Closed

Comments

@processing-bot
Copy link
Collaborator

Created by: philipp-lehmann

Description

When opening an exported application, it immediately quits and MacOS displays an alert saying that the application "quit unexpectedly".

Previous Bug Report

This has been an issue a while back (processing/processing#5983), so maybe its my environment.
However I tried a clean new installation with a very simple sketch and couldn't export a functional app.

Steps to Reproduce

  • Downloaded the beta
  • Created a test sketch
  • Exported the app

Environment

  • Processing version: 4.0b
  • Operating System and OS version: MacOS Big Sur 11.5.1

My Test Sketch

float rX = 0.0;
float rY = 0.0;

void setup() {
  size(400,400, P3D);
  frameRate(30); // Calling frameRate could help...
  rectMode(CENTER);
}

void draw() {
  background(255);
  translate(width/2, height/2);
  rotateX(rX += 0.005);
  rotateY(rY += 0.01);
  rect(0,0,200,200); 
}

The error messages

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGILL (0x4) at pc=0x00007fff201fa25d, pid=18786, tid=12547
#
# JRE version: OpenJDK Runtime Environment Temurin-11.0.12+7 (11.0.12+7) (build 11.0.12+7)
# Java VM: OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (11.0.12+7, mixed mode, tiered, compressed oops, g1 gc, bsd-amd64)
# Problematic frame:
# C  [libdispatch.dylib+0x525d]  _dispatch_assert_queue_fail+0x63
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/Philipp/hs_err_pid18786.log
#
# If you would like to submit a bug report, please visit:
#   https://github.com/adoptium/adoptium-support/issues
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
@processing-bot
Copy link
Collaborator Author

Created by: codeanticode

Confirming that it affects my MacOS Big Sur machine (m1 macbook air). I'm attaching the full error log.

hs_err_pid99767.log

@processing-bot
Copy link
Collaborator Author

Created by: benfry

Does that mean you're looking into it?

Might be Java 11.0.12 versus 11.0.11, since it's crashing inside the JVM. We should also see if there are any JOGL reports/updates for this.

@processing-bot
Copy link
Collaborator Author

Created by: codeanticode

I'll look into it on the m1 macbook, and will update as I find more.

@processing-bot
Copy link
Collaborator Author

Created by: codeanticode

This error in the log seems telling:

Application Specific Information:
BUG IN CLIENT OF LIBDISPATCH: Assertion failed: Block was expected to execute on queue [com.apple.main-thread]
abort() called

@benfry could it be that the application is not running on the correct thread when exported?

@processing-bot
Copy link
Collaborator Author

Created by: sampottinger

Sorry @philipp-lehmann just confirming this was happening in 3 as well? Digging into the jogl bugs, the only thing that stood out was https://jogamp.org/bugzilla/show_bug.cgi?id=1398 but I'm guessing it's something with launch4j and a fork.

@processing-bot
Copy link
Collaborator Author

Created by: sampottinger

Including or excluding the runtime does not help. Unfortunately 11.0.11 doesn't have a release on adoptium. :-/

@processing-bot
Copy link
Collaborator Author

Created by: philipp-lehmann

With 3.5.4 I was able to export P3D applications. However on M1 Macs they only showed a gray screen, as described here: https://discourse.processing.org/t/problems-with-p2d-and-p3d-renderers-with-new-apple-m1-processor/27287

Edit: This still could be this issue? processing/processing#5983

@processing-bot
Copy link
Collaborator Author

Created by: philipp-lehmann

Would it theoretically be possible to include a different jre, optimized for the m1 architecture, for the exported application?
For example this https://www.azul.com/downloads/?version=java-11-lts&os=macos&architecture=arm-64-bit&package=jdk

Or is this the wrong approach?

Idea is from here:
https://stackoverflow.com/a/64940420/3611146

@processing-bot
Copy link
Collaborator Author

Created by: REAS

When exporting with "Embed Java" received this in the command line:
2021-09-10 12:09:39.564 debug_launch[36155:1213366] NSString *findJavaDylib(NSString *, _Bool, _Bool, _Bool, _Bool) Searching for a JRE.
and it looked like it was stuck there

@processing-bot
Copy link
Collaborator Author

Created by: REAS

When exporting without embedding Java, this was reported on the command line, which look like i need to update the Java version locally, but nothing is reported unless it's opened through the command line:

2021-09-10 12:07:48.737 debug_launch[36128:1212132] NSString *findJavaDylib(NSString *, _Bool, _Bool, _Bool, _Bool) Searching for a JRE.
2021-09-10 12:07:48.954 debug_launch[36128:1212170] NSString *findJavaDylib(NSString *, _Bool, _Bool, _Bool, _Bool) Searching for a JRE.
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: debug_launch has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:601)

@processing-bot
Copy link
Collaborator Author

Created by: matejsemancik

I just came across this issue while trying to solve this exact error in my application builds.

The issue started to appear with Azul OpenJDK to 11.0.12. I downgraded to 11.0.11 and issue went away.
I'm on macOS Big Sur 11.3 and I run Processing using Gradle, so my use-case was a little bit different. Same error, though.

@processing-bot
Copy link
Collaborator Author

Created by: philipp-lehmann

Thats something, how did you tell your exported application which version of the JDK to use?

@processing-bot
Copy link
Collaborator Author

Created by: matejsemancik

Well, since I use the Gradle build system, it's pretty straightforward. I just set the $JAVA_HOME environment variable to directory where my JDK is installed. Unfortunately I cannot tell if the same would work for exporting applications using the Processing IDE.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

Would it theoretically be possible to include a different jre, optimized for the m1 architecture, for the exported application? For example this azul.com/downloads/?version=java-11-lts&os=macos&architecture=arm-64-bit&package=jdk

Or is this the wrong approach?

Idea is from here: stackoverflow.com/a/64940420/3611146

Not that simple; longer explanation here: #128 (comment)

@processing-bot
Copy link
Collaborator Author

Created by: benfry

When exporting without embedding Java, this was reported on the command line, which look like i need to update the Java version locally, but nothing is reported unless it's opened through the command line:

2021-09-10 12:07:48.737 debug_launch[36128:1212132] NSString *findJavaDylib(NSString *, _Bool, _Bool, _Bool, _Bool) Searching for a JRE.
2021-09-10 12:07:48.954 debug_launch[36128:1212170] NSString *findJavaDylib(NSString *, _Bool, _Bool, _Bool, _Bool) Searching for a JRE.
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: debug_launch has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

The UnsupportedClassVersionError is the clue here, it means that there isn't another Java 11 installed on the system (explained in the Export dialog), and it's trying to run the application with Java 8 or something else that you have installed.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

This error in the log seems telling:

Application Specific Information:
BUG IN CLIENT OF LIBDISPATCH: Assertion failed: Block was expected to execute on queue [com.apple.main-thread]
abort() called

@benfry could it be that the application is not running on the correct thread when exported?

Certainly possible, but I don't know why that would be different between Java 11.0.10 and 11.0.11 (if the report that it actually works with 11.0.10 is correct). It's a fairly major change, though I guess it could be a matter of enforcement.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

10.0.10 from AdoptOpenJDK doesn't seem to be working (though I haven't tried with the Azul builds), so I think it's just plain broken.

It's obviously a threading issue, but I've not yet been able to identify what changed/broke that's now causing the problem. In fact, very rarely, it works just fine: I just double-clicked a test .app file I'd been working with and it actually ran. Quitting and trying again went back to crashing. So: threads.

In the meantime, here's a workaround for folks who are desperate:

  1. Copy and paste the code below into a text file called sketch.tool
  2. Open a Terminal window and type chmod +x and then drag and drop sketch.tool into the window, which will put the full path to your sketch.tool into the window.
  3. Hit return, and then close the Terminal window.

Now you can copy that sketch.tool file to the same folder as any .app you create, double-click, and it should launch just fine (albeit with a Terminal window popping up).

Again, not an ideal solution, but it works in the meantime.

#!/usr/bin/python3

import os
import plistlib
import sys


def find_first_dot_app(path):
    ''' what's the name of the .app for the sketch? '''
    with os.scandir(path) as it:
        for entry in it:
            if entry.name.endswith('.app') and entry.is_dir():
                return entry.path


def find_jdk_path(app_path):
    ''' figure out the path to the JDK in the PlugIns directory '''
    path = f'{app_path}/Contents/PlugIns'
    with os.scandir(path) as it:
        for entry in it:
            if entry.name.startswith('jdk-') and entry.is_dir():
                return entry.path
    return None


def find_jars(app_path):
    ''' return the full paths for all .jar files, separate with : '''
    path = f'{app_path}/Contents/Java'
    jar_paths = [ ]
    with os.scandir(path) as it:
        for entry in it:
            if entry.name.endswith('.jar') and entry.is_file():
                jar_paths.append(entry.path)
    return ':'.join(jar_paths)


def find_main_class(app_path):
    ''' parse the Info.plist file to get the name of the sketch '''
    with open(f'{app_path}/Contents/Info.plist', 'rb') as f:
        pl = plistlib.load(f)
        return pl['JVMMainClassName']


def process_exec(args):
    ''' run a process and get output from it '''
    from subprocess import Popen, PIPE
    p = Popen(args, stdout=PIPE, stderr=PIPE)
    (out_data, err_data) = p.communicate()
    result = p.wait()
    return (result, out_data.decode('utf-8'), err_data.decode('utf-8'))


if __name__ == "__main__":
    # the current directory
    HERE = os.path.dirname(os.path.realpath(__file__))

    dot_app = find_first_dot_app(HERE)
    # print(dot_app)

    jdk_path = find_jdk_path(dot_app)
    if jdk_path:
        # use an embedded JDK
        cmd = [ f'{jdk_path}/Contents/Home/bin/java' ]
    else:
        # use built-in java_home to identify a Java 11 version
        cmd = [ '/usr/libexec/java_home', '--version', '11', '--exec', 'java' ]

    cmd += [ '-cp', find_jars(dot_app) ]

    sketch_name = find_main_class(dot_app)
    cmd += [ 'processing.core.PApplet', sketch_name ]

    # run the command, wait, and print the result when the app finishes
    (result, out, err) = process_exec(cmd)
    sys.stderr.write(err)
    sys.stdout.write(out)
    if result != 0:
        print(f'Exit code was {result}.')

@processing-bot
Copy link
Collaborator Author

Created by: benfry

For anyone looking into this further: my current theory is that we have some (older) code that's not being run from the correct thread. And it wasn't a problem before, but a recent OS update or something similar may have been enough to trigger something that was waiting to break.

(This was working fine in my testing before recent releases… Export to Application with an OpenGL sketch is usually one of the things I'll test before putting out a release.)

I've tried shutting off the AWT (--disable-awt) and running headless and that doesn't help. Using -XstartOnFirstThread just makes things hang (again: threads).

Edit: it also seems to be working with alpha 4, and broken in alpha 5. So that may be another clue (though the breaking is inconsistent, so that's not 100% certain…)

@processing-bot
Copy link
Collaborator Author

Created by: benfry

Have tracked it down to changes in the macOS app launcher between alpha 4 and 5… fix should be coming soon.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

!@#$!% and it's caused by the launcher being recompiled… not the result of any actual changes.

So either something has changed in the macOS SDK, or the recompile is just enough to trigger a threading problem that's present.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

Now fixed for beta 2 by compiling appbundler on a Mojave machine instead of Catalina or Big Sur.

If you can't wait for beta 2, replace appbundler.jar from inside Processing.app with the one from alpha 4. (Hm, that may break signing; not sure. If it does, you'll have to re-sign yourself or… wait for beta 2.)

@processing-bot
Copy link
Collaborator Author

Created by: philipp-lehmann

Thanks for the Update and all your work. I'll test this soon.

@processing-bot
Copy link
Collaborator Author

Created by: philipp-lehmann

I can confirm that this works again. Awesome!!!
Many thanks.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

Great, thanks for reporting back.

@processing-bot
Copy link
Collaborator Author

Created by: github-actions[bot]

This issue has been automatically locked. To avoid confusion with reports that have already been resolved, closed issues are automatically locked 30 days after the last comment. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant