当前位置: 首页 > 知识库问答 >
问题:

VSCode:缺少JavaFX运行时组件

尉迟边浩
2023-03-14

我有一个maven项目,我想导出到runnable中。jar文件。

在VSCode中,项目可以正常工作。导出的项目包括。jar文件和包含所有javaFX文件的libs文件夹:

Documents/prosjekt/target
├── classes
├── generated-sources
├── generated-test-sources
├── libs
│   ├── apiguardian-api-1.1.0.jar
│   ├── javafx-base-18.0.1-mac-aarch64.jar
│   ├── javafx-base-18.0.1.jar
│   ├── javafx-controls-18.0.1-mac-aarch64.jar
│   ├── javafx-controls-18.0.1.jar
│   ├── javafx-fxml-18.0.1-mac-aarch64.jar
│   ├── javafx-fxml-18.0.1.jar
│   ├── javafx-graphics-18.0.1-mac-aarch64.jar
│   ├── javafx-graphics-18.0.1.jar
│   ├── javafx-media-18.0.1-mac-aarch64.jar
│   ├── javafx-media-18.0.1.jar
│   ├── junit-jupiter-api-5.7.0.jar
│   ├── junit-jupiter-engine-5.7.0.jar
│   ├── junit-platform-commons-1.7.0.jar
│   ├── junit-platform-engine-1.7.0.jar
│   └── opentest4j-1.2.0.jar
├── maven-archiver
├── maven-status
├── surefire-reports
├── prosjekt_boilerplate-1.0-SNAPSHOT.jar
└── test-classes

运行以下命令时出现问题:

❯ java -jar /Users/user/Documents/prosjekt/target/prosjekt_boilerplate-1.0-SNAPSHOT.jar 
Error: JavaFX runtime components are missing, and are required to run this application

我不明白为什么会出现这个错误,因为所有JavaFX文件都位于libs文件夹中并且可见。

我目前使用SDKman的Java Temurin 18.0.1。

❯ java -version
openjdk version "18.0.1" 2022-04-19
OpenJDK Runtime Environment Temurin-18.0.1+10 (build 18.0.1+10)
OpenJDK 64-Bit Server VM Temurin-18.0.1+10 (build 18.0.1+10, mixed mode)

<代码>Pom。xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>project</groupId>
    <artifactId>prosjekt_boilerplate</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>prosjekt_boilerplate</name>
    

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>18.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>18.0.1</version>
        </dependency>

        <!-- JUnit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.7.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <release>17</release>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    <argLine>--enable-preview</argLine>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                    <version>3.0.0-M5</version>
                    <configuration>
                        <argLine>--enable-preview</argLine>
                    </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/libs
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>
                                asteroids.AsteroidsApp
                            </mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

我尝试下载JavaFX SDK并运行以下命令:

❯ java -jar --module-path /Users/user/Downloads/javafx-sdk-18.0.1/lib \
--add-modules=javafx.controls,javafx.media,javafx.fxml,javafx.graphics \
/Users/user/Documents/prosjekt/target/prosjekt_boilerplate-1.0-SNAPSHOT.jar

成功了!但它仍然没有回答我最初的问题。

共有1个答案

拓拔烨赫
2023-03-14

尽管出于解释目的,这是一个很长的答案,但修复实际上非常简单。

另外需要做的唯一一件事是将带有模块的jar放在模块路径而不是类路径上。

回答您的问题,解释您最初的方法失败的原因。

运行以下命令时出现问题:

java-jar/Users/user/Documents/prosjekt/target/prosjekt\u样板文件-1.0-SNAPSHOT。罐子

Error: JavaFX runtime components are missing, and are required to run this application

我不明白为什么会出现这个错误,因为所有JavaFX文件都位于libs文件夹中并可见。

您收到此错误的原因是您正在类路径而不是模块路径上运行所有代码。

现代JavaFX版本的设计或支持都不能从类路径运行。它们应该从模块路径运行。

您完成了以下操作,这将使程序仅在类路径上执行:

  1. 使用应用程序创建了一个jar

背景信息

您的应用程序类不需要是模块化的,并且能够从类路径而不是模块路径执行的其他(非JavaFX)库在放置在类路径上时将起作用,但JavaFX库将失败。

解决方案是至少将JavaFX类放在模块路径上。理想情况下,您还可以将应用程序模块化(为其定义模块信息java文件),并在应用程序中仅使用非自动模块化jar(也定义模块信息java的jar)。但并不需要理想的方法(除非您想使用jlink打包应用程序),只需要在模块路径上有JavaFX类。

您不能(当前)通过jar清单将其他jar或文件夹添加到模块路径中,就像您当前对类路径所做的那样。有关这方面的信息,请参阅此问题的答案(以及对此答案的评论):

  • Java模块和JAR MANIFEST类路径属性

相反,您需要指定在命令行中添加的模块的位置(或依赖于由jlink创建的预先捆绑所需模块的JRE映像)。

此外,如果您的应用程序是模块化的,那么您应该使用-m开关来指定它所在的模块所限定的主类,并且您的应用程序jar也应该位于模块路径上。如果您的应用程序不是模块化的,那么您仍然可以使用jar说明符,并在jar清单中对主类名进行编码,而不是作为命令行开关。

示例

因此,假设您将应用程序作为zip分发,其中包含名为lib的子文件夹中的应用程序jar和依赖库。

对于这些示例,应用程序jar是一个普通的瘦jar(它不是一个被着色或包含JavaFX运行时代码的胖jar)。

对于非模块化应用,这将在eden编码中讨论。用户解压缩包后,假设主类名编码在清单中,则应用程序可以通过以下方式运行:

java -jar myJar.jar --module-path lib --add-modules javafx.controls,javafx.fxml

如果您使用其他JavaFX模块,如JavaFX media,这些模块不是可传递的依赖项,那么也包括这些模块。

如果您的应用程序是模块化的,那么您不需要在jar清单中编码额外的信息,但是您确实需要在jar文件中包含一个module-info.java。执行此操作时,最好将您的jar与您使用的其余模块放在同一个lib目录中,这样您就不需要将其单独添加到模块路径中。完成此操作后,您可以像这样运行应用程序(此示例来自jenkov关于Java模块的教程):

 java --module-path lib -m com.jenkov.mymodule/com.jenkov.mymodule.Main

您可以使用jar命令设置一个主类来运行模块化jar文件(jenkov教程中也有演示)。然后,您可以运行模块化jar,而无需显式提供主类,但需要指定jar文件和模块路径(JavaFX应用程序仍然需要模块路径):

 jar -c --file=lib/com-jenkov-mymodule.jar --main-class=com.jenkov.mymodule.Main -C out/com.jenkov.mymodule .
 java --module-path lib -jar lib/com-jenkov-javafx.jar

我不知道jar命令是如何将执行命令添加到jar文件中的,但我认为它并没有使用清单来实现这一点。目前,我不认为maven-jar命令能够正确地做到这一点(我认为它只是将信息放在清单中,而不是将模块化的主类执行信息放在jar中)。

总之,使用Java模块和使用类路径是不同的,而且容易混淆…:-)

乱劈

有(至少对于Java 17而言)一种黑客方法可以创建一个单独的启动器类,该类绕过运行时检查,允许从模块路径而不是类路径启动JavaFX框架,但它不受支持。我不建议这样做,所以我不会在这里进一步解释。

进一步建议

由于命令行开关很容易出错或键入错误,因此在部署JavaFX应用程序时,最好提供一个特定于平台的执行脚本(unix/mac shell脚本或windows批处理文件),用户可以更轻松地使用该脚本执行应用程序。

还可以考虑通过压缩的jlink映像或jpackage创建的安装程序使用Java运行时进行分发。这使您的用户更容易使用,因为这样他们就不需要找到并安装适当的java运行时来使用您的应用程序。另外,jlink可以创建一个示例shell脚本来执行应用程序。通过maven实现这一点很容易,可以使用maven javafx插件的jlink选项并指定jlinkZipName。

jpack可以创建一个操作系统级别的图标,用户只需单击即可运行应用程序,但不能直接从maven-javafx-plugin使用。

其他资源

>

  • 更多信息,包括指向打包选项的链接,如javafx标记信息打包资源中的JPackageScriptFX。

    相关问题:如何使用Maven Assembly插件为JavaFX项目创建一体式jar?

  •  类似资料:
    • 我第一次尝试使用JavaFX。我在IntelliJ中创建了一个*.fxml文件的项目。然后,我在IntelliJ中打开了内置的fxml gui编辑器。我得到一个警告,我需要为JavaFX添加一个SDK。我转到了项目结构设置、模块、依赖项,并添加了“IntelliJ dir\jre64\lib\ext\jfxrt.jar”。警告消失了。模块作用域设置为编译。如果我试图通过单击IntelliJ中类声明

    • 我在open sdk 11.0.12中使用IntelliJ。我有一个基于maven的项目。我从空项目开始,并添加了一些依赖项。我正在创建JavaFX应用程序。 我的pom。xml文件如下所示: 4.0.0 当我用maven运行它时,效果很好。我已经设定了目标:清理javafx:run。我想在intellij中本地运行此项目,但错误显示: 我试图创建模块文件,但它显示了javafx。应用缺少应用程序

    • 这里的Java新手。我想在VSCode上了解JavaFX,但是当我启动JavaFX时,它给了我这个错误。我试图在项目上添加引用的库和配置在上,但它给了我同样的东西。 这是我的配置。 谁能帮我?

    • 我正在和几个朋友一起做一个项目,我们正在使用vscode,这样我们就可以有效地使用git(这是一个学校项目,所以IDE是不可协商的,不要告诉我使用不同的),我们遇到了一个问题,他们都不能运行这个javafx应用程序,我已经在那里测试了。一开始我在运行它时遇到了麻烦,并且得到了同样的错误,但是我今天早上修复了它,现在我放在那里的任何javafx文件都可以为我运行,只要我在json中有正确的vmarg

    • 我使用javafx和java-9在eclipse中处理java项目,但我遇到了一个错误: 错误:缺少JavaFX运行时组件,运行此应用程序需要这些组件 我已安装: java-9-openjdk。x86\u 64 java-9-openjdk-devel-9.0.4.11-4。fc27。x86\u 64 openjfx-8.0.152-12。b04。fc27。x86\u 64 openjfx-dev