Exceptions aren't raised in threads? Is this normal behavior?

I have a question about using threads. I’ve been losing lots of time over this behavior but I couldn’t spot this until recently and after making a test case, I can reproduce this issue easily and all the time. I’m way more cautious now.

Let’s say I have a project in which I run threads. Why is that if one of the threads SHOULD crash, it simply doesn’t? I’ve looked in the dependant libraries for exception try/catch and couldn’t find any. The console is empty and no error shows up anywhere. The thread simply skips and does not execute. I mean, it took a while for me to spot this. I was wondering what was wrong when suddenly while reading my source code I saw I was accessing an array 1 unit too high and that should have raised an out of bounds error, but in the thread, it simply does nothing and stops executing only that thread, but continues to execute the rest of the application like if nothing happened.

Is it me or has anybody come upon this situation too?

I think this should be “fixed” no?

Thx

Are you using Nifty? 'Cause Nifty loves to catch exceptions and not do anything with them.

You’ll have to show us code if you want a more specific answer but in general if you start a thread then it’s up to you to handle the exceptions of that thread. If you don’t catch them then the thread may die because of them… though the default exception handler should dump the stack trace to the console there are lots of ways this could be disrupted.

If you are using Executors to execute your threads then depending on how you start them it can also swallow exceptions. Any path that could return a Future will swallow all exceptions that the thread doesn’t handle.

…but again, now I venture into the realm of guessing. You say you have a test case then you should post it.

@sgold Yes I use Nifty. That may well be the culprit then. I’ll try without it later and see.

Hi Paul, yes I would have thought it would show /something/ in the console at the very least. I could show you the code, but seriously, it’s @jayfella’s “world” terrain pager he posted in january. I simply had an out of bounds scenario in the chunk loading thread and that chunk of terrain wouldn’t load nor display any kind of error, until I found out it was an out of bounds exception that was NOT raised lol.

I’ll try @sgold suggestion first and post results here. Thx.

When nifty encounters an error, it will vomit a wall-of-china length warning in the console.

Have fun finding the appropriate spot. I suggest turning on logging for nifty even if it`s damn too verbose to start with.

LOL @ madjack

If you are using an executor service and want exceptions to be thrown you need to call the Future.get() method

@ben-2 I hope you mean TerrainWorld and not World because the world project was abandoned in favour of creating replacement for the deprecated TerrainGrid. TerrainWorld should work fine, though. We tested that quite extensively.

@jayfella: wait… I’m not saying there is an issue with your “World” project. All I’m saying is that exceptions are not thrown from within “World” threads. ON A SIDE NOTE, why is “World” abandonned in favour of “TerrainWorld” when “World” was updated in january versus “TerrainWorld” was updated in november?! What’s the difference between two and why is “World” more recent if it’s not good? It works REALLY GREAT here! What’s the difference or what kind of issues/limitations, if any, are there between the two?

@zzuegg: OK, well maybe that explains it, because “World” does not call Future.get() anywhere that I can see, unless it’s hidden in the ScheduledThreadPoolExecutor class somewhere or from within dependant classes which I did not dig through yet.

Thx guys for your time.

@.Ben. said: @jayfella: wait... I'm not saying there is an issue with your "World" project. All I'm saying is that exceptions are not thrown from within "World" threads. ON A SIDE NOTE, why is "World" abandonned in favour of "TerrainWorld" when "World" was updated in january versus "TerrainWorld" was updated in november?! What's the difference between two and why is "World" more recent if it's not good? It works REALLY GREAT here! What's the difference or what kind of issues/limitations, if any, are there between the two?

@zzuegg: OK, well maybe that explains it, because “World” does not call Future.get() anywhere that I can see, unless it’s hidden in the ScheduledThreadPoolExecutor class somewhere or from within dependant classes which I did not dig through yet.

Thx guys for your time.

This is why I was curious to see the code about how the jobs are submitted to the executor. It matters. If they are submitted using the method that returns a Future then the Future needs to have get() called or exceptions are lost. Else the job code needs to be careful to wrap everything in one big try/catch.

In your original post you said “I couldn’t spot this until recently and after making a test case”… I assumed incorrectly this was a classic test case that we could look at ourselves and not just a “I arranged things to fail consistently with all of the various dependencies that I’m using”.

For example, if you create your own threading test case you can see under what conditions it will and won’t report stack traces. This would be the approach if you wanted to track down what the real issue is in the dependencies that you are using since you could modify your test case until it fails in a similar way (still isolated from the failing dependencies).

@ Paul, yes… by a test case, I indeed only arranged a scenario that I could reproduce the bug every execution, in other words, I isolated the bug in my app. Sorry for the confusion. I’d have to set up a real test case, but at the moment I’m at work so I’ll have to delay this as this would take quite some time for me to make a test case from scratch, but basically, I’m just using “World” and anywhere in the chunk creation thread, just try to access an out of bounds array position and that chunk won’t attach and no error will ever output anywhere and the app will continue to run smoothly without any sign of failure except for that terrain chunk that will not render because it was not attached because the thread exited silently.

@.Ben. said: @sgold Yes I use Nifty. That may well be the culprit then. I'll try without it later and see.

Hi Paul, yes I would have thought it would show /something/ in the console at the very least. I could show you the code, but seriously, it’s @jayfella’s “world” terrain pager he posted in january. I simply had an out of bounds scenario in the chunk loading thread and that chunk of terrain wouldn’t load nor display any kind of error, until I found out it was an out of bounds exception that was NOT raised lol.

I’ll try @sgold suggestion first and post results here. Thx.

The Nifty issue I’m aware of has to do with when you use a control (such as a button) with an interact tag (such as onRelease) to initiate some action. For some reason, Nifty invokes your action code in such a way as to silently ignore any exceptions which it generates.

To work around, this, I try and catch all throwables in my action code, as in this code sample from my TestSkyControl application:
[java]
/**
* Perform the action specified by an action string. Invoked by means of
* reflection, so both the class and method must be public.
*
* @param actionString (not null)
*/
public static void perform(String actionString) {
Validate.nonNull(actionString, “action string”);

    logger.log(Level.INFO, "actionString={0}",
            MyString.quote(actionString));
    boolean isOnGoing = true;
    float simInterval = 0f;
    ActionListener actionListener = application.getEnabledScreen().listener;
    try {
        actionListener.onAction(actionString, isOnGoing, simInterval);
    } catch (Throwable throwable) {
        logger.log(Level.SEVERE, "Caught unexpected throwable:", throwable);
        application.stop(false);
    }
}

[/java]

1 Like
@.Ben. said: @jayfella: wait... I'm not saying there is an issue with your "World" project. All I'm saying is that exceptions are not thrown from within "World" threads. ON A SIDE NOTE, why is "World" abandonned in favour of "TerrainWorld" when "World" was updated in january versus "TerrainWorld" was updated in november?! What's the difference between two and why is "World" more recent if it's not good? It works REALLY GREAT here! What's the difference or what kind of issues/limitations, if any, are there between the two?

@zzuegg: OK, well maybe that explains it, because “World” does not call Future.get() anywhere that I can see, unless it’s hidden in the ScheduledThreadPoolExecutor class somewhere or from within dependant classes which I did not dig through yet.

Thx guys for your time.

I wrote terrainworld with some advice from the core devs. It works great. I then wanted to improve upon it so that it could be added in the sceneExplorer and also page pre-created scenes (see here). This improvement was called World. A week or so in I started pushing it to the jmonkey plugin repository instead. A week or so later and I started contributing toward replacing the deprecated terraingrid, and also improving the scenecomposer terrain editor. And thus the World project was left in favour of using the jmonkey repository. Hope that makes sense :stuck_out_tongue:

I can’t remember what state I left World in, but i know that TerrainWorld does work as intended, which is why I recommended that instead.

@jayfella said: [...] A week or so in I started pushing it to the jmonkey plugin repository instead.

Where is that? I searched in the TOOLS > PLUGINS window and couldn’t find anything with “world” or “terrain” besides an abandoned 2012-2013 “terraintiler” plugin.

@jayfella said: I can't remember what state I left World in, but i know that TerrainWorld does work as intended, which is why I recommended that instead.

So you’re basically telling me to use the oldest of the two? Currently I’m using World and it works really great. I haven’t found any limitation yet. It’s quite memory hungry because the GC doesn’t collect often, but today’s computers have 8+ GB of RAM so this is not an issue at all. You’ll notice: on the same link you pushed in your previous message, I posted screenshots of what I’m doing: that’s “World” at work. People are amazed by this idea of smooth graphics and infinite land to discover :smiley: Tough, I had to install the nightly build as it wouldn’t run on the stable release, but i’ve been on the nightly build for almost 2 months now and it runs great :smiley:

I ended up using @sgold’s advice, altough I am not 100% pleased with exceptions <span style=“text-decoration:line-through;”>not being thrown</span> being swallowed under these circumstances, but hey, it’s nobody’s fault but mine for trying to access an out of bounds index in an array lol.

Thank you everybody for your time. Case closed. +1’ed Stephen.

Oh, the exception is being thrown. You just have to catch it before Nifty gobbles it up. Thanks for the +1.

Yes that’s what I meant. Sorry for the confusing wording :stuck_out_tongue: