Boost your java application with low level programming no JNI required

Doing low level programming is hard to achieve on Java, and if you need it you might be forced to use JNI which requires you to do it in C or C++, and it might lead to an app that is dependent to a specific platform.

For this article we want to discover one of the coolest internal API sun.misc.Unsafe which has no official documentation and oracle apparently hates people for using it, but it so wildly used that every major framework/library is currently using it to do some internal optimizations, think of Spring, Guava, GWT, Netty, Jersey-Common, Infinispan, JBoss-Modules, and many more, so if you aren't using it directly, you're definitely using it inside one of these frameworks

Getting the Unsafe instance.

Before we start working with Unsafe we need to get its instance but it's not an easy task because it has a private constructor and calling Unsafe.getUnsafe() will likely throw a security exception, because it's supposed to be used by the JVM for its internal manipulations.

public static Unsafe getUnsafe() {
  Class cc = sun.reflect.Reflection.getCallerClass(2);
  if (cc.getClassLoader() != null)
    throw new SecurityException("Unsafe");
  return theUnsafe;
}

You can however make your code trusted by running this flag "bootclasspath" but it's an easy task

java -Xbootclasspath:/usr/jdk8.0/jre/lib/rt.jar:. com.myclass.UnSafeConsumer

The best way to do it is by stealing the instance using reflection, which we will find it by accessing a field called theUnsafe if you're using HotSpot virtual machine, for android JVM the field is called THE_ONE

Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);

Now let's have some fun

The Unsafe class provides 105 methods to do some low level manipulation (mostly memory manipulations)

Creating new instance of a class without a constructor

Using the Unsafe, we can create a new instance bypassing any security checks made inside its constructor or if it was doing some heavy initialization let's consider this following class:

public final class Singleton {
    private static final Singleton INSTANCE = new Singleton();
    private String unsafe;

    private Singleton() { 
        unsafe = "using Unsafe Is Unsafe"
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
    public String getUsafe(){
    return unsafe
    }
}

We can allocate an instance directly on the heap using the method allocateInstance:

Singleton  newInstance = (Singleton) unsafe.allocateInstance(Singleton.class);
System.out.println(newInstance.getUnsafe()) //prints nothing

Now imagine what we just did to the singleton pattern.

There areso much more useful tricks you can do with class from Native memory allocation to native concurrency to very a fast serialisation cycle. which is still supported in Java 9

To use it here Here is the module declaration for jdk.unsupported:

module jdk.unsupported {
    exports sun.misc;
    exports sun.reflect;
    exports com.sun.nio.file;
    opens sun.misc;
    opens sun.reflect;
}

To use Unsafe, you need to add jdk.unsupported to your code module declaration:

module java9unsafe {
    requires jdk.unsupported;
}

To view or add a comment, sign in

More articles by Karim OURRAI

Explore content categories