0

Situation

I'm trying to build a JavaFX App and for GUI I use SceneBuilder to produce fxml files for the different roots to use. Then I launch the App and at some point I'm trying to load some fxml file with new FXMLLoader(App.class.getResource("myFXML.fxml")).load() and set it as root on the scene on the stage.


Issue

99% of the times the loading has no problem at all and everything works as intended, but that 1% will fail and prevent the fxml loading without stopping the App but only throws the warning bellow.

WARNING: Caught 'java.lang.ClassCastException: class java.lang.String 
cannot be cast to class javafx.scene.paint.Paint (java.lang.String is in
module java.base of loader 'bootstrap'; javafx.scene.paint.Paint is in 
module javafx.graphics@18 of loader 'app')' while converting value for 
'-fx-background-color' from rule '*.list-view' in stylesheet 
jar:file:///C:/mysystem/.m2/repository/org/openjfx/javafx-controls/18/javafx-controls-18-win.jar!/com/sun/javafx/scene/control/skin/modena/modena.bss

The fxml that causes it most of the time is the one with a ComboBox in it but i don't think this has to do with it since it happened anywhere.

Important the warning is not consistent as well, at the pre-last line instead of *.list-view other times says *.button as well, but i am doing the same action to test it.


Reproducing the Issue

Reproducing is not consistent at all, the warning is descriptive and seems that the problem is on a JavaFX file (mentioned in the warning) and not in something I wrote. Thus I can't find a consistent way to reproduce it or handle the exception or something.


Tried so far

  • Removing the ComboBox (just in case)
  • Searched the internet to find nothing about it
  • Re-installing JDK did nothing

Note

I know there is much more information I can provide that may help but I'm exhausted right now. Maybe will add with edit later on.

ioannis-kokkalis
  • 432
  • 1
  • 3
  • 13
  • 2
    Provide a [mcve]. A *minimal*, *complete* example that only replicates the issue. Without you cannot expect useful assistance. – jewelsea Jul 22 '22 at 06:18
  • As you _produce the fxml file and then load it while the App runs_ and _it is not consistent at all_, might you have a latent synchronization error? – trashgod Jul 22 '22 at 12:15
  • @trashgod i updated the question to make it more clear. The answer on your question is probably no since i have all my fxml files ready and after i run the App. – ioannis-kokkalis Jul 22 '22 at 12:42
  • I have seen warnings like those from running tests - faintly remember that for some reason there had been two versions of the modules somewhere. I ignored them until they went away somtime .. (sry for the many "some", I never really found out - and wasn't interested enough - why they appeared/vanished ;) – kleopatra Jul 22 '22 at 13:20
  • @kleopatra fair enough but mine can't be ignored since it breaks other stuff if the fxml doesn't load properly. Sooo, just ran 10-15 tests each one simulating 1000 times what i was doing and getting the issue. Only the first and second test triggered it sometimes, all the rest was clean and had no issue at all. Problem not solved but i will keep working on the rest of the App and pretend that never happened and the Question remains. – ioannis-kokkalis Jul 22 '22 at 14:26
  • 1
    Manual review is tedious and error prone; in Swing, I'd do one of [these](https://stackoverflow.com/a/7788806/230513); maybe you can log `Platform.isFxApplicationThread()` when you load the FXML? – trashgod Jul 22 '22 at 16:09
  • @trashgod the simulations were mostly automated but i will add that in the question on what i tried for more details. BUT you are actually right on the second part, i was loading the FXML file while i was in another Thread (i cleared the server workspace and tested both cases and confirm that) but seems like after first time warning me it cached the warning and next time i tried to load the same FXML it did not bother loading the file that cause the warning but after some time (timeout of cache?) it tried again and got hit with the same warning repeating the circle. – ioannis-kokkalis Jul 22 '22 at 17:20
  • @trashgod i will look forward to update the Question so it describes better the situation and post an answer mentioning your comment. – ioannis-kokkalis Jul 22 '22 at 17:26
  • 1
    The "randomness" of the warning indicates a threading problem. You _should_ be able to load an FXML file on a background thread, as long as you aren't creating objects such as `Window` or `WebView` (see documentation for details). But you must only interact with the **live** UI (i.e., the UI showing on screen) on the _JavaFX Application Thread_. And object such as `Window` and `WebView` must never be accessed by a background thread, regardless of whether they're live or not. – Slaw Jul 22 '22 at 18:48
  • My guess is that you are writing multi-threading code that generates [race conditions](https://en.wikipedia.org/wiki/Race_condition), corrupting the JavaFX framework state and breaking your app in unpredictable ways. Without an [mcve], I don't think you will get a lot more assistance. Why are you loading FXML on other threads? You speculate that your issue may be due to a "timeout of cache", but that is unlikely. – jewelsea Jul 22 '22 at 21:06
  • @jewelsea it must be something along the lines of what you guessed. I resolved the issue by putting my FXML loading inside ```Platform.runLater(...);``` to ensure it runs in the FX Thread correctly, but currently i don't have the time to update the question (will soon) with 'minimal reproducible example' to research further the issue that i described as "cache time out" which was just a reference point on how it seems like when i try it. The comment of @slaw may be useful on that. – ioannis-kokkalis Jul 22 '22 at 21:54
  • 1
    @jewelsea App needed another Thread since i have a Client-Server scenario and i need to constantly hear for Server updates, and if there is a specific one i have to change Client's root (on scene) from the Thread i received the Server update. Without a new Thread, the FX Thread was waiting for Server updates so the GUI was frozen which is not what i wanted. – ioannis-kokkalis Jul 22 '22 at 21:58
  • @ioannis-kokkalis Thanks for the clarifications, you generated race conditions through modifications that affected the active scene graph from another thread. Your addition of Platform.runLater calls fixed some (maybe all) of your issues. – jewelsea Jul 22 '22 at 22:27
  • I advise thoroughly studying JavaFX and concurrency. See: [Slaw's writeup on periodic tasks](https://stackoverflow.com/a/60685975/1155209), [Task API javadoc](https://javadoc.io/static/org.openjfx/javafx-base/18-ea+1/javafx.graphics/javafx/concurrent/Task.html) + [JavaFX concurrency](https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm) – jewelsea Jul 22 '22 at 22:31

1 Answers1

1

Long Story Short

I was doing the FXML loading (new FXMLLoader(App.class.getResource("myFXML.fxml")).load()) and scene.setRoot(...) on another Thread and not the FX Thread. So make sure with Platform.isFxApplicationThread(); (as mentioned in the comments) that the operation happens on the FX Thread to ensure expected behavior.


Important

The answer is not complete, it is a placeholder for anyone searching it currently and this resolves the issue.


Improvements

I will try as soon as possible to update the question with more information and reproducible example. Also I will with the help of the comments continue the research to find solid explanation for the issue. In the mean time feel free for edits or post new better answers.

ioannis-kokkalis
  • 432
  • 1
  • 3
  • 13