Linux环境下无法找到JavaFX依赖的问题求助
问题描述
我们使用Java 21、JavaFX 21、Gradle 8.6及JavaFX Gradle插件(可查看Gradle 8.6的兼容性矩阵)。在Azure Pipelines的托管Windows代理和自托管Linux代理上运行应用单元测试时,Windows代理上测试正常,但Linux代理抛出UnsatisfiedLinkError,提示找不到javafx_font_pango库。
已知缺失的原生依赖已打包在javafx-graphics jar中,但程序似乎期望该依赖存在于java.library.path指定的路径中,异常信息如下:
java.lang.UnsatisfiedLinkError: no javafx_font_pango in java.library.path: /agent/_work/1/s/<path to java.library.path> at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2458) at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:916) at java.base/java.lang.System.loadLibrary(System.java:2063) at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:170) at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:58) at com.sun.javafx.font.freetype.OSPango.lambda$static$0(OSPango.java:37) at java.base/java.security.AccessController.doPrivileged(AccessController.java:319) at com.sun.javafx.font.freetype.OSPango.<clinit>(OSPango.java:36) at com.sun.javafx.font.freetype.PangoGlyphLayout.<clinit>(PangoGlyphLayout.java:45) at com.sun.javafx.font.freetype.FTFactory.createGlyphLayout(FTFactory.java:87) at com.sun.javafx.text.GlyphLayout.newInstance(GlyphLayout.java:407) at com.sun.javafx.text.GlyphLayout.<clinit>(GlyphLayout.java:402) at com.sun.javafx.text.PrismTextLayout.buildRuns(PrismTextLayout.java:818) at com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1070) at com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:230) at com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:256) at javafx.scene.text.Text.getLogicalBounds(Text.java:432) at javafx.scene.text.Text.doComputeLayoutBounds(Text.java:1137) at javafx.scene.text.Text$1.doComputeLayoutBounds(Text.java:143) at com.sun.javafx.scene.shape.TextHelper.computeLayoutBoundsImpl(TextHelper.java:95) at com.sun.javafx.scene.NodeHelper.computeLayoutBounds(NodeHelper.java:108) at javafx.scene.Node$13.computeBounds(Node.java:3474) at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9749) at javafx.scene.Node$LazyBoundsProperty.get(Node.java:9740) at javafx.scene.Node.getLayoutBounds(Node.java:3489)
相关Gradle配置
JavaFX Gradle插件配置
javafx { version = project.properties['javafxVersion'] modules = [ 'javafx.base', 'javafx.controls', 'javafx.graphics', 'javafx.swing', 'javafx.web', 'javafx.media' ] configurations = [ 'implementation', 'testImplementation', 'testRuntimeOnly', 'testFixturesImplementation', 'guiTestImplementation' ] }
测试任务配置
tasks.withType(Test) { doFirst { delete getReports().getJunitXml().getOutputLocation() } jvmArgs "-Djava.library.path=${project.nativeLibsDir}" // our custom native libs directory } test { useJUnitPlatform() ext.testSrcDirs = project.sourceSets.test.java.srcDirs jvmArgs "-Dglass.platform=Monocle", "-Dmonocle.platform=Headless", "-Dprism.order=sw", "-Dprism.text=t2k" forkEvery 100 maxParallelForks = Runtime.getRuntime().availableProcessors() - 1 testLogging { events "started", "passed", "skipped", "failed" } }
解决方案
1. 修复java.library.path配置,避免覆盖原生路径
当前配置直接用自定义目录覆盖了java.library.path,导致JavaFX插件自动添加的原生库路径丢失。需要将自定义路径追加到原有路径后,而非替换:
tasks.withType(Test) { doFirst { delete getReports().getJunitXml().getOutputLocation() } // 跨平台方式追加自定义原生库路径 def pathSeparator = System.getProperty('path.separator') def originalLibPath = System.getProperty('java.library.path') jvmArgs "-Djava.library.path=${project.nativeLibsDir}${pathSeparator}${originalLibPath}" }
2. 确保Linux代理安装必要的字体依赖
Linux下JavaFX的字体渲染依赖系统字体库,在Headless模式下需提前安装相关包(以Debian/Ubuntu为例):
apt-get update && apt-get install -y fontconfig fonts-dejavu-core
可将此命令添加到Azure Pipelines的Linux代理初始化步骤中。
3. 验证JavaFX原生库的下载与加载
检查Gradle构建日志,确认JavaFX Gradle插件已为Linux平台下载对应原生库(如javafx-graphics-21-linux.jar)。插件会自动解压这些库到Gradle缓存目录,并添加到java.library.path,修复路径配置后即可正常加载。
内容的提问来源于stack exchange,提问作者QuasiG
相关产品推荐
相关产品推荐

