MacOS NSWindow drag regions should only be invalidated on the Main Thread!

So, I am doing some testing of my outside engine on OSX, and I ran into an interesting issue.

[email protected] client_dist % ../jvm/Contents/Home/bin/java -jar OutsideClient.jar
File context at: /Users/trevor/Desktop/Outside.app/Contents/client_dist/.
[2020-07-31 08:54:50] [INFO   ] Running on MacOS  
Unable to create basic Accelerated OpenGL renderer.
Unable to create basic Accelerated OpenGL renderer.
Core Image is now using the software OpenGL renderer. This will be slow.
WARNING: GL pipe is running in software mode (Renderer ID=0x1020400)
[2020-07-31 08:54:52] [FINE   ] Entering outside on thread main  
[2020-07-31 08:54:54] [INFO   ] Server has client version: 0:0.0.0  
[2020-07-31 08:54:57] [INFO   ] Outside Client starting  
[2020-07-31 08:54:57] [INFO   ] Framework Version: 0.0.0  
[2020-07-31 08:54:57] [INFO   ] Version: 0.0.0  
[2020-07-31 08:54:57] [FINE   ] Starting JME on thread main  
[2020-07-31 08:54:57] [INFO   ] Starting Groovy script engine  
[2020-07-31 08:54:57] [FINE   ] Creating Groovy Class Loader  
[2020-07-31 08:54:57] [INFO   ] Running on jMonkeyEngine 3.4.0-SNAPSHOT
 * Branch: master
 * Git Hash: 72b751c
 * Build Date: 2020-07-24  
[2020-07-31 08:54:57] [FINE   ] Loading groovy classpath  
[2020-07-31 08:54:57] [FINE   ] Adding classpath: /Users/trevor/Desktop/Outside.app/Contents/client_dist/./scripts  
[2020-07-31 08:54:57] [FINE   ] Loading class: io/tlf/outside/game/ScriptGameInteraction  
2020-07-31 08:54:57.534 java[701:11689] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow drag regions should only be invalidated on the Main Thread!'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff2cb1cc63 __exceptionPreprocess + 250
	1   libobjc.A.dylib                     0x00007fff61fe506b objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff2cb37218 -[NSException raise] + 9
	3   AppKit                              0x00007fff29e6fe06 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 310
	4   AppKit                              0x00007fff29e6d311 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1416
	5   AppKit                              0x00007fff29e6cd83 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 42
	6   libglfw.dylib                       0x000000015c1cabc9 libglfw.dylib + 68553
	7   libglfw.dylib                       0x000000015c1c4416 libglfw.dylib + 42006
	8   ???                                 0x0000000112870330 0x0 + 4605805360
	9   ???                                 0x000000011286a6d0 0x0 + 4605781712
)
libc++abi.dylib: terminating with uncaught exception of type NSException
zsh: abort      ../jvm/Contents/Home/bin/java -jar OutsideClient.jar

It looks like NSWindow drag regions should only be invalidated on the Main Thread! is killing me here. I am testing on my VM, hence the opengl warnings at the top, I also get this same NSWindow error on a real mac:

*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff30c3ab57 __exceptionPreprocess + 250
	1   libobjc.A.dylib                     0x00007fff698e85bf objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff30c6334c -[NSException raise] + 9
	3   AppKit                              0x00007fff2de5d5ec -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 310
	4   AppKit                              0x00007fff2de45052 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1416
	5   AppKit                              0x00007fff2de44ac3 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 42
	6   libglfw.dylib                       0x0000000160ac2bc9 libglfw.dylib + 68553
	7   libglfw.dylib                       0x0000000160abc416 libglfw.dylib + 42006
	8   ???                                 0x0000000116dc2330 0x0 + 4678492976
	9   ???                                 0x0000000116dbc6d0 0x0 + 4678469328
)
libc++abi.dylib: terminating with uncaught exception of type NSException

I can confirm that JME and the OpenGL context are on the main thread.

Any thoughts? This is my very first time even attempting to run jme on OSX.

I think I understand what is going on, I need to use -XstartOnFirstThread, but it prevents swing from starting…

Lwjgl 2 or 3? Have you tried both?

1 Like

You can’t use Swing with lwjgl3 on OSX. As far as I know, there isn’t a way around that still.

1 Like

Yeah, I am using LWJGL3, my app is only compatible with 3.

I just discovered this… Why does apple always try to make my life hard…

OK, I have worked around my swing and main thread issue.

I am now hitting where jme just never starts. I loaded up a small test app and tried to run it, jme just hangs somewhere in the start. There are no error messages.

Here is a dump using my new favorite CTRL+BREAK

On test app

[email protected] client_dist % ../jvm/Contents/Home/bin/java -XstartOnFirstThread -jar OutsideClient.jar pbr-test
File context at: /Users/trevor/Desktop/Outside.app/Contents/client_dist/.
[2020-07-31 13:44:56] [INFO   ] Running on MacOS  
WARNING: GL pipe is running in software mode (Renderer ID=0x1020400)
[2020-07-31 13:44:57] [FINE   ] Entering outside on thread main  
[2020-07-31 13:44:57] [INFO   ] Running on jMonkeyEngine 3.4.0-SNAPSHOT
 * Branch: master
 * Git Hash: 72b751c
 * Build Date: 2020-07-24  
Unable to create basic Accelerated OpenGL renderer.
Unable to create basic Accelerated OpenGL renderer.
Core Image is now using the software OpenGL renderer. This will be slow.
^\2020-07-31 13:45:15
Full thread dump OpenJDK 64-Bit Server VM (11.0.8+10 mixed mode):

Threads class SMR info:
_java_thread_list=0x00007fae715a5ac0, length=11, elements={
0x00007fae72809000, 0x00007fae72086000, 0x00007fae72009000, 0x00007fae7301f000,
0x00007fae73012000, 0x00007fae7302e000, 0x00007fae7302f000, 0x00007fae72088000,
0x00007fae7306e000, 0x00007fae725e5800, 0x00007fae729e7800
}

"main" #1 prio=5 os_prio=31 cpu=1390.55ms elapsed=19.70s tid=0x00007fae72809000 nid=0x307 runnable  [0x00007ffeeb8c0000]
   java.lang.Thread.State: RUNNABLE
	at org.lwjgl.system.JNI.invokeI(Native Method)
	at org.lwjgl.glfw.GLFW.glfwInit(GLFW.java:830)
	at com.jme3.system.lwjgl.LwjglWindow.createContext(LwjglWindow.java:197)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:501)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:632)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:473)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:481)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:441)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:128)
	at io.tlf.outside.client.test.TestPBRLighting.main(TestPBRLighting.java:38)
	at io.tlf.outside.client.Main.main(Main.java:87)

"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=1.02ms elapsed=19.60s tid=0x00007fae72086000 nid=0x4703 waiting on condition  [0x0000700003f82000]
   java.lang.Thread.State: RUNNABLE
	at java.lang.ref.Reference.waitForReferencePendingList([email protected]/Native Method)
	at java.lang.ref.Reference.processPendingReferences([email protected]/Unknown Source)
	at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Unknown Source)

"Finalizer" #3 daemon prio=8 os_prio=31 cpu=1.00ms elapsed=19.60s tid=0x00007fae72009000 nid=0x3503 in Object.wait()  [0x0000700004085000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x0000000787105930> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x0000000787105930> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	at java.lang.ref.Finalizer$FinalizerThread.run([email protected]/Unknown Source)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 cpu=0.69ms elapsed=19.58s tid=0x00007fae7301f000 nid=0x3d03 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 cpu=546.21ms elapsed=19.57s tid=0x00007fae73012000 nid=0x3e03 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"C1 CompilerThread0" #7 daemon prio=9 os_prio=31 cpu=418.36ms elapsed=19.57s tid=0x00007fae7302e000 nid=0xa803 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"Sweeper thread" #8 daemon prio=9 os_prio=31 cpu=27.56ms elapsed=19.57s tid=0x00007fae7302f000 nid=0x5803 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Service Thread" #9 daemon prio=9 os_prio=31 cpu=0.16ms elapsed=19.54s tid=0x00007fae72088000 nid=0xa603 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #10 daemon prio=8 os_prio=31 cpu=3.41ms elapsed=19.53s tid=0x00007fae7306e000 nid=0x5b03 in Object.wait()  [0x00007000048a0000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x00000007871063f8> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x00000007871063f8> (a java.lang.ref.ReferenceQueue$Lock)
	at jdk.internal.ref.CleanerImpl.run([email protected]/Unknown Source)
	at java.lang.Thread.run([email protected]/Unknown Source)
	at jdk.internal.misc.InnocuousThread.run([email protected]/Unknown Source)

"Java2D Disposer" #13 daemon prio=10 os_prio=31 cpu=0.51ms elapsed=18.70s tid=0x00007fae725e5800 nid=0x9803 in Object.wait()  [0x0000700004cac000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x0000000787654898> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x0000000787654898> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	at sun.java2d.Disposer.run([email protected]/Unknown Source)
	at java.lang.Thread.run([email protected]/Unknown Source)

"Java2D Queue Flusher" #14 daemon prio=10 os_prio=31 cpu=32.67ms elapsed=18.66s tid=0x00007fae729e7800 nid=0x680b in Object.wait()  [0x0000700004daf000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000078769f3c0> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
	at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x000000078769f3c0> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
	at java.lang.Thread.run([email protected]/Unknown Source)

"VM Thread" os_prio=31 cpu=30.32ms elapsed=19.61s tid=0x00007fae7285e800 nid=0x4903 runnable  

"GC Thread#0" os_prio=31 cpu=24.68ms elapsed=19.67s tid=0x00007fae72818800 nid=0x2b03 runnable  

"GC Thread#1" os_prio=31 cpu=24.59ms elapsed=19.04s tid=0x00007fae7186f000 nid=0x5d03 runnable  

"GC Thread#2" os_prio=31 cpu=24.05ms elapsed=19.04s tid=0x00007fae71874000 nid=0x9f03 runnable  

"G1 Main Marker" os_prio=31 cpu=3.26ms elapsed=19.67s tid=0x00007fae7202c800 nid=0x5003 runnable  

"G1 Conc#0" os_prio=31 cpu=0.30ms elapsed=19.67s tid=0x00007fae7202d800 nid=0x2e03 runnable  

"G1 Refine#0" os_prio=31 cpu=3.18ms elapsed=19.65s tid=0x00007fae7207e000 nid=0x4e03 runnable  

"G1 Young RemSet Sampling" os_prio=31 cpu=10.31ms elapsed=19.65s tid=0x00007fae73008800 nid=0x4c03 runnable  
"VM Periodic Task Thread" os_prio=31 cpu=43.32ms elapsed=19.54s tid=0x00007fae72800800 nid=0xa403 waiting on condition  

JNI global refs: 72, weak refs: 8

Heap
 garbage-first heap   total 131072K, used 22995K [0x0000000780000000, 0x0000000800000000)
  region size 1024K, 20 young (20480K), 2 survivors (2048K)
 Metaspace       used 17131K, capacity 17575K, committed 17920K, reserved 1064960K
  class space    used 1793K, capacity 1956K, committed 2048K, reserved 1048576K

On my main app

Full thread dump OpenJDK 64-Bit Server VM (11.0.8+10 mixed mode):

Threads class SMR info:
_java_thread_list=0x00007fa7567f9240, length=12, elements={
0x00007fa754010000, 0x00007fa75402f800, 0x00007fa754032800, 0x00007fa753848800,
0x00007fa753849800, 0x00007fa754842000, 0x00007fa755869800, 0x00007fa75403c000,
0x00007fa754037000, 0x00007fa753c5c000, 0x00007fa7559c3800, 0x00007fa755c0e800
}

"main" #1 prio=5 os_prio=31 cpu=1580.69ms elapsed=22.20s tid=0x00007fa754010000 nid=0x307 runnable  [0x00007ffee359c000]
   java.lang.Thread.State: RUNNABLE
	at org.lwjgl.system.JNI.invokeI(Native Method)
	at org.lwjgl.glfw.GLFW.glfwInit(GLFW.java:830)
	at com.jme3.system.lwjgl.LwjglWindow.createContext(LwjglWindow.java:197)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:501)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:632)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:473)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:481)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:441)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:128)
	at io.tlf.outside.client.Client.load(Client.java:72)
	at io.tlf.outside.client.Main.internalLaunch(Main.java:205)
	at io.tlf.outside.client.Main.main(Main.java:84)

"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=2.74ms elapsed=22.18s tid=0x00007fa75402f800 nid=0x3503 waiting on condition  [0x00007000065c4000]
   java.lang.Thread.State: RUNNABLE
	at java.lang.ref.Reference.waitForReferencePendingList([email protected]/Native Method)
	at java.lang.ref.Reference.processPendingReferences([email protected]/Unknown Source)
	at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Unknown Source)

"Finalizer" #3 daemon prio=8 os_prio=31 cpu=4.05ms elapsed=22.18s tid=0x00007fa754032800 nid=0x3703 in Object.wait()  [0x00007000066c7000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000078047bc50> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x000000078047bc50> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	at java.lang.ref.Finalizer$FinalizerThread.run([email protected]/Unknown Source)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 cpu=0.39ms elapsed=22.16s tid=0x00007fa753848800 nid=0x3f03 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 cpu=8207.74ms elapsed=22.16s tid=0x00007fa753849800 nid=0x3d03 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"C1 CompilerThread0" #7 daemon prio=9 os_prio=31 cpu=3731.25ms elapsed=22.16s tid=0x00007fa754842000 nid=0x5603 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"Sweeper thread" #8 daemon prio=9 os_prio=31 cpu=61.92ms elapsed=22.16s tid=0x00007fa755869800 nid=0xa603 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Service Thread" #9 daemon prio=9 os_prio=31 cpu=0.07ms elapsed=22.11s tid=0x00007fa75403c000 nid=0x5803 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #10 daemon prio=8 os_prio=31 cpu=4.05ms elapsed=22.10s tid=0x00007fa754037000 nid=0xa203 in Object.wait()  [0x0000700006ee2000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000078047a550> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x000000078047a550> (a java.lang.ref.ReferenceQueue$Lock)
	at jdk.internal.ref.CleanerImpl.run([email protected]/Unknown Source)
	at java.lang.Thread.run([email protected]/Unknown Source)
	at jdk.internal.misc.InnocuousThread.run([email protected]/Unknown Source)

"Java2D Disposer" #13 daemon prio=10 os_prio=31 cpu=1.11ms elapsed=20.98s tid=0x00007fa753c5c000 nid=0x6703 in Object.wait()  [0x00007000072ee000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000078047c130> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x000000078047c130> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove([email protected]/Unknown Source)
	at sun.java2d.Disposer.run([email protected]/Unknown Source)
	at java.lang.Thread.run([email protected]/Unknown Source)

"Java2D Queue Flusher" #14 daemon prio=10 os_prio=31 cpu=17.09ms elapsed=20.91s tid=0x00007fa7559c3800 nid=0x990f in Object.wait()  [0x00007000073f1000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000078047a8c0> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
	at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run([email protected]/Unknown Source)
	- waiting to re-lock in wait() <0x000000078047a8c0> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
	at java.lang.Thread.run([email protected]/Unknown Source)

"outside-client" #15 prio=5 os_prio=31 cpu=9188.67ms elapsed=20.58s tid=0x00007fa755c0e800 nid=0x15403 waiting on condition  [0x00007000074f4000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep([email protected]/Native Method)
	at io.tlf.outside.world.JmeWorld.load(JmeWorld.java:118)
	at io.tlf.outside.client.Client.buildClient(Client.java:148)
	at io.tlf.outside.client.Client$1.run(Client.java:63)

"VM Thread" os_prio=31 cpu=45.72ms elapsed=22.18s tid=0x00007fa753841000 nid=0x3303 runnable  

"GC Thread#0" os_prio=31 cpu=252.93ms elapsed=22.20s tid=0x00007fa753815800 nid=0x5303 runnable  

"GC Thread#1" os_prio=31 cpu=262.96ms elapsed=21.58s tid=0x00007fa754351800 nid=0x9e03 runnable  

"GC Thread#2" os_prio=31 cpu=258.30ms elapsed=21.58s tid=0x00007fa754074000 nid=0x9d03 runnable  

"GC Thread#3" os_prio=31 cpu=242.57ms elapsed=19.38s tid=0x00007fa753d49000 nid=0x12203 runnable  

"G1 Main Marker" os_prio=31 cpu=0.93ms elapsed=22.20s tid=0x00007fa755828800 nid=0x5103 runnable  

"G1 Conc#0" os_prio=31 cpu=13.06ms elapsed=22.20s tid=0x00007fa754810000 nid=0x2e03 runnable  

"G1 Refine#0" os_prio=31 cpu=58.68ms elapsed=22.20s tid=0x00007fa75482b000 nid=0x4e03 runnable  

"G1 Young RemSet Sampling" os_prio=31 cpu=5.94ms elapsed=22.20s tid=0x00007fa754011000 nid=0x3003 runnable  
"VM Periodic Task Thread" os_prio=31 cpu=12.99ms elapsed=22.11s tid=0x00007fa754036000 nid=0x5a03 waiting on condition  

JNI global refs: 72, weak refs: 2

Heap
 garbage-first heap   total 285696K, used 84307K [0x0000000780000000, 0x0000000800000000)
  region size 1024K, 49 young (50176K), 12 survivors (12288K)
 Metaspace       used 34436K, capacity 35722K, committed 35888K, reserved 1081344K
  class space    used 3817K, capacity 4213K, committed 4224K, reserved 1048576K```

EDIT 2: Edited to have better dumps.

It looks like org.lwjgl.glfw.GLFW.glfwInit(GLFW.java:830) is never completing.

I feel like I am getting closer. I discovered that you cannot even have an unused import statement to awt or swing.

I have stripped out all swing and awt. Now I am just getting a crash:

[2020-07-31 15:01:08] [INFO   ] LWJGL 3.2.3 build 13 context running on thread main
 * Graphics Adapter: GLFW 3.4.0 Cocoa NSGL EGL OSMesa dynamic  
[2020-07-31 15:01:08] [SEVERE ] Failed to create display 
java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
	at org.lwjgl.opengl.GL.createCapabilities(GL.java:378)
	at com.jme3.system.lwjgl.LwjglContext.initContextFirstTime(LwjglContext.java:180)
	at com.jme3.system.lwjgl.LwjglContext.internalCreate(LwjglContext.java:470)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:505)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:632)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:473)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:481)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:441)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:128)
	at io.tlf.outside.client.Client.load(Client.java:72)
	at io.tlf.outside.client.Main.internalLaunch(Main.java:73)
	at io.tlf.outside.client.Main.main(Main.java:43)
 
[2020-07-31 15:01:08] [SEVERE ] Display initialization failed. Cannot continue.

It is most definitely on the main thread. Started using java -XstartOnFirstThread OutsideClient.jar Jme runs directly on the main thread. I am running out of ideas.

It sounds like it still isn’t in the main thread. How are you starting the JME application itself? I recall someone made a pull request that would have caused issues on osx, but I don’t know if it was merged or not.

1 Like

I am starting jme like so:

public void load(String server, int port, String user, char[] pass) {
        this.server = server;
        this.port = port;
        LOGGER.info("Outside Client starting");
        LOGGER.log(Level.INFO, "Framework Version: {0}", super.getVersion());
        LOGGER.log(Level.INFO, "Version: {0}", this.getVersion());

        buildJme(); //This will create our jme env, but not start it

        Thread outsideThread = new Thread("outside-client") {
            @Override
            public void run() {
                buildClient();
            }
        };

        //Start our threads
        outsideThread.start();

        LOGGER.fine("Starting JME on thread " + Thread.currentThread().getName());
        try {
            jme.start(); //This will ensure that our openGL thread is the main thread for OSX support
        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, "Uncaught exception from JME", ex);
        }
    }

    private void buildJme() {
        //Start JME
        AppSettings settings = new AppSettings(true);
        settings.setFrameRate(60);
        jme = new JmeApplication() {
            @Override
            public void destroy() {
                unload();
                super.destroy();
            }
        };
        jme.setSettings(settings);
        jme.setShowSettings(false);
        try {
            File appSettings = new File("graphics.properties");
            if (appSettings.exists()) {
                settings.load(new FileInputStream(appSettings));
            } else {
                settings.save(new FileOutputStream(appSettings));
            }

            //Load outside icons
            BufferedImage[] icons = new BufferedImage[Config.CLIENT_ICONS.length];
            for (int i = 0; i < icons.length; i++) {
                icons[i] = ImageIO.read(new File(RemoteAssetLoader.ASSET_DIR, Config.CLIENT_ICONS[i]));
            }
            settings.setIcons(icons);
        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, null, ex);
        }
    }

The main function directly calls the load with the variables passes in over command line from the launcher application. I create a parent thread for other non-jme related engine tasks, but jme is created and started on the main thread.

I can confirm that it is running on the main thread. The last error (not sure if this log is from jme or lwjgl) states it is on the main thread.

My thread dumps from the jvm several posts up show the jme stack and glfw running on the main thread:

Here is a full log of a load:

[2020-07-31 15:19:42] [FINE   ] Entering outside on thread main  
[2020-07-31 15:19:42] [INFO   ] Outside Client starting  
[2020-07-31 15:19:42] [INFO   ] Framework Version: 0.0.0  
[2020-07-31 15:19:42] [INFO   ] Version: 0.0.0  
[2020-07-31 15:19:42] [FINE   ] Starting JME on thread main  
[2020-07-31 15:19:42] [INFO   ] Starting Groovy script engine  
[2020-07-31 15:19:42] [INFO   ] Running on jMonkeyEngine 3.4.0-SNAPSHOT
 * Branch: master
 * Git Hash: 72b751c
 * Build Date: 2020-07-24  
[2020-07-31 15:19:42] [FINE   ] Creating Groovy Class Loader  
[2020-07-31 15:19:42] [FINE   ] Loading groovy classpath  
[2020-07-31 15:19:42] [INFO   ] LWJGL 3.2.3 build 13 context running on thread main
 * Graphics Adapter: GLFW 3.4.0 Cocoa NSGL EGL OSMesa dynamic  
[2020-07-31 15:19:42] [SEVERE ] Failed to create display 
java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
	at org.lwjgl.opengl.GL.createCapabilities(GL.java:378)
	at com.jme3.system.lwjgl.LwjglContext.initContextFirstTime(LwjglContext.java:180)
	at com.jme3.system.lwjgl.LwjglContext.internalCreate(LwjglContext.java:470)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:505)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:632)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:473)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:481)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:441)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:128)
	at io.tlf.outside.client.Client.load(Client.java:72)
	at io.tlf.outside.client.Main.internalLaunch(Main.java:73)
	at io.tlf.outside.client.Main.main(Main.java:43)
 
[2020-07-31 15:01:08] [SEVERE ] Display initialization failed. Cannot continue.

My very first log output is the thread name from the main right when the application is started.

Am I missing something? I am using the latest snapshot from master because I am dependent on several of the recent changes.

I am really starting to wonder if on jdk11 the XstartOnFirstThread actually works on osx for OpenGL. The only thing I can confirm is that it does prevent swing apps from loading…

I’m getting closer to figuring this one out. I got my hands on a newer mac, and opengl works the first couple launches, but with some graphical issues unless I resize the client.


After a resize:

This is very reproducible (every launch).

After I attempt to load the game, it crashes due to the error documented here: https://hub.jmonkeyengine.org/t/running-jfx-inside-of-jme-inside-of-jfx/43527/8

But what is interesting, after I crash due to the javafx error, macos will not give me opengl anymore on launch

java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
	at org.lwjgl.opengl.GL.createCapabilities(GL.java:378)
	at com.jme3.system.lwjgl.LwjglContext.initContextFirstTime(LwjglContext.java:180)
	at com.jme3.system.lwjgl.LwjglContext.internalCreate(LwjglContext.java:470)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:505)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:632)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:473)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:481)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:441)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:128)
	at io.tlf.outside.client.Client.load(Client.java:72)
	at io.tlf.outside.client.Main.internalLaunch(Main.java:73)
	at io.tlf.outside.client.Main.main(Main.java:43)
 

I can get it to give me opengl again by deleing the file and recopying the program back onto the computer. I’m not sure why but it is like it remembers I crashed so it will not give me opengl again.

I think I am going to call it good and just say we don’t support apple as it looks like there are other issues with javafx that makes it not possible for now.

I haven’t read everything but the initial exception is indeed by violating glfw/lwjgl3’s rule to only launch on the OS MainThread.
The other exception was when I tried to create the window on the mainthread but then rebind the context on a different thread, I think, I didn’t give that more thought.
It’s just that Mac OS X is enforcing that and we can’t do much on that.