DEV Community

João Paulo Martins Silva
João Paulo Martins Silva

Posted on

2 + 2 = 5 in Java 21

A few years ago, I found a video by podcaster Lex Friedman where he demonstrates that it's possible to make 2+2 equal five in Java using some tricks.


import java.lang.reflect.Field;   
    public class Main {
        public static void main(String[] args) throws Exception {
            Class cache = Integer.class.getDeclaredClasses()[0];
            Field c = cache.getDeclaredField("cache");
            c.setAccessible(true);
            Integer[] array = (Integer[]) c.get(cache);
            array[132] = array[133];

            System.out.printf("%d",2 + 2);
        }
    }

Enter fullscreen mode Exit fullscreen mode

Out of curiosity, I decided to run the code available in the video links and encountered the following error:

Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field static final java.lang.Integer[] java.lang.Integer$IntegerCache.cache accessible: module java.base does not "opens java.lang" to unnamed module @8efb846
 at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391)
 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367)
 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315)
 at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:183)
 at java.base/java.lang.reflect.Field.setAccessible(Field.java:177)
 at Old2Plus2.main(Old2Plus2.java:7)
Enter fullscreen mode Exit fullscreen mode

I realized that, for the newer versions of Java, this hack was no longer possible. Therefore, in this article, I will demonstrate how to perform this trick for Java 21.

The error message says that the java.base module is not open. This means that it is not possible to use reflection from the Main class created for this example. If you are not very familiar with modules, I recommend refreshing your memory.

In other words, in Java 21, it's harder to perform this kind of hack with the language. Fortunately, there is a class that allows us to neglect the module system: the sun.misc.Unsafe. This class is used to perform low-level operations and is not recommended for the everyday use of ordinary programmers.

Thus, the new version of the code that makes 2+2 = 5 would look like this:

import java.lang.reflect.Field;

public class New2Plus2 {
    public static void main(String[] args) throws Exception {
        Class usf = Class.forName("sun.misc.Unsafe");//pega o objeto que representa a classe Unsafe
        Field unsafeField = usf.getDeclaredField("theUnsafe");//pega o campo theUnsafe da classe Unsafe
        unsafeField.setAccessible(true);//define o campo theUnsafe como público
        sun.misc.Unsafe unsafe = (sun.misc.Unsafe)unsafeField.get(null);//pega o valor do campo theUnsafe, como ele é static é passado o parâmetro null
        Class<?> clazz = Class.forName("java.lang.Integer$IntegerCache");// pega o objeto que representa a classe IntegerCache
        Field field = clazz.getDeclaredField("cache");//pega o campo cache da classe IntegerCache
        Integer[] cache = (Integer[])unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));//utiliza a classe Unsafe para pegar o cache de Integer
        cache[132] = cache[133];// troca o valor 4 pelo 5
        System.out.printf("2+2 = %d",2 + 2);
    }
}
Enter fullscreen mode Exit fullscreen mode

Running the code above, you will see that the result of the addition will be 5. Obviously, I do not recommend using this code in production if you want to maintain your sanity and your job.

References:

https://github.com/joao9aulo/2plus2equals5

https://javax0.wordpress.com/2017/05/03/hacking-the-integercache-in-java-9/

https://www.youtube.com/watch?v=amXXYgu0eFY

https://ideone.com/o1h0hR

https://www.oracle.com/br/corporate/features/understanding-java-9-modules.html

https://www.baeldung.com/java-unsafe

Top comments (0)