This article is tested on Eclipse Mars Release, tomcat 8.0.24, opencv 2.4.10, Windows 8(shame, but… should be similar on linux)
Nearly all the articles on web point to this: http://wiki.apache.org/tomcat/HowTo#I.27m_encountering_classloader_problems_when_using_JNI_under_Tomcat
This is a good answer and explained what should you do to solve the problem. However, for opencv, the opencv-xxxx.jar does not load the native library from inside the classes in the jar package. OpenCV document asked developers to load the native lib from their code. For example:
public class SomeClassUsesOpenCV { static { System.loadLibrary("opencv_java2410"); } } |
To solve this delimma, I created a java project called OpenCVLoader, and created a single class called OpenCVLoader, in this class, use the static field to load the library. And then, pack this java project as a jar package. In Eclipse, you can use the export option of the project to easily export a jar package(for example, opencv-loader.jar). Put this in “apache-tomcat-8.0.24\lib”. Why this dir? Because this dir is under common class loader in catalina.properties, you can also config the shared.loader and put the jar package into that dir. Basicly, we are trying to avoid using app specific class loader to load the opencv lib.
Then, put opencv-xxxx.jar into the same dir with the opencv-loader.jar . Then, make sure your opencv_javaxxxx.dll/so is in the java.library.path. There are a lot of posts about this. However, there is something that I really need to mention. Just like the opencv-xxxx.jar which must be loaded by the tomcat non-webapp-specific class loader, this dll should also be loaded by the same class loads opencv-xxxx.jar. So, if you want to use the -Djava.library.path method, it should be in the command which starts the tomcat server. In eclipse, you can achieve this by going to run > run configuration… > Apache Tomcat > your_server_name_here and in Arguments tab, append -Djava.library.path=”D:\path_to_your_opencvxxx.dll”. If you don’t see any thing under Apache Tomcat tree node, start the server once, then a default configuration will be created.
Then, in the servlet class that you want to use opencv, use this instead the loadLirary thing.
public class SomeClassUsesOpenCV { static { // trigger the opencv loader static field // which leads to loading the opencv jni // there are many ways to trigger it, I just used this new OpenCVLoader(); } } |
OK, now try to do some modification and save to trigger the tomcat reload.