Skip to main content

Why rendering stops if there's an exception in the EventDispatchThread?

22 replies [Last post]
paasiala
Offline
Joined: 2004-09-17
Points: 0

Hello,

For a while I've been wondering the following: If there's an uncaught bug in
some action, the rendering stops. To make sure that this is not a bug in our
way of using Java3D, I modified the HelloUniverse application and got the
problem duplicated there also. I added the following lines in the init
method:

Action dummyAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
throw new UnsupportedOperationException("crash");
}
};

JButton dummy = new JButton("D");
dummy.addActionListener(dummyAction);

add(dummy, BorderLayout.SOUTH);

If I now press the "D" button, the rendering of the canvas stops. This must
be a known bug. Is there a workaround for it? Of course, there should never
be exceptions, but I remember that even I have sometimes written code that
crashes :)

Regards,

Pasi

Here's the full code still.

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.vecmath.*;

public class HelloUniverse extends Applet {

private SimpleUniverse u = null;

public BranchGroup createSceneGraph() {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();

// Create the TransformGroup node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at run time. Add it to
// the root of the subgraph.
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRoot.addChild(objTrans);

// Create a simple Shape3D node; add it to the scene graph.
objTrans.addChild(new ColorCube(0.4));

// Create a new Behavior object that will perform the
// desired operation on the specified transform and add
// it into the scene graph.
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, 4000);

RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
objRoot.addChild(rotator);

// Have Java 3D perform optimizations on this scene graph.
objRoot.compile();

return objRoot;
}

public HelloUniverse() {
}

public void init() {
setLayout(new BorderLayout());
GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();

Canvas3D c = new Canvas3D(config);
add("Center", c);

Action dummyAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
throw new UnsupportedOperationException("crash");
}
};

JButton dummy = new JButton("D");
dummy.addActionListener(dummyAction);

add(dummy, BorderLayout.SOUTH);

// Create a simple scene and attach it to the virtual universe
BranchGroup scene = createSceneGraph();
u = new SimpleUniverse(c);

// This will move the ViewPlatform back a bit so the
// objects in the scene can be viewed.
u.getViewingPlatform().setNominalViewingTransform();

u.addBranchGraph(scene);
}

public void destroy() {
u.cleanup();
}

//
// The following allows HelloUniverse to be run as an application
// as well as an applet
//
public static void main(String[] args) {
new MainFrame(new HelloUniverse(), 256, 256);
}
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nvaidya
Offline
Joined: 2004-08-03
Points: 0

> Vaidya,
>
> Can you post your findings in the bug, unless you've
> already done so? They
> should help in fixing it. Thanks for putting effort
> into this annoying, but
> for some reason, low priority bug.
>
> Pasi

OK ! done !

Though the custom EventQueue is the only workaround that obviates the need for detaching and attaching the Canvas3D to keep it from freezing, I'm not sure if it is as standard an approach as the ones based on custom ThreadGroup or JDK 1.5 stock handlers. I've been testing it in a few apps. and seem to encounter no issues.

Also, I believe that there was an issue in installing JDK 1.5 Exception handlers on specific threads. In light of that, the difference between using setUncaughtExceptionHandler() and setDefaultUncaughtExceptionHandler(...) above is interesting.

-- Vaidya

kcr
Offline
Joined: 2004-03-17
Points: 0

The bug report has been updated.

https://java3d.dev.java.net/issues/show_bug.cgi?id=78

We will have a fix shortly (in time for 1.4.0-beta3).

-- Kevin

nvaidya
Offline
Joined: 2004-08-03
Points: 0

> The bug report has been updated.
>
> https://java3d.dev.java.net/issues/show_bug.cgi?id=78
>
> We will have a fix shortly (in time for
> 1.4.0-beta3).
>
> -- Kevin

Thanks very much for getting the fix into beta3 !

--Vaidya

kcr
Offline
Joined: 2004-03-17
Points: 0

The fix has been checked in, and will be available in tomorrow morning's build. We would appreciate your testing it if you have the time. Thanks.

-- Kevin

nvaidya
Offline
Joined: 2004-08-03
Points: 0

Absolutely !

OK ! downloaded the latest Java 3D daily build and ran the tests.

The system/env is:

GeForce 6600GT, ForceWare 81.95
j3d.version = 1.4.0-pre9-0512210103-experimental 21 Dec 2005
Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b60, mixed mode, sharing)

All my tests so far have worked out perfectly, i.e., with or w/o an Exception Handler, rendering doesn't freeze when an uncaught exception is thrown. Excellent Fix !

On a minor note, which seems to be a purely JDK 1.5 weirdness, there is still this problem with Case 2(b) as mentioned in my earlier post. That is with setUncaughtExceptionHandler(...) as against setDefaultUncaughtExceptionHanlder(...), Dialog shows up only when the first Exception is thrown and not with later ones. IOW, the "catch-all" ExceptionHandler works but the EDT specific handler works only the first time. This may be the case (also) of the handler probably not recognizing the new EDT.

Thanks

-- Vaidya

paasiala
Offline
Joined: 2004-09-17
Points: 0

Nice to hear that I'm not alone. I'm running Windows 2000 with Nvidia GeForce2. I thought that this isn't a platform specific issue.

Pasi

kcr
Offline
Joined: 2004-03-17
Points: 0

I must not have tried this on Windows recently, because I get the same behavior on my Windows/XP system with an NVIDIA 5950. So it looks like a Windows-specific bug, but not necessarily related to the graphics driver. My guess would be a bug in Java 3D (most likely) or a bug in AWT (possible, but less likely).

Could the person who originially reported this please file an Issue at:

https://java3d.dev.java.net/servlets/ProjectIssues

See the following for more information on filing Java 3D issues:

https://java3d.dev.java.net/#Reporting_Issues

-- Kevin

paasiala
Offline
Joined: 2004-09-17
Points: 0

I filed issue#78 for the bug. I didn't put the code in the description, since I thought that I'd add it as a separate comment, but seems that I didn't have the rights to do it. Anyway, I put a pointer to this thread, so the code can be found that way.

Pasi

kcr
Offline
Joined: 2004-03-17
Points: 0

> I filed issue#78 for the bug. I didn't put the code in the description, since I thought that I'd add
> it as a separate comment, but seems that I didn't have the rights to do it.

In order to update an existing bug, you need to be a member of the java3d project on java.net. To do this, go to the start page (https://java3d.dev.java.net), click on the "Request project membership/role" link, and request the "Observer" role.

> Anyway, I put a pointer to this thread, so the code can be found that way.

Yes, this is fine. Thanks.

-- Kevin

paasiala
Offline
Joined: 2004-09-17
Points: 0

I noticed that if I remove the canvas after crash and then put it back,
rendering starts again. I added sample code for this in the bug.

Pasi

nvaidya
Offline
Joined: 2004-08-03
Points: 0

Hi Kevin,

This issue hasn't been fixed yet, am I right ? Any chance that it could be done anytime soon (before 1.3.2 beta ???)considering the present priorities and schedule ? I've a GUI with scores of controls to manipulate the scenegraph and a fix will indeed be most convenient.

Thanks

--Vaidya

paasiala
Offline
Joined: 2004-09-17
Points: 0

A while ago the priority was lowered from P3 to P4, so I don't think that this is in any milestone yet.

Pasi

kcr
Offline
Joined: 2004-03-17
Points: 0

This won't be fixed for 1.3.2-beta, which we plan to release today or tomorrow. We don't currently plan to fix any more non-critical bugs, and I would argue that this falls into the category of non-critical bug, since it isn't a regression (i.e., the bug was there in 1.3.1) and it has a workaround, although I believe that the workaround is inconvenient for many applications.

This would be a good bug for someone in the community to volunteer to help out with. If we could get more information about why it is failing we might be able to look into a solution without spending a lot of time on it. Btw, I'm not 100% convinced that this is a Java 3D bug -- it could be an AWT bug.

-- Kevin

nvaidya
Offline
Joined: 2004-08-03
Points: 0

> This won't be fixed for 1.3.2-beta, which we plan to
> release today or tomorrow. We don't currently plan to
> fix any more non-critical bugs, and I would argue
> that this falls into the category of non-critical
> bug, since it isn't a regression (i.e., the bug was
> there in 1.3.1) and it has a workaround, although I
> believe that the workaround is inconvenient for many
> applications.

If the workaround is to detach and reattach the canvas, then I concur that it is most inconvenient. I still believe, though not absolutely, that the problem wasn't there with Win98.

>
> This would be a good bug for someone in the community
> to volunteer to help out with. If we could get more
> information about why it is failing we might be able
> to look into a solution without spending a lot of
> time on it. Btw, I'm not 100% convinced that this is
> a Java 3D bug -- it could be an AWT bug.
>
> -- Kevin

Well, I'd volunteer but my knowledge of AWT innards is as good as my knowledge of quantum electrodynamics ! We all will be mighty pleased if you could chat with the AWT folks about this. As an aside, my issues with JFile/JColorChooser could also be possibly AWT related and again atleast to the extent that those were not there with Win98.

And as for AWT volunteers maybe Pasi could make a new and more visible post here to get their attention for help with this issue.

Thanks

--Vaidya

paasiala
Offline
Joined: 2004-09-17
Points: 0

Thanks Vaidya for supporting me and giving pressure to Kevin.

Kevin, is there something that we could look at? I tried to look at the fields of canvas after the rendering had stopped, but saw nothing helpfull there, as far as I can remember. Since this doesn't happen on all platforms, I assume that it is somewhere in the native code. If the situation could be noticed automatically on Java side, then the workaround could be automated until the real cause has been fixed. So is there a check that could be run to verify that the renderer is alive?

I believe that my understanding of AWT is maybe on the same level as Vaidya's (unless he is being too modest ;). I wouldn't like to blame AWT unless I could be sure that the problem really lies there.

Regards,

Pasi

nvaidya
Offline
Joined: 2004-08-03
Points: 0

Any news on this issue ?

Until yesterday I didn't realize that Pasi had actually posted a workaround based on JDK 1.5 to automatically catch the uncaught exception on the EDT and detach and reattach the Canvas3D to keep it alive. A smart fix ! Might have saved me the trouble of doing some tinkering on my own.

But then, it looks like there is a way to catch the uncaught exception and keep the rendering alive without the need for detaching and reattaching the Canvas. That and some of my other findings from alternatives below might provide additional clues to fix this issue.

The testcase is the one formulated by Pasi with a JButton to trigger an UnSupportedOperationException on the EDT. In the exception handler I show a JOptionPane instead to indicate that the exception has been caught.

1. Custom ThreadGroup (JDK 1.4):
[code]
public static void main(String[] args) {

new Thread( new EDTThreadGroup(), "EDTThreadWrapper" ) {
public void run() {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
new MainFrame(new HelloUniverseTG(), 256, 256);
}
}
);
}
}.start();

static class EDTThreadGroup extends ThreadGroup {
public EDTThreadGroup() {
super( "EDTThreadGroup" );
}
public void uncaughtException( Thread thread, Throwable throwable ) {
JOptionPane.showMessageDialog( null, throwable );
}
}
}
[/code]

Dialog gets displayed when the button is clicked. Rendering continues until the time the Dialog is disposed. With subsequent clicks, the Dialog promptly shows up each time but the Canvas3D remains frozen.

2. UnCaughtExceptionHandler (JDK 1.5):
[code]
public static void main(String[] args) {

try {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(
new EDTExceptionHandler() );
}
});
} catch ( Exception ex ) {
ex.printStackTrace();
}

SwingUtilities.invokeLater( new Runnable() {
public void run() {
new MainFrame(new HelloUniverseJ5(), 256, 256);
}
});
}

static class EDTExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException( Thread thread, Throwable throwable ) {
JOptionPane.showMessageDialog( null, throwable );
}
}
[/code]
Checked 2 cases here:
a) Same as Pasi's using setDefaultUncaughtExceptionHandler(...). Results same as (1) above.
b) using setUncaughtExceptionHandler(...). Results same as (1) with the first button click. Interestingly, with subsequent clicks, the Dialog doesn't show up and the stack traces are dumped to the console instead.

3. Custom EventQueue (JDK 1.4):
[code]
public static void main(String[] args) {

Toolkit.getDefaultToolkit().getSystemEventQueue().push(
new EventQueue() {
protected void dispatchEvent(final AWTEvent evt) {
try {
super.dispatchEvent(evt);
}
catch (Exception ex) {
Thread t = Thread.currentThread();
System.out.println( t.getName() );
JOptionPane.showMessageDialog( null, ex );
}
}
});

SwingUtilities.invokeLater(
new Runnable() {
public void run() {
new MainFrame(new HelloUniverseEQ(), 256, 256);
}
});
}
[/code]
Bingo ! This seems to work perfectly. Dialog gets displayed each time and the rendering proceeds uninterrupted. For extra safety, exception handlers of the type (1) or 2(a) can be also set on the main thread.

So what really happens when an uncaught exception is thrown ? AIUI, the current EDT dies and a new one takes its place when a subsequent event is triggered. If I have to venture a guess, it appears that for some reason Java3D doesn't seem to take note of the new EDT or fails to feed to it. You may want check this with the Netbeans thread profiler too.

Hope this helps

-- Vaidya

Pasi Paasiala

Vaidya,

Can you post your findings in the bug, unless you've already done so? They
should help in fixing it. Thanks for putting effort into this annoying, but
for some reason, low priority bug.

Pasi

-----Original Message-----
From: java3d-interest@javadesktop.org
[mailto:java3d-interest@javadesktop.org]
Sent: 9. joulukuuta 2005 21:30
To: interest@java3d.dev.java.net
Subject: Re: Why rendering stops if there's an exception in the
EventDispatchThread?

Any news on this issue ?

Until yesterday I didn't realize that Pasi had actually posted a workaround
based on JDK 1.5 to automatically catch the uncaught exception on the EDT
and detach and reattach the Canvas3D to keep it alive. A smart fix ! Might
have saved me the trouble of doing some tinkering on my own.

But then, it looks like there is a way to catch the uncaught exception and
keep the rendering alive without the need for detaching and reattaching the
Canvas. That and some of my other findings from alternatives below might
provide additional clues to fix this issue.

The testcase is the one formulated by Pasi with a JButton to trigger an
UnSupportedOperationException on the EDT. In the exception handler I show a
JOptionPane instead to indicate that the exception has been caught.

1. Custom ThreadGroup (JDK 1.4):
[code]
public static void main(String[] args) {

new Thread( new EDTThreadGroup(), "EDTThreadWrapper" ) {
public void run() {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
new MainFrame(new HelloUniverseTG(), 256, 256);
}
}
);
}
}.start();

static class EDTThreadGroup extends ThreadGroup {
public EDTThreadGroup() {
super( "EDTThreadGroup" );
}
public void uncaughtException( Thread thread, Throwable throwable )
{
JOptionPane.showMessageDialog( null, throwable );
}
}
[/code]
Dialog gets displayed when the button is clicked. Rendering continues until
the time the Dialog is disposed. With subsequent clicks, the Dialog promptly
shows up each time but the Canvas3D remains frozen.

2. UnCaughtExceptionHandler (JDK 1.5):
[code]
public static void main(String[] args) {

try {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(
new EDTExceptionHandler() );
}
});
} catch ( Exception ex ) {
ex.printStackTrace();
}

SwingUtilities.invokeLater( new Runnable() {
public void run() {
new MainFrame(new HelloUniverseJ5(), 256, 256);
}
});
}

static class EDTExceptionHandler implements
Thread.UncaughtExceptionHandler {
public void uncaughtException( Thread thread, Throwable throwable )
{
JOptionPane.showMessageDialog( null, throwable );
}
}
[/code]
Checked 2 cases here:
a) Same as Pasi's using setDefaultUncaughtExceptionHandler(...). Results
same as (1) above.
b) using setUncaughtExceptionHandler(...). Results same as (1) with the
first button click. Interestingly, with subsequent clicks, the Dialog
doesn't show up and the stack traces are dumped to the console instead.

3. Custom EventQueue (JDK 1.4):
[code]
public static void main(String[] args) {

Toolkit.getDefaultToolkit().getSystemEventQueue().push(
new EventQueue() {
protected void dispatchEvent(final AWTEvent evt) {
try {
super.dispatchEvent(evt);
}
catch (Exception ex) {
Thread t = Thread.currentThread();
System.out.println( t.getName() );
JOptionPane.showMessageDialog( null, ex );
}
}
});

SwingUtilities.invokeLater(
new Runnable() {
public void run() {
new MainFrame(new HelloUniverseEQ(), 256, 256);
}
});
[/code]
Bingo ! This seems to work perfectly. Dialog gets displayed each time and
the rendering proceeds uninterrupted. For extra safety, exception handlers
of the type (1) or 2(a) can be also set on the main thread.

So what really happens when an uncaught exception is thrown ? AIUI, the
current EDT dies and a new one takes its place when a subsequent event is
triggered. If I have to venture a guess, it appears that for some reason
Java3D doesn't seem to take note of the new EDT or fails to feed to it. You
may want check this with the Netbeans thread profiler too.

Hope this helps

-- Vaidya
---
[Message sent by forum member 'NVaidya' (N. Vaidya)]

http://www.javadesktop.org/forums/thread.jspa?messageID=129575&#129575

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

Pasi Paasiala

[duplicate message deleted]

Message was edited by: kcr

paasiala
Offline
Joined: 2004-09-17
Points: 0

One more thing: I'm using the OpenGL version.

Pasi

nvaidya
Offline
Joined: 2004-08-03
Points: 0

I've had this problem on some systems for a while now. IIRC, the following combo *did not* trigger this issue:
Java3D 1.3.1, J2SDK 1.4.2_01 and earlier, winOGL, *WIN98*, nvidia Detonator driver.

And the ones that can deterministically reproduce this issue are:
Java 3D 1.3.1 and latest 1.3.2-experimental builds, J2SDK 1.4.2_03, JDK 1.5.0-RC, winOGL, winXP, nvidia ForceWare driver.

I'm almost inclined to believe that switching to WinXP coincided with my observing this issue but I could be wrong. If Pasi has a win98, he could probably put that empirical theory to test.

paasiala
Offline
Joined: 2004-09-17
Points: 0

I'm using Java3D 1.3.1 on Windows JDK1.4.2_05. I think we've had this problem for some time, but I thought it was the way we use j3d. I just wanted to test this in a trivial environment and got it duplicated. Did you try the example?

Pasi

kcr
Offline
Joined: 2004-03-17
Points: 0

What version of Java 3D are you running? What version of the JDK? What platform (Windows/XP, Linux, etc)? We've never seen this bug and have run plenty of programs that throw exceptions in the AWT Event Thread.

-- Kevin