In this repo, the problem is that
ApplicationController transitively extends
FxmlLoader during the construction of
ApplicationController while trying to initialize the field
FxmlLoader gets an instance which has not finished construction and then reflectively invokes
ApplicationController.initialize on that incomplete instance, which tries to read the
root field from
ViewController that has not yet been assigned, because it’s in the middle of evaluating the expression that would assign it.
This has nothing to do with threading or final fields and everything to do with dynamic dispatch from constructors. It is very brittle and not recommended to invoke anything other than private or final methods from constructors because that invocation may be dispatched to a subclass whose implementation may try to read a superclass’ field which has not been assigned due to the constructor not completing. Dynamic dispatch from constructors can work in cases where everything the subclass reads is already initialized, but it is brittle because future changes to the base class or subclass with no changes to the other may cause it to break and there is nothing to alert or prevent this.
Without actual application code I can’t say what your exact fix should be, but you definitely need to avoid the dynamic dispatch during construction, and should very likely restructure so that
this is not required at all and thereby only pass a completely constructed object to
These dependencies can be added directly too, as they are all Java modules, but should probably match your JRE version.
libraryDependencies ++= Seq(
"org.openjfx" % "javafx" % "11.0.1",
"org.openjfx" % "javafx-base" % "11.0.1",
"org.openjfx" % "javafx-fxml" % "11.0.1",