Saturday, October 27, 2012

EXCEPTION_ACCESS_VIOLATION while using JavaCV Facerecognizer class


The below error while executing JavaCV code happen mostly when you try to invoke a method on a non-existing pointer.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007feea1adf5f, pid=10548, tid=8644
#
# JRE version: 7.0_07-b11
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.3-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [jniopencv_contrib.dll+0xdf5f]
#

We need to understand that JavaCV is a JNI wrapper for OpenCV and other similar native libraries. The objects returned using these methods work a bit different from the normal java objects. The above error happens mainly due to trying to operate on a pointer that no longer exists.
Please refer to the below class, for example



Class Test{
FaceRecognizer fr = null;
Test(){
FaceRecognizerPtr ptr_binary = createLBPHFaceRecognizer(1, 8, 8, 8, binaryTreshold);
fr = ptr_binary.get();
}
}
In this case, normal java will keep the reference to fr even if the constructor is executed. But in JNI it totally depends on the underlying implementation. Since OpenCV is implemented based on C++ and what is being returned is a pointer, the fr will be garbage collected once ptr_binary go out of scope. So invoking any method on the class level variable will cause the ACCESS_VIOLATION exception.
Changing the class as shown below will resolve the issue

Class Test{
FaceRecognizer fr = null;
FaceRecognizerPtr ptr_binary =null;
Test(){
ptr_binary = createLBPHFaceRecognizer(1, 8, 8, 8, binaryTreshold);
fr = ptr_binary.get();
}
}
So, the point is if you find this kind of exception, please make sure you are not operating on objects that has a potential to go out of scope. And keep in mind that general java rules for object relations and scope might not hold good while using JNI.

Blog Archive