1

免责声明不是以英语为母语的人,如果需要,请随时编辑。

我遇到了一个类似的问题,这里解释了: java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader

我正在尝试遵循 user2543253 的答案。但是我真的缺乏Java知识,而且上下文有点不同。

链接

  1. .dll 已经加载到另一个类加载器中了吗?似乎也与这个问题有关。
  2. https://github.com/PatternConsulting/opencv/issues/7类似。
  3. https://cycling74.com/articles/mxj-class-loading解释 MXJ 的类加载器行为

语境

编辑:不确定该上下文是否真的很重要,它似乎与链接 1 中描述的问题相同。

我想在名为 Max/MSP 的应用程序中使用 OpenCV。

给出一个想法,它看起来像这样:

在此处输入图像描述

Max/MSP 允许用户通过将一些称为externals的对象连接在一起来组装 Patch ,其中大多数是用 C 编码的,但您也可以在 Java 中创建 externals。为此,您需要通过一个名为“mxj”的对象来实例化它们。例如,如果我的 Java 类名为 TestOpenCV,我将创建一个框并将“mxj TestOpenCV”放入其中。

OpenCV 似乎正确实现,例如,我可以实例化一个 Mat 对象并将其内容发布到 Max 控​​制台。

当我更改 mxj 对象的 Java 代码时出现问题。为了更新我的对象,我将其删除并重新创建。然后,出现了此处解释的相同问题...

在此处输入图像描述

最大控制台返回此错误消息:

java.lang.UnsatisfiedLinkError: Native Library C:\Windows\System32\opencv_java300.dll 已经 在 java.lang.ClassLoader.loadLibrary0(Unknown Source) 的 java.lang.ClassLoader.loadLibrary1(Unknown Source)的另一个类加载器中加载。 lang.ClassLoader.loadLibrary(Unknown Source) at java.lang.Runtime.loadLibrary0(Unknown Source) at java.lang.System.loadLibrary(Unknown Source) at OpenCVClassLoad.loadNativeLibrary(OpenCVClassLoad.java:5) at TestOpenCV.(TestOpenCV. java:22) (mxj) 无法分配 TestOpenCV 的实例

我试过的

我试图实现user2543253的答案。他建议创建一个小类来导入本机库并将其导出为 JAR。所以我创建了一个新的 Eclipse 项目,向它添加了一个源文件

import org.opencv.core.Core;

public class OpenCVClassLoad {
  public static void loadNativeLibrary() {
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  }
}

我将 openCV JAR 添加到该项目并将其导出为 JAR。

然后我根据 user2543253 的解释更改了我的代码(代码更多,我保留了必要的):

import com.cycling74.max.*;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;

public class TestOpenCV extends MaxObject {  
  static {
    // System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    OpenCVClassLoad.loadNativeLibrary();
  }

  public TestOpenCV(Atom[] args)
  {
    // ... 
  }

  public void notifyDeleted()
  {
    // ...
  }

  public void bang() {
    // Executed when I trig the little bang button you can see

    Mat m = new Mat(5, 9, CvType.CV_8UC4, new Scalar(0));
    post("OpenCV Mat: " + m);

    Mat mr1 = m.row(1);
    mr1.setTo(new Scalar(1));

    Mat mc5 = m.col(3);
    mc5.setTo(new Scalar(5));

    post("OpenCV Mat data:\n" + m.dump()); 
  }
}

当然,但这有点奇怪,为了正确构建该项目,我将来自 OpenCV 的 JAR 保留在构建路径中:

在此处输入图像描述

如您所见,我还在项目构建路径中添加了小类。在所有这些修改之后,mxj 对象第一次正确加载并且 bang() 方法仍然有效,但问题仍然存在。实际上它并没有改变过去的情况:如果我修改Java代码,删除Max中的对象并创建一个新对象,就会出现错误......

问题

有很多 SO 问题解决了相同类型的问题,但上下文总是不同的,很难弄清楚该怎么做,尤其是在我对 Java 的基础知识的情况下。

一种解决方法应该是简单地重用已经加载的库,不是吗?但是如何实现呢?因为如果我检查库是否已经被加载,我会使用 Try / Catch 来完成,如果我什么都不做的话。外部行为就像从未加载过库一样......

如何重用该本地库?(当然,欢迎任何替代解决方案)

4

1 回答 1

0

只需删除OpenCVClassLoad.loadNativeLibrary();bang()方法中的第二个。在普通的 Java 应用程序中,static块中的代码只执行一次。

或者,您可以在 Eclipse 中指定本机库位置,而不是通过 Java 源代码加载库。

于 2017-09-16T09:45:36.793 回答