Home > Back-end >  Risks of directly getting DirectByteBuffer address in JNI
Risks of directly getting DirectByteBuffer address in JNI

Time:07-12

I have a JNI library which accepts a DirectByteBuffer and operates over it.

To get the buffer address, I was using:

(unsigned char *) env->GetDirectBufferAddress(input)

That was good, but after profiling it I noticed that a long time was spent in jni_IsInstanceOf:

profiler.

I then replaced it with direct access to Buffer.address

java_nio_Buffer = env->FindClass("java/nio/Buffer");
java_nio_Buffer_address = env->GetFieldID(java_nio_Buffer, "address", "J");
(...)
(unsigned char *) env->GetLongField(input, java_nio_Buffer_address)

That caused a huge speedup in that code.

Are there any major risks in getting a DirectByteBuffer address that way, given I know my object will always be a DirectByteBuffer?

CodePudding user response:

Java 9 apparently makes access to the address field illegal via reflection.

Google posted an issue with protobuf: JDK 9 warning: Illegal reflective access by com.google.protobuf.UnsafeUtil to field java.nio.Buffer.address #3781.

Note the posted error message:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.protobuf.UnsafeUtil
    (file:/Users/mmueller/.gradle/caches/modules-2/files-2.1/com.google.protobuf/protobuf-java/3.4.0/b32aba0cbe737a4ca953f71688725972e3ee927c/protobuf-java-3.4.0.jar)
    to field java.nio.Buffer.address
WARNING: Please consider reporting this to the maintainers of com.google.protobuf.UnsafeUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Given the All illegal access operations will be denied in a future release warning, it appears you risk future versions of Java potentially preventing access to the field, even via JNI.

It may also be possible, depending on how you use the field's value, that the address of the underlying buffer could change out from under you.

And finally, you're dependent on the internal implementation of the class. Should that change, your code will be broken.

You'll have to weigh those risks against the benefits you get from accessing the field directly.

  • Related