Name: vrR10176 Date: 03/12/2003
JNI functions CallNonvirtual<Type>Method() do not throw NullPointerException
if they are provided with obj or clazz parameters set to null.
Java Native Interface Specification, Chapter "JNI Functions"
says about the functions:
"<NativeType> CallNonvirtual<Type>Method(
JNIEnv *env, jobject obj, jclass clazz,
jmethodID methodID, ...);
...
Invokes an instance method, specified using a class and a method ID, on an object.
...
Parameters
env: the JNIEnv interface pointer.
clazz: a reference to the class from which the method ID is derived.
obj: a reference to the object on which the method is invoked.
methodID: a method ID that is valid with the class reference clazz.
Additional arguments: arguments to be passed to the method.
Return
Values Returns the result of calling the method.
Exceptions
Any exception raised during the execution of the method.
"
This bug causes failure of new JCK-1.5beta tests:
vm/jni/CallMethod/call001/call00105m4/call00105m4.html
vm/jni/CallMethod/call001/call00105m5/call00105m5.html
vm/jni/CallMethod/call001/call00105m6/call00105m6.html
To reproduce the issue execute the following test.
Test tries to execute CallNonvirtualVoidMethod and CallVoidMethod
with obj parameter set to null. All other CallNonvirtual<Type>Method,
CallNonvirtual<Type>MethodA, CallNonvirtual<Type>MethodV functions are
failing also. Call<Type>Method, Call<Type>MethodA, Call<Type>MethodV
functions throw NullPointerException if obj parameter set to null.
------------ TestNullJNIRecv.java -------------------------------
public class TestNullJNIRecv {
public static void main(String[] args) {
System.loadLibrary("TestNullJNIRecv");
try {
invokeRun1(null);
System.out.println("Checking CallNonvirtualVoidMethod. TEST FAILED.");
} catch (NullPointerException e) {
System.out.println("Checking CallNonvirtualVoidMethod. Test passed.");
}
try {
invokeRun2(null);
System.out.println("Checking CallVoidMethod. TEST FAILED.");
} catch (NullPointerException e) {
System.out.println("Checking CallVoidMethod. Test passed.");
}
}
private static native void invokeRun1(Object receiver);
private static native void invokeRun2(Object receiver);
public void run() {
System.out.println("non-static method run() is executed in a static context !!!");
}
}
------------ TestNullJNIRecv.c ----------------------------------
#include "jni.h"
#include "jni_md.h"
JNIEXPORT void JNICALL Java_TestNullJNIRecv_invokeRun1(JNIEnv *env, jclass clazz, jobject recv)
{
jmethodID mid;
mid = (*env)->GetMethodID(env, clazz, "run", "()V");
(*env)->CallNonvirtualVoidMethod(env, recv, clazz, mid);
}
JNIEXPORT void JNICALL Java_TestNullJNIRecv_invokeRun2(JNIEnv *env, jclass clazz, jobject recv)
{
jmethodID mid;
mid = (*env)->GetMethodID(env, clazz, "run", "()V");
(*env)->CallVoidMethod(env, recv, mid);
}
------------ Logs ----------------------------------------
$java -version
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b02)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b02, mixed mode)
$
$javac TestNullJNIRecv.java
$
$cc -G -KPIC -I/<jdk1.5.0-b02>/solaris-sparc/include -I/<jdk1.5.0-b02>/solaris-sparc/include/solaris -o libTestNullJNIRecv.so TestNullJNIRecv.c
$
$java -Xfuture TestNullJNIRecv
non-static method run() is executed in a static context !!!
Checking CallNonvirtualVoidMethod. TEST FAILED.
Checking CallVoidMethod. Test passed.
$
----------------------------------------------------------
======================================================================