Tutoriel Java RMI - AccessControlException: accès refusé (java.io.FilePermission


Answers

Ok, je l'ai. Ce n'était pas la propriété rmiregistry (fonctionne sans aucun paramètre). Il y avait deux erreurs dans mon code VM-Parameter:

-cp C:\ProjX\server\serverProj\bin\usermanager\
-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/
-Djava.rmi.server.hostname=XYZ (anonymized)
-Djava.security.policy=server.policy

... devrait plutôt ressembler à ceci:

-Djava.rmi.server.codebase=file:/C:/ProjX/server/serverProj/bin/
-Djava.rmi.server.hostname=XYZ (anonymized)
-Djava.security.policy=server.policy

=> fichier: / (une seule barre oblique) + fin du paquetage erroné.

Mais la trace était si confuse, ma première pensée était, que quelque chose doit être faux avec le fichier de politique ou la configuration de la politique.

Néanmoins: Merci pour l'aide et le piratage heureux. ;-)

Question

Hier, j'ai essayé de démarrer avec Java RMI. J'ai trouvé ce tutoriel sur le soleil ( http://java.sun.com/docs/books/tutorial/rmi/index.html ) et j'ai commencé avec l'implémentation du serveur. Mais chaque fois que je lance le pogram (le rmiregistry est en cours d'exécution), j'obtiens une AccessControlException avec le StackTrace suivant:

LoginImpl exception:
java.security.AccessControlException: access denied (java.io.FilePermission \\\C\ProjX\server\serverProj\bin\usermanager read)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
    at java.security.AccessController.checkPermission(AccessController.java:427)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
    at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
    at java.io.File.exists(File.java:700)
    at sun.net.www.protocol.file.Handler.openConnection(Handler.java:80)
    at sun.net.www.protocol.file.Handler.openConnection(Handler.java:55)
    at java.net.URL.openConnection(URL.java:943)
    at sun.rmi.server.LoaderHandler.addPermissionsForURLs(LoaderHandler.java:1020)
    at sun.rmi.server.LoaderHandler.access$300(LoaderHandler.java:52)
    at sun.rmi.server.LoaderHandler$Loader.<init>(LoaderHandler.java:1108)
    at sun.rmi.server.LoaderHandler$Loader.<init>(LoaderHandler.java:1089)
    at sun.rmi.server.LoaderHandler$1.run(LoaderHandler.java:861)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.server.LoaderHandler.lookupLoader(LoaderHandler.java:858)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:541)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1457)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:375)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
    at sun.rmi.transport.Transport$1.run(Transport.java:153)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
    at java.lang.Thread.run(Thread.java:595)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
    at sun.rmi.server.UnicastRef.invoke(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at startserver.StartServer.main(StartServer.java:22)

Mon fichier server.policy ressemble à ceci:

grant {
    permission java.security.AllPermission;
};

Mais j'ai aussi essayé celui-là ...

grant {
    permission java.security.AllPermission;
    permission java.io.FilePermission "file://C:/ProjX/server/serverProj/bin/usermanager", "read";
};

... et celui-ci (et plusieurs autres :-():

grant codeBase "file:///-" {
    permission java.security.AllPermission;
};

Mais dans tous les cas, le résultat est le même. Et oui, le fichier de politique est dans le chemin (je vois une exception d'analyse, quand j'écris de fausses déclarations dans le fichier de politique). J'ai essayé plusieurs autres constellations "/" et "\" mais cela n'a aucun effet.

J'utilise Eclipse et mes paramètres VM sont comme ceci:

-cp C:\ProjX\server\serverProj\bin\usermanager\
-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/
-Djava.rmi.server.hostname=XYZ (anonymized)
-Djava.security.policy=server.policy

Les classes de l'interface distante compilée et de la classe d'implémentation d'interface (LoginImpl) se trouvent dans ce chemin: "C: / ProjX / server / serverProj / bin / usermanager /". La méthode principale, où j'instancie et reloue le talon au registre est dans un autre paquet et ressemble à ceci:

public static void main(String[] args) {
    if (System.getSecurityManager() == null) {
        System.setSecurityManager(new SecurityManager());
    }
    try {
        String name = "Login";
        Login login = new LoginImpl();
        Login stub = (Login) UnicastRemoteObject.exportObject(login, 0);
        Registry registry = LocateRegistry.getRegistry();
        registry.rebind(name, stub);
        System.out.println("LoginImpl bound");
    } catch (Exception e) {
        System.err.println("LoginImpl exception:");
        e.printStackTrace();
    }
}

Est-ce que quelqu'un a un conseil pour moi? Merci pour l'aide.

Donc la question est la même (java.rmi.UnmarshalException montre que changer la base de code n'est pas la solution de mon AccessControlException). Et non: je ne veux pas acheter un plugin "GB" ;-).




Je pense que l'exception vient en fait de l'esprit. Cette partie de la trace de la pile est ce qui me fait penser. Le talon pour rmiregistry reçoit l'exception et la remonte à la suite de la tentative de relier.

    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
    at sun.rmi.server.UnicastRef.invoke(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)

Essayez d'exécuter rmiregistry avec -J-Djava.security.policy=all.policy , où le fichier de stratégie accorde toutes les permissions (au moins pour faire avancer les choses).

Finalement, vous voudrez peut-être aussi passer à une URL de base de code HTTP, juste pour pouvoir exécuter des clients sur une machine séparée de celle de votre serveur.




Cela fonctionne correctement lorsque j'ai corrigé la variable CLASSPATH avant de démarrer le registre rmi. Je pense que l'idée est que le Registre RMI chargera vos talons distants et qu'il devrait y avoir accès. C'était facile en mettant mes classes sur le CLASSPATH avant d'exécuter le registre. Donc, il n'est pas lié à d'autres raisons telles que JDK 7 ou fichier: / protocole.




Links