NullPointerException in GLJPanel

Hi all,

This is my first post to this forum so in the beginning please let me thank
you all for sharing your information about JOGL and Java. I’ve been
following your discusions for some time with great pleasure.

I’ve built an application for data visualisation using GLJPanel and
JInternalFrame objects. After opening and closing approximately 20
JInternalFrame windows performance of my application begins to deteorate:
it means that GLJPanel is not as responsive as it was in the beginning. If
I continue with opening and closing internal windows my application begins
really to crawl after approximately 50-60 open and close actions
counting from the beginning and at that moment I receive a NullPointerException.
This bug is repeatable. I don’t know whether it is important or not but
I would also like to mention that there are only 5 internal windows
opened at the same time. I have tried different combinations of options
but without success: -client/-server, -Dsun.java2d.noddraw=true/false,
-Djogl.1thread=true/false.

My environment is the following:
Windows XP, version 5.1, sp1

java version “1.5.0”
Java™ 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot™ Client VM (build 1.5.0-b64, mixed mode, sharing)

Jogl Version = 1.1.0-b10

OpenGL Renderer = GeForce FX 5700LE/AGP/SSE2/3DNOW!
OpenGL Version = 1.5.0
OpenGL Vendor = NVIDIA Corporation

The exception I receive is the following:

Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
at net.java.games.jogl.GLJPanel.paintComponent(GLJPanel.java:160)
at javax.swing.JComponent.paint(JComponent.java:1003)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
at java.awt.Container.paint(Container.java:1709)
at javax.swing.JComponent.paintChildren(JComponent.java:852)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4930)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4883)
at javax.swing.JComponent._paintImmediately(JComponent.java:4826)
at javax.swing.JComponent.paintImmediately(JComponent.java:4633)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:114)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
at net.java.games.jogl.GLJPanel.paintComponent(GLJPanel.java:160)
at javax.swing.JComponent.paint(JComponent.java:1003)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
at java.awt.Container.paint(Container.java:1709)
at javax.swing.JComponent.paintChildren(JComponent.java:852)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paint(JComponent.java:1012)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
at java.awt.Container.paint(Container.java:1709)
at javax.swing.JComponent.paintChildren(JComponent.java:852)
at javax.swing.JComponent.paint(JComponent.java:1012)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:559)
at javax.swing.JComponent.paintChildren(JComponent.java:840)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4937)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4883)
at javax.swing.JComponent.paint(JComponent.java:993)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
at java.awt.Container.paint(Container.java:1709 )
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248 )
at sun.awt.RepaintArea.paint(RepaintArea.java:224 )
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:254)
at java.awt.Component.dispatchEventImpl(Component.java:4031)
at java.awt.Container.dispatchEventImpl(Container.java:2024)
at java.awt.Window.dispatchEventImpl(Window.java:1766)
at java.awt.Component.dispatchEvent(Component.java:3803)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

This bug is really a show stopper. Is there any other information I should
provide to resolve this problem?

Your advice how to continue would be very helpful.

Best regards,
Andrei

If you could boil your application down to a repeatable test case that would be helpful. There are definitely some resource leaks in the GLJPanel that need to be cleaned up but some of them I’m not 100% sure how to fix. If you could at least get your stack trace recorded in a bug report that would be good.

FYI, I filed and fixed Issue 160 just now which should clean up the resource leaks in the GLJPanel. The new code hasn’t been tested on a wide variety of machines yet but both the hardware-accelerated path and software rendering path in the GLJPanel have been stress tested on one machine and seem to be working. This fix will show up in the next JOGL release, or you can take a CVS update and build the tree. I’d be interested to hear if the new code makes your application work better.

Hi Ken,

thank you very much for your quick response and please excuse me for not answering you sooner.

I’ve tested the latest JOGL version beta11 but I’m sorry to say that my application does not work properly any more. Actually, I think that it falls into a deadlock. Did GLJPanel drastically change during previous and this version?

I enclose stack traces:


JOGL version 1.1.0-b11
Using single-threaded workaround of dispatching display() on event thread
Full thread dump Java HotSpot(TM) Client VM (1.5.0_02-b09 mixed mode):

"Thread-3" prio=7 tid=0x1fac9070 nid=0x198 runnable [0x1765f000..0x1765fbe8]
        at net.java.games.jogl.impl.windows.WGL.NativeEventLoop(Native Method)
        at net.java.games.jogl.impl.windows.WindowsGLContextFactory$NativeWindow
Thread.run(WindowsGLContextFactory.java:323)

"pool-1-thread-3" prio=5 tid=0x1fabc208 nid=0x1b4 waiting on condition [0x1761f000..0x1761fc68]
        at sun.misc.Unsafe.park(Native Method)
        at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireNanos(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireNanos(Unknown Source)
        at java.util.concurrent.SynchronousQueue$Node.waitForPut(Unknown Source)
        at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"pool-1-thread-2" prio=5 tid=0x16e29d88 nid=0x650 waiting on condition [0x172df000..0x172dfce8]
        at sun.misc.Unsafe.park(Native Method)
        at java.util.concurrent.locks.LockSupport.parkNanos(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireNanos(Unknown Source)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireNanos(Unknown Source)
        at java.util.concurrent.SynchronousQueue$Node.waitForPut(Unknown Source)
        at java.util.concurrent.SynchronousQueue.poll(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"TimerQueue" daemon prio=5 tid=0x16eaa1f8 nid=0x148 in Object.wait() [0x1732f000..0x1732fd68]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x03f9f1d0> (a javax.swing.TimerQueue)
        at javax.swing.TimerQueue.run(Unknown Source)
        - locked <0x03f9f1d0> (a javax.swing.TimerQueue)
        at java.lang.Thread.run(Unknown Source)

"DestroyJavaVM" prio=5 tid=0x000368b8 nid=0x27c waiting on condition [0x00000000..0x0007fae8]

"AWT-EventQueue-0" prio=7 tid=0x16e642a0 nid=0xc0 waiting for monitor entry [0x1722f000..0x1722fbe8]
        at java.awt.Frame.removeNotify(Unknown Source)
        - waiting to lock <0x03ea6030> (a java.awt.Component$AWTTreeLock)
        at java.awt.Window$1DisposeAction.run(Unknown Source)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

"pool-1-thread-1" prio=5 tid=0x16e5ec80 nid=0x530 in Object.wait() [0x171ef000..0x171efae8]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x02bbad48> (a java.awt.EventQueue$1AWTInvocationLock)
        at java.lang.Object.wait(Unknown Source)
        at java.awt.EventQueue.invokeAndWait(Unknown Source)
        - locked <0x02bbad48> (a java.awt.EventQueue$1AWTInvocationLock)
        at java.awt.Window.doDispose(Unknown Source)
        at java.awt.Window.dispose(Unknown Source)
        at net.java.games.jogl.GLJPanel.removeNotify(GLJPanel.java:195)
        at java.awt.Container.remove(Unknown Source)
        - locked <0x03ea6030> (a java.awt.Component$AWTTreeLock)
        at java.awt.Container.remove(Unknown Source)
        - locked <0x03ea6030> (a java.awt.Component$AWTTreeLock)
        at java.awt.Container.addImpl(Unknown Source)
        - locked <0x03ea6030> (a java.awt.Component$AWTTreeLock)
        at java.awt.Container.add(Unknown Source)
        at application.modelviewer.CnsViewer$LayoutFactory.getCnsViewerPanel(CnsViewer.java:285)
        at application.modelviewer.CnsViewer$EventListenerAdapter.handleEvent(CnsViewer.java:188)
        at application.events.core.impl.EventHandlerImpl.notifyListeners(EventHandlerImpl.java:134)
        at application.events.core.impl.EventHandlerImpl$2.run(EventHandlerImpl.java:111)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"Java2D Disposer" daemon prio=10 tid=0x16db76f0 nid=0x590 in Object.wait() [0x1716f000..0x1716fce8]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x03f22a28> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        - locked <0x03f22a28> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        at sun.java2d.Disposer.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"AWT-Windows" daemon prio=7 tid=0x16db1418 nid=0xcc runnable [0x170bf000..0x170bfd68]
        at sun.awt.windows.WToolkit.eventLoop(Native Method)
        at sun.awt.windows.WToolkit.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

"AWT-Shutdown" prio=5 tid=0x16db0f30 nid=0x4c8 in Object.wait() [0x1707f000..0x1707f9e8]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x03ea45a8> (a java.lang.Object)
        at java.lang.Object.wait(Unknown Source)
        at sun.awt.AWTAutoShutdown.run(Unknown Source)
        - locked <0x03ea45a8> (a java.lang.Object)
        at java.lang.Thread.run(Unknown Source)

"Low Memory Detector" daemon prio=5 tid=0x00a8c0c8 nid=0x388 runnable [0x00000000..0x00000000]

"CompilerThread0" daemon prio=10 tid=0x00a8aca0 nid=0x2e8 waiting on condition [0x00000000..0x16cbf8c0]

"Signal Dispatcher" daemon prio=10 tid=0x00a8a028 nid=0x658 waiting on condition [0x00000000..0x00000000]

"Finalizer" daemon prio=9 tid=0x00a81660 nid=0x6ec in Object.wait() [0x16c3f000..0x16c3fc68]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x03ea4750> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        - locked <0x03ea4750> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

"Reference Handler" daemon prio=10 tid=0x00a801d0 nid=0x638 in Object.wait() [0x16bff000..0x16bffce8]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x03ea47d0> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Unknown Source)
        at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
        - locked <0x03ea47d0> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x00a7c088 nid=0x7e0 runnable

"VM Periodic Task Thread" prio=10 tid=0x00a8d2a0 nid=0x47c waiting on condition

Best regards,
Andrei

In 1.1 b11 the resource leaks you pointed out in the GLJPanel were fixed by overriding addNotify and removeNotify. Thanks for pointing them out. The deadlock above is a bug in your application caused by GLJPanel.removeNotify now doing more work. Any modifications to a Swing widget hierarchy after it has been constructed must be done on the AWT event queue thread via SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater(). You need to wrap the code which removes the GLJPanel in a Runnable and invoke it using one of those methods.

Hi Ken,

I’ve tested my application and can confirm that the exception which was reported before is not present anymore with the latest JOGL 1.1-beta11 version. I have also found the reason for a deadlock in my application. Unfortunately, I needed more than a day because I didn’t carefully listen to your advice. Thanks.

Best regards,
Andrei