C language calls java

Keywords: Programming Java jvm Linux Makefile

Java is also called by C language through JNI. Linux platform can be realized by introducing libjvm.so dynamic link library. First, you need to write java classes

 

public class Sample {
	
	public static void test2() {
		
		System.out.println("java Printed helloword");
	}
}

This is a very simple java class. There is only one Java method in it. We will call this method through C later. The jvm only knows class. First, compile it, java Sample.java. Get a Sample.class file in the current directory. This file will be loaded by our c program later.

 

And then write C code.

#Include < jni. H > / / introduce the jni header file. The following methods for loading and calling classes are implemented through the functions in jni
#include <string.h>
int main() 
{ 
	JavaVMOption options[1]; 
	JNIEnv *env; 
	JavaVM *jvm; 
	JavaVMInitArgs vm_args; 
	long status; 
	jclass cls; 
	jmethodID mid; 
	jint square; 
	jboolean not; 

	options[0].optionString = "-Djava.class.path=."; //Set classpath
	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) 
	{ 
		//cls = (*env)->FindClass(env, "java/lang/Object"); 
		cls=(*env)->FindClass(env,"Sample");//Find this class through the FindClass function. The description of the added class should match. If it is an Object, it should be java/lang/Object.
		printf("find the class\n");
		if(cls !=0) 
		{
			//mid = (*env)->GetStaticMethodID(env, cls, "main", "(I)I"); 
		        mid=(*env)->GetStaticMethodID(env,cls,"main","([Ljava/lang/String;)V");//Find the method through the function, which should be the descriptor of the method.
			printf("find the method\n");
			if(mid !=0) 
			{
				printf("exec method\n");
				square = (*env)->CallStaticIntMethod(env, cls, mid, NULL); //Execution method
				printf("Result of intMethod: %d\n", square); 
			} 

			mid = (*env)->GetStaticMethodID(env, cls, "booleanMethod", "(Z)Z"); 
			if(mid !=0) 
			{ not = (*env)->CallStaticBooleanMethod(env, cls, mid, 1); 
				printf("Result of booleanMethod: %d\n", not); 
			} 
		} 
		else{
			printf("not found\n");
		}
		(*jvm)->DestroyJavaVM(jvm); 
		return 0; 
	} 
	else 

		return -1; 
}

, if gcc directly reports an error, because the jni header file is not in the system header file. And the dynamic link library is not in the default library of the system. So write a Makefile:

compile:
        gcc calljvm.c -I  $JAVA_HOME/include/  -I $JAVA_HOME/include/linux/  -L$JAVA_HOME/jre/lib/amd64/server/ -ljvm  -o calljvm

If you execute make, you should compile successfully, but the execution will report an error. Because libjvm.so is not in / usr/lib. So we have to add the jvm library to the system library path.


export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/:$JAVA_HOME/jre/lib/amd64/servr

By default, the system will find the dynamic link library in / usr/lib. If there is a LD library path, it will first find it in the path specified by LD library path. If it cannot find it, then go to / usr/lib.

 

Compile link again to run, print successfully!

Posted by mattbrad on Fri, 01 Nov 2019 20:13:43 -0700