Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm defining a Java class from C with DefineClass() but get UnsatisfiedLinkError

I'm defining a java class from C with the JNI call DefineClass() and then I register the native callbacks for the methods in the class that are native. The class has two static methods, both of which are native. I use RegisterNatives() to register the native functions. Both calls succeed.

But when I reference these native methods from my Java code I get java.lang.UnsatisfiedLinkError myPackage.myClass.myMethod(I)V

But I know that DefineClass returned a class object for myPackage.myClass and I know that myMethod(I)V has been registered as a method on that class.

I get this failure just as it is about to execute main() - where the call to my native method is (for the time being, for testing).

As a test, I tried calling DefineClass twice on the same JNIEnv to see what happened. I get a duplicate class definition error. I've also tried calling FindClass() after defining it and the JNIEnv returns a reference to the defined class.

Thus I'm definity creating the class dynamically, but it fails when I try to refer to its methods.

Any ideas? All input appreciated.

Platform: Windows, 32 bit code on 64 bit XP.

like image 951
Stephen Kellett Avatar asked Jul 30 '10 16:07

Stephen Kellett


1 Answers

Seems that you cannot define a native method using DefineClass() and call that native method directly from your injected code. You have to have a trampoline method in your injected class (in the form of Java byte codes) that then calls your native methods. Only then will it work. Took me three days to work that out.

Another gotcha is make sure that your injected code is valid. The code I was trying looked valid, but on closer inspection I was pulling a 4 byte sized constant from the constant pool as an operand for an 8 byte instruction. So that failed the verifier. Once that was fixed (and the native trampoline), it all worked.

However to get there through all the various permutations I had to try took 3 days. Felt good when if was working though.

How to do the trampoline? See the examples (in C) that ship with the Java SDK. They are quite long and not appropriate for posting here.

like image 181
Stephen Kellett Avatar answered Nov 13 '22 16:11

Stephen Kellett