Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to limit setAccessible to only "legitimate" uses?
    text
    copied!<p>The more I learned about the power of <code>java.lang.reflect.AccessibleObject.setAccessible</code>, the more astonished I am at what it can do. This is adapted from my answer to the question (<a href="https://stackoverflow.com/questions/2474017/using-reflection-to-change-static-final-file-separatorchar-for-unit-testing/2474242#2474242">Using reflection to change static final File.separatorChar for unit testing</a>).</p> <pre><code>import java.lang.reflect.*; public class EverythingIsTrue { static void setFinalStatic(Field field, Object newValue) throws Exception { field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() &amp; ~Modifier.FINAL); field.set(null, newValue); } public static void main(String args[]) throws Exception { setFinalStatic(Boolean.class.getField("FALSE"), true); System.out.format("Everything is %s", false); // "Everything is true" } } </code></pre> <p>You can do truly outrageous stuff:</p> <pre><code>public class UltimateAnswerToEverything { static Integer[] ultimateAnswer() { Integer[] ret = new Integer[256]; java.util.Arrays.fill(ret, 42); return ret; } public static void main(String args[]) throws Exception { EverythingIsTrue.setFinalStatic( Class.forName("java.lang.Integer$IntegerCache") .getDeclaredField("cache"), ultimateAnswer() ); System.out.format("6 * 9 = %d", 6 * 9); // "6 * 9 = 42" } } </code></pre> <p>Presumably the API designers realize how abusable <code>setAccessible</code> can be, but must have conceded that it has legitimate uses to provide it. So my questions are:</p> <ul> <li>What are the truly legitimate uses for <code>setAccessible</code>? <ul> <li>Could Java has been designed as to NOT have this need in the first place?</li> <li>What would the negative consequences (if any) of such design be?</li> </ul></li> <li>Can you restrict <code>setAccessible</code> to legitimate uses only? <ul> <li>Is it only through <code>SecurityManager</code>? <ul> <li>How does it work? Whitelist/blacklist, granularity, etc?</li> <li>Is it common to have to configure it in your applications?</li> </ul></li> <li>Can I write my classes to be <code>setAccessible</code>-proof regardless of <code>SecurityManager</code> configuration? <ul> <li>Or am I at the mercy of whoever manages the configuration?</li> </ul></li> </ul></li> </ul> <hr> <p>I guess one more important question is: DO I NEED TO WORRY ABOUT THIS???</p> <p>None of my classes have any semblance of enforceable privacy what-so-ever. The singleton pattern (putting doubts about its merits aside) is now impossible to enforce. As my snippets above show, even some basic assumptions of how Java fundamental works is not even close to being guaranteed.</p> <p>ARE THESE PROBLEMS NOT REAL???</p> <hr> <p>Okay, I just confirmed: thanks to <code>setAccessible</code>, Java strings are <em>NOT</em> immutable.</p> <pre><code>import java.lang.reflect.*; public class MutableStrings { static void mutate(String s) throws Exception { Field value = String.class.getDeclaredField("value"); value.setAccessible(true); value.set(s, s.toUpperCase().toCharArray()); } public static void main(String args[]) throws Exception { final String s = "Hello world!"; System.out.println(s); // "Hello world!" mutate(s); System.out.println(s); // "HELLO WORLD!" } } </code></pre> <p>Am I the only one who thinks this is a HUGE concern?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload