Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

There has been a history of "how to launch an application without a main method" questions, most stating something along the lines of "you can't". I noticed how JavaFX applications can now be launched simply by extending Application. I've been using a method similar to Application.launch(), but I've always seen the main method as boilerplate code in that situation. So I started looking for answers again.

I found this answer linking us to where we can learn about creating our own JVM launchers, but sadly the article no longer exists. I've spent quite a while looking for anything that might hint me on what I should do, but no results.

My Question

How would one create a custom JVM launcher to launch an application based on what is being extended? For example, imagine a project with 1 declared class:

class MyApplcation extends App {

} 

No main method is needed for the project to be launched, since it extends App. This is not the question, although it is my target goal. The question is how could someone create a custom JVM launcher?

My guess is that it would involve using some kind of base, to give us a skeleton of some sort, but I'm not sure where to find such a thing.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
267 views
Welcome To Ask or Share your Answers For Others

1 Answer

How JavaFX Implements its Application Execution Model

JavaFX applications which contain no main method can be launched because of the implementation of JEP 153: Enhance the java command-line launcher to launch JavaFX applications.

This was modification of the openjdk launcher logic to check if the class to be launched extends Application, and, if so, call out to a JavaFX specific launcher which started up the Java runtime and associated threads, created a GUI window (in JavaFX terms a Stage), then, created an instance of the avaFX application and invoked init and start methods on the application as per the the JavaFX application lifecycle rules.

Tracing the implementation through in code:

  1. main.c for JVM invokes JLILaunch in java.c
  2. java.c looks for a Java class sun.launcher.LauncherHelper and calls into the java class using JNI, invoking the checkAndLoadMain function.
  3. If the class to be launched has no main method, but does extend the JavaFX application class, a FXHelper class is created holding the launch parameters.
  4. A reference to the FXHelper is returned to java.c via JNI.
  5. java.c invokes the main method on the FXHelper via JNI.
  6. The FXHelper uses reflection to invoke com.sun.javafx.application.LauncherImpl.launchApplication().
  7. The JavaFX LauncherImpl will setup the application classloader, then first try to invoke a main() method on the main class of the application.
  8. If there is no main() method, the JavaFX LauncherImpl will start up the JavaFX launcher thread.
  9. On the launcher thread, the LauncherImpl will call init() on the JavaFX application.
  10. On the JavaFX application thread, the LauncherImpl will create a new Stage (window) and pass it to the start method of the application.
  11. When the last stage is closed or the JavaFX platform is exited, the stop method on the application is called by the LauncherImpl.
  12. All the call traces return and the application exits because there is nothing more to do.

How you could customize the launcher

  1. Grab a copy of the sun.launcher.LauncherHelper code.
  2. Ignore the warning at the top of the code "This is NOT part of any API supported by Sun Microsystems. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice." and start modifying the code anyway.
  3. Create your own version of the FXHelper which will invoke your own LauncherImpl rather than the JavaFX one (in the case that the target main application class extends your application framework class rather than the JavaFX one).
  4. Write your own LauncherImpl that sets up the classloader for your application, creates an instance of your application class and invokes whatever launch entry points you want on your application type.
  5. Run your applications, placing the hacked version of the sun.launcher.LauncherHelper and your LauncherImpl on the boot class path, so they get picked up instead of the default versions which ship the JDK.

Sample launch command, assuming the target application to be launched is com.mycompany.MyApplication:

java -Xbootclasspath/p <launcher class directory> com.mycompany.MyApplication

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...