I'm currently attempting to debug a medium scale (in the 10's of thousands of lines ballpark) Java project which uses both JavaFX and Swing, and I'm hitting some odd exceptions every so often which I'm pretty sure are because of UI code not being called on the correct thread. The stack trace for these exceptions isn't really helpful at all, since they pretty much all originate from the UI drawing thread.
Now, sure I could sit down with a toothcomb and debug every UI call until I find one that's not being called on the correct thread, and keep doing that for the entire project, but that would be an incredibly long task. Is there some form of easier way to do this sort of debugging? For instance, somehow cause UI code to print out a debug message or throw an exception when it's not been called from its appropriate thread?
Running JavaFX and Swing on the same thread might help fix your threading issues.
There is an experimental feature in Java 8 to run JavaFX and Swing on the same thread:
https://javafx-jira.kenai.com/browse/RT-30694
http://bugs.sun.com/view_bug.do?bug_id=8015477
I think -Djavafx.embed.singleThread=true is the command line property setting to enable the experimental single threading system.
I am not sure if the experimental feature is available in the current Java 8 builds, but I think it might be now, so you may wish to try it.
If you need more information on the experimental single threading feature, you could ask the developers on the openjfx-dev mailing list.
Java 8 has better inbuilt reporting of when code is not run on the correct thread, it's not comprehensive, but it might assist you in locating the source of your error, even if you are not using the single threading option.
Some other users running large applications merging Swing and JavaFX reported similar hard to debug threading issues, so you could check those threads to see if your issues have the same cause.
You could turn on thread checks in glass by -Dglass.disableThreadChecks=false. This would switch on the thread checks in the lowest layer of JavaFX which is responsible for working with OS level APIs. In most cases those checks would be sufficient, because most of the calls are ending up in Glass. These checks would be enabled by default soon.
Related
I am really new to this and trying to get the JaamSim Tool running within Eclipse to run a Simulation for my Bachelors Thesis.
When ever I try to run the config im getting an libc++abi.dylib: terminating with uncaught exception of type NSException. The JaamSim Loading Window always opens for a brief moment and then closes again with the note "GUIFrame was unexpectedly closed"
I tried for days new and im out of ideas... installed the newest jdk from adoptopenjdk, as well as apache ant and maven. Also linked everything within the .bash_profile
I would be really grateful if somebody could guide me to an solution.I added the terminal log form eclipse here1
Btw I am on Mac if that helps
The "exception" you are encountering is not a Java exception. It is a native Objective-C NSException. The "NS" stands for NeXTSTEP. It is a shibboleth of the old NeXTSTEP OS that is the ancestor of OS X and macOS. I can understand your confusion because both Objective-C and Java use the term "exception".
The logs you posted are, likewise, not a Java stack trace but an NSLog based thread dump from the native frameworks that your Java graphics depend on. You cut off the text of the actual exception in the image you linked. I'm guessing you didn't recognize the format and so didn't see the helpful message.
I'm going to guess that full text of the NSException message was "NSWindow drag regions should only be invalidated on the Main Thread!" If this is the case, then I think your problem is likely caused by changing some graphics from a background thread.
System graphics, such as windows, alerts, etc. are managed in macOS through a framework called "Cocoa". NSWindow is a Cocoa object. One of the important rules of Cocoa (and most UI frameworks) is that you should only alter Cocoa objects (like NSWindow) from the main thread. Probably, you are making some alterations to your GUI (specifically, invalidating drag regions) from a background thread. Java doesn't have any inherent problem with this, but Cocoa does. So you get a native error instead of a Java error.
TL;DR: Only work with your GUI from the main thread. You are getting this error because you are changing the GUI from a background thread.
EDIT: After doing a little research.
It appears that this particular issue occurs with certain Java OpenGL libraries, in particular lwjgl. You can see a very determined but ultimately fruitless effort to fix the problem here. I'm not sure what OpenGL Java interface is used in JaamSim, but they documented this same problem as far back as 2018, saying
The bug turns out to be a known problem with the JOGL software we use for 3d graphics. Unfortunately, it will take a while to get a fix in place.
The same JOGL bug was documented again in 2019. There, it seems to be resolved. Their report of the fix was
encapsulated both construction fully to run on the Main-Thread
I'm not sure how much control over this you have. Your best bet is to start by adding the -XstartOnFirstThread flag to your java command. I would also check if anyone in your class has been able to make this work on a Mac. Sometimes, it's nice to do a quick impossibility check before wasting time.
I have a JavaFX 8 app that is occasionally hanging/freezing. I feel I've ruled out many causes of the problem, but it's still happening.
Unfortunately I cannot reproduce the freeze/hang on demand. It actually only happens (so far) on my colleague's computer. It can happen not long after the App has been running, or it may happen after many hours, or it may not happen at all. It does not happen after any user initiated event (such as pressing a button).
I have a few background threads running that read data from sockets and update the JavaFX UI. These updates are always done via the Platform.runLater() method.
The background threads may read many hundreds of data updates per second, so I have applied throttling to prevent too many updates on the UI, as suggested here: Throttling javafx gui updates
The user can initiate some long(ish) tasks, which are run on the JavaFX UI thread, or using the Task method. I know and expect the JavaFX UI to block/freeze when calling a method with long execution time on the JavaFX UI thread. But such calls are only made by the user pressing a button and as stated above, the freeze occurs without the user interacting the the App in any way.
I have caught the freezing (twice) on my colleagues computer and inspected the process in JConsole and VisualVM. The thread dump showed no deadlocks. When I compare the thread dump with a non-frozen JavaFX App thread dump, there are no obvious differences.
It appears that only the JavaFX UI is frozen. The background threads continue without error.
The CPU is not high and the computer is not running slow when the freeze occurs.
My App code consists of many classes, so it's not straight forward to include it here, especially as I don't know which method causes to freeze. And therefore my question is rather broader than I would like:
Given the assertions above, do you have any suggestions as to what
might be a cause of such an error?
Given the assertions above, do
you have any suggestions as to what might be another way to trace
such an error?
Thanks to John16384 and Mipa for their replies...
I use the javafx-maven-plugin Maven plugin, so the JavaVM arguments by including:
<jvmArgs>
<jvmArg>-Dprism.verbose=true</jvmArg>
<jvmArg>-Dprism.order=sw</jvmArg>
</jvmArgs>
in my plugin configuration. Since including this, we haven't had the freeze for a couple of days. I'm hoping this is the final fix!
Have you tried AOP ?
Aspect Orientated programming
It in your case would allow you to run a method before and after every method you use, if you logged something if these times were greater than a certain time, then you could determine which bit of code was causing it e.g. log if the time inside a method is greater than 5 seconds
See here for a tutorial to just that
I have problem similar to my previous one presented here.
This time I want use program written in c/c++ to track execution of JAVA program. So as I stated before same code which track stdout printing for c/c++ and register syscall 4 haven't done it for JAVA. I assume it's because execlp which I trace is used just to run jvm. And later on there are created more processes (by inner mechanism of jvm) which I do not track. I found this topic which seems to be partial solution. If I got it right every child will be traced. But that's is a problem as well I want to track only that process which handles my application and not all others that jvm might create. Is there any chance to get know which jvm thread/process handles my program and track only it?
For make it a bit easier let's assume my JAVA program is one-thread.
If you start the binary through your tracer app, all threads will be traced.
But if you attach to a process, then you won't attach to all it's threads. You have to attach to all of its threads using the threadids, that you can found listed eg. in /proc/%d/task/.
Also, I suggest reading through strace's source code, I've learnt a lot from it. If you can use strace to successfully follow java threads as you want, you can get the logic from it.
One day our java web application goes up to 100% CPU usage.
A restart solve the incident but not the problem because a few hours after the problem came back.
We suspected a infinite loop introduced by a new version but we didn't make any change on the code or on the server.
We managed to find the problem by making several thread dumps with kill -QUIT and by looking and comparing every thread details.
We found that one thread call stack appear in all the thread dumps.
After analysis, there was a while loop condition that never go false for some data that was regularly updated in the database.
The analysis of several thread dumps of web application is really tedious.
So do you know any better way or tools to find such issue in a production environment ?
After some queries, I found an answer in Monitoring and Managing Java SE 6 Platform Applications :
You can diagnose looping thread by using JDK’s provided tool called JTop that will show the CPU time each thread is using:
With the thread name, you can find the stack trace of this thread in the “Threads” tab of by making a thread dump with a kill -QUIT.
You can now focus on the code that cause the infinite loop.
PS.: It seems OK to answer my own question according to https://blog.stackoverflow.com/2008/07/stack-overflow-private-beta-begins/ :
[…]
“yes, it is OK and even encouraged to answer your own questions, if you find a good answer before anyone else.”
[…]
PS.: In case sun.com domain will no longer exists:
You can run JTop as a stand-alone GUI:
$ <JDK>/bin/java -jar <JDK>/demo/management/JTop/JTop.jar
Alternately, you can run it as a JConsole plug-in:
$ <JDK>/bin/jconsole -pluginpath <JDK>/demo/management/JTop/JTop.jar
Fix the problem before it occurs! Use a static analysis tool like FindBugs or PMD as part of your build system. It won't find everything, but it is a good first step.
Think of using coverage tools like Cobertura.
It would have shown you, that you didn't test these code-paths.
Testing sth. like this can become really cumbersome, so try to avoid this by introducing quality measurements.
Anyways tools like VisualVM will give you a nice overview of all threads, so it becomes relatively easy to identify threads which are working for an unexpectedly long time.
What is the best solution for multi threading in flex, I notice if I play a mp3 in flex and do something else at the same time something ends up giving out, either the song stops playing or the UI hangs for about a split second. It doesn't have that fluid response that I am looking to achieve. If possible I would like to call a multi threaded java class to do some of the client-side end back end processing. I just don't know if that is possible. Any insight would be greatly appreciated I am stuck on this one.
-Phil
Flex/Flash alone don't support multithreading - Adobe keeps argumenting that multithreading is not necessary for most of potential flex applications and would just increase complexity for the average flex developer too much.
Looking for solutions myself I have only found snippets where the task to be done simultanously gets logically cut into smaller pieces, then you run them piece by piece, letting UI get time slices in between. It might work for some but is no solution to your problem.
Now to Java - using the native process api could make it work. Java process would take over some part of the processing and you would control its working writing to and reading from input/output streams which gets connected between java process and flex app. Another possibility could be inter-process socket communication (did it myself before native process api was there - works!)
If the UI is hanging you have another issue. It seems to me like you are looping through some sort of data to make this "lag". What you can do is format the data better so you don't run into this. Or look into your process that you run when the hanging happens and optimize it better.
Flex/Flash has no blocking methods and so doesn't need threading, just call a function on a timer or enterframe, and make sure it yields in under 25ms or so. As for speed, Java (running in Android's 'Dalvik' VM ) is not a lot better... C is the only option for ultimate speed.
Here is a rather complete 'Greean Thread' lib - http://blog.generalrelativity.org/actionscript-30/green-threads/
I have found it useful, as irrespective of Tom's views Threading is most definitely often a needed things that is not supported properly (yet??)
Also bear in my mind that the debug player behaves very differently from the standard player, and (a separate issue) that during a debug session, significant slowdowns can be apparent with performance critical code... Only believe the browser plugin, non-debug version, running in a browser, not debugging. That is the only reliable test. I have seen speed up of 25-30x just by changing to the release player (extreme case). Thought I had a major performance problem, but actually didn't :)