Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How unsafe is the use of sun.misc.Unsafe actually?

Tags:

java

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.

like image 341
Rafael Winterhalter Avatar asked Dec 10 '13 12:12

Rafael Winterhalter


People also ask

Is Java 8 Unsafe?

Of the three, Unsafe is the most potentially dangerous (and therefore powerful) because it provides a way to do certain things that are otherwise impossible and that break well-established rules of the platform. The Java 8 Unsafe class, sun.

Why is Java considered unsafe?

The Java programming language and Java software platform have been criticized for design choices including the implementation of generics, forced object-oriented programming, the handling of unsigned numbers, the implementation of floating-point arithmetic, and a history of security vulnerabilities in the primary Java ...

What is unsafe in Java?

Unsafe such for example objenesis and therewith all libraries that build on the latter such for example kryo which is again used in for example Twitter's Storm. Therefore, it is time to have a look, especially since the functionality of sun. misc. Unsafe is considered to become part of Java's public API in Java 9.


Video Answer


2 Answers

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.

like image 132
Stephen C Avatar answered Oct 18 '22 22:10

Stephen C


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).

like image 4
Jaroslav Tulach Avatar answered Oct 18 '22 23:10

Jaroslav Tulach