我正在尝试将JXBrowser嵌入到运行Java11的SpringBoot JavaFX应用程序中。我的问题是,当我从创建的可执行jar运行应用程序时,浏览器未显示在场景中。浏览器已加载,可提供有关已加载网站的反馈,并且已成为场景的一部分,但不可见。 当前正在IntelliJ内部运行或与Maven exec一起运行。当我将浏览器mod切换到LIGHTWEIGHT时,这三种运行方式都可以正常工作。在HEAVYWEIGHT mod中从jar运行会出现什么问题?
我的系统:Windows10-64,Java11,SpringBoot 2.1.0.RELEASE,JXBrowser 6.21,OpenJFX 11
Main.class
@Slf4j
@SpringBootApplication
public class Main extends Application
{
private ConfigurableApplicationContext springContext;
public static void main(final String[] args)
{
Application.launch(args);
}
@Override
public void init()
{
springContext = SpringApplication.run(Main.class);
springContext.getAutowireCapableBeanFactory().autowireBean(this);
}
@Override
public void start(Stage stage)
{
final Browser browser = new Browser();
stage.setScene(new Scene(new BrowserView(browser)));
stage.show();
browser.loadURL("http://www.google.de");
}
@Override
public void stop()
{
springContext.close();
}
}
StartMain.class
public class StartMain
{
public static void main(String[] args)
{
Main.main(args);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>de</groupId>
<artifactId>app</artifactId>
<version>1.0.10-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<jxbrowser.version>6.21</jxbrowser.version>
<javafx.version>11</javafx.version>
</properties>
<repositories>
<repository>
<id>com.teamdev</id>
<url>http://maven.teamdev.com/repository/products</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.teamdev.jxbrowser</groupId>
<artifactId>jxbrowser-cross-platform</artifactId>
<type>pom</type>
<version>${jxbrowser.version}</version>
</dependency>
<dependency>
<groupId>com.teamdev.jxbrowser</groupId>
<artifactId>jxbrowser-win64</artifactId>
<version>${jxbrowser.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>${javafx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
<mainClass>...StartMain</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>build-info</goal>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
答案 0 :(得分:4)
我已经成功构建了项目,并获得了试用许可证,我可以运行它。如您所述,从IDE或从命令行mvn compile exec:exec
运行(我也尝试过Gradle,./gradlew run
,添加了必需的--add-exports),工作正常,浏览器是显示并加载给定的URL。
但是,正如您所说的,如果创建一个胖jar并运行它,它不会显示浏览器,但是JavaFX可以工作,并且您可以看到正在进行的活动,只有没有渲染。
我已经在JDK 8、9、10和11下进行了尝试。只有在8以下,我才能看到胖子来显示浏览器。
使用胖罐子通常是一个不好的做法,现在变得更糟,因为您必须包括JavaFX SDK中的JavaFX类。
一种更好的分发应用程序的方法是使用jlink。
鉴于com.teamdev.jxbrowser:jxbrowser
不是模块化的,您不能在项目中完全使用jlink
,但是只能使用JavaFX模块创建自定义运行时映像,并使用它来运行应用程序与jxBrowser
的唯一依赖关系(为方便起见,我不使用SpringBoot)。
因此,如果您从here下载JavaFX jmod,请解压缩它们并运行:
export PATH_TO_FX_MODS=/path-to/javafx-jmods-11
$JAVA_HOME/bin/jlink --module-path $PATH_TO_FX_MODS \
--add-modules=java.se,javafx.web,javafx.fxml,javafx.swing \
--output jre
您将创建一个包含JavaFX的JRE。
然后,您可以运行项目,包括在类路径中的依赖项:
jre/bin/java -cp \
/Users/<user>/.gradle/caches/modules-2/files-2.1/com.teamdev.jxbrowser/jxbrowser/6.22/c9...6b/jxbrowser-6.22.jar:\
/Users/<user>/.gradle/caches/modules-2/files-2.1/com.teamdev.jxbrowser/jxbrowser-mac/6.22/fa...d4/jxbrowser-mac-6.22.jar:\
build/libs/browserApp.jar jxbrowser.BrowserApp
这也很好,将显示浏览器。因此,我们放弃了JavaFX 11可能存在的任何问题。
现在,我们仍然可以对项目和jxBrowser依赖项做一个 small 胖子罐。然后,如果您运行:
jre / bin / java -cp build / libs / browserApp.jar jxbrowser.BrowserApp
您可以想象,这行不通,浏览器也不会显示。
所以我的最终结论是,即使仅具有两个jxBrowser
依赖项,添加胖子也不起作用。
例如,查看此post的可能原因:
在多个JAR中可能存在具有相同路径的文件,默认情况下,shadow插件在胖JAR中包含第一个文件,而将其余文件丢弃。
因此,我建议您将问题提交到项目问题跟踪器(如果存在),并且我也建议您找到一种无需繁琐即可运行应用程序的方法。