海康威视(HIKVISION) JAVA SDK 打包方法

  • 问题
  • 疑问
  • 解决方法一
  • 解决方法二
  • 结语


问题

最近项目中需要调用海康的摄像头然后进行抓拍图片,由于使用的是 spring-boot 框架,然后将 DLL 动态链接库打包到 jar包,导致 JNA

疑问

为什么在开发的时候可以加载到DLL,打包后就会获取不到?

经过检查,发现打包后,系统会将 jar 包当成一个文件,这时候我们使用 classgetResource() 就会获取不到DLL的绝对路径。这主要是因为jar包是一个单独的文件而非文件夹,绝对不可能通过 file:/e:/.../ResourceJar.jar/resource /res.txt 这种形式的文件URL来定位文件。所以即使是相对路径,也无法定位到jar文件内的文件。我们不能用常规操作文件的方法来读取jar中的资源文件。

可能这块的东西有些童鞋不太懂,可以去搜索相关的知识或者自己读取一个资源文件,打成 jar 包试试就明白了。

解决方法一

这时候就有办法了,那么获取不到怎么办,我们是不是可以将DLL放在 jar 包外面,然后给一个绝对路径,答案是可以的。

海康威视java是外包吗 海康威视 外包_海康威视SDK打包


上图中 HCNetSDK 文件夹中放的是海康的DLL文件,hcnet-0.0.1-SNAPSHOT.jar 是项目的 jar 包。

还有一个问题,我们在部署的时候不知道运维人员到底会将项目部署到哪里,我们不能限定运维人员说必须部署到哪个盘哪个位置。这样的话,估计运维小伙伴会跟我们兵戎相见。那么我们可以在运行的时候指定 JNA 的运行路径。

@echo off
TITLE 拍照服务
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_111
path path;C:\Program Files\Java\jdk1.8.0_111\bin
java -Dfile.encoding=UTF-8 -Djna.library.path=C:\cam -jar hcnet-0.0.1-SNAPSHOT.jar
pause

脚本中第二行是设置标题,第二行和第三行是设置运行的 JDK 环境。-Djna.library.path=C:\cam 是设置 JNA 的运行路径为 C:\cam 文件夹。这样我们在开发的时候 load 方法中直接写DLL的名称即可。

获取文件路径 DllLoad

import java.io.UnsupportedEncodingException;

public class DllLoad {
    public static String DLL_PATH;
    static {
        String root = DllLoad.class.getResource("/").getPath();
        if (root.startsWith("file:/")) {  // jar包中获取到的路径
            DLL_PATH = "";
        } else {  // 实际开发中获取到的路径不带 file:/
            root = root.replaceAll("%20", " ").substring(1);
            try {
                DLL_PATH = java.net.URLDecoder.decode(root, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }
}

在引用的地方使用:

HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(DllLoad.DLL_PATH + "HCNetSDK\\Win32\\HCNetSDK",
            HCNetSDK.class);

这样就解决了打 jar 后获取不到文件的尴尬情况。

解决方法二

这个方法很简单,直接打成 war 一了百了。spring-boot 如何打包成 war 网上有太多的文章,此处不在赘述。

结语

其实打成 war 包是我当初没研究成打成 jar 的方法,最后将项目上线后,自己也反思了,回去花了半晚上的时间研究了打成 jar 包的方法,如果哪位大神有更好的方法也可以借鉴。

最后说一些题外话吧,我觉得,干技术行业,没有钻研精神是不行的,而且当一个具有挑战性难题解决的时候,相信心中的成就感对于每一个干技术的都不言而喻。可能这个问题对于大神来说都是很简单的事情。说了这么多,还是希望大家读到我文章的兄弟们都能具有钻研解决问题的精神,人人都成为大佬。

Keep Calm And Make Epic Shit.