如何让Gradle仅加载当前平台的JavaCV二进制文件?
当前使用的javacv-platform、ffmpeg-platform-gpl这类-platform后缀的依赖会包含所有操作系统架构的本地库(Windows、Linux、macOS、Android等),这是体积过大的核心原因。只需保留当前平台的必要依赖即可:
解决方案步骤:
替换平台依赖为单平台核心依赖
移除javacv-platform和ffmpeg-platform-gpl,换成对应平台的FFmpeg GPL包+JavaCV核心包。Gradle可自动检测当前系统,通过以下配置引入对应平台的依赖:dependencies { // 替换原platform依赖 implementation 'org.bytedeco:javacv:1.5.9' implementation 'org.bytedeco:ffmpeg-gpl:6.0-1.5.9' // 自动引入当前平台的本地库 implementation group: 'org.bytedeco', name: 'ffmpeg-gpl', version: '6.0-1.5.9', classifier: org.gradle.internal.os.OperatingSystem.current().getNativePrefix() implementation group: 'org.bytedeco', name: 'flandmark', version: '1.07-1.5.8', classifier: org.gradle.internal.os.OperatingSystem.current().getNativePrefix() }注:若需支持多平台打包,可通过Gradle的
osdetector插件针对不同平台构建,但单平台构建时用上述方式即可大幅缩减体积。排除不必要的传递依赖
JavaCV默认会引入一些非必需库(如artoolkit、tesseract等),在configuration里添加排除规则:configurations { implementation { exclude group: "commons-logging", module: "commons-logging" exclude group: 'com.google.code.findbugs', module: 'jsr305' // 排除不需要的JavaCV传递依赖 exclude group: 'org.bytedeco', module: 'artoolkitplus-platform' exclude group: 'org.bytedeco', module: 'tesseract-platform' exclude group: 'org.bytedeco', module: 'leptonica-platform' exclude group: 'org.bytedeco', module: 'opencv-platform' } }优化jlink打包参数
打开jlink注释的压缩和精简参数,进一步减小镜像体积:jlink { options = ['--bind-services', '--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages'] addExtraDependencies 'javafx' // 其余配置不变 }
错误提示的Package lib.x86 in both module...是因为-platform依赖引入了多个包含相同包名的Android平台模块(如artoolkitplus和tesseract的x86模块),这些模块在模块路径中冲突,导致启动层初始化失败。
解决方案步骤:
测试阶段使用非platform依赖
在测试配置中排除所有-platform后缀的依赖,只引入核心JavaCV和对应平台的本地库,避免多余模块:dependencies { // 主依赖配置不变 testImplementation "org.junit.jupiter:junit-jupiter-api:${rootProject.ext.junitVersion}" testImplementation 'org.hamcrest:hamcrest-library:2.2' testImplementation 'org.mockito:mockito-junit-jupiter' testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${rootProject.ext.junitVersion}" // 排除测试依赖中的冲突模块 testImplementation('org.bytedeco:javacv:1.5.9') { exclude group: 'org.bytedeco', module: 'artoolkitplus-platform' exclude group: 'org.bytedeco', module: 'tesseract-platform' } testImplementation group: 'org.bytedeco', name: 'ffmpeg-gpl', version: '6.0-1.5.9', classifier: org.gradle.internal.os.OperatingSystem.current().getNativePrefix() }调整module-info.java
替换原platform模块依赖为核心模块,减少冲突来源:module main { // 其余requires不变 // 替换原platform requires为核心模块 requires org.bytedeco.javacv; requires org.bytedeco.ffmpeg; requires org.bytedeco.flandmark; // 移除org.bytedeco.javacv.platform、org.bytedeco.flandmark.platform }强制测试使用类路径而非模块路径(备选)
若模块冲突难以解决,可让测试任务使用类路径运行,绕过模块系统检查:test { useJUnitPlatform() // 强制使用类路径运行测试 jvmArgs += '--add-modules', 'ALL-MODULE-PATH' jvmArgs += '--illegal-access=warn' }
内容的提问来源于stack exchange,提问作者Nick Charney Kaye

