the cPP process starts the jvm virtual machine and gets the java-related class methods (using FindClass
). If only one class name is successful, but if there is a package, the call will fail. The related code is as follows:
//MyTest.java
package com;
import java.lang.management.ManagementFactory;
public class MyTest {
//private static int magic_counter = 777;
public static boolean start(String path) {
System.out.print("MyTest start: " + path);
return true;
}
}
// main.cpp
-sharpinclude <iostream>
-sharpinclude <jni.h>
-sharpinclude <memory.h>
int main()
{
char opt1[] = "-Djava.compiler=NONE";
char opt2[] = "-Djava.class.path=./MyTest.jar";
//char opt2[] = "-Djava.class.path=.";
char opt3[] = "-verbose:NONE";
JavaVMOption options[3];
options[0].optionString = opt1; options[0].extraInfo = NULL;
options[1].optionString = opt2; options[1].extraInfo = NULL;
options[2].optionString = opt3; options[2].extraInfo = NULL;
JavaVMInitArgs jargv;
jargv.version = JNI_VERSION_1_6;
jargv.nOptions = 3;
jargv.options = options;
jargv.ignoreUnrecognized = JNI_TRUE;
JavaVM* jvm = NULL;
JNIEnv* jenv = NULL;
jint res = JNI_CreateJavaVM( &jvm, (void**)&jenv, &jargv );
if ( 0 != res )
return 1;
jclass jc = jenv->FindClass("/com/MyTest");
//jclass jc = jenv->FindClass("MyTest");
//jclass jc = jenv->FindClass("java/lang/String");
if ( NULL == jc ) {
if( jenv->ExceptionOccurred() )
jenv->ExceptionDescribe();
else {
std::cout << "jc null" << std::endl;
}
return 1;
}
jmethodID jmid = jenv->GetStaticMethodID( jc, "start", "(Ljava/lang/String;)Z");
if ( NULL == jmid) {
std::cout << "jmid null" << std::endl;
return 1;
}
else {
std::cout << "jmid ok" << std::endl;
}
jstring jniStr = jenv->NewStringUTF("jni to java");
jboolean res1 = jenv->CallBooleanMethod( jc, jmid, jniStr);
if(res1) {
std::cout << "CallBooleanMethod ok" << std::endl;
}
std::cout << "\n";
std::cout << "Hello, World!" << std::endl;
return 0;
}
related commands are as follows:
javac MyTest.java
jar cvf MyTest.jar MyTest.class
gPP main.cpp -I
~/jdk/include/ -I~/jdk/include/linux -L~s/jdk/jre/lib/amd64/server -ljvm
this is the error message when running a.out: the class cannot be found:
Exception in thread "main" java.lang.NoClassDefFoundError: / com/MyTest
Caused by: java.lang.ClassNotFoundException: .com.MyTest
if the package name com is removed from java and the class MyTest
is found directly in cPP, then FindClass
is successful.
Environment: ubuntu 16.04 jdk 1.8