首页 > 解决方案 > 浏览器 HEAVYWEIGHT 在场景中不可见

问题描述

我正在尝试将 JXBrowser 嵌入到使用 Java11 运行的 SpringBoot JavaFX 应用程序中。我的问题是当我从创建的可执行 jar 运行应用程序时,浏览器没有显示在场景中。浏览器已加载,提供有关已加载网站的反馈,并且已经是场景的一部分,但不可见。在 IntelliJ 中运行或使用 Maven exec 目前正在运行。当我将浏览器模块切换到 LIGHTWEIGHT 时,这三种运行可能性都运行良好。在 HEAVYWEIGHT mod 中从 jar 运行有什么问题?

我的系统:Windows10-64、Java11、SpringBoot 2.1.0.RELEASE、JXBrowser 6.21、OpenJFX 11

主类

@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();
}

}

开始主类

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>

标签: spring-bootjavafxjxbrowserjava-11

解决方案


我已经设法构建了该项目,并获得了可以运行它的试用许可证。正如您所提到的,从 IDE 或命令行运行mvn compile exec:exec(我也尝试过使用 Gradle,./gradlew run添加所需的--add-exports)工作得非常好,显示浏览器并加载给定的 URL。

但是,正如您所说,如果您创建一个胖 jar 并运行它,它不会显示浏览器,但 JavaFX 可以工作,您可以看到一些活动正在进行,只是没有渲染。

我在 JDK 8、9、10 和 11 下都试过了。只有在 8 下我才能得到 fat jar 来显示浏览器。

一般来说,使用胖 jar 是一种不好的做法,现在更糟糕的是,您必须包含 JavaFX SDK 中的 JavaFX 类。

分发应用程序的更好方法是使用jlink

鉴于这com.teamdev.jxbrowser:jxbrowser不是模块化的,您不能完全使用jlink您的项目,但您可以仅使用 JavaFX 模块创建自定义运行时映像,并使用它来运行您的应用程序,唯一的依赖项是jxBrowser(为了方便,我没有使用弹簧启动)。

因此,如果您从此处下载 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 依赖项做一个小胖 jar 然后如果你运行:

jre/bin/java -cp build/libs/browserApp.jar jxbrowser.BrowserApp

可以想象,这不起作用,浏览器不会出现。

所以我的最终结论是,即使只有两个jxBrowser依赖项,添加一个 fat jar 也是行不通的。

例如,请参阅这篇文章,了解可能的原因:

多个 JAR 中可能存在具有相同路径的文件,默认情况下,shade 插件包含 fat JAR 中的第一个文件并丢弃其余文件。

因此,我建议您向项目问题跟踪器提交问题(如果存在),并且我还建议您找到一种方法来运行您的应用程序而无需使用 fat-jars。


推荐阅读