如何创建自定义JVM启动器?

时间:2015-04-03 00:28:11

标签: java jvm launcher

有一段历史" 如何在没有主要方法的情况下启动应用程序"问题,大多数陈述的东西都是" 你不能"。我注意到现在可以通过扩展Application来启动JavaFX应用程序。我一直在使用类似于Application.launch()的方法,但在这种情况下,我总是将主要方法视为样板代码。所以我又开始寻找答案了。

我发现this answer将我们链接到我们可以学习创建自己的JVM启动器的地方,但遗憾的是文章已不复存在。我花了很长时间寻找任何可能暗示我应该做什么的事情,但没有结果。

我的问题

如何创建自定义JVM启动程序以根据正在扩展的内容启动应用程序?例如,想象一个具有1个声明类的项目:

class MyApplcation extends App {

} 

启动项目不需要主要方法,因为它扩展了App。这不是问题,尽管这是我的目标。问题是如何有人创建自定义JVM启动器?

我的猜测是,它会涉及使用某种基础,给我们某种骨架,但我不知道在哪里可以找到这样的东西。

1 个答案:

答案 0 :(得分:7)

JavaFX如何实施其应用程序执行模型

由于JEP 153: Enhance the java command-line launcher to launch JavaFX applications的实现,可以启动不包含main方法的JavaFX应用程序。

这是对openjdk启动程序逻辑的修改,以检查要启动的类是否扩展了Application,如果是,则调用JavaFX特定的启动程序,启动Java运行时和关联的线程,创建一个GUI窗口(在JavaFX术语一个阶段),然后创建一个avaFX应用程序的实例,并根据JavaFX application lifecycle rules在应用程序上调用init和start方法。

通过代码跟踪实现:

    JVM的
  1. main.cjava.c
  2. 中调用JLILaunch
  3. java.c looks,用于Java类sun.launcher.LauncherHelpercalls into the java class using JNI,调用checkAndLoadMain函数。
  4. 如果要启动的类没有主要方法,但是extend the JavaFX application class,则会创建一个包含启动参数的FXHelper类。
  5. 对FXHelper的引用通过JNI返回给java.c。
  6. java.c invokes main method on the FXHelper来自JNI。
  7. FXHelper uses reflection调用com.sun.javafx.application.LauncherImpl.launchApplication()
  8. JavaFX LauncherImpl将设置应用程序类加载器,然后在应用程序的主类上设置第一个try to invoke a main()方法。
  9. 如果没有main()方法,JavaFX LauncherImpl将start up the JavaFX launcher thread
  10. 在启动器线程上,LauncherImpl将call init() on the JavaFX application
  11. 在JavaFX应用程序线程上,LauncherImpl将create a new Stage (window)pass it to the start method of the application
  12. 当最后一个阶段关闭或退出JavaFX平台时,LauncherImpl将the stop method on the application is called
  13. 所有调用跟踪都返回,应用程序退出,因为没有其他任何操作。
  14. 如何自定义启动器

    1. 抓取sun.launcher.LauncherHelper代码的副本。
    2. 忽略代码顶部的警告“这不是Sun Microsystems支持的任何API的一部分。如果您编写的代码依赖于此,您需要自担风险。此代码及其内部接口是主题更改或删除,恕不另行通知。“并开始修改代码。
    3. 创建自己的FXHelper版本,它将调用您自己的LauncherImpl而不是JavaFX(在目标主应用程序类扩展您的应用程序框架类而不是JavaFX类的情况下)。
    4. 编写自己的LauncherImpl,为应用程序设置类加载器,创建应用程序类的实例,并在应用程序类型上调用所需的启动入口点。
    5. 运行你的应用程序,放置sun.launcher.LauncherHelper和你的LauncherImpl on the boot class path的黑客版本,这样它们就会被拿起而不是JDK的默认版本。
    6. 示例启动命令,假设要启动的目标应用程序是com.mycompany.MyApplication

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