I am writing some FFI code in Java that makes heavy use of sun.misc.Unsafe
.
In Java 9, this class will become inaccessible, and will become jdk.unsupported.Unsafe
. I would like to write my code so that it works now, but continues to work in Java 9.
What is the least hacky way to do this? I would prefer binary compatibility, but source compatibility is also okay.
Edit: I am 100% not okay with using reflection – or even virtual dispatch – every time a method on Unsafe
is called. Most of those methods compile to a single machine instruction. Therefore, performance really matters. It's okay to have wrappers – but only if I can be sure the JIT will inline them, every time.
My current plan is to load an appropriate class at runtime.
One option: You could have a small shim helper interface for the method(s) on Unsafe that you need access to, with two implementations: one for sun.misc.Unsafe
and one for the new jdk.unsupported.Unsafe
. Both classes could be stored as binary resources in your JAR, and during class initialization (that is, in a static
block) you could create a new ClassLoader and load the shim class. This would give you some reflective overhead during class initialization, but at runtime there's no reflection involved, only a virtual method dispatch -- which the JIT should be able to inline, so long as you only load the one implementation class.
If you can introduce a library dependency, cglib's FastClass will basically do this for you with a lot less effort.
As always with low-level performance hacks like this, you need some data. Create a JMH test harness for this and verify that the reflection overhead really is intolerable, and that the JIT really can inline your solution -- that's the only way to be certain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With