超级大坑 java springboot使用opencv问题: java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J异常

1、出错代码:首先这段代码没有语法或逻辑问题

@Service
@Slf4j
public class DetectServiceImpl implements IDetectService {

    ......

    static { // 执行顺序1
        // 得保证先执行该语句,用于加载库,才能调用其他操作库的语句,
        // 设置本地库路径 这句话很重要,如果没有,下面这个函数将报错:Mat img = Imgcodecs.imread(path);
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("DetectServiceImpl Loading Lib: opencv");
    }

    /**
     *
     * 类初始化调用顺序: Constructor >> @Autowired >> @PostConstruct
     */
    @PostConstruct
    public void init() { // 执行顺序3
        Mat mat = new Mat(3, 3, CvType.CV_8UC3);// 出错处!!!!!!!!!!
        System.out.println("mat113 = " + mat.dump());
    }

    public DetectServiceImpl() { // 执行顺序2
        this.env = OrtEnvironment.getEnvironment();
        System.out.println("DetectServiceImpl object ok");
    }
    .......//执行顺序1-3
}
  • 出错语句: Mat mat = new Mat(3, 3, CvType.CV_8UC3);

  • 日志报错:Caused by: java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J

  • 已加载opencv动态库,但依然报上面的错误

2、奇怪现象及排查过程:

2.1、在springboot Junit的单元测试中,DetectServiceImpl加载正常,spring主类启动正常,方法能正常调用。

“Mat mat = new Mat(3, 3, CvType.CV_8UC3);”不报错

public class DetectServiceTest extends BaseTest {

    @Autowired
    private IDetectService detectService;
    。。。。。。
    。。。。。。
 }

2.2、如果正常启动项目,即执行springboot的主类Application.class的main方法,DetectServiceImpl加载异常,”Mat mat = new Mat(3, 3, CvType.CV_8UC3);“会报错,具体异常如下。

异常日志:

22:09:50.718 [restartedMain] INFO  o.a.s.c.e.EhCacheManager - [getCache,169] - Using existing EHCache named [sys-dict]
DetectServiceImpl Loading Lib: opencv
DetectServiceImpl object ok
22:09:51.006 [restartedMain] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - [refresh,591] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'yoloDetectController': Unsatisfied dependency expressed through field 'detectService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'detectServiceImpl': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J
22:09:51.006 [restartedMain] INFO  c.a.d.p.DruidDataSource - [close,2174] - {dataSource-1} closing ...
22:09:51.006 [restartedMain] INFO  c.a.d.p.DruidDataSource - [close,2247] - {dataSource-1} closed
22:09:51.006 [restartedMain] INFO  o.a.c.c.StandardService - [log,173] - Stopping service [Tomcat]
22:09:51.034 [restartedMain] ERROR o.s.b.SpringApplication - [reportFailure,870] - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'yoloDetectController': Unsatisfied dependency expressed through field 'detectService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'detectServiceImpl': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J
 。。。。。。
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'detectServiceImpl': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J
。。。。。。
Caused by: java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J
	at org.opencv.core.Mat.n_Mat(Native Method)
	at org.opencv.core.Mat.<init>(Mat.java:32)
	at com.ruoyi.ai.service.impl.DetectServiceImpl.init(DetectServiceImpl.java:93)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)
	... 37 common frames omitted

也就代码相同情况下,都是调用中opencv中的Mat对象的方法,用springboot的主类Application.class的main方法启动就异常,如果用spring test启动就无异常

2.3、具体查询“java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J”错误,大多是说连接本地opencv库异常,即未加载类似"lib/opencv_java455.dll"的本地动态库文件。大多数情况加下面的语句就可解决

    static {
        // 得保证先执行该语句,用于加载库,才能调用其他操作库的语句,
        // 设置本地库路径 这句话很重要,如果没有,下面这个函数将报错:Mat img = Imgcodecs.imread(path);
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("DetectServiceImpl Loading Lib: opencv");
    }

其实项目中DetectServiceImpl类原本就有上面这个加载语句。

实施措施:在程序几个必经路口都加上上面的代码,都未报错,重复加载的异常也没有出现

2.4、单独开文件测试“Mat mat = new Mat(3, 3, CvType.CV_8UC3);”,代码如下,运行正常

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;

public class Test23 {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 得保证先执行该语句,用于加载库,才能调用其他操作库的语句,
        System.out.println("Test23 Loading Lib: opencv");
    }

    public static void main(String[] args) {
        //System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat mat = new Mat(3, 3, CvType.CV_8UC3);
        System.out.println("mat111 = " + mat.dump());
    }
}

经过上面3个步骤的测试,这个出错十分鬼怪,代码一致情况下,执行却不一样。对于”new Mat(3, 3, CvType.CV_8UC3)“语句报“java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J”这个错误,

  • 不使用springboot进行单独测试,程序正常

  • 使用springboot的主类Application.class启动,程序异常

  • 使用spring 单元测试junit启动,程序正常

3、解决措施

在google上搜索这个问题很久(“springboot 运行java.lang.UnsatisfiedLinkError org.opencv.core”),有两三个题主提到

可能是spring-boot-devtools的问题!!!!!!!!

在pom.xml中注释掉spring-boot-devtools就解决了!!!!!!

注释以下内容:

        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 表示依赖不会传递 -->
        </dependency>

修正后正常时的日志:

22:15:52.947 [main] INFO  o.a.s.c.e.EhCacheManager - [getCache,169] - Using existing EHCache named [sys-dict]
22:15:52.947 [main] INFO  o.a.s.c.e.EhCacheManager - [getCache,169] - Using existing EHCache named [sys-dict]
DetectServiceImpl Loading Lib: opencv
DetectServiceImpl object ok
mat113 = [  0, 101, 110, 115, 111, 114,  40, 105, 110;
 116,  54,  52,  41,   0,   0,   0,   0,   0;
   0,   0,   0,   0,   0,   0,  15,   0,   0]
DetectUtils Loading Lib: opencv
22:15:54.029 [main] INFO  o.q.i.StdSchedulerFactory - [instantiate,1220] - Using default implementation for ThreadExecutor
22:15:54.044 [main] INFO  o.q.c.SchedulerSignalerImpl - [<init>,61] - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
22:15:54.044 [main] INFO  o.q.c.QuartzScheduler - [<init>,229] - Quartz Scheduler v.2.3.2 created.
22:15:54.044 [main] INFO  o.q.s.RAMJobStore - [initialize,155] - RAMJobStore initialized.

4、总结

  • spring-boot-devtools可能会使opencv native 动态链接库加载异常,导致调用Mat对象的方法异常,报“java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat(III)J”错误
  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值