Access package private variables using a reserved package name

I was studying the source code of java.util.HashMap , and I wanted to see how well the hashcode function distributes the key in Entry 's internal array (this is a private package variable). So I made a package called java.util in my project to check the weather. I can trick the compiler into considering it to be the same package. Surprisingly this worked, and I wrote the following code:

 package java.util; public class HashMapExt<K, V> extends HashMap<K, V> implements Map<K, V> { public static void main(String[] args) { HashMapExt<Integer, String> mp = new HashMapExt<Integer, String>(); mp.put(1, "Hello"); mp.put(2, "Map"); mp.put(3, "Extention"); mp.printData(); } void printData() { System.out.println(Arrays.toString(table)); } } 

It compiled successfully, but on startup, it threw an exception:

 Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.util at java.lang.ClassLoader.preDefineClass(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) 

Now the question arises: is it possible to change the default security model so that I can access the table internal variable or is there another alternative (possibly using reflection)?

+3
java access-modifiers
source share
2 answers

Even if there is an option for your class to be in the java.util package (for example, replacing the kernel of the kernel or defining your custom class loader, for example), you are better off using reflection. It is simple and clear:

 Field tableField = HashMap.class.getDeclaredField("table"); tableField.setAccessible(true); Map.Entry[] entries = (Map.Entry[]) tableField.get(yourMap); 
+6
source share

You can try either adding your jar to the classpath, or using the approved directory .

First:

 java -Xbootclasspath/p:youJarHere.jar ..... 

And the effect is that you first load the classes that you have in your Jar, even when overriding the main classes.

A later form is to put $JAVA_HOME/lib/endorsed classes / banks in your directory, it has a similar effect.

I have not used any of them for several years, but I used them once to replace the main class (something in the CORBA package or something like that).

Try and let us know if this worked.

Here are some links:

http://blogs.sourceallies.com/2010/02/replacing-and-patching-java-application-and-core-classes/

http://download.oracle.com/javase/6/docs/technotes/guides/standards/

+2
source share

All Articles