sun.security.provider.PolicyFile assumes that the internal policy state is read-only (that it can not change once the policy data has been read in). In a multi-threaded environment, however, asynchronous refreshes can affect policy state. The following is a rudimentary way to reproduce the problem: 1. Change PolicyFile.getPermissions: private Permissions getPermissions(Permissions perms, final CodeSource cs, Principal[] principals) { int numEntries = policyInfo.policyEntries.size(); try { Thread.currentThread().sleep(5000); } catch (Exception e) { } PolicyEntry entry; for (int i = 0; i < numEntries; i++) { // remainder is the same 2. Run this test program: import java.security.AllPermission; import java.security.Policy; public class Refresh extends Thread { private boolean refresh; // call Policy.refresh versus Policy.implies public Refresh(boolean refresh) { this.refresh = refresh; } public void run() { if (refresh) { while (true) { Policy.getPolicy().refresh(); } } else { while (true) { Policy.getPolicy().implies (getClass().getProtectionDomain(), new AllPermission()); } } } public static void main(String[] args) throws Exception { Refresh implies = new Refresh(false); implies.start(); Refresh refresh = new Refresh(true); refresh.start(); } } 3. During the 5 seconds PolicyFile puts the "implies" thread to sleep, update: ~/lib/security/java.policy Remove one of the grant entries. Save the file. 4. Observe this exception: angeles(218):java Refresh Exception in thread "Thread-0" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 at java.util.ArrayList.RangeCheck(ArrayList.java:547) at java.util.ArrayList.get(ArrayList.java:322) at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1261) at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1223) at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1165) at sun.security.provider.PolicyFile.implies(PolicyFile.java:1120) at Refresh.run(Refresh.java:19)
|