Hazelcast on Unsafe – “The biggest problem is that it was available for so long”
Christoph Engelbert is back to talk more about Java’s Unsafe class and the effect it will have on Hazelcast and its customers. As we’ve seen over the last couple of weeks, this issue is still contentious and developers are still looking for answers.
JAXenter: There seem to be plans to remove the sun.misc.Unsafe API from JDK 9. What is the reason for that?
Christoph Engelbert: The reasons are actually pretty simple. First of all, there is a desire to split up the JDK itself into modules using Project Jigsaw, and another obvious reason is security. Since not all modules need to be installed, there is less chance of security issues on certain computers.
To support that, Project Jigsaw introduces a new kind of visibility. Next to private, package private and public there is a module. That means the module meta-data defines which packages are actually exported from the module – an idea pretty close to OSGi. Therefore, it is the intention to also clean up packages that were never meant to be visible to the user.
That said, sun.misc.Unsafe does not really disappear but is hidden from the user’s perspective. The JDK / JRE internals are still able to use it.
There is a very controversial debate going on about this move. Where do you see the problem in removing sun.misc.Unsafe?
The biggest problem is that it was available for so long. People used it for all kinds of solutions. There are uses where AtomicX classes would solve the problem but people used it, maybe because it was cool. Or you use it to write to an array which is slightly faster but not essentially necessary, and then you have the use cases where sun.misc.Unsafe is the only real solution.
One of these use cases is interaction with native code. A simple example is a small project I wrote which implements a Java wrapper around the libbz2 library. The C code uses native pointers to read and write memory and you only have memory addresses. It is just not possible to read from or write to memory addresses in Java without sun.misc.Unsafe.
Another reason for Unsafe is performance, it that almost all methods are intrinsified that means that the actual native call is never really executed but a special piece of Assembler code is injected right into the jitted Java code. This is essentially necessary if you work in the low latency space.
There are plenty of more use cases but it would take too long to name them all, just as a short overview: fast deserialization, mocking frameworks, Java object layout analysis, network libraries, etc.
What would the removal mean for Hazelcast and its customers?
This heavily depends on how the migration path, that Oracle offers, will look like. The current plan is to provide a command line flag to re-export the intentionally hidden sun.misc package. What the flag will look like exactly is not yet clear but it will give the chance to use sun.misc.Unsafe in Java 9.
Hazelcast Enterprise uses sun.misc.Unsafe for it’s HD Memory implementation to store huge amounts of data in the Java process memory space. We will most likely have to reimplement the HD storage engine to use a possible replacement API.
That means anyone of our enterprise customers using HD Memory will have problems with Java 9, at least for the first time. We will start to engage people to remember to set the command line flag for Java 9 whenever it is announced.
The real problem I see here is that people will have to put a new and unknown parameter into their JVM startup configuration. Most people probably don’t even know they use Unsafe, because it is a transient dependency from one or more libraries hidden in their applications. If you look at the document that has been going around now for some days, you’ll see how many big and typically used frameworks rely on Unsafe in one way or another.
That means to me:
- This parameter will either not be set and applications won’t start anymore or slow down or
- It’ll become a kind of a de-facto standard.
But there is more – even if libraries offer fallbacks for the case that sun.misc.Unsafe is unavailable, they’re often not as extensively tested as the Unsafe code path. The reason is simple, there was just no necessity for it. That said users might see problems they never experienced before.
Why isn’t it as easy as updating the libraries which use sun.misc.Unsafe to the officially supported APIs?
Users might use libraries that are not actively developed anymore. Like my example library above (the libbz2 wrapper), there is no active development for a long time, it is just feature complete. Whereas I might do an update, other libraries might be abandoned by now.
As long as a library or application is open source there is a high chance someone will pick up development and create a new version, but there are plenty of paid libraries in use where the original company that created it does just doesn’t exist anymore. Nobody can update it and buying a replacement is an investment from the company that used it.
These companies will most probably stay on Java 8.
Hazelcast has proposed some solutions in the previously mentioned public Google Doc. Could you summarize your ideas?
The Google Doc does not propose any solutions yet. It is simply a collection of our findings. It visualizes the amount of libraries and it shows that almost every bigger application on the market is affected.
We kicked off a basic Working Group to work on ideas for a smooth migration path and to also work on alternatives to sun.misc.Unsafe.
While the working group is still in an early state, I started to engage with Paul Sandoz and actively work on his VarHandles proposal to find missing use cases and problems in the API. I also looked into first performance benchmarks to make sure it offers the necessary performance. However it is still only a replacement for a subset of sun.misc.Unsafe.
Who is supporting your position?
Looking at the Google Doc, you see a huge variety of companies, ranging from banks, over JVM developers to Java user groups like SouJava. In addition to that there are a lot of industry-wide known individuals like Peter Lawrey and Martijn Verburg. In addition a couple of Java Champions, which are not directly working on the Google Doc or Working Group, support our position – like Kirk Pepperdine.
Since sun.misc.Unsafe is the Performance-Swiss-Army-Knife of Java it is widely used and a complete branch of the Java ecosystem depends on it. That’s why we had to take action. Peter Lawrey and I already had a try last year to create the awareness but we failed. It is finally getting the attention it deserves.
What do you think will be the probable outcome? Will you be able to convince Oracle to find another solution than just removing sun.misc.Unsafe?
I don’t think we want to do this. I might have a different opinion here from lots of other people but the Unsafe API is ugly, clunky and… did I say ugly? Even before Oracle came up with the plan to remove it, I was in favor of a clean and supported replacement API, Unsafe should “disappear” but please keep the command line flag for people with old libraries.
What we really need to ensure is that we have replacements to meet the current use cases that are fast and that solve the problems in a clean way. If I look back at the Oracle survey last year, most sun.misc.Unsafe users were prepared to reimplement their logic based on a replacement. The percentage of naysayers was quite close and it is unlikely they would do anything else, no matter what the solution looks like.
I want to finish with a fact that feels weird to me personally.
A couple of days ago there was a tweet on Twitter saying “Framework developers just don’t like to be put in the position of users”. Apart from the fact that the sentence might be correct, I wonder why Oracle should be able to write faster Java code than myself. To me it sounds like a very wrong idea and looking at other VM languages like .NET or Python or whatever, almost all of them have a definition of an “unsafe section” where pure memory accesses are possible – I guess for a reason. If we would’ve never had sun.misc.Unsafe, who knows where Java would be today. Most likely at least not in high frequency trading.