如何修复Gluon打包Android时的JNI_OnLoad_javajpeg符号缺失错误
环境信息
- Ubuntu 22.04 LTS
- Java 17(Java 11测试无差异)
- graalvm-svm-java17-linux-gluon-22.1.0.1-Final
- Maven 3.8.8
- android-ndk-r25c
执行步骤
$ mvn -Pandroid gluonfx:build $ mvn -Pandroid gluonfx:package $ mvn -Pandroid gluonfx:install $ mvn -Pandroid gluonfx:nativerun
报错详情
[INFO] [SUB] --------- beginning of crash
[INFO] [SUB] E/AndroidRuntime(28624): FATAL EXCEPTION: main
[INFO] [SUB] E/AndroidRuntime(28624): Process: com.thevegcat.TheVegCatApp, PID: 28624
[INFO] [SUB] E/AndroidRuntime(28624): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "JNI_OnLoad_javajpeg" referenced by "/data/app/~~MsvDADBiJ40PbJ6YgoWjVw==/com.thevegcat.TheVegCatApp-jeiDsmOewudHMN1dhopxxA==/lib/arm64/libsubstrate.so"...
[INFO] [SUB] E/AndroidRuntime(28624): at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
[INFO] [SUB] E/AndroidRuntime(28624): at java.lang.Runtime.loadLibrary0(Runtime.java:998)
[INFO] [SUB] E/AndroidRuntime(28624): at java.lang.System.loadLibrary(System.java:1656)
[INFO] [SUB] E/AndroidRuntime(28624): at com.gluonhq.helloandroid.MainActivity.surfaceCreated(MainActivity.java:107)
已尝试的方案
- 手动创建假符号修复启动问题,但因缺失图形相关实现,启动后仅显示黑屏,无法正常渲染界面
- 确认该问题为共性问题(对应GitHub PR #1000)
相关代码(图片加载逻辑)
private Image fetchImage(final String photo) { final String imageUrl = this.host + photo; try { final BufferedImage image = ImageIO.read(new URL(imageUrl)); return SwingFXUtils.toFXImage(image, null); } catch (final IOException e) { return null; } }
有效解决方案
1. 替换图片加载方式
当前用的ImageIO和SwingFXUtils依赖AWT/Swing桌面组件,Gluon Mobile在Android环境下对这类API支持有限。直接改用JavaFX原生Image类加载网络图片,无需依赖AWT:
private Image fetchImage(final String photo) { final String imageUrl = this.host + photo; try { // 异步加载模式,更适配移动端 return new Image(imageUrl, true); } catch (Exception e) { return null; } }
2. 升级Gluon依赖版本
当前使用的graalvm-svm 22.1.0.1-Final存在已知的javajpeg符号缺失问题,升级到Gluon最新稳定版本(如22.3.14及以上),新版本已修复该类JNI依赖问题。修改pom.xml中的插件版本:
<plugin> <groupId>com.gluonhq</groupId> <artifactId>gluonfx-maven-plugin</artifactId> <version>22.3.14</version> <configuration> <!-- 保留原有配置 --> </configuration> </plugin>
3. 切换兼容的NDK版本
android-ndk-r25c与部分Gluon版本兼容性不佳,建议换成Gluon官方推荐的android-ndk-r21e,避免因NDK版本过高导致的符号链接问题。
4. 显式配置JNI依赖打包
在pom.xml的gluonfx插件配置中,明确声明要包含javajpeg库,确保打包时不会遗漏:
<plugin> <groupId>com.gluonhq</groupId> <artifactId>gluonfx-maven-plugin</artifactId> <version>22.3.14</version> <configuration> <target>android</target> <attachList> <list>display</list> <list>lifecycle</list> <list>statusbar</list> <list>storage</list> </attachList> <bundlerArgs> <property> <name>android.ndk.path</name> <value>/你的NDK路径/android-ndk-r21e</value> </property> <property> <name>jni.libs.included</name> <value>javajpeg</value> </property> </bundlerArgs> </configuration> </plugin>
验证步骤
- 清理旧构建产物:
mvn clean - 重新执行打包运行命令:
mvn -Pandroid gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun
内容的提问来源于stack exchange,提问作者user1034461

