MXJ Class Loader problem with OpenCV Native Library

djlbe's icon

I'm using OpenCV with MXJ but I encounters an annoying problem. Let me explains

Instructions for OpenCV with mxj

(Windows 7 , Max 7 64 bit)
1.
I downloaded the OpenCV archive, this is a 7-zip self extractor.
2. I obtain a folder called opencv which contains a build folder which contains java.
3.
This java folder contains the native library of OpenCV and the JNI Jar I need to add to my Eclipse project


4. Then I create a Eclipse project, in the properties of this project I set up my Buildpath to use the OpenCV JNI and all an mxj externals needs :

5. The OpenCV Native Library dll is placed in one of my PATH folder, "c:\windows\system32" in my case

by the way, I use the 1.7 JRE and it seems to work properly like that :

Code


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); }

public TestOpenCV(Atom[] args)
{
declareInlets(new int[]{DataTypes.ALL});
declareOutlets(new int[]{DataTypes.ALL});
}

public void bang() {
Mat m = new Mat(5, 9, CvType.CV_8UC4, new Scalar(0));
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());
}
}

Problem

OpenCV seems correctly implemented, for exemple, I can instantiate a Mat object and post its content to Max console.

Sending a bang I get the content of the Mat Object :

OpenCV Mat data: [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
... And so on

Problems appears when I change the Java code of the mxj object. To update my object, I delete it and recreate it again. Then, the errors appears in Max Console :

java.lang.UnsatisfiedLinkError: Native Library C:\Windows\System32\opencv_java300.dll already loaded in another classloader at java.lang.ClassLoader.loadLibrary1(Unknown Source) at java.lang.ClassLoader.loadLibrary0(Unknown Source) at java.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) unable to alloc instance of TestOpenCV

Reading this article : https://cycling74.com/articles/mxj-class-loading , It's clear that when I create a new MXJ with a more recent class file, a new class loader is used, but the Native Library stills loaded and that's what generate this errors. Unfortunatly, that article don't seems to provide any solutions.

Only things I can do then is close and restart Max/MSP.

"Solutions" I've found

I found a lot of questions about this kind of problem on Stack Overflow but nothing helped, most of the time it concerns something called Tomcat that I never used.

1. Use a custom class loader ? That's a solution I read here but it seems hard to implement. With this solution, I could maybe unload the Native Library inside a notifyDelete() method.

2. Re-use the Native Library already loaded ? Don't know if it's possible..

3. Doing some research on Github, hoping to find an example using Native Library I find this one : https://github.com/timini/maxSerial (the only one) He don't use "System.loadLibrary" so he has an alternative method, I notice he recommend to place the DLL in java/lib (Max5), probably resources\packages\max-mxj\java-classes\lib Today. Could it be the solution ?

4. A magical stuff to do in notifyDelete() ?

5. Someone tell me it was possible to solve this by setting "Native Library Location" in build path's Eclipse project but it doesn't helped, maybe I'm doing it wrong ?

6. Place the DLL in '.../Max 7/resources/support' ?

I don't know what to do against this and that's really annoying because I'm really near to have the complete solution to use OpenCV properly with mxj :'(

djlbe's icon

anyone ? :(