You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非Application类JavaFX绘图库开发及FatJar打包问题求助

问题:开发非Application类的JavaFX绘图弹窗库及FatJar打包问题

问题简述

如何开发可创建JavaFX弹窗、具备绘图能力的Java库(无需继承JavaFX的Application类),以及如何将使用该库的应用打包为FatJar?

详细描述

我正在开发一个支持序列化的DataFrame库(Java生态中未找到同类支持序列化的库),核心逻辑已完成。通过chart-fx库实现了表格数据绘图功能,用带静态main的测试类在IntelliJ中运行正常,但Maven打包成FatJar后运行报错:

java.lang.UnsupportedOperationException: Cannot resolve 'fa-arrows-alt'

因为是开发库而非应用,我没有遵循JavaFX标准的继承Application类的方式,而是使用Platform.startup(/* 包含JavaFX代码的Lambda函数 */)方法。添加-Dprism.verbose=true参数运行FatJar的控制台日志如下:

jan. 25, 2024 3:55:38 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @3b192d32'
Prism pipeline init order: d3d sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.d3d.D3DPipeline
Loading D3D native library ...
        succeeded.
D3DPipelineManager: Created D3D9Ex device
Direct3D initialization succeeded
(X) Got class = class com.sun.prism.d3d.D3DPipeline
Initialized prism pipeline: com.sun.prism.d3d.D3DPipeline
Maximum supported texture size: 16384
Maximum texture size clamped to 4096
OS Information:
        Windows version 10.0 build 19042
D3D Driver Information:
        NVIDIA GeForce GT 710
        \\.\DISPLAY1
        Driver nvldumdx.dll, version 27.21.14.5671
        Pixel Shader version 3.0
        Device : ven_10DE, dev_128B, subsys_118B10DE
        Max Multisamples supported: 4
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
java.lang.UnsupportedOperationException: Cannot resolve 'fa-arrows-alt'
        at org.kordamp.ikonli.AbstractIkonResolver.resolve(AbstractIkonResolver.java:61)
        at org.kordamp.ikonli.javafx.IkonResolver.resolve(IkonResolver.java:73)
        at org.kordamp.ikonli.javafx.FontIcon.setIconLiteral(FontIcon.java:251)
        at org.kordamp.ikonli.javafx.FontIcon.<init>(FontIcon.java:92)
        at io.fair_acc.chartfx.plugins.Zoomer.getZoomInteractorBar(Zoomer.java:421)
        at io.fair_acc.chartfx.plugins.Zoomer.<init>(Zoomer.java:148)
        at io.fair_acc.chartfx.plugins.Zoomer.<init>(Zoomer.java:252)
        at io.fair_acc.chartfx.plugins.Zoomer.<init>(Zoomer.java:243)
        at sst.visualization.chartFxBased.LineChart.lambda$plot$1(LineChart.java:85)
        at com.sun.javafx.application.PlatformImpl.lambda$startup$5(PlatformImpl.java:294)
        at com.sun.glass.ui.Application.invokeAndWait(Application.java:470)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runToolkit(QuantumToolkit.java:377)
        at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$startup$10(QuantumToolkit.java:290)
        at com.sun.glass.ui.Application.lambda$run$1(Application.java:155)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
        at java.base/java.lang.Thread.run(Thread.java:1583)
 vsync: true vpipe: true

已尝试方案

  • 使用--module-path和--add-modules参数运行,命令为java --module-path C:/javafx-jmods --add-modules javafx.base -jar sst-0.0.1.0-withDependencies.jar,但出现Module javafx.base not found错误,更换其他模块名也无效。
  • 在pom.xml中添加javafx-maven-plugin,但无效果。

个人想法

之前开发过继承Application类的JavaFX应用,可正常运行。

补充问题

不确定Platform.startup是否是开发非应用类JavaFX绘图弹窗的正确方式,不想花太多时间系统学习JavaFX。


解决方案

1. 关于Platform.startup的正确性

Platform.startup()是开发非Application类的JavaFX库的正确方式,它可以在非JavaFX应用的上下文初始化JavaFX运行时,适合库的场景。但要注意:

  • 必须确保Platform.startup()只被调用一次,多次调用会抛出异常
  • 所有JavaFX UI操作必须在JavaFX应用线程执行,后续更新UI可以用Platform.runLater()

2. 解决FatJar打包后的图标解析错误

报错Cannot resolve 'fa-arrows-alt'是因为chart-fx依赖的ikonli字体图标在FatJar打包时没有被正确包含,或者资源路径被破坏。解决步骤:

  • 确保依赖完整:在pom.xml中显式添加ikonli的Font Awesome依赖,因为chart-fx可能是间接依赖,打包时可能遗漏:
    <dependency>
        <groupId>org.kordamp.ikonli</groupId>
        <artifactId>ikonli-fontawesome-pack</artifactId>
        <version>12.3.1</version> <!-- 使用与chart-fx兼容的版本 -->
    </dependency>
    
  • 修正Maven打包配置:使用maven-shade-plugin打包时,需要配置资源转换器,处理ikonli的字体资源:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.5.1</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <transformers>
                        <!-- 处理ikonli的字体资源 -->
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ResourceBundleAppendingTransformer">
                            <resource>META-INF/org/kordamp/ikonli/ikonli.properties</resource>
                        </transformer>
                        <!-- 设置主类(如果是测试用的FatJar) -->
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>your.test.MainClass</mainClass>
                        </transformer>
                    </transformers>
                    <filters>
                        <!-- 排除重复的签名文件,避免打包错误 -->
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
            </execution>
        </executions>
    </plugin>
    
  • 避免模块路径冲突:因为你是用非模块化方式打包(unnamed module),不要用--module-path参数运行FatJar,直接用java -jar your-fatjar.jar即可,之前的Module javafx.base not found是因为你的FatJar已经包含了JavaFX类,不需要额外指定模块路径。

3. 额外注意事项

  • 如果你的库需要被其他应用依赖,建议将JavaFX依赖设置为provided,让使用方自行管理JavaFX依赖,避免冲突:
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>21.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>21.0.1</version>
        <scope>provided</scope>
    </dependency>
    
  • 测试时,确保IntelliJ的运行配置中没有添加额外的模块路径参数,避免和打包后的运行方式不一致。

内容的提问来源于stack exchange,提问作者Lucas Monteiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 17:37:32