JDK-8313874 : JNI NewWeakGlobalRef throws exception for null arg
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 17,21,22
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-08-07
  • Updated: 2023-10-03
  • Resolved: 2023-08-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17 JDK 21 JDK 22
17.0.10-oracleFixed 21.0.1Fixed 22 b08Fixed
Related Reports
Relates :  
Description
According to the JNI spec for NewWeakGlobalRef:

> Returns NULL if obj refers to null, or if obj was a weak global reference, or if the VM runs out of memory. If the VM runs out of memory, an OutOfMemoryError will be thrown.

The current behaviour is that `NewWeakGlobalRef(nullptr)` throws an OutOfMemoryError, which it should not.

```
 #include <stdio.h>
 #include <jni.h>
 #include "TestNull.h"

 JNIEXPORT void JNICALL Java_TestNull_testNull(JNIEnv *env, jclass a) {
     env->NewWeakGlobalRef(nullptr);
     env->ExceptionDescribe();
 }
```

```
class TestNull {
    static { System.loadLibrary("testNull"); }
    public static void main(String[] args) {
        testNull();
    }
    public static native void testNull();
}
```

```
java -Djava.library.path=. TestNull
Exception in thread "main" java.lang.OutOfMemoryError: C heap space
	at TestNull.testNull(Native Method)
	at TestNull.main(TestNull.java:4)
```

It seems that [this code](https://github.com/openjdk/jdk/blob/dc01604756c22889412f9f25b534488180327317/src/hotspot/share/prims/jni.cpp#L2879-L2881) forgets to handle the case where the original argument was null.

Thanks to Boris Rasin for reporting this issue in https://github.com/corretto/corretto-17/issues/145.


Comments
17u, 21u fix request - clean (21) or nearly clean (17) backport for simple issue breaking JNI spec.
24-08-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/1688 Date: 2023-08-23 10:17:50 +0000
23-08-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u/pull/88 Date: 2023-08-23 10:11:13 +0000
23-08-2023

Changeset: 028b3ae1 Author: Oli Gillespie <ogillespie@openjdk.org> Committer: Aleksey Shipilev <shade@openjdk.org> Date: 2023-08-10 08:51:50 +0000 URL: https://git.openjdk.org/jdk/commit/028b3ae1b162bd8f7c340bfa6e9487ca83697955
10-08-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/15188 Date: 2023-08-08 10:40:30 +0000
08-08-2023

Yes it was an oversight on my part when fixing JDK-8194309. Usually passing NULL is a programming error in JNI and we don't have to detect it, but not in this case. Suggested fix: if (ret == nullptr && !ref_handle().is_null()) { THROW_OOP_(Universe::out_of_memory_error_c_heap(), nullptr); }
07-08-2023