title: Java AccessControlException despite granting appropriate file permission
body: <p>I'm getting a bizarre error trying to run a Java RMI application with a SecurityManager. When the server starts up, I want it to read in text from a file supplied as a command-line argument. I'm using Eclipse, and this file is in the same directory as the root of the Java project (so I can just give the filename in the command-line argument instead of a full path). I know that RMI's SecurityManager forbids file I/O by default, so I've created a policy file for my server that looks like this:</p>
  
  <pre><code>grant codeBase "file:///C:/Users/Edward/College/CS197/authmatch/bin/-" {
      //Giving the server permission to make connections
      permission java.net.SocketPermission "127.0.0.1:1024-", "connect, resolve";
      permission java.net.SocketPermission "127.0.0.1:1024-", "accept, resolve";
      //File I/O permissions
      permission java.io.FilePermission "C:/Users/Edward/College/CS197/authmatch/-", "read,write,delete";
      permission java.util.PropertyPermission "user.dir", "read";
      permission java.lang.RuntimePermission "readFileDescriptor";
      permission java.lang.RuntimePermission "modifyThread";
  };
  </code></pre>
  
  <p>(Note that the name of my Eclipse project is "authmatch", and this is running on Windows). In my Eclipse run configuration, I enable this policy file with the following VM flags:</p>
  
  <pre><code>-Djava.rmi.server.codebase=file:///C:/Users/Edward/Documents/College/CS197/authmatch/bin/
  -Djava.security.policy=server.policy
  </code></pre>
  
  <p>I know that the policy file is being parsed and loaded because if I introduce a syntax error in server.policy Java complains about it ("error parsing file") when my application runs. However, the security manager seems to be somehow ignoring the permissions I grant in my policy, because when I run the application I get this error: </p>
  
  <pre><code>Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "smalltest.txt" "read")
      at java.security.AccessControlContext.checkPermission(Unknown Source)
      at java.security.AccessController.checkPermission(Unknown Source)
      at java.lang.SecurityManager.checkPermission(Unknown Source)
      at java.lang.SecurityManager.checkRead(Unknown Source)
      at java.io.RandomAccessFile.&lt;init&gt;(Unknown Source)
      at etremel.authmatch.text.TextFileFormatter.&lt;init&gt;(TextFileFormatter.java:39)
      at etremel.authmatch.source.PatternMatcherSource.main(PatternMatcherSource.java:302)
  </code></pre>
  
  <p>Since the file I'm asking it to read (smalltest.txt) is in the "authmatch" project directory, and I explicitly gave my application permission to read that directory with the line</p>
  
  <pre><code>permission java.io.FilePermission "C:/Users/Edward/College/CS197/authmatch/-", "read,write,delete";
  </code></pre>
  
  <p>why is it still insisting that it doesn't have read permission for the file? I suspect this may be a Windows issue because I have the same project running on a Linux computer and a similar policy file allows it to read from its local project directory just fine.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I ran the server with <code>-Djava.security.debug=access,failure</code> and it generated a bunch of debug messages while parsing the policy file. You can see the entire log at <a href="http://pastebin.com/ijjg3FC9" rel="nofollow">this pastebin</a>, but there seem to be two important parts:</p>
  
  <pre><code>access: access allowed ("java.security.SecurityPermission" "getPolicy")
  access: access allowed ("java.io.FilePermission" "C:\Users\Edward\Documents\College\CS197\authmatch\bin" "read")
  access: domain that failed ProtectionDomain  (file:/C:/Users/Edward/Documents/College/CS197/authmatch/bin/ &lt;no signer certificates&gt;)
   sun.misc.Launcher$AppClassLoader@74ba86ef
   &lt;no principals&gt;
   java.security.Permissions@7a8a44a6 (
   ("java.io.FilePermission" "\C:\Users\Edward\Documents\College\CS197\authmatch\bin\-" "read")
   ("java.net.SocketPermission" "localhost:1024-" "listen,resolve")
   ...
  </code></pre>
  
  <p>...and much later:</p>
  
  <pre><code>access: access allowed ("java.io.FilePermission" "C:\Users\Edward\Documents\College\CS197\authmatch\bin\etremel\authmatch\text\TextFileFormatter.class" "read")
  access: access allowed ("java.util.PropertyPermission" "user.dir" "read")
  access: access denied ("java.io.FilePermission" "smalltest.txt" "read")
  </code></pre>
  
  <p>It looks like there's some kind of "domain protection" failure because my codebase isn't signed, but I thought it was acceptable to specify a security policy without a signature using the <code>grant codeBase</code> setup. More puzzling, it doesn't look like it ever reads the FilePermission for the root authmatch directory, just the authmatch/bin directory. Then it concludes that it should deny access to "smalltest.txt," but it never resolves the full directory path of that file. </p>
  
  <p>Remember, the same project and policy work fine on Linux.</p>