How to correctly clean up Java3D?

classic Classic list List threaded Threaded
18 messages Options
Flo
Reply | Threaded
Open this post in threaded view
|

How to correctly clean up Java3D?

Flo
Hello,

I've got a Java class that creates a Java3D (1.5.2) Canvas3D, adds some things, rotate it a bit and then saves it as an image - without actually displaying the Canvas3D in a JFrame or similar. That part works fine, based on the Java3D print_canvas3d example.

Unfortunately, the whole thing seems to have troubles cleaning up, because I see two symptoms:

a) After the image is saved, the application should be finished, but it does not exit. Calling System.exit(0) does fix that, but since the class will be used in an application server later, that is not a solution.

b) After the first image is saved, trying to create a second one (by creating a new Canvas3D, etc.) blocks the whole application on GraphicsConfiguration.getDevice() (and, if that is worked around by storing the Device in a static member, on similar places).

So, somehow the cleanup of the Java3D code seems to lack something very important. Unfortunately I can't seem to be able to find that...

I tried the solution found on Google[1], tried to SimpleUniverse.cleanUp, SimpleUniverse.getViewer.getView.attachViewPlatform(null) and other stuff, but nothing seems to change it. The only workaround I found is to place the code inside daemon threads and save the whole Canvas3D part in a static variable, but honestly, that looks more like a mess and not a solution. Unfortunately, I don't have the time left to rewrite the whole thing in JOGL or similar and I also can't simply create an external application to write the image and exit for each call... So I need to know how to do it correctly.

My question is simple: How do I clean up a Java3D application correctly without System.exiting it?

Regards,

Flo

[1] https://stackoverflow.com/questions/16470930/is-there-a-way-to-terminate-a-java-application-that-uses-java3d-without-calling)
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
Hi

Please switch to Java3D 1.6.0 first if you want to get some help here, we don't maintain Java3D 1.5.2 which is obsolete. The suggestion on Java3dThread.finish() might work but I can't be 100% sure.
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
I tried switching to 1.6.0-pre11, which was the latest version I found, unfortunately, it didn't even start, as the class CapabilitiesImmutable was missing (and not inside one of the three .jar files provided).

Is there a never version avaible via Maven?
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
You didn't follow my instructions, you forgot to uninstall the obsolete version, you didn't install JOGL 2, ........
http://jogamp.org/wiki/index.php/Downloading_and_installing_Java3D

Java3D 1.6.0 isn't available on Maven but if you clean your machine, it will work correctly.
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
Ok, I installed 1.6 and tried to run it with one of the old examples, which works fine... Unfortunately, the same behavior is seen with that version:

Take of the old Java3D examples, remove the JFrame.setVisible(true) and the application will never exit. So, still missing a way to stop/dispose/clean up Java3D here, as it doesn't seem to happen automatically... SimpleUniverse.cleanUp doesn't seem to help there, neither does View().removeAllCanvas3D(), etc.
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
Flo wrote
Ok, I installed 1.6 and tried to run it with one of the old examples, which works fine... Unfortunately, the same behavior is seen with that version:
Please keep the version 1.6.0 anyway. It doesn't mean that we won't try to help you but if you plan to stick on the version 1.5.2, I will give up. It's clearly written "JogAmp's Java3D continuation = Java3D 1.6.0 and later". We don't help the developers who want to use obsolete pieces of software in order to avoid any confusion and because nobody is able to rebuild Java3D 1.5.2.

Flo wrote
Take of the old Java3D examples, remove the JFrame.setVisible(true) and the application will never exit. So, still missing a way to stop/dispose/clean up Java3D here, as it doesn't seem to happen automatically... SimpleUniverse.cleanUp doesn't seem to help there, neither does View().removeAllCanvas3D(), etc.
Please can you indicate precisely what the expected behaviour for a disposed Java3D canvas? What about Java3dThread.finish()?
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
I don't have a problem upgrading to 1.6, will just have to chose the correct .jars, because putting 50MB .jar files into our build will not be a famous decision ;-) But that's a minor problem and for any upgrade it will have to work first.

So, what is the expected behavior? Quite simple:

Before doing anything with J3D the VM is in state X (Threads, memory, etc.). Then I want to start J3D, use it, print, etc.etc. and then I want to go back to state X. No J3D or AWT Threads should be left, everything should be as if I never called J3D (except for the file I created, of course), so that I can start it again from scratch (in the same process) without any problems.

Simply put, I want to completely remove any traces of using J3D, cleaning up my VM.

I am testing the whole thing locally by simply starting a small application and testing, if I can call the J3D code twice, after which the application should close itself, since the main thread is done. Unfortunately, both things don't work.

And yes, I tried to call the protected finish() Method there, using reflection (I really like reflection, but that's almost as bad as the setFinalMember(...) method a colleague had to write a long time ago ;-) ), but while the method is executed without an error, it doesn't change anything. The application still doesn't close.

Another minor question: Whenever I start the OffScreenTest from the old J3D examples (with J3D 1.6, of course), with JFrame.setVisible(true) removed, some Java windows pop up for a moment, immediately closing again. Is this expected? I would prefer J3D not opening any windows at all for my purposes (as I need to render a 3D image to a file, but not on the screen).



Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
Maybe it's caused by the query canvas. Please use JVisualVM to know what is going on.
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
Sorry, never used that tool. What am I looking for?

There are several threads left after the java3d is finished and the test application should exit but doesn't...

Made Thread dump ( http://pastebin.com/AK0gNs7D ), but don't see anything really unusual. Can you reproduce the behavior? And how can we test your hypothesis?
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
Hi

I see nothing wrong in your thread dump, there is only one thread used by JOGL, "main-SharedResourceRunner". It can stay alive. I see no thread created by Java3D still alive.

JVisualVM is a profiler provided in the Oracle JDK and available separately too for OpenJDK users.
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
Well, as I said, it happens. Can reproduce it with the Offscreen-Example from the old 1.5.2 files (using J3D 1.6), just with a simple main Method that does not but initialize the JFrame but doesn't set it visible.
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
Feel free to fill a bug report, please be very accurate and don't mention Java3D 1.5.2, mention the example that you use (put at least a link to its source code). In my humble opinion, you should open and close a JFrame without Java3D and you would see that there are some thread that don't die immediately even though you dispose it.
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
Without Java3D, creating a new JFrame without setting it to visible will not prevent that code from exiting, just tried that... Java3D can create thousand threads for all I care, as long as everything goes away when it's done ;-)

Will probably open a ticket in our own JIRA to switch to another 3D Framework. *shrug*
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
I don't disagree with you, we can find some solutions and I don't deny that Java3D creates numerous threads whereas JogAmp's Ardor3D Continuation, JMonkeyEngine and LibGDX don't. I'd like to know Harvey's opinion and suggesting you to fill a bug report wasn't a mean to give up. However, I asked you to provide a thread dump to illustrate your problem and I only saw one thread created by JOGL. I do what I can.
Julien Gouesse | Personal blog | Website
Flo
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

Flo
Please, don't get me wrong, I don't accuse you of not doing enough or anything, the problem seems not quite common and obviously, not many people have encountered it. So, while I have to give up for time-reasons, the issue couldn't wait any longer, I'll try to post a bug report for the next user who encounters the problem ;-).
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
I'm going to look at your bug report. I assume that there is at least one thread called "J3D-Renderer", maybe another one for the sound and a last one for JOGL.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

runiter
In reply to this post by Flo
Flo wrote
Another minor question: Whenever I start the OffScreenTest from the old J3D examples (with J3D 1.6, of course), with JFrame.setVisible(true) removed, some Java windows pop up for a moment, immediately closing again. Is this expected? I would prefer J3D not opening any windows at all for my purposes (as I need to render a 3D image to a file, but not on the screen).
To prevent this, simply remove any calls to the following method in your code:

Canvas3D.queryProperties();

Saeid Nourian, Ph.D. Eng. | Graphing Calculator 3D
Reply | Threaded
Open this post in threaded view
|

Re: How to correctly clean up Java3D?

gouessej
Administrator
Thank you so much. Please put it into the bug report :)
Julien Gouesse | Personal blog | Website