Sometimes when I shutdown by pressing the X button in the top right corner, I get a null pointer on the jawtWindow inside attachNewtChild. Call stack is below. All IsoCanvas.paint does is call super.paint(). Problem is a simple race condition - destroyImpl sets jawtWindow to null while paint is in progress. Null check at top of attachNewtChild() gets bypassed but by the time it hits jawtWindow.isOffscreenLayerSurfaceEnabled, jawtWindow is null. Either need synchronization around destroy / paint or destroy needs to be called from the same EDT that's running the paint so it's sequential. Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.jogamp.newt.awt.NewtCanvasAWT.attachNewtChild(NewtCanvasAWT.java:745) at com.jogamp.newt.awt.NewtCanvasAWT.validateComponent(NewtCanvasAWT.java:660) at com.jogamp.newt.awt.NewtCanvasAWT.paint(NewtCanvasAWT.java:461) at Iso3d.IsoCanvas.paint(IsoCanvas.java:103) at sun.awt.RepaintArea.paintComponent(RepaintArea.java:264) at sun.awt.RepaintArea.paint(RepaintArea.java:240) at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:347) at java.awt.Component.dispatchEventImpl(Component.java:4937) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729) at java.awt.EventQueue.access$200(EventQueue.java:103) at java.awt.EventQueue$3.run(EventQueue.java:688) at java.awt.EventQueue$3.run(EventQueue.java:686) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) at java.awt.EventQueue$4.run(EventQueue.java:702) at java.awt.EventQueue$4.run(EventQueue.java:700) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:699) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
d8f7418f170aba4703df2b11d5ae11598f71a796 As suggested: Employ synchronization on lifecycle actions _and_ perform destroyImpl(..) always on AWT-EDT to avoid a deadlock.