Is returning a value != '0' or '1' as jboolean from a JNI function legal?

Volker Simonis volker.simonis at gmail.com
Mon Aug 20 10:22:16 UTC 2018


On Fri, Aug 17, 2018 at 7:25 PM, Aleksey Shipilev <shade at redhat.com> wrote:
> On 08/17/2018 05:12 PM, Volker Simonis wrote:
>> The offending code in Console_md.c looks as follows:
>>
>> #define ECHO    8
>>
>> JNIEXPORT jboolean JNICALL
>> Java_java_io_Console_echo(...) {
>>
>>     jboolean old;
>>     ...
>>     old = (tio.c_lflag & ECHO);
>>     ...
>>     return old;
>> }
>>
>> The intention of this code is to return "true" if the ECHO flag was
>> set but it really returns the value of ECHO (which is defined as '8'
>> in a system header).
>>
>> The question now is, if a Java SE compatible VM guarantees that any
>> arbitrary, non-zero valued jboolean will be interpreted as "JNI_TRUE"
>> and only a zero valued jboolean will be interpreted as "JNI_FALSE"?
>>
>> Or, the other way round, is the normalization performed by the HotSpot
>> result handlers necessary (i.e. enforced by the specification) or just
>> a convenience to fix broken code like the above from Console.echo()?
>
> I think this is intentional aftermath of boolean value normalization:
>   https://bugs.openjdk.java.net/browse/JDK-8161720
>

OMG - I'm getting old :)

Thanks for the link to JDK-8161720! Funny enough I was one of the
reviewers of JDK-8161720 and almost exactly two years ago I already
asked the exactly same question [1]:

"And I have a question about JNI: is it only a convention that JNI
functions should return JNI_TRUE/JNI_FALSE or is this required by the
specification?"

Zoltan answered to that question by citing an excerpt from the JNI
Programmer's Guide & Specification [2]:

"A |jboolean| is an 8-bit unsigned C type that can store values from 0
to 255. The value 0 corresponds to the constant |JNI_FALSE|, and the
values from 1 to 255 correspond to |JNI_TRUE|."

But the "JNI Programmer's Guide & Specification" is from 1999 and it
only contains the cited sentence in its "Traps and Pitfalls" section
and not in the "Specification" part. The latest JNI Specification [3]
doesn't seem to contain such a rule.

So to summarize, my current view on this topic is:
 - JNI functions returning a jboolean are only allowed to return
JNI_TRUE/JNI_FALSE (or 1/0) according to the current JNI spcification.
 - to code in Java_java_io_Console_echo() should be fixed (as
confirmed by Sherman later in this thread)
 - normalization of native, off-heap 8-bit values to Java booleans as
currently implemented in the HotSpot (and fixed by JDK-8161720) is (1)
only for convenience to simply access to off-heap data in Unsafe, (2)
to implement better Java/Native integration in projects like Panama
and (3) to fix legacy JNI code which was developed under the
assumption that the advice in the "JNI Programmer's Guide &
Specification" book is specification relevant.

Do you agree?

Thank you and best regards,
Volker

[1] http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2016-August/024192.html
[2] https://web.archive.org/web/20120626012047/http://java.sun.com/docs/books/jni/html/pitfalls.html#30066
[3] https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html

> So, Java_java_io_Console_echo looks broken and needs to be fixed, by e.g.:
>
> -   old = (tio.c_lflag & ECHO);
> +   old = (tio.c_lflag & ECHO) != 0;
>
> Thanks,
> -Aleksey
>


More information about the core-libs-dev mailing list