免责声明不是以英语为母语的人,如果需要,请随时编辑。
我遇到了一个类似的问题,这里解释了: java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader
我正在尝试遵循 user2543253 的答案。但是我真的缺乏Java知识,而且上下文有点不同。
链接
- .dll 已经加载到另一个类加载器中了吗?似乎也与这个问题有关。
- https://github.com/PatternConsulting/opencv/issues/7类似。
- 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 来完成,如果我什么都不做的话。外部行为就像从未加载过库一样......
如何重用该本地库?(当然,欢迎任何替代解决方案)