Skip to content

Instantly share code, notes, and snippets.

@brunoborges
Created September 27, 2022 05:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brunoborges/2cace368fd01ebb7bbfcdc4c8fa10d80 to your computer and use it in GitHub Desktop.
Save brunoborges/2cace368fd01ebb7bbfcdc4c8fa10d80 to your computer and use it in GitHub Desktop.
// Start jshell as such:
// jshell -R--add-opens=java.base/java.lang=ALL-UNNAMED -R--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
var GET_VALUE = String.class.getDeclaredField("value");
GET_VALUE.setAccessible(true);
var name = "Foo Bar";
var bytes = name.getBytes();
var rawBytes = new byte[bytes.length];
System.arraycopy(bytes, 0, rawBytes, 0, 7);
var reflectionBytes = GET_VALUE.get(name);
System.out.println("Are all arrays of the same type?");
System.out.println(bytes.getClass().equals(reflectionBytes.getClass()));
System.out.println(rawBytes.getClass().equals(reflectionBytes.getClass()));
System.out.println(bytes.getClass().equals(rawBytes.getClass()));
System.out.println(reflectionBytes.getClass());
System.out.println("bytes: " + java.util.Arrays.toString(bytes));
System.out.println("rawBytes: " + java.util.Arrays.toString(rawBytes));
bytes[0] = (byte) 'B';
rawBytes[0] = (byte) 'B';
var newString = new String(bytes);
System.out.println("newString: " + newString);
System.out.println("Are both non-reflection arrays content equal? 'bytes' and 'rawBytes': " + java.util.Arrays.equals(bytes, rawBytes));
System.out.println("Now let's play with the reflection-sourced byte array...");
System.out.println("reflectionBytes: " + java.util.Arrays.toString(reflectionBytes)); // here you will see a 'no suitable method found'
reflectionBytes[0] = (byte) 'B';
var newReflectionString = new String(reflectionBytes); // here you will see a 'no suitable constructor found'
System.out.println("Reflection String: " + newReflectionString); // here, of course, symbol not found
/exit
@sundararajana
Copy link

  1. Using --add-opens on JDK packages is a bad idea. JDK implementation can and will change. And that's break your code that uses deep reflection.

  2. In any case you don't need to open up java.lang.reflect package. You just need to open java.lang (because you only use deep reflection on java.lang.String)

  3. In line 12, you have

    var reflectionBytes = GET_VALUE.get(name);

GET_VALUE is a java.lang.reflect.Field instance. "get" method returns java.lang.Object type. So type inferred for reflectionBytes is "Object" and that's why you get subsequent errors.

if you change that to

var reflectionBytes = (byte[])GET_VALUE.get(name);

the above code will run fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment