I just faced a strange behavior and I can't even say if it is a JavaFX specific problem, Eclipse problem or even where to start fixing first.
But first things first: I'm writing a JavaFX application (Eclipse Kepler/ Java 1.7), containing some extended ListViews. The program takes about 1sec to load.
The extended ListViews look something like that:
public class NewList<T extends Obj> extends ListView<T>{
public NewList(){
// addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>(){
//
// #Override
// public void handle(KeyEvent arg0) {
// if(arg0.getText().equals(KeyCode.DELETE)){
// getItems().remove(getSelectionModel().getSelectedItem());
// }
// }
// });
}
}
There are also some MouseEvents (like drag and drop) inside the same constructor, and they are working as expected.
Now I want to add an EventHandler to my extended ListView (see commend in the code above).
The code takes now about 8sec to start aka 8 times longer as normal. To my surprise 90% of the loading time the program is inside the .show() method of my primaryStage (there is just one). After the loading time, the GUI is extreme slow and the cpu usage is on 100%.
Maybe the Handler is implemented wrongly and is doing some strange stuff during the whole time.
I can't find any solution or even comparable problem on the internet....but now the real problem just begun:
When I delete the Handler and run the program again, it will stay slow! So the program is in the same state as before - just still broken! That makes me crazy, because I can't see any logical explanation for that behavior.
What I have already tried:
delete the bin folder inside the repository and build the code again (+reboot)
reset the repository via git
throw half of the code away and started again. At any point it worked again, unfortunately I was not able to reproduce the effect. Then I implemented the Handler again and the problems started from the beginning...
edit: it looks like there goes something wrong during the building process/updating the binarys. I deleted 99% of the code (>5k LOC), then it worked. I copy/pasted the original project back into my workspace and the hole code worked smoothly - even with the Handler on. So I can't imagine a way to produce a minimalistic setup. btw: I'm not allowed to release the complete project folder (university stuff...)
edit2: I' using win7 64bit with java64. other javaFX programs are working (even then grafic intensive oracle samples). I'm not using any JavaFX specific repository setup or builder
Okay, I faced the same problem a few minutes ago and I think I found the source this time.
I'm running my code ALWAYS in debugging mode. To check the EventHandlers condition, I created some breakpoints in Eclipse. I also created a breakpoint at the following line of code (see above for more code)
public void handle(KeyEvent arg0) {
A mouseover over the breakpoint provides the following information:
Multiple markers at this line
Method breakpoint:NewList [Entry] - handle(KeyEvent)
implements:javafx.event.EventHandler .handle
I don't know what is happening here exactly but I think its something like this:
I'm overriding a JavaFX EventHandler Method and the debugger has to check the breakpoint on every single JavaFX interaction/EventHandler call. So Eclipse cant handle the flood of checks in a propper time and all seems to be very slow.
To clear that out: the breakpoint itself does not have to be called at any time, just the existing of it is enough to cause the problems.
Deactivating the breakpoint or running the application in a non-debugging mode will fix all problems. I think it should be a good idea to avoid all entry-breakpoints in any kind of Listener/EventHandler :)
Related
This is not your usual "my breakpoints don't work" question.
Consider the following code:
Runnable runnable = new Runnable()
{
#Override public void run()
{
Log.debug( "in run()" ); // <-- place one breakpoint here
}
};
#Test public void test()
{
Log.debug( "in test()" ); // <-- place another breakpoint here
runnable.run();
}
If you were to run this test from within IntellijIdea, using IntellijIdea's built-in JUnit support, the following things would happen:
Both logging statements produce output.
Both breakpoints hit.
However:
If you were to run this test from within some other framework, (e.g. Testana) which discovers the test class at runtime, loads it dynamically, and executes each test method in it, then the following happens:
Both logging statements produce output.
The breakpoint in the test() method hits.
The breakpoint in the run() method does not hit.
As a matter of fact, when the breakpoint in the test() method hits, you can see that the breakpoint in the run() method remains a red circle without a checkmark, which means that IntellijIdea does not recognize it as being on executable code.
Just in case it matters, I am currently using macOS, in a few days I am hoping to be able to try under Windows.
There were a couple of similar issues in IntellijIdea reported and fixed a long time ago:
https://youtrack.jetbrains.com/issue/IDEA-79268 (10 years ago)
https://youtrack.jetbrains.com/issue/IDEA-133881 (7 years ago)
Judging by a comment by CrazyCoder (a well known JetBrainiac on Stackoverflow) from May 29 '13 at 13:11 on this question Line breakpoints don't work in some classes which mentions some "debug scope" I suspect that the problem is something along these lines:
The testing framework is launched with its own classpath which does not include the test class.
The testing framework discovers the module containing the test class, creates a new ClassLoader with the class path of the module, uses that ClassLoader to load the test class, and runs the test methods in it.
The IntellijIdea debugger somehow detects that the test class was dynamically loaded, and includes it in whatever that "debug scope" is, so the breakpoint in the test() method hits.
The IntellijIdea debugger fails to detect that the anonymous inner class is also loaded, so it fails to include it in the "debug scope", so the breakpoint in the run() method does not hit.
And now the question:
Is there any workaround that would make the IntellijIdea debugger hit the breakpoint in the anonymous inner class?
Ideally, the workaround would be a general-purpose solution that can be implemented in the testing framework to take care of any similar situation.
A workaround that would make breakpoints work in anonymous inner classes by extra bureaucracy on the side of the test class would also be (barely) acceptable.
(But if you were going to suggest that I convert my anonymous inner class to a separate top-level class, please don't.)
EDIT
Behavior is same on Windows.
Steps to reproduce:
Check out this project: https://github.com/mikenakis/Public
Go to class T01_CompilingIntertwine
Place a breakpoint on line 57 (first line of function run())
Hit your Debug key to bring up the run configurations dialog
There will be a run configuration called Testana - All; launch it.
The breakpoint will not hit.
Make a minor modification to the file and save it (because testana does not run tests that have not changed.)
Place a breakpoint on line 53 (new Runnable())
Relaunch (Debug) Testana - All.
The breakpoint on line 53 will hit. If you resume, then the breakpoint on line 57 will also hit.
So, Konstantin Annikov from JetBrains found this worthy of creating an new issue for it on the IntelliJ IDEA issue tracker, see https://youtrack.jetbrains.com/issue/IDEA-287858
Then, Egor Ushakov from JetBrains looked into it, and found that this is happening because the testing framework is loading the classes in a non-standard order, while IntelliJ IDEA contains some logic that relies on the assumption that the classes will be loaded in the standard order.
The standard order of loading classes (when classes are being loaded by their classloader as they are being executed) is to have the outermost class loaded first, and the inner classes loaded afterwards.
Testana was loading the classes in the order in which the class files are yielded by java.nio.file.Files.walkFileTree(), which is apparently alphabetic, and it just so happens that $ sorts before ., so Testana was loading the inner classes first, and the outermost class last.
I fixed the problem in Testana, and Egor expressed the intention to try and implement a workaround for this case in IntelliJ IDEA. (This is such an edge case that I am not sure it is worth fixing, but anyway, it is his call.)
I write Java code in the IntelliJ IDEA IDE and it seems to me that each time I hit a key it reparses (evaluates) my whole sources.
To be clear, when I want to write this:
public class MyApp {
public static void main(String arg[])
{
System.out.println("hello");
}
}
and I am at this point ([CARET/CURSOR] = position of current):
public class MyApp {
public static void main(String arg[])
{
System.out.prin[CARET/CURSOR]
}
}
IDEA alraedy tells me already the helpful message:
Cannot resolve symbol 'prin'.';' expected
I have tried very hard to get IDEA not to do this (as obviously while I still type the source line,I do not want this unfinished work to be compiled/evaluate)
How can I get IDEA to not do this? Not only do those idioticly pointless message disturb, they are also making typing a pain, as the responsiveness is nil, while the CPU searches the unfinished code.
Addition/Update
This picture below illustrates the problem, i.e. that the inspection is rerun at each keystroke:
In the mean time I have used an open source Java profiler https://visualvm.github.io/, available form my distro's package manager. Which has (as suggested in the comments) helped in finding out, that the delay and slowness incurred to inspection, is not the parsing in the first place, but rather the yet imperfect wayland linux display server support of IntelliJ, which recurring to an indirection via Xwayland, has slowed down the delay between "finger hits key" to "glyph is added to source" to unbearable limits.
The Inspection feature of the IntelliJ IDEA IDE, can be adjusted at different places within the IDE. The comment by #MonteChristo with turning on File -> Power Save Mode has indeed already led into the right direction, to prevent IntelliJ IDEA from parsing the code at each keystroke.
There is however another setting which can be found as illustrated here:
where then it is possible to swiftly reduce or inhibit inspection alltogether, using this settings menu.
As visible the connection to power save mode which is maybe the quickest workaround persists.
Also please note that even though inspection gets disabled, results from previous inspection runs (i.e. red underlines, red text) will remain.
It seems to me that according to my test only the setting power save mode was really able to completely disable the parsing at each keystroke, while all other settings kept the code parsed at each keystroke.
I have a problem with my GWT/libgdx app (GWT ver: 2.6.0, Gdx ver: 1.9.2) and I cannot find any recent solution, or something that match my issue, on the Internet. Short story is, sometimes, "randomly" (or inexplicably, to be honest), my app choose not to load on the first try (or second, third...), and then after one (or two, three) refresh, it works (... and sometimes it doesn't, at all). Sometimes it loads immediatly, too.
This behviour happens on various browser (firefox, chrome, chrome for mobile... Surprisingly enough IE is not the most problematic browser here), on various machines (and OS). So, on my Linux/firefox, I often have no problems (not always). But on my colleague Windows10/Chrome, we have to refresh the page two or three times, and on his phone (Android/Chrome) it never displays. I don't exactly know the versions.
On Firefox, I thought I had a hint first, because the blablabla.cache.html file seemed not to be loaded (in the sources page of the inspector) when the page refused to load (which would explains why, even if it would be totally not normal that this part would randomly be there or not!). But then, the .cache.html was here, and not my app...
All that I know for sure is that onModuleLoad() is never called when my app is not displayed. Neither is this part (from gdx):
public PreloaderCallback getPreloaderCallback() {
return new PreloaderCallback() {
#Override
public void error(String file) {
alert("error");
}
#Override
public void update(PreloaderState state) {
if (state.hasEnded()) {
alert("loaded");
}
}
};
}
So I know that, with these weird and little pieces of information, it will be impossible to know what is wrong. But did anyone get such a curious and untrusty behaviour with a GWT and / or gdx app?
EDIT : I noticed two possible explanations for my problem. Now it is mostly solved but I'd like to help anyone who could have the same trouble in the future.
The first one is in the html file. It was impossible for you to know because I did not think it was a possible cause for my issue. I was using React and GWT to display my app, and both React and GWT were rendered in a unique div.
When React is rendered first, the GWT part is added in the div, so everything works well. Yet, when GWT is rendered first, the React part replace it in the div. Most of the time React was faster and I did not see any problem. The solution was easy: I added another div specifically for React.
The second issue was on iOS10. Gdx uses an old version of SoundManager2 that needs a patch to work on iOS10, and even stops the application loading. I had to use more recent sources of SM2.
I'm trying to create a game where JADE Agents are the 'enemies' and they chase a player around a maze.
So far I have:
MazeView.java (uses Swing to paint various things on the screen, and lets the user interact through button presses)
Enemy.java (a JADE agent that will have behaviours like search, pursue, etc.)
And a few other classes doing things like generating the actual maze data structure etc.
My problem is that, while I can instantiate an Agent and paint it on the screen, for some reason I can't add any behaviours. For example, if I wanted something like this (in Enemy.java):
protected void setup() {
// Add a TickerBehaviour that does things every 5 seconds
addBehaviour(new TickerBehaviour(this, 5000) {
protected void onTick() {
// This doesn't seem to be happening?
System.out.println("5 second tick... Start new patrol/do something?");
myAgent.addBehaviour(new DoThings());
}
}); // end of addBehaviour
System.out.println("End of setup()...");
} // end of setup
When I run the code, no errors are thrown, and I can see "End of setup()..." displayed in console. So for some reason it's just not going into the addBehaviour() method at all. Even if the DoThings() behaviour didn't work (right now it just prints a message), it should at least display the "5 second tick" message before throwing an error. What is going wrong here?
I think it could be something to do with the fact that currently there is no concept of 'time' in my maze. The user presses a key, and THEN processing happens. So having an agent that does things every 5 seconds might not work when there is no real way to facilitate that in the maze? But I'm still confused as to why it just skips addBehaviour() and I don't get an error.
A possible solution might be to re-implement my maze as a constant loop that waits for input. Would that allow a concept of 'time'? Basically I'm not sure how to link the two together. I am a complete beginner with JADE.
Any ideas would be appreciated. Thanks!
I've never used Jade, but my first thought was that you are adding behaviors and then assuming that Jade will decide to run them at some point. When you say that you never see your behaviors activate, it strengthened that hypothesis.
I looked at the source and sure enough, addBehaviour() and removeBehaviour() simply add and remove from a collection called myScheduler. Looking at the usages, I found a private method called activateAllBehaviours() that looked like it ran the Behaviours. That method is called from the public doWake() on the Agent class.
I would guess that you simply have to call doWake() on your Agent. This is not very apparent from the JavaDoc or the examples. The examples assume that you use the jade.Boot class and simply pass the class name of your agent to that Boot class. This results in the Agent getting added to a container that manages the "waking" and running of your Agents. Since you are running Swing for your GUI, I think that you will have to run your Agents manually, rather than the way that the examples show.
I got more curious, so I wrote my own code to create and run the Jade container. This worked for me:
Properties containerProps = new jade.util.leap.Properties();
containerProps.setProperty(Profile.AGENTS, "annoyer:myTest.MyAgent");
Profile containerProfile = new ProfileImpl(containerProps);
Runtime.instance().setCloseVM(false);
Runtime.instance().createMainContainer(containerProfile);
This automatically creates my agent of type myTest.MyAgent and starts running it. I implemented it similar to your code snippet, and I saw messages every 5 seconds.
I think you'll want to use setCloseVM(false) since your UI can handle closing down the JVM, not the Jade container.
Greetings fellow developers!
Since SO was almost always helpful with my programming problems, I decided to sign up and give it a shot with my most recent problem. It really is a strange phenomenon that neither I nor my collegue can figure out. I'm sorry I can't provide a working sample, but the project is way to complex to break it down, and specific hardware is needed to run it properly. So I'll try my best to explain it.
The foundation of our project is a native library (a 32-Bit Windows C-DLL in this case) to access project-specific hardware via a Java application (JNA). The purpose is to manage and display the proprietary file-system of the hardware (connected via USB) in a Swing UI. This is a pretty common project configuration for us, since we integrated a lot of native libraries and drivers in Java applications.
Summary: Unit-tests for enumerating devices work fine. A module of the native library allocates memory and fills it with structs, each containing information for a connected device. It is not good practice, but since we do not have any influence on this part we have to go with it. I mapped this struct in Java/JNA, call the native function, copy the struct content to a Java transfer class and print it in the console. Works just fine.
Now if there are UI-operations active while enumerating devices, the native library crashes with an access violation. Even if this UI-operations have nothing to do with the library. The JNA error message shows an EXCEPTION_ACCESS_VIOLATION (0xc0000005), which SO research revealed as invalid/empty memory.
Has anyone ever encountered such problems before? We certainly never did. It took me days to narrow down the error source to this part of the code. Debugging is not easy when native libraries are involved.
Is it possible that there is a JVM memory concurrency problem? Since the native library allocates memory by itself and the JVM doesn't know anything about it - so the JVM tries to allocate memory for new Swing components in already used memory?
Code:
The following snippet is from my unit-test, broken down as far as possible. The intended sequence is obvious: Remove nodes from the root-node, load connected devices and add these devices as new nodes. This code crashes with an access violation, but NOT AT THE NATIVE CALL - it crashes as soon as I access tree components.
public void loadDevices(){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
rootNode.removeAllChildren();
rootNode.add(new LoadingNode());
tree.expandPath(new TreePath(rootNode));
}
});
final List<Device> devices = lib.loadDevices(); // wrapped native call
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
rootNode.removeAllChildren();
if(!devices.isEmpty()){
for (Device dev : devices ) {
DevNode node = new DevNode(dev);
rootNode.add(node);
}
}
}
});
}
Note: The DevNode does not contain any native data, the content of each native struct is copied to a Java transfer object. The GC should not have issues when trying to move object data, because all unmanaged code is handled locally in the lib#loadDevices() method.
When I remove the calls to the SwingUtilities completely and print the resulting device information to the console instead of creating nodes, this part works fine.
As soon as I try to access the JTree or TreeModel members, the code crashes. It doesn't metter if I do this in a call to SwingUtitilies#invokeLater() or in the same thread.
I know this is a very specific problem that hardly anybody would be interested in (what makes it really hard to search for solutions in SO/Google). But maybe I am lucky and somebody has already encountered this problem.
So long
xander
Edit: Originally this code was wrapped in a worker thread, leading to the same results. This is just a snippet of my unit-test.
Edit 2: It seems I didn't make myself clear enough or forgot to mention something important here, sorry. The access to the tree or its model doesn't necessarily have to do with the native library. Look at the code again: The first call to invokeLater does nothing but remove nodes from the tree. Even when I remove the second call to invokeLater, the native library crashes!
I have struggeled a lot with JTree untill I learned this:
On JTree one should not edit the nodes itself, but use the methods provided on the DefaultTreeModel:
setRoot(TreeNode root)
removeNodeFromParent(MutableTreeNode node)
insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index)
Editing the nodes itself can (and will sooner or later) lead to strange behaviour.
This ofcourse when you are using DefaultTreeModel and MutableTreeNode. I would strongly advise to do this as I have seen to many wrong implementations of TreeModel.
final List<Device> devices = lib.loadDevices();
(by assuming that your code by using JNA is able to returns each node separatelly or collection of List<Device>'s one time if ended) should be called from Worker Thread, e.g. Runnable#Thread or SwingWorker
all output from to Worker Thread add to the DefaultTreeModel directly (or by creating a new MutableTreeNode) should be wrapped into invokeLater
no idea whats happens withut posting an SSCCE (List<Device>'s could be list of USB ports), short, runnable, compilable, just about JTree, is Model, and JNI/JNA ...