With the following code I can call static methods (so presumeably my class path is correct), yet the JNI GetMethodID method cannot find the constructor in this same class:
java_test.cpp C++ MWE:
#include <jni.h>
#include <cstring>
int main( void )
{
JNIEnv * env;
JavaVM * jvm;
JavaVMOption options[1];
JavaVMInitArgs vm_args;
long status;
options[0].optionString = (char*)"-Djava.class.path=/home/kadmin/workspace/kata/JavaTest/build/classes";
memset( &vm_args, 0, sizeof( vm_args ) );
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM( &jvm, (void**)&env, &vm_args );
if ( status == JNI_ERR )
{
return 1;
}
/* Call static method to cube x */
jclass cls = env->FindClass( "javatest/Sample" );
jmethodID int_method_id = env->GetStaticMethodID( cls, "intMethod", "(I)I" );
int x = 5;
jint cubed = env->CallStaticIntMethod( cls, int_method_id, x );
printf("(%i)^3 = %i\n", x, cubed );
/* Call static method to print "Hello World!" */
jmethodID print_method_id = env->GetStaticMethodID( cls, "printMethod", "()V" );
env->CallStaticVoidMethod( cls, print_method_id );
/* Attempt to instantiate `Sample' class */
jmethodID constructor_method_id = env->GetMethodID( cls, "<init>", "V(I)" );
if ( constructor_method_id != 0 )
{
jobject jobj = env->NewObject( cls, constructor_method_id );
}
else
{
printf("`Sample' constructor not found.\n");
}
return 0;
}
JavaTest MWE:
package javatest;
public class Sample
{
int myint;
public Sample(int n)
{
myint = n;
System.out.println("[JavaTest] Instantiated");
}
public static int intMethod (int n)
{
return n*n*n;
}
public static void printMethod( )
{
System.out.println("Hello World!");
}
}
The output is always
$ ./java_test
(5)^3 = 125
Hello World!
`Sample' constructor not found.
Any ideas? Most other issues with JNI are related to incorrect class path but this example has the correct path judging by the static methods.
Did not know about the java dissassembler, javap. Running
$ javap -s JavaTest.class
shows that the correct signature is (I)V.
Change:
jmethodID constructor_method_id = env->GetMethodID( cls, "<init>", "V(I)" );
To:
jmethodID constructor_method_id = env->GetMethodID( cls, "<init>", "(I)V" );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With