JDK-4831190 : CallNonvirtualMethod[A|V] does not throw NullPointerException
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.4.1,5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_8
  • CPU: sparc
  • Submitted: 2003-03-12
  • Updated: 2016-07-19
  • Resolved: 2003-03-13
Related Reports
Relates :  
Description

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.
$
----------------------------------------------------------

======================================================================

Comments
EVALUATION ###@###.### 2003-03-13 The two arguments in question provide two different situations. (a) The clazz parameter is ignored in hotspot. The class information used by hotspot is actually derived from the method id. Setting the clazz parameter to null (or any other value) will not interfere with the java program in hotspot. Other JVMs may vary. (b) The obj parameter is not referenced in the JNI method processing and is passed to the Java method, where it becomes the "this" value. Since the run method in this test does nothing which requires the use of the "this" reference, no error is seen (but a crash would occur otherwise). In either case, the arguments to the JNI methods are invalid. From the JNI spec: http://java.sun.com/j2se/1.4/docs/guide/jni/spec/design.doc.html#17593 The JNI does not check for programming errors such as passing in NULL pointers or illegal argument types. ... The programmer must not pass illegal pointers or arguments of the wrong type to JNI functions. Doing so could result in arbitrary consequences, including a corrupted system state or VM crash. No exception should be thrown. Not a bug.
11-06-2004