16

I am wondering about how unsafe the use sun.misc.Unsafe actually is. I want to create a proxy of an object where I intercept every method call (but the one to Object.finalize for performance considerations). For this purpose, I googled a litle bit and came up with the following code snippet:

class MyClass {
  private final String value;
  MyClass() {
    this.value = "called";
  }
  public void print() {
    System.out.println(value);
  }
}

@org.junit.Test
public void testConstructorTrespassing() throws Exception {
  @SuppressWarnings("unchecked")
  Constructor<MyClass> constructor = ReflectionFactory.getReflectionFactory()
      .newConstructorForSerialization(MyClass.class, Object.class.getConstructor());
  constructor.setAccessible(true);
  assertNull(constructor.newInstance().print());
}

My consideration is:

  • Even though Java is advertised as Write once, run everywhere my reality as a developer looks rather like Write once, run once in a controllable customer's run time environment
  • sun.misc.Unsafe is considered to become part of the public API in Java 9
  • Many non-Oracle VMs also offer sun.misc.Unsafe since - I guess - there are quite some libraries already use it. This also makes the class unlikely to disappear
  • I am never going to run the application on Android, so this does not matter for me.
  • How many people are actually using non-Oracle VMs anyways?

I am still wondering: Are there other reasons why I should not use sun.misc.Unsafe I did not think of? If you google this questions, people rather answer an unspecified because its not safe but I do not really feel it is besides of the (very unlikely) possibility that the method will one day disappear form the Oracle VM.

I actually need to create an object without calling a constructor to overcome Java's type system. I am not considering sun.misc.Unsafe for performance reasons.

Additional information: I am using ReflectionFactory in the example for convenience which delegates to Unsafe eventually. I know about libraries like objenesis but looking at the code I found out that they basically do something similar but check for other ways when using Java versions which would not work for me anyways so I guess writing four lines is worth saving a dependency.

Community
  • 1
  • 1
Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
  • Note: if it becomes a public API in Java 9, it will definitely not be in the package `com.sun`. – Jesper Dec 10 '13 at 12:54
  • Keep in mind that you will not be allowed to use Unsafe on systems where you do not have sufficient authority. – Hot Licks Dec 10 '13 at 12:55
  • Both is true. Hiwever, all rights you need is the right to read private fields by reflection. This is a quite common requirement for many libraries. – Rafael Winterhalter Dec 10 '13 at 20:35

2 Answers2

7

There are three significant (IMO) issues:

  • The methods in the Unsafe class have the ability to violate runtime type safety, and do other things that can lead to your JVM "hard crashing".

  • Virtually anything that you do using Unsafe could in theory be dependent on internal details of the JVM; i.e. details of how the JVM does things and represents things. These may be platform dependent, and may change from one version of Java to the next.

  • The methods you are using ... or even the class name itself ... may not be the same across different releases, platforms and vendors.

IMO, these amount to strong reasons not to do it ... but that is a matter of opinion.

Now if Unsafe becomes standardised / part of the standard Java API (e.g. in Java 9), then some of the above issues would be moot. But I think the risk of hard crashes if you make a mistake will always remain.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
4

During one JavaOne 2013 session Mark Reinhold (the JDK architect) got a question: "how safe it is to use the Unsafe class?". He replied with sort of surprising answer: "I believe its should become a stable API. Of course properly guarded with security checks, etc..."

So it looks like there may be something like java.util.Unsafe for JDK9. Meanwhile using the existing class is relatively safe (as safe as doing something unsafe can be).

Jaroslav Tulach
  • 519
  • 4
  • 7