MacOS support overhaul, Apple M1 and breaking changes

So, if i understand this correctly, LWJGL 3.3.1 has the async glfw patch?
If so, i think we probably agree that it should be implemented with an AppSetting field that is true by default, right?

4 Likes

The release notes say:

Improvements

GLFW: An alternative macOS build now supports Cocoa calls on any thread.
A different window toolkit (AWT, JavaFX, etc.) may now run at the same time as GLFW. It must be initialized before glfwInit is called.
Enabled with Configuration.GLFW_LIBRARY_NAME.set("glfw_async");

I donā€™t want to rush into this, but it seems worth pursuing for JME v3.6.

9 Likes

Iā€™ve tried the above with LWJGL 3.3.1 with no luck. If anyone has gotten this to work, Iā€™d really appreciate knowing how you did it.

2 Likes

Iā€™m pursuing this and will update this topic with my progress.

2 Likes

Tonight I got the TestJaime app from ā€œjme3-examplesā€ to run on a Mac mini G5A.

I built ā€œmasterā€ branch at 989dbfea with the following changes:

  1. In ā€œcommon.gradleā€, change the lwjgl3Version setting from ā€œ3.3.0ā€ to ā€œ3.3.1ā€. (Since I believe we want LWJGL v3.3.1 going forward, I went ahead and committed this change to ā€œmasterā€ branch at ae750c06.)

  2. In ā€œjme3-examples/build.gradleā€, apply the following patch:

@@ -1,8 +1,9 @@
 ext.mainClassName = 'jme3test.TestChooser'
 
 task run(dependsOn: 'build', type:JavaExec) {
-    mainClass = mainClassName
+    mainClass = 'jme3test.animation.TestJaime'
     classpath = sourceSets.main.runtimeClasspath
+    jvmArgs '-XstartOnFirstThread'
 
     if (System.properties['java.util.logging.config.file'] != null) {
         systemProperty "java.util.logging.config.file", System.properties['java.util.logging.config.file']
@@ -19,8 +20,8 @@ dependencies {
     implementation project(':jme3-effects')
     implementation project(':jme3-jbullet')
     implementation project(':jme3-jogg')
-    implementation project(':jme3-lwjgl')
-//    implementation project(':jme3-lwjgl3')
+//    implementation project(':jme3-lwjgl')
+    implementation project(':jme3-lwjgl3')
     implementation project(':jme3-networking')
     implementation project(':jme3-niftygui')
     implementation project(':jme3-plugins')

This builds with the ā€œjme3-lwjgl3ā€ library (instead of ā€œjme3-lwjglā€), causes the ā€œrunā€ task to execute TestJaime (instead of TestChooser), and adds the ā€œ-XstartOnFirstThreadā€ JVM runtime option.

  1. In ā€œjme3-examples/src/main/java/jme3test/animation/TestJaime.javaā€, insert app.setShowSettings(false); just before app.start(). (This bypasses the Settings Dialog.)

The Java version used was:

administrator@26674 jmonkeyengine % java --version
openjdk 11.0.14 2022-01-18 LTS
OpenJDK Runtime Environment Zulu11.54+23-CA (build 11.0.14+9-LTS)
OpenJDK 64-Bit Server VM Zulu11.54+23-CA (build 11.0.14+9-LTS, mixed mode)

I tried inserting Configuration.GLFW_LIBRARY_NAME.set("glfw_async"); into ā€œjme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.javaā€ just before if (!glfwInit()), but it didnā€™t seem to make any difference.

hm, I tried to retrace your steps and for me it works fine if I remove jvmArgs '-XstartOnFirstThread'
otherwise it crashes on startup or hangs and does nothing if it tries to open settings dialog

1 Like

If youā€™re opening a Settings Dialog, then your app doesnā€™t do app.setShowSettings(false); (step 3).

example works with and without settings dialog if I remove -XstartOnFirstThread

If I remove ā€œ-XstartOnFIrstThreadā€, I get the following crash:

ar 03, 2022 10:18:01 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.6.0-SNAPSHOT
 * Branch: master
 * Git Hash: ae750c0
 * Build Date: 2022-03-03
Mar 03, 2022 10:18:01 AM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.ExceptionInInitializerError
        at org.lwjgl.glfw.GLFW.glfwInit(GLFW.java:1046)
        at com.jme3.system.lwjgl.LwjglWindow.createContext(LwjglWindow.java:229)
        at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:585)
        at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:707)
        at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:549)
        at com.jme3.app.LegacyApplication.start(LegacyApplication.java:490)
        at com.jme3.app.LegacyApplication.start(LegacyApplication.java:442)
        at com.jme3.app.SimpleApplication.start(SimpleApplication.java:126)
        at jme3test.animation.TestJaime.main(TestJaime.java:83)
Caused by: java.lang.IllegalStateException: GLFW may only be used on the main thread and that thread must be the first thread in the process. Please run the JVM with -XstartOnFirstThread. This check may be disabled with Configuration.GLFW_CHECK_THREAD0.
        at org.lwjgl.glfw.EventLoop.<clinit>(EventLoop.java:30)
        ... 9 more

[JME ERROR] Uncaught exception thrown in Thread[jME3 Main,5,main]
ExceptionInInitializerError

Since weā€™re seeing very different behavior, itā€™s time to play ā€œTwenty Questionsā€ :wink:

  • On which platform are you testing?
  • Which Git branch and commit are you testing?
  • What local changes have you made to the repo?
  • Which JDK are you using?
  • What arguments did you pass to the Gradle wrapper?
  • What messages appear on the console?
  • After the hang, what is the status of each Java thread according to ā€œjstackā€?

Even if you set Configuration.GLFW_LIBRARY_NAME.set("glfw_async"); ?

1 Like

With glfw_asynch but no startOnFirstThread, the application hangs. Here is the console output:

Mar 03, 2022 11:04:17 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.6.0-SNAPSHOT
 * Branch: master
 * Git Hash: ae750c0
 * Build Date: 2022-03-03

and hereā€™s the jstack output:

administrator@26674 ~ % jstack 1080
2022-03-03 11:05:30
Full thread dump OpenJDK 64-Bit Server VM (11.0.14+9-LTS mixed mode):

Threads class SMR info:
_java_thread_list=0x00006000034ee960, length=10, elements={
0x000000013480b000, 0x0000000134080000, 0x0000000134083000, 0x0000000134088000,
0x0000000134095800, 0x0000000134096000, 0x0000000134097000, 0x0000000126009000,
0x0000000134959000, 0x0000000134d87800
}

"jME3 Main" #1 prio=5 os_prio=31 cpu=69100.62ms elapsed=73.58s tid=0x000000013480b000 nid=0x2803 runnable  [0x000000016b7fa000]
   java.lang.Thread.State: RUNNABLE
	at org.lwjgl.system.JNI.invokeI(Native Method)
	at org.lwjgl.glfw.GLFW.glfwInit(GLFW.java:1047)
	at com.jme3.system.lwjgl.LwjglWindow.createContext(LwjglWindow.java:231)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:587)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:709)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:551)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:490)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:442)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:126)
	at jme3test.animation.TestJaime.main(TestJaime.java:83)

"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.04ms elapsed=73.57s tid=0x0000000134080000 nid=0x3503 waiting on condition  [0x000000016c64e000]
   java.lang.Thread.State: RUNNABLE
	at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.14/Native Method)
	at java.lang.ref.Reference.processPendingReferences(java.base@11.0.14/Reference.java:241)
	at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.14/Reference.java:213)

"Finalizer" #3 daemon prio=8 os_prio=31 cpu=0.10ms elapsed=73.57s tid=0x0000000134083000 nid=0x3603 in Object.wait()  [0x000000016c85a000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <0x0000000747f09008> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(java.base@11.0.14/ReferenceQueue.java:155)
	- waiting to re-lock in wait() <0x0000000747f09008> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(java.base@11.0.14/ReferenceQueue.java:176)
	at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.14/Finalizer.java:170)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 cpu=0.13ms elapsed=73.56s tid=0x0000000134088000 nid=0x3f03 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Service Thread" #5 daemon prio=9 os_prio=31 cpu=0.01ms elapsed=73.56s tid=0x0000000134095800 nid=0xa903 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 cpu=92.85ms elapsed=73.56s tid=0x0000000134096000 nid=0xa603 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"C1 CompilerThread0" #9 daemon prio=9 os_prio=31 cpu=102.91ms elapsed=73.56s tid=0x0000000134097000 nid=0xa403 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"Sweeper thread" #10 daemon prio=9 os_prio=31 cpu=0.02ms elapsed=73.56s tid=0x0000000126009000 nid=0x5703 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #11 daemon prio=8 os_prio=31 cpu=0.07ms elapsed=73.55s tid=0x0000000134959000 nid=0x9f03 in Object.wait()  [0x000000016d7c6000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <0x0000000747e28cd8> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(java.base@11.0.14/ReferenceQueue.java:155)
	- waiting to re-lock in wait() <0x0000000747e28cd8> (a java.lang.ref.ReferenceQueue$Lock)
	at jdk.internal.ref.CleanerImpl.run(java.base@11.0.14/CleanerImpl.java:148)
	at java.lang.Thread.run(java.base@11.0.14/Thread.java:829)
	at jdk.internal.misc.InnocuousThread.run(java.base@11.0.14/InnocuousThread.java:161)

"Attach Listener" #13 daemon prio=9 os_prio=31 cpu=0.34ms elapsed=48.40s tid=0x0000000134d87800 nid=0x6b07 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=31 cpu=0.76ms elapsed=73.57s tid=0x0000000134078800 nid=0x4803 runnable  

"GC Thread#0" os_prio=31 cpu=0.19ms elapsed=73.58s tid=0x0000000134810000 nid=0x5103 runnable  

"G1 Main Marker" os_prio=31 cpu=0.05ms elapsed=73.58s tid=0x000000013483f800 nid=0x5003 runnable  

"G1 Conc#0" os_prio=31 cpu=0.01ms elapsed=73.58s tid=0x0000000134840800 nid=0x4c03 runnable  

"G1 Refine#0" os_prio=31 cpu=0.03ms elapsed=73.57s tid=0x00000001348a1000 nid=0x4b03 runnable  

"G1 Young RemSet Sampling" os_prio=31 cpu=1.12ms elapsed=73.57s tid=0x00000001348a2000 nid=0x3003 runnable  
"VM Periodic Task Thread" os_prio=31 cpu=4.55ms elapsed=73.55s tid=0x00000001348aa000 nid=0x5803 waiting on condition  

JNI global refs: 10, weak refs: 0

administrator@26674 ~ % 

Maybe we should report this on LWJGL GitHub.(?)

Edit:
By the way, to make sure if the issue is not on the JME side, we can also try directly with lwjgl3-demos

1 Like
  • On which platform are you testing?
    macbook pro, m1 pro, macos Monterey 12.2.1
  • Which Git branch and commit are you testing?
    master, ae750c0696c561774ea8271d521b9bc40a2be0ee
  • What local changes have you made to the repo?
Index: jme3-examples/build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/jme3-examples/build.gradle b/jme3-examples/build.gradle
--- a/jme3-examples/build.gradle	(revision ae750c0696c561774ea8271d521b9bc40a2be0ee)
+++ b/jme3-examples/build.gradle	(date 1646335989690)
@@ -1,8 +1,10 @@
 ext.mainClassName = 'jme3test.TestChooser'
 
 task run(dependsOn: 'build', type:JavaExec) {
-    mainClass = mainClassName
+//    mainClass = mainClassName
+    mainClass = 'jme3test.animation.TestJaime'
     classpath = sourceSets.main.runtimeClasspath
+//    jvmArgs '-XstartOnFirstThread'
 
     if (System.properties['java.util.logging.config.file'] != null) {
         systemProperty "java.util.logging.config.file", System.properties['java.util.logging.config.file']
@@ -19,8 +21,8 @@
     implementation project(':jme3-effects')
     implementation project(':jme3-jbullet')
     implementation project(':jme3-jogg')
-    implementation project(':jme3-lwjgl')
-//    implementation project(':jme3-lwjgl3')
+//    implementation project(':jme3-lwjgl')
+    implementation project(':jme3-lwjgl3')
     implementation project(':jme3-networking')
     implementation project(':jme3-niftygui')
     implementation project(':jme3-plugins')
Index: jme3-examples/src/main/java/jme3test/animation/TestJaime.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/jme3-examples/src/main/java/jme3test/animation/TestJaime.java b/jme3-examples/src/main/java/jme3test/animation/TestJaime.java
--- a/jme3-examples/src/main/java/jme3test/animation/TestJaime.java	(revision ae750c0696c561774ea8271d521b9bc40a2be0ee)
+++ b/jme3-examples/src/main/java/jme3test/animation/TestJaime.java	(date 1646299006070)
@@ -67,6 +67,7 @@
 import com.jme3.scene.shape.Quad;
 import com.jme3.shadow.EdgeFilteringMode;
 import com.jme3.shadow.SpotLightShadowRenderer;
+import org.lwjgl.system.Configuration;
 
 /**
  *
@@ -78,7 +79,9 @@
     private Cinematic cinematic;
     
     public static void main(String... argv){
+        Configuration.GLFW_LIBRARY_NAME.set("glfw_async");
         TestJaime app = new TestJaime();
+//        app.setShowSettings(false);
         app.start();
     }
 
  • Which JDK are you using?
    OpenJDK BellSoft Liberica 11.0.14 aarch64
  • What arguments did you pass to the Gradle wrapper?
    ./gradlew :jme3-examples:run
  • What messages appear on the console?
> Configure project :
Latest tag:v3.5.0-alpha1
Auto-detecting version
Revision: 7607
Hash: ae750c0696c561774ea8271d521b9bc40a2be0ee
Short Hash: ae750c0
Tag: null
Build Date: 2022-03-03
Build Branch: master
Use commit hash as version false
Base Version: 3.6.0
Build Suffix: SNAPSHOT
Build Version: 3.6.0-SNAPSHOT
Use natives snapshot: https://objects.jmonkeyengine.org/native-snapshots/ec136bac246ac6ff21426b227076541ce036555a/jme3-natives.zip
  • After the hang, what is the status of each Java thread according to ā€œjstackā€?
2022-03-03 20:46:04
Full thread dump OpenJDK 64-Bit Server VM (11.0.14+9-LTS mixed mode):

Threads class SMR info:
_java_thread_list=0x0000600002a3c680, length=13, elements={
0x000000015a01a800, 0x000000015980f000, 0x000000013980c800, 0x0000000139808800,
0x000000015981c800, 0x000000013a011000, 0x0000000159820000, 0x000000013100a800,
0x000000013a08c800, 0x0000000139a73000, 0x000000013a1ab000, 0x000000013a3c2800,
0x000000015986f000
}

"main" #1 prio=5 os_prio=31 cpu=140.19ms elapsed=44.94s tid=0x000000015a01a800 nid=0x103 in Object.wait()  [0x000000016f78e000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <0x00000005df44dd00> (a java.lang.Object)
	at java.lang.Object.wait(java.base@11.0.14/Object.java:328)
	at com.jme3.system.JmeDesktopSystem.showSettingsDialog(JmeDesktopSystem.java:184)
	- waiting to re-lock in wait() <0x00000005df44dd00> (a java.lang.Object)
	at com.jme3.system.JmeSystem.showSettingsDialog(JmeSystem.java:159)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:120)
	at jme3test.animation.TestJaime.main(TestJaime.java:85)

"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.05ms elapsed=44.93s tid=0x000000015980f000 nid=0x3503 waiting on condition  [0x000000017066e000]
   java.lang.Thread.State: RUNNABLE
	at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.14/Native Method)
	at java.lang.ref.Reference.processPendingReferences(java.base@11.0.14/Reference.java:241)
	at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.14/Reference.java:213)

"Finalizer" #3 daemon prio=8 os_prio=31 cpu=0.10ms elapsed=44.93s tid=0x000000013980c800 nid=0x4603 in Object.wait()  [0x000000017087a000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <0x00000005dfe09008> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(java.base@11.0.14/ReferenceQueue.java:155)
	- waiting to re-lock in wait() <0x00000005dfe09008> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(java.base@11.0.14/ReferenceQueue.java:176)
	at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.14/Finalizer.java:170)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 cpu=0.32ms elapsed=44.92s tid=0x0000000139808800 nid=0x3f03 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Service Thread" #5 daemon prio=9 os_prio=31 cpu=0.02ms elapsed=44.92s tid=0x000000015981c800 nid=0x3e03 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 cpu=84.08ms elapsed=44.92s tid=0x000000013a011000 nid=0xa903 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"C1 CompilerThread0" #9 daemon prio=9 os_prio=31 cpu=84.38ms elapsed=44.92s tid=0x0000000159820000 nid=0xa603 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"Sweeper thread" #10 daemon prio=9 os_prio=31 cpu=0.03ms elapsed=44.92s tid=0x000000013100a800 nid=0xa303 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #11 daemon prio=8 os_prio=31 cpu=0.04ms elapsed=44.91s tid=0x000000013a08c800 nid=0x5a03 in Object.wait()  [0x00000001717e6000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <0x00000005dffada78> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(java.base@11.0.14/ReferenceQueue.java:155)
	- waiting to re-lock in wait() <0x00000005dffada78> (a java.lang.ref.ReferenceQueue$Lock)
	at jdk.internal.ref.CleanerImpl.run(java.base@11.0.14/CleanerImpl.java:148)
	at java.lang.Thread.run(java.base@11.0.14/Thread.java:829)
	at jdk.internal.misc.InnocuousThread.run(java.base@11.0.14/InnocuousThread.java:161)

"AWT-Shutdown" #14 prio=5 os_prio=31 cpu=0.04ms elapsed=44.80s tid=0x0000000139a73000 nid=0x9c03 in Object.wait()  [0x00000001719f2000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <0x00000005df453f50> (a java.lang.Object)
	at java.lang.Object.wait(java.base@11.0.14/Object.java:328)
	at sun.awt.AWTAutoShutdown.run(java.desktop@11.0.14/AWTAutoShutdown.java:291)
	- waiting to re-lock in wait() <0x00000005df453f50> (a java.lang.Object)
	at java.lang.Thread.run(java.base@11.0.14/Thread.java:829)

"AWT-EventQueue-0" #13 prio=6 os_prio=31 cpu=7.99ms elapsed=44.80s tid=0x000000013a1ab000 nid=0x9b03 runnable  [0x0000000171bfc000]
   java.lang.Thread.State: RUNNABLE
	at sun.java2d.opengl.CGLGraphicsConfig.getCGLConfigInfo(java.desktop@11.0.14/Native Method)
	at sun.java2d.opengl.CGLGraphicsConfig.getConfig(java.desktop@11.0.14/CGLGraphicsConfig.java:146)
	at sun.awt.CGraphicsDevice.<init>(java.desktop@11.0.14/CGraphicsDevice.java:71)
	at sun.awt.CGraphicsEnvironment.initDevices(java.desktop@11.0.14/CGraphicsEnvironment.java:179)
	- locked <0x00000005df4a7d70> (a sun.awt.CGraphicsEnvironment)
	at sun.awt.CGraphicsEnvironment.<init>(java.desktop@11.0.14/CGraphicsEnvironment.java:115)
	at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(java.base@11.0.14/Native Method)
	at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(java.base@11.0.14/NativeConstructorAccessorImpl.java:62)
	at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(java.base@11.0.14/DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(java.base@11.0.14/Constructor.java:490)
	at java.awt.GraphicsEnvironment$LocalGE.createGE(java.desktop@11.0.14/GraphicsEnvironment.java:108)
	at java.awt.GraphicsEnvironment$LocalGE.<clinit>(java.desktop@11.0.14/GraphicsEnvironment.java:83)
	at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(java.desktop@11.0.14/GraphicsEnvironment.java:129)
	at java.awt.Window.initGC(java.desktop@11.0.14/Window.java:487)
	at java.awt.Window.init(java.desktop@11.0.14/Window.java:507)
	at java.awt.Window.<init>(java.desktop@11.0.14/Window.java:549)
	at java.awt.Frame.<init>(java.desktop@11.0.14/Frame.java:423)
	at java.awt.Frame.<init>(java.desktop@11.0.14/Frame.java:388)
	at javax.swing.JFrame.<init>(java.desktop@11.0.14/JFrame.java:180)
	at com.jme3.app.SettingsDialog.<init>(SettingsDialog.java:141)
	at com.jme3.system.JmeDesktopSystem$3.run(JmeDesktopSystem.java:174)
	- locked <0x00000005df44dd00> (a java.lang.Object)
	at java.awt.event.InvocationEvent.dispatch(java.desktop@11.0.14/InvocationEvent.java:313)
	at java.awt.EventQueue.dispatchEventImpl(java.desktop@11.0.14/EventQueue.java:770)
	at java.awt.EventQueue$4.run(java.desktop@11.0.14/EventQueue.java:721)
	at java.awt.EventQueue$4.run(java.desktop@11.0.14/EventQueue.java:715)
	at java.security.AccessController.doPrivileged(java.base@11.0.14/Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(java.base@11.0.14/ProtectionDomain.java:85)
	at java.awt.EventQueue.dispatchEvent(java.desktop@11.0.14/EventQueue.java:740)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(java.desktop@11.0.14/EventDispatchThread.java:203)
	at java.awt.EventDispatchThread.pumpEventsForFilter(java.desktop@11.0.14/EventDispatchThread.java:124)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(java.desktop@11.0.14/EventDispatchThread.java:113)
	at java.awt.EventDispatchThread.pumpEvents(java.desktop@11.0.14/EventDispatchThread.java:109)
	at java.awt.EventDispatchThread.pumpEvents(java.desktop@11.0.14/EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.run(java.desktop@11.0.14/EventDispatchThread.java:90)

"Java2D Queue Flusher" #15 daemon prio=10 os_prio=31 cpu=20.92ms elapsed=44.77s tid=0x000000013a3c2800 nid=0x970f in Object.wait()  [0x0000000171e0a000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait(java.base@11.0.14/Native Method)
	- waiting on <no object reference available>
	at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(java.desktop@11.0.14/OGLRenderQueue.java:205)
	- waiting to re-lock in wait() <0x00000005df4af870> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
	at java.lang.Thread.run(java.base@11.0.14/Thread.java:829)

"Attach Listener" #16 daemon prio=9 os_prio=31 cpu=0.76ms elapsed=16.58s tid=0x000000015986f000 nid=0x6503 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=31 cpu=4.55ms elapsed=44.93s tid=0x000000015a9bf000 nid=0x3303 runnable  

"GC Thread#0" os_prio=31 cpu=2.30ms elapsed=44.94s tid=0x000000015a029000 nid=0x5303 runnable  

"G1 Main Marker" os_prio=31 cpu=0.06ms elapsed=44.94s tid=0x000000015a845000 nid=0x5103 runnable  

"G1 Conc#0" os_prio=31 cpu=0.01ms elapsed=44.94s tid=0x000000015a845800 nid=0x2e03 runnable  

"G1 Refine#0" os_prio=31 cpu=0.07ms elapsed=44.94s tid=0x000000015a966800 nid=0x4d03 runnable  

"G1 Young RemSet Sampling" os_prio=31 cpu=4.87ms elapsed=44.94s tid=0x000000015a967000 nid=0x3003 runnable  
"VM Periodic Task Thread" os_prio=31 cpu=20.07ms elapsed=44.91s tid=0x000000013a084000 nid=0x5803 waiting on condition  

JNI global refs: 11, weak refs: 0
2 Likes

without settings dialog:

* What went wrong:
Execution failed for task ':jme3-examples:run'.
> Process 'command '/Users/wizzardo/Library/Java/liberica-11.0.14/bin/java'' finished with non-zero exit value 133

One difference is that you put Configuration.GLFW_LIBRARY_NAME.set("glfw_async"); in main(), whereas I added it to the ā€œjme3-lwjgl3ā€ library. Iā€™ll test whether that makes a difference.

EDIT: That was the key difference. Iā€™ll find a good place in ā€œjme3-lwjgl3ā€ to configure GLFW.

EDIT^2: Oops! I was mistaken.

The key was the Java version. After I installed a Liberica SDK and set ā€œJAVA_HOMEā€ appropriately, I was able to run the app with the Settings dialog. When I set ā€œJAVA_HOMEā€ to point back to the Zulu SDK, the app crashed.

Hereā€™s the exact setting I used, for future reference:

% export JAVA_HOME=/Library/Java/JavaVirtualMachines/liberica-jdk-11-full.jdk/Contents/Home

Iā€™m back to searching for a good place to put the set("glfw_async") ā€¦

EDIT^3: I believe I found a good place.

Iā€™ve decided to draft a pull request that implements Riccardoā€™s suggestion from last week:

So, if i understand this correctly, LWJGL 3.3.1 has the async glfw patch?
If so, i think we probably agree that it should be implemented with an AppSetting field that is true by default, right?

EDIT^4: I wound up with something similar to what Riccardo suggested, but more flexible.
Here it is ā€¦ PR 1779.

3 Likes

Not sure why it works with one SDK but not the other. But here is some info I get from the LWJGL GitHub page in this comment.

glfw_async currently only targets macOS.
And it also does not allow you to create any AWT/Swing windows.
It only lets you use the ImageIO subsystem (e.g. for image loading/storing) and lets you open/use modal dialog windows.
glfw_async is basically there to avoid people who already use GLFW to add the -XstartOnFirstThread JVM argument.

Does JMEā€™s Settings dialog use a modal window?

1 Like

Seems not, but I donā€™t know why not:

https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-desktop/src/main/java/com/jme3/app/SettingsDialog.java#L149

Seems like it could have been modal without issue. I didnā€™t do a git blame to see who commented it out though.

2 Likes

Apparently it was to fix ā€œissue 574ā€. I believe thatā€™s a reference to the Google Code issue tracker. I searched the Forums and didnā€™t find a reference to it. Any ideas how to gain access to those old bug reports?

Some googling found it:
https://code.google.com/archive/p/jmonkeyengine/issues/574

1 Like

I had some crashes today where GLFW thought it was in a headless environment, even with Liberica. So apparently the SDK isnā€™t the determining factor.

The issue comes and goes, but doesnā€™t seem random. The last time it happened, I fixed it by rebooting. Itā€™s as if AWT relies on some state (a daemon, perhaps?) that occasionally disappears or gets corrupted.

Edit: Iā€™m also struggling to find JME apps (other than TestJaime and TestCinematic) that I can run from TestChooser on the Mac Mini. Most apps in ā€œjme3-examplesā€ cause the JVM to crash with exit value 133 and a problem report that says ā€œBUG IN CLIENT OF LIBDISPATCH: dispatch_sync called on queue already owned by current threadā€.

3 Likes