Lets say, we have the following class:
import javafx.application.Application;
import javafx.stage.Stage;
public class Test extends Application
{
public Test()
{
System.out.println("Constructor");
}
@Override
public void start(Stage primaryStage) throws Exception
{
System.out.println("start");
}
public static void main(String... args)
{
System.out.println("main");
}
}
It's derived from Application
but it doesn't use any of its methods. Usually you start a JavaFX application by calling launch(args)
in the main.
When I start this program the only output is "main", so the constructor and start aren't called, but the program doesn't terminate because there is a JavaFX Application thread running. But where does it come from?
I did some debugging and found out that the thread is started from the main thread before the main method runs. The stack trace starts with NativeMethodAccessorImpl
.
To get even weirder: when I start the main method from a different class, the JavaFX Application thread isn't started:
public class Test2
{
public static void main(String[] args)
{
Test.main(args);
}
}
So what kind of black magic is this?
Java uses different approaches to launch the two applications.
Try running the following code:
public class Test3 {
public static void main(String[] args) {
Class<?> actualMainClassTest = LauncherHelper.checkAndLoadMain(true, 1, Test.class.getName());
Class<?> actualMainClassTest2 = LauncherHelper.checkAndLoadMain(true, 1, Test2.class.getName());
System.out.println("Actual loaded main class for Test: " + actualMainClassTest.getName());
System.out.println("Actual loaded main class for Test2: " + actualMainClassTest2.getName());
}
}
The output is
You can see that the actual loaded main class for the Test2
class is Test2
, but the loaded main class for
Test
is sun.launcher.LauncherHelper$FXHelper
.
This happens because the Java launcher checks if the main class to be launched is a subclass of javafx.application.Application
.
If it is, it loads the main method of sun.launcher.LauncherHelper$FXHelper
instead, which invokes a launcher method
for JavaFX applications (com.sun.javafx.application.LauncherImpl#launchApplication
).
This method is responsible for launching the JavaFX application. Test#main
is called after the application is launched:
When Test#main
is called by Test2, the FX launcher is not used because Test2 is not a subclass of javafx.application.Application
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With