我有一个非常基本的JavaFX应用程序,如果Application类不是 Main类,它可以完美地工作:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
public class Main {
public static void main(String[] args) {
Application.launch(App.class, args);
}
}
public class App extends Application {
@Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(); // works
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我将两者合并在一起时(这是大多数教程中推荐的方式,包括OpenJFX的官方文档),模块系统抛出IllegalAccessError
(至少在OpenJDK 11.0.2上):
public class MainApp extends Application {
@Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(); // throws IllegalAccessError
}
public static void main(String[] args) {
launch(MainApp.class, args);
} …
Run Code Online (Sandbox Code Playgroud) 我想不用说,我应该能够将Oracle自己的JDK与JavaFX(来自gluonhq)一起使用,以构建用户可以使用的可分发jar文件。
经过详尽的搜索,大量阅读(过去几个月中24小时或更长时间),最后是这个Google搜索查询:
how to make a fat jar -maven -gradle -scala -eclipse -ant -docker -hadoop -netbeans -jerkar -phy -mozni -yogurt -pizza - throwing -python -bacon
Run Code Online (Sandbox Code Playgroud)
我绝对在路的尽头。到底为什么这么多工作?我该如何构建JavaFX应用程序并将其提供给想要实际使用它的人,而又不知道如何使用应用程序本身呢?
我的JavaFx
应用程序从源代码运行得很好,但是当我编译为单个 jar 文件时,出现错误:
错误:缺少 JavaFX 运行时组件,运行此应用程序需要这些组件。
我正在Maven
用作我的存储库管理器,并且我的 Maven 安装成功。
注意:在我的Intellij
构建工件中,我可以看到Intellij
包含JavaFx
及其所有库
我有一个Javafx应用程序,我想通过Windows命令提示符将其及其模块依赖项(javaFX)压缩到一个jar文件中,以便您可以在任何地方双击运行它而无需javafx sdk。
我正在使用的javaFX模块是控件和Web。
我已广泛搜索有关如何执行此操作的信息。但是,我所发现的只是与javaFX模块一起运行jar的东西。但是,这不符合单个jar文件的要求,因为您需要单独下载javaFX sdk。
我正在尝试使用maven-shade-plugin但收到警告:
javafx-controls-18.0.1-win.jar、javafx-graphics-18.0.1-win.jar、javafx-media-18.0.1-win.jar、javafx-web-18.0.1-win.jar 定义 1 个重叠资源:
- META-INF/substrate/config/resourcebundles javafx-graphics-18.0.1-win.jar、javafx-media-18.0.1-win.jar、javafx-web-18.0.1-win.jar 定义 2 个重叠资源:
- META-INF/substrate/config/jniconfig-x86_64-linux.json
- META-INF/substrate/config/reflectionconfig-x86_64-linux.json javafx-base-18.0.1-win.jar,javafx-controls-18.0.1-win.jar,javafx-graphics-18.0.1-win.jar定义 1 个重叠资源:
- META-INF/substrate/config/reflectionconfig.json maven-shade-plugin 检测到某些类文件存在于两个或多个 JAR 中。发生这种情况时,只会将该类的一个版本复制到 uber jar 中。通常这没有什么害处,您可以跳过这些警告,否则尝试根据 mvn dependency:tree -Ddetail=true 和上述输出手动排除工件。请参阅 https://maven.apache.org/plugins/maven-shade-plugin/
此警告可能会发生变化(可能来自我的行为)。
我试图用这个来修复它,但它不起作用:
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*</exclude>
</excludes>
</filter>
</filters>
Run Code Online (Sandbox Code Playgroud)
由于 Shadow-jar 由于错误而无法启动,我开始尝试修复此警告:
错误:缺少 JavaFX 运行时组件,并且需要运行该应用程序
请告诉我如何修复此错误并运行shade-jar?
我的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>com.test</groupId>
<artifactId>TEST</artifactId>
<version>1.0</version>
<name>TEST</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.2</junit.version>
<javafx.version>18.0.1</javafx.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency> …
Run Code Online (Sandbox Code Playgroud) 目前,我在启动程序时使用 JVM 参数来查找 JavaFX 库,如下所示:
java -javaagent:lib/aspectjweaver-1.9.5.jar -javaagent:lib/spring-instrument-5.2.3.RELEASE.jar --module-path lib/javafx-sdk-13.0.2/lib --add-modules=javafx.controls -jar target/Some_Service-1.0.jar
Run Code Online (Sandbox Code Playgroud)
我的 POM.xml 的插件部分非常简单。除了 Docker 和 Launch4j 插件之外,我只有这个:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉Maven将整个lib目录(其中包含JavaFX库和aspectJ/spring仪器java代理)捆绑在jar中?这样做可以解决在我部署应用程序的任何地方都必须携带该 lib 文件夹的问题!谢谢!
******编辑******
我搞乱了 spring boot maven 插件选项,不幸的是我的 jar 仍然不包含我的文件夹:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<folders>
<folder>lib</folder>
</folders>
<agent>lib/aspectjweaver-1.9.5.jar</agent>
<agent>lib/spring-instrument-5.2.3.RELEASE.jar</agent>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)
*****编辑2*****
我刚刚发现了一个很棒的库,它完全消除了对 -javaagent 参数的需要,而是让您在运行时以编程方式加载它们。看来我的类路径中存在 AspectJ 和 Spring-Instrument 也正是它所需要的!查看: https: //github.com/subes/invesdwin-instrument。
我现在需要的是以某种方式将 JavaFX 运行时捆绑到我的 jar 中,而不是使用命令行参数从外部引用它。
我的应用程序使用Java Fx Web来显示html页面,问题是只有当我直接运行.jar时才会出现此错误,因为当我从我的ide(eclipse)运行它时它运行没有问题。有谁知道这是关于什么的吗?我正在使用 AdoptOpenJdk11。我也在同事的电脑上测试过,也是不行。
Graphics Device initialization failed for : d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:244)
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:261)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.embed.swing.JFXPanel.initFx(JFXPanel.java:241)
at javafx.embed.swing.JFXPanel.<init>(JFXPanel.java:257)
at com.rubicon.game.client.window.main.menu.GameMenuPanel.<init>(GameMenuPanel.java:62)
at com.rubicon.game.client.network.states.LobbyConnectionState.enable(LobbyConnectionState.java:12)
at com.rubicon.game.client.ClientApplication.loadComponents(ClientApplication.java:115)
at com.rubicon.game.client.ClientApplication.lambda$initializate$0(ClientApplication.java:98)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at com.rubicon.game.client.network.NetworkConnection.lambda$login$0(NetworkConnection.java:124)
at com.rubicon.game.core.network.packets.PacketResponse.lambda$whenComplete$0(PacketResponse.java:30)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at com.rubicon.game.core.network.packets.PacketResponse.complete(PacketResponse.java:24)
at com.rubicon.game.core.network.packets.request.PacketRequestLogin.onClientReceive(PacketRequestLogin.java:43)
at com.rubicon.game.client.network.callback.PacketCallbackRequester.onReceive(PacketCallbackRequester.java:33)
at com.rubicon.game.client.network.NetworkConnection.execute(NetworkConnection.java:94)
at java.base/java.lang.Thread.run(Thread.java:834) …
Run Code Online (Sandbox Code Playgroud) 这是使用 Maven 创建多模块 JavaFX 应用程序的尝试。
鉴于该项目的结构如下:
project
| pom1.xml
|_____ Word Generator (Folder)
| pom2.xml
|_____logic (folder)
| WordGenerator
|_____UI (folder)
| pom3.xml
|_____marty
| App
| PrimaryController
| SecondaryController
Run Code Online (Sandbox Code Playgroud)
按照上述方案的顺序,我们有以下 pom 文件结构:
pom1.xml
project
| pom1.xml
|_____ Word Generator (Folder)
| pom2.xml
|_____logic (folder)
| WordGenerator
|_____UI (folder)
| pom3.xml
|_____marty
| App
| PrimaryController
| SecondaryController
Run Code Online (Sandbox Code Playgroud)
pom2.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.games.marty</groupId>
<artifactId>words</artifactId>
<packaging>pom</packaging>
<version>0.1</version>
<modules>
<module>UI</module>
<module>Word Generator</module>
</modules>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target> …
Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的 Java 类src/main/java/webbrowser/WebBrowser.java
:
package webbrowser;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
public class WebBrowser extends Application {
@Override
public void start(Stage stage) {
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.load("http://www.oracle.com");
Scene scene = new Scene(browser, 1200, 900);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个pom.xml
列出 JavaFX 依赖项并配置程序集插件的文件:
<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>webbrowser</groupId>
<artifactId>WebBrowser</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>WebBrowser</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies> …
Run Code Online (Sandbox Code Playgroud) 被这个问题困扰好几天了。我正在尝试使用 gradle build 命令导出 jar 文件,但它提供了一个小 jar 文件。当我运行 jar 文件时,它给出以下错误,表明 javafx 依赖项未包含在构建中:
Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Application
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at newcare.home.Main_1.main(Main_1.java:6)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
... 10 more
Run Code Online (Sandbox Code Playgroud)
我看过类似这样的帖子在 IntelliJ IDEA 中创建 Java Gradle 项目并构建 .jar 文件 - 如何?他们似乎帮助了别人,但没有帮助我。这是我的 build.gradle:
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
group 'newcare'
version …
Run Code Online (Sandbox Code Playgroud)