我对这个问题感到抱歉,这个问题在 StackOverflow 上已经被问过很多次了。 我使用 Java Swing 编写了许多 GUI 应用程序,但我想切换到现代 JavaFX。 我陷入了基本问题 - 我无法构建一个胖罐子。
当我尝试运行 fat jar(有 8 MB)时,它崩溃了:
$ java -jar app-1.0-SNAPSHOT-jar-with-dependencies.jar
Error: JavaFX runtime components are missing, and are required to run this application
但是如果我使用这些参数运行它,它就会起作用:
$ java --module-path /usr/share/openjfx/lib --add-modules javafx.controls,javafx.fxml -jar app-1.0-SNAPSHOT-jar-with-dependencies.jar
这很烦人。我以前的 Swing 应用程序没有这个就可以工作。我用Maven玩了半天,没有成功。
有人可以帮助我吗?我完全陷入困境:-(
有我的简单应用程序的源文件:
module-info.java
:
module test.app {
requires javafx.controls;
requires javafx.fxml;
opens test.app to javafx.fxml;
exports test.app;
}
App.java
:
package test.app;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class App extends Application {
private static Scene scene;
@Override
public void start(Stage stage) throws IOException {
scene = new Scene(loadFXML("primary"), 640, 480);
stage.setScene(scene);
stage.show();
}
private static Parent loadFXML(String fxml) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
return fxmlLoader.load();
}
public static void main(String[] args) {
launch();
}
}
PrimaryController.java
:
package test.app;
public class PrimaryController {
}
primary.fxml
:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.app.PrimaryController">
<children>
<Label text="Test" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
pom.xml
:
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>test.app.App</mainClass>
</manifest>
</archive>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
</dependency>
</dependencies>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>test.app.App</mainClass>
</configuration>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
</execution>
<execution>
<!-- Configuration for manual attach debugging -->
<!-- Usage: mvn clean javafx:run@debug -->
<id>debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000</option>
</options>
</configuration>
</execution>
<execution>
<!-- Configuration for automatic IDE debugging -->
<id>ide-debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option>
</options>
</configuration>
</execution>
<execution>
<!-- Configuration for automatic IDE profiling -->
<id>ide-profile</id>
<configuration>
<options>
<option>${profiler.jvmargs.arg1}</option>
<option>${profiler.jvmargs.arg2}</option>
<option>${profiler.jvmargs.arg3}</option>
<option>${profiler.jvmargs.arg4}</option>
<option>${profiler.jvmargs.arg5}</option>
</options>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
以下存储库包含完整的预配置项目,每个项目都可以创建可执行的 fat JAR。 他们都开箱即用。只需下载并根据您的需要更改它们即可。
这是如何完成的:
使用 Maven: https://github.com/davidweber411/javafx-JavaFxAppMavenNonModular
使用 Gradle: https://github.com/davidweber411/javafx-JavaFxAppGradleNonModular
使用 Maven 和 Spring Boot(!): https://github.com/davidweber411/javafx-JavaFxSpringBootMavenApp
PS:如果他们帮助了你,你可以给他们一颗星星! <3