AddThis Social Bookmark Button

The UnsatisfiedLinkError appears when the native method could not be stitched while called, at runtime.There are many scenarios while this error may come ,

this is just one of the  very trivial mistake people do ( Which I did once ) is they create a class ( which consists of the native methods) in a package, generate the files ( header and native libs like .dll or .so) and use this class in a different package.For a regular non-native class it would not matter (just change the package name) , but the native methods will throw UnsatisfiedLinkError if used in the different package . The reason as follows

Let s take an example:


public class MyJniClass {

	public  native void getNative();
}

As with the above class, it is clearly in the default package, but copy this  class to a diffent package and start calling the getNative() method will give you the UnsatisfiedLinkError, and could a big srach trying to understand where is it going wrong.

The reason is this. When this class generates the MyJniClass header file it looks like below

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyJniClass */

#ifndef _Included_MyJniClass
#define _Included_MyJniClass
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MyJniClass
 * Method:    getNative
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_MyJniClass_getNative
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Look at the name of the method, we have it is "Java_MyJniClass_getNative" , also the implementing method would look the same way . But just change the package structure of the class to lets say com.bullraider.nativ


package com.bullraider.nativ;
public class MyJniClass {

	public  native void getNative();
}

 

So offcourse the generated header file will look like below 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_bullraider_nativ_MyJniClass */

#ifndef _Included_com_bullraider_nativ_MyJniClass
#define _Included_com_bullraider_nativ_MyJniClass
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_bullraider_nativ_MyJniClass
 * Method:    getNative
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_bullraider_nativ_MyJniClass_getNative
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Needless to say the method name changed to a fully qualified name patten , and also the name of the header file also changed. So  when Java system tries to call the method , it would use the qualified name to call the,by using the native library ( .dll or .so) 
 

So a lesson learnt , always decide the package the class will be  used , this way the generated header and so is the native language will be coded by conforming the fully qualified class. And you keep your sanity.