根据OS自动加载不同的native库和本地jar包
目录
- 背景
- 加载本地jar包
- 加载native库
- 打jar包时如何处理native库
- 根据OS自动选择、或者手动选择加载文件
背景
在SpringBoot项目中调用虹软SDK,来实现人脸、性别检测等功能。且此项目需要部署到不同环境,包括Windows和Linux。以Windows为例,从下图可见,需要加载本地jar包(maven的公开库找不到此依赖),和native库(Windows上为.dll文件,Linux上为.so文件)。
加载本地jar包
pom.xml中的本地依赖如下。当使用了 system 作用域,Maven 不会尝试从远程仓库下载这个依赖,而是直接使用指定路径的本地文件:
<dependency> <!--虹软 人像识别--><groupId>com.arcsoft.face</groupId><artifactId>arcsoft-sdk-face</artifactId><version>3.0.0.0</version><scope>system</scope><systemPath>${pom.basedir}/libs/WIN64/arcsoft-sdk-face-3.0.0.0.jar</systemPath></dependency>
另外注意需要进行以下设置,不然打jar包时,不会包含system作用域的依赖:
加载native库
可简单通过os.name等系统属性来自动选择不同路径。核心代码:
private static String getLibPath() { //native库路径String osName = System.getProperty("os.name").toLowerCase();String localPath = System.getProperty("user.dir");String libPath = localPath + File.separator + "libs";if (osName.contains("win")) {libPath += File.separator + "WIN64";} else {libPath += File.separator + "linux";}return libPath;}@PostConstruct
public void init() {faceEngine = new FaceEngine(getLibPath());。。。
从虹软的代码中可以看到,加载native库的底层关键方法是System.load等方法。
打jar包时如何处理native库
处理 native 库(如 DLL 文件) 的几种思路:
-
方案一:手动复制DLL到JAR外部的指定目录(如应用根目录或系统库路径)
-
方案二:将dll打进jar包,运行时再提取DLL到临时目录(感觉不如方案三,放弃)
-
方案三(推荐):使用 Maven 在构建阶段复制 DLL 到外部 lib 目录 。和方案一一样不将native 文件打进jar包,比方案一优秀在复制动作是自动化的。
亲测有效。示例:修改 pom.xml,在<project><build><plugins>
标签中加入:
<plugin><artifactId>maven-antrun-plugin</artifactId><executions><execution><id>copy-native-libs</id><phase>process-resources</phase><goals><goal>run</goal></goals><configuration><target><!-- 创建目标目录 --><mkdir dir="${project.build.directory}/libs"/><!-- 复制 WIN64 目录下的内容 --><copy todir="${project.build.directory}/libs/WIN64"><fileset dir="libs/WIN64"/></copy></target></configuration></execution></executions></plugin>
运行mvn pacakge命令后,可以看到target目录下有了复制过来的文件:
原理(by通义千问):Maven 本身不提供直接复制文件的功能,但可以通过使用 maven-antrun-plugin 插件 来调用 Ant 任务实现文件复制。
根据OS自动选择、或者手动选择加载文件
包括本地jar包和native库。可在pom.xml文件中使用profile标签,亲测有效:
其中 <activation> <os> <family>windows</family> </os> </activation>
表示当操作系统是 Windows 时,此 Profile 将被自动激活。此Profile还配置了要包含的本地依赖,和mvn package时要复制的native库,具体内容都在前面介绍过了。
构建项目时既可以自动激活Profile,也可以直接指定Profile。比如指定ID为win的profile: mvn package -Pwin
: