如何创建自定义JVM启动器? [英] How would one create a custom JVM launcher?

查看:245
本文介绍了如何创建自定义JVM启动器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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.

我的问题

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

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 {

} 

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

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.

推荐答案

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

由于 JEP 153:增强java命令行启动程序以启动JavaFX应用程序

这是对openjdk启动器逻辑的修改,以检查要启动的类是否扩展了Application,如果是,则调用一个启动了JavaFX的启动器Java运行时和关联的线程,创建一个GUI窗口(在JavaFX术语中是一个舞台),然后创建一个avaFX应用程序的实例,并根据 JavaFX应用程序生命周期规则

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.

通过代码跟踪实现:


  1. main.c for JVM在 java.c

  2. ja va.c 查找一个Java类 sun.launcher.LauncherHelper 使用JNI调用java类,调用 checkAndLoadMain function。

  3. 如果要启动的类没有main方法,但是扩展Jav aFX应用程序类 FXHelper 类是使用启动参数创建的。

  4. 对FXHelper的引用通过JNI返回到java.c 。

  5. java.c 调用 FXHelper上的主要方法通过JNI。

  6. FXHelper 使用反射来调用 com.sun.javafx.application.LauncherImpl.launchApplication()

  7. JavaFX LauncherImpl将设置应用程序类加载器,然后首先尝试在应用程序的主类上调用main()方法。

  8. 如果没有main()方法,JavaFX LauncherImpl将启动JavaFX启动程序线程

  9. 在启动程序线程上,LauncherImpl将在JavaFX应用程序上调用init()

  10. 在JavaFX应用程序线程上, LauncherImpl将创建一个新的舞台(窗口)将其传递给应用程序的start方法

  11. 当最后一个阶段关闭或退出JavaFX平台时, LauncherImpl调用应用程序的停止方法。

  12. 所有调用跟踪都返回,应用程序退出,因为没有其他任何事情要做。

  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.

如何自定义启动器


  1. 获取 sun.launcher.LauncherHelper 代码。

  2. 忽略代码顶部的警告这不是任何一部分Sun Microsystems支持的API。如果您编写的代码依赖于此,您需要自担风险。此代码及其内部接口可能会更改或删除,恕不另行通知。并开始修改代码。

  3. 创建自己的FXHelper版本,它将调用您自己的LauncherImpl而不是JavaFX one(在目标主应用程序类扩展应用程序框架类而不是JavaFX类的情况下)。

  4. 编写自己的LauncherImpl,为应用程序设置类加载器,创建一个应用程序类的实例,并在您的应用程序类型上调用您想要的任何启动入口点。

  5. 运行您的应用程序,放置sun.launcher.LauncherHelper的黑客版本和LauncherImpl 在引导类路径上,所以它们被拾起而不是发布JDK的默认版本。

  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.

示例启动命令,假设目标要启动的应用程序是 com.mycompany.MyApplication

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

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

这篇关于如何创建自定义JVM启动器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆