Issue
I'm trying to access String.isLatin1()
which is declared (as of JDK 14) as
boolean isLatin1() {
return COMPACT_STRINGS && coder == LATIN1;
}
I can do this with reflection
class="lang-java prettyprint-override">Method isLatin1 = String.class.getDeclaredMethod("isLatin1");
isLatin1.setAccessible(true);
isLatin1.invoke(""); //true
but I wonder whether I can do the same with SharedSecrets
?
I've tried
SharedSecrets.getJavaLangAccess().getDeclaredPublicMethods(String.class, "isLatin1");
but for obvious reason it returns an empty list. Also I've tried to utilize jdk.internal.access.JavaLangReflectAccess
available from SharedSecredts
, but it doesn't have any suitable method.
Solution
It is not going to work. The shared secrets mechanism provides a way to specific package private methods. If you look at the source code, you will see that there is an "access" interface that exposes a fixed set of methods. The shared secrets interface for the java.lang
package exposes some methods for getting a string's internal byte array without copying it. But it doesn't provide a method that does what you want.
Furthermore, the isLatin1()
method that you are trying to access is private
rather than package private, so it cannot be exposed anyway ... unless you change that.
In short, you can't use SharedSecrets
for this unless you are prepared to modify the OpenJDK source code and build your own JVM. It might be acceptable to do that as an experiment, but there are lots of red flags for production use.
Use reflection. It is more practical ... modulo that you risk causing future portability problems for your application. (Consider that the internal representation of String
have changed 2 or 3 times so far since Java 1.1. It could happen again.)
Answered By - Stephen C
Answer Checked By - David Goodson (JavaFixing Volunteer)