JEP draft: Prepare to Restrict The Use of JNI

CC 4evnyuij at gmail.com
Tue Aug 29 22:07:06 UTC 2023


I've looked through the JEP a bit more, and can confidently say that this
will be the first step towards a future I, personally, would not want to
live in regarding java.

> Unfortunately, any interaction *at all* between Java code and native code
is risky because /it can compromise the integrity of applications and the
Java Platform itself/. According to the policy of (
https://openjdk.org/jeps/8305968), all JDK features that are capable of
breaking integrity must obtain explicit approval from the end user or the
application assembler.

So what about reflection? Method handles? Accessing even just the smallest
of internals? Unsafe? All of those could compromise the integrity of the
java platform, and should therefore be locked behind the library user
accepting them to be used. Why aren't they locked behind flags?

> Calling native code can lead to arbitrary undefined behavior
<https://en.wikipedia.org/wiki/Undefined_behavior>, including JVM crashes.
Such problems cannot be prevented by the Java runtime or caught by Java
code.
Unsafe. Misconfigured method handles.

> Native code and Java code often exchange data through byte buffers
<https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#newdirectbytebuffer>,
which are regions of memory not managed by the JVM's garbage collector.
Native code can produce a byte buffer that is backed by an invalid region
of memory, and using the byte buffer in Java code is practically certain to
cause undefined behavior.
The foreign memory API will allow you to do that directly from the comfort
of java.

> Native code could use the JNI API to access fields
<https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#accessing-fields-of-objects>
and call methods
<https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#calling-instance-methods>
without any access checks by the JVM or even change the values of final
fields long after they are initialized because the implementation of JNI
does not perform the appropriate checks. Java code that uses JNI could
therefore circumvent any of the invariants established through strong
encapsulation of any other Java code.
So what? There are legitimate reasons for this, changing internal fields
may sometimes be required to make something work the way you want. There is
no reason to use this as an argument against JNI, because it legitimately
is a good use case. While I agree that changing a String instance's data
array would be a bit silly, that example is also about the least practical
example of this.

> Native code which uses certain functions of the JNI API incorrectly
(principally GetPrimitiveArrayCritical
<https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#getprimitivearraycritical-releaseprimitivearraycritical>
and GetStringCritical
<https://docs.oracle.com/en/java/javase/20/docs/specs/jni/functions.html#getstringcritical-releasestringcritical>)
may cause undesirable behavior by the garbage collector
<https://shipilev.net/jvm/anatomy-quarks/9-jni-critical-gclocker/> that can
manifest at any time during the program's lifetime.
This can be said about a lot of other things as well; A feature is not at
fault for a bad programmer using it.

Other arguments in this thread are so extremely out of touch with how the
modern java world works, they have me questioning the timeline I am living
in.

This thread is a prideful demonstration of the sheer incompetence managing
the Java specification, and I am ashamed even being apart of it.

This will be my final message on the topic, lest these changes run into the
danger of being merged.

Constantin

Am Di., 29. Aug. 2023 um 18:16 Uhr schrieb Alex Buckley <
alex.buckley at oracle.com>:

> On 8/29/2023 8:47 AM, Quân Anh Mai wrote:
> > There is a huge difference between --add-opens and
> > --enable-native-access here. While the sole purpose of --add-opens is to
> > break encapsulation and open implementation details, dependence on which
> > is a major factor causing the friction of migration from 8 to 9, the
> > purpose of JNI is not to break anything, but to simply enable native
> > accesses from Java. While encapsulation breakage is possible in JNI,
> > equating it as its sole purpose seems illogical. As a result, forcing
> > the users to treat it similarly as --add-opens and friends seems not to
> > be reasonable to me.
>
> We are not saying that breaking encapsulation is the sole purpose of
> JNI. We are saying that the use of native code, while sometimes the only
> way to do something, is risky. The JEP identifies four risks --
> https://openjdk.org/jeps/8307341#Motivation -- of which the first two --
> undefined behavior and bad buffers -- are by far the worst.
>
> We are then saying something further: the risks are so high that the
> user should explicitly agree to take them.
>
> Alex
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20230830/8a05a7b0/attachment-0001.htm>


More information about the jdk-dev mailing list