title: Java ProtectionDomain seems not to work
body: <p>I have some problem with granting permissions in Java. I would like to implement app (e.g. <code>myapp</code>), which runs normaly, with all permissions, but when it loads code (from .jar or .class)(e.g. <code>foo.jar</code> and <code>bar.class</code>) from specific location (e.g <code>http://example.net/libs</code>), this code should run with specific permissions.</p>
  
  <p>I thought the only one which I have to do is grant all permissions to <code>myapp</code> (via policy file) and then just simply create <code>ProtectionDomain</code> (on location <code>http://example.net/libs/*</code> and with specified permissions) and run libs via <code>AccessController</code>.</p>
  
  <p><strike>But when I grant permissions (<strong>only</strong>)(via policy file, see bottom) to <code>myapp</code>, they are granted to all code (including libraries <code>foo.jar</code> and <code>bar.class</code>) - which musn't.</strike></p>
  
  <p><strike>So I stopped exploring how to grant permissions to libs and I have to solve this problem first.</strike></p>
  
  <p><em>(see EDIT at bottom)</em></p>
  
  <h3>Structure</h3>
  
  <p>I have <code>myapp</code> which contains main class (<code>myapp.Main</code>) and it's located in <code>/home/java/</code>:</p>
  
  <pre><code>/home/java/src/myapp/Main.java
  /home/java/bin/myapp/Main.class
  </code></pre>
  
  <p>and libraries</p>
  
  <pre><code>http://example.net/libs/foo.jar
  http://example.net/libs/bar.class
  </code></pre>
  
  <h3>Implementation</h3>
  
  <p>I wrote <code>myapp.Main.java</code> like this:</p>
  
  <pre><code>package myapp;
  
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLClassLoader;
  
  public class Main {
  
      public static void main(String[] args) throws IOException {
          //myapp should access
          System.out.println("myapp.Main: " + System.getProperty("user.home"));
  
          //find Foo class
          Class&lt;?&gt; fooClass = findFooClass();
  
          //invoke some its method
          // this should fail
          try {
              System.out.println(fooClass.newInstance().toString());
          } catch (InstantiationException | IllegalAccessException e) {
              e.printStackTrace();
              return;
          }
  
      }
  
      private static Class&lt;?&gt; findFooClass() throws IOException {
          URL fooClassURL;
          try {
              fooClassURL = new URL("http://example.net/libs/foo.jar");
          } catch (MalformedURLException e) {
              e.printStackTrace();
              return null;
          }
  
          URLClassLoader ucl = new URLClassLoader(new URL[]{fooClassURL});
          Class&lt;?&gt; fooClass;
          try {
              fooClass = ucl.loadClass("foopackage.Foo");
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
              return null;
          } finally {
              ucl.close();
          }
  
          return fooClass;
      }
  
  }
  </code></pre>
  
  <p>and class <code>foopackage.Foo</code> like</p>
  
  <pre><code>package foopackage;
  
  public class Foo {
  
      public Foo() {
      }
  
      private void tryProperty() {
          System.out.println("foopackage.Foo: " + System.getProperty("user.home"));
      }
  
      @Override
      public String toString() {
          tryProperty();
          return super.toString();
      }
  }
  </code></pre>
  
  <h3>Running</h3>
  
  <p>When I run myapp via this command</p>
  
  <pre><code> java -Djava.security.manager -Djava.security.policy=/home/java/myapp.policy myapp.Main
  </code></pre>
  
  <p>where file <code>myapp.policy</code> looks like</p>
  
  <pre><code>grant codeBase "file:/home/java/*" {
     permission java.security.AllPermission;
  };
  </code></pre>
  
  <p><strike>it outputs twice home directory and then original value of <code>Foo.toString</code>.</strike>
  <em>(see EDIT at bottom)</em></p>
  
  <p>I am asking - what am I doing wrong? What did I disunderstand?</p>
  
  <hr>
  
  <h3>EDIT:</h3>
  
  <p>The reason why permissions were granted to whole code was simply - while I was exploring security, I've got litle bit tangled and I granted all permissions via file <code>~/java.policy</code>. </p>
  
  <p>So, now I can grant permissions via policy file as expected. But still not works granting permissions via <code>AccessController</code>. <code>myapp.Main</code> has permissions granted via policy file and works fine (so it prints once home directory), but when it (via <code>AccessController.doPrivileged</code>) calls <code>FooClassToStringAction</code>'s action, the <code>foopackage.Foo</code> has no permission to access property (which I IMHO grant by <code>ProtectionDomain</code>). Updated <code>myapp.Main</code> class' code:</p>
  
  <pre><code>package myapp;
  
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.security.AccessControlContext;
  import java.security.AccessController;
  import java.security.AllPermission;
  import java.security.CodeSource;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.PrivilegedAction;
  import java.security.ProtectionDomain;
  import java.security.cert.Certificate;
  
  public class Main {
  
      public static class FooClassToStringAction implements PrivilegedAction&lt;Void&gt; {
  
          private Class&lt;?&gt; fooClass;
  
          public FooClassToStringAction(Class&lt;?&gt; fooClass) {
              this.fooClass = fooClass;
          }
  
          @Override
          public Void run() {
              try {
                  System.out.println(fooClass.newInstance().toString());
              } catch (InstantiationException | IllegalAccessException e) {
                  e.printStackTrace();
                  return null;
              }
  
              return null;
          }
      }
  
      public static void main(String[] args) throws IOException {
          //myapp should access
          System.out.println("myapp.Main: " + System.getProperty("user.home"));
  
          //find Foo class
          Class&lt;?&gt; fooClass = findFooClass();
  
          ProtectionDomain domain = createProtectionDomain();
          PrivilegedAction&lt;Void&gt; action = new FooClassToStringAction(fooClass);
          AccessControlContext context = new AccessControlContext(new ProtectionDomain[] {domain});
          AccessController.doPrivileged(action, context);
  
      }
  
      private static Class&lt;?&gt; findFooClass() throws IOException {
          URL fooClassURL;
          try {
              fooClassURL = new URL("http://example.net/libs/*");
          } catch (MalformedURLException e) {
              e.printStackTrace();
              return null;
          }
  
          URLClassLoader ucl = URLClassLoader.newInstance(new URL[] {fooClassURL});//new URLClassLoader(new URL[]{fooClassURL});
          Class&lt;?&gt; fooClass;
          try {
              fooClass = ucl.loadClass("foopackage.Foo");
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
              return null;
          } finally {
              ucl.close();
          }
  
          return fooClass;
      }
  
      private static ProtectionDomain createProtectionDomain() {
          URL url;
          try {
              url = new URL("http://example.net/libs/*");
          } catch (MalformedURLException e) {
              e.printStackTrace();
              return null;
          }
  
          //I tried url=null or url=file:/- but no change
          CodeSource codesource = new CodeSource(url, (Certificate[]) null);
  
          PermissionCollection permissions = new Permissions();
          //add various permissions to libraries here
          permissions.add(new AllPermission());
  
          return new ProtectionDomain(codesource, permissions);
      }
  }
  </code></pre>