JDK-8187450 : JNI local refs exceeds capacity warning in NetworkInterface::getAll
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 8u144,9,10,11.0.11,17
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2017-09-12
  • Updated: 2025-01-21
  • Resolved: 2021-03-22
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 11 JDK 17 JDK 8 Other
11.0.12-oracleFixed 17 b15Fixed 8u421Fixed openjdk8u322Fixed
Related Reports
Cloners :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
example using 8u122:
===
$ cat NITest.java
public class NITest {
    public static void main(String[] args) throws java.net.SocketException {
        java.net.NetworkInterface.getNetworkInterfaces();
    }
}
$ javac NITest.java
$ java -Xcheck:jni NITest
WARNING: JNI local refs: 33, exceeds capacity: 32
        at java.net.NetworkInterface.getAll(Native Method)
        at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343)
        at NITest.main(NITest.java:5)
===

While not a serious problem, this creates noise when we are trying to use Xcheck:jni to find real issues. It also prompts questions from users.
Comments
review request (8u) I would like to backport this to 8u, too. RFR: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2021-March/013591.html Webrev: https://cr.openjdk.java.net/~jdowland/webrevs/JDK-8187450/webrev.jdk8u.00/ review: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2021-April/013762.html
08-09-2021

fix request (11u) I would like to backport this patch to 11u. It improves the usability of -Xcheck:jni when using getNetworkInterfaces. The patch did not apply cleanly, the test metadata needed some hand-holding. Webrev: https://cr.openjdk.java.net/~jdowland/webrevs/JDK-8187450/webrev.00/ RFR thread: https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2021-March/005416.html
23-03-2021

Changeset: ba504fce Author: Jonathan Dowland <jdowland@openjdk.org> Committer: Chris Hegarty <chegar@openjdk.org> Date: 2021-03-22 15:29:47 +0000 URL: https://git.openjdk.java.net/jdk/commit/ba504fce
22-03-2021

[~jdowland] I'm not following. The same code reproduces the same issue for JDK 17. It's NOT fixed for any recent JDK. It must be fixed for the most recent JDK (17 currently) first, then any backport can be attempted. It might then well be that the patch listed here might be re-used for an 11 backport, but the master bug should really be this one and JDK-8263379 closed as a duplicate.
10-03-2021

The relevant code was refactored after JDK11. The patch above resolves the issue for JDK11, but not for Trunk. I've filed JDK-8263379 to track fixing this in Trunk. As a consequence, I'm going to submit a fix request for jdk11u which is not strictly a backport.
10-03-2021

Assigning to Jon. Thanks, [~chegar]
17-12-2020

[~sgehwolf] I am not actively working on this issue. Please reassign it to yourself if you have time to work on it. Thanks.
17-12-2020

[~chegar] Are you working on this bug? Otherwise I'll assign to jdowland as he was looking into it too. Thanks!
17-12-2020

jdk-dev patch: diff -r 3dfb497695fd src/java.base/unix/native/libnet/NetworkInterface.c --- a/src/java.base/unix/native/libnet/NetworkInterface.c Mon Dec 11 02:43:36 2017 -0800 +++ b/src/java.base/unix/native/libnet/NetworkInterface.c Mon Dec 11 22:53:54 2017 -0800 @@ -450,6 +450,7 @@ // put the NetworkInterface into the array (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj); + (*env)->DeleteLocalRef(env, netifObj); curr = curr->next; } @@ -647,9 +648,9 @@ static jobject createNetworkInterface(JNIEnv *env, netif *ifs) { jobject netifObj; jobject name; - jobjectArray addrArr; - jobjectArray bindArr; - jobjectArray childArr; + jobjectArray addrArr = NULL; + jobjectArray bindArr = NULL; + jobjectArray childArr = NULL; netaddr *addrs; jint addr_index, addr_count, bind_index; jint child_count, child_index; @@ -714,6 +715,7 @@ } else { return NULL; } + (*env)->DeleteLocalRef(env, ia2Obj); } (*env)->SetShortField(env, ibObj, ni_ib4maskID, addrP->mask); (*env)->SetObjectArrayElement(env, bindArr, bind_index++, ibObj); @@ -752,6 +754,8 @@ (*env)->SetObjectArrayElement(env, addrArr, addr_index++, iaObj); addrP = addrP->next; + (*env)->DeleteLocalRef(env, iaObj); + (*env)->DeleteLocalRef(env, ibObj); } // see if there is any virtual interface attached to this one. @@ -783,6 +787,11 @@ (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr); (*env)->SetObjectField(env, netifObj, ni_childsID, childArr); + (*env)->DeleteLocalRef(env, name); + (*env)->DeleteLocalRef(env, addrArr); + (*env)->DeleteLocalRef(env, bindArr); + (*env)->DeleteLocalRef(env, childArr); + // return the NetworkInterface return netifObj; } @@ -953,7 +962,7 @@ // Deal with the virtual interface now. if (vname[0]) { - netaddr *tmpaddr; + netaddr *tmpaddr = NULL; currif = parent->childs; diff -r 3dfb497695fd src/java.base/windows/native/libnet/NetworkInterface.c --- a/src/java.base/windows/native/libnet/NetworkInterface.c Mon Dec 11 02:43:36 2017 -0800 +++ b/src/java.base/windows/native/libnet/NetworkInterface.c Mon Dec 11 22:53:54 2017 -0800 @@ -525,9 +525,9 @@ jobject createNetworkInterface (JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP) { - jobject netifObj; - jobject name, displayName; - jobjectArray addrArr, bindsArr, childArr; + jobject netifObj = NULL; + jobject name = NULL, displayName = NULL; + jobjectArray addrArr = NULL, bindsArr = NULL, childArr = NULL; netaddr *addrs; jint addr_index; jint bind_index; @@ -575,7 +575,7 @@ addr_index = 0; bind_index = 0; while (addrs != NULL) { - jobject iaObj, ia2Obj; + jobject iaObj = NULL, ia2Obj = NULL; jobject ibObj = NULL; if (addrs->addr.sa.sa_family == AF_INET) { iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID); @@ -630,11 +630,18 @@ (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj); addrs = addrs->next; addr_index++; + (*env)->DeleteLocalRef(env, iaObj); + (*env)->DeleteLocalRef(env, ibObj); + (*env)->DeleteLocalRef(env, ia2Obj); } (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr); (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr); free_netaddr(netaddrP); + (*env)->DeleteLocalRef(env, name); + (*env)->DeleteLocalRef(env, displayName); + (*env)->DeleteLocalRef(env, addrArr); + (*env)->DeleteLocalRef(env, bindsArr); /* * Windows doesn't have virtual interfaces, so child array @@ -645,6 +652,7 @@ return NULL; } (*env)->SetObjectField(env, netifObj, ni_childsID, childArr); + (*env)->DeleteLocalRef(env, childArr); /* return the NetworkInterface */ return netifObj; @@ -853,7 +861,7 @@ curr = ifList; arr_index = 0; while (curr != NULL) { - jobject netifObj; + jobject netifObj = NULL; netifObj = createNetworkInterface(env, curr, -1, NULL); if (netifObj == NULL) { @@ -862,6 +870,7 @@ /* put the NetworkInterface into the array */ (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj); + (*env)->DeleteLocalRef(env, netifObj); curr = curr->next; }
09-07-2018

jdk8u-dev$ java -Xcheck:jni JNITest WARNING: JNI local refs: 33, exceeds capacity: 32 at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) jdk8u-dev$ java -Xcheck:jni -Djava.net.preferIPv4Stack=true JNITest jdk8u-dev$ Please note with -Djava.net.preferIPv4Stack=true reproducer doesn't emits any warning.
21-09-2017

On window: $ ./jdk8/jdk1.8.0_112/bin/java.exe -version java version "1.8.0_112" Java(TM) SE Runtime Environment (build 1.8.0_112-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode) $ ./jdk8/jdk1.8.0_112/bin/java.exe -Xcheck:jni JNITest WARNING: JNI local refs: zu, exceeds capacity: zu at java.lang.System.initProperties(Native Method) at java.lang.System.initializeSystemClass(System.java:1166) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3) WARNING: JNI local refs: zu, exceeds capacity: zu at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at JNITest.main(JNITest.java:3)
21-09-2017

$ ~/binaries/jdk1.8.0_65/bin/java -version java version "1.8.0_65" Java(TM) SE Runtime Environment (build 1.8.0_65-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode) $ ~/binaries/jdk1.8.0_65/bin/java -Xcheck:jni NITest WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod WARNING: JNI local refs: 33, exceeds capacity: 32 at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at NITest.main(NITest.java:3) WARNING: JNI local refs: 66, exceeds capacity: 65 at java.net.NetworkInterface.getAll(Native Method) at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) at NITest.main(NITest.java:3)
20-09-2017