example docs java rmi policy

docs - Tutorial de Java RMI-AccessControlException: acceso denegado(java.io.FilePermission



rmi java docs (6)

Ayer intenté comenzar con Java RMI. Encontré este tutorial sobre el sol ( http://java.sun.com/docs/books/tutorial/rmi/index.html ) y comencé con la implementación del servidor. Pero cada vez que comienzo el pograma (el rmiregistry se está ejecutando) obtengo una AccessControlException con el siguiente StackTrace:

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)

Mi archivo server.policy se ve así:

grant { permission java.security.AllPermission; };

Pero también he probado este ...

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

... y este (y muchos otros :-():

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

Pero en todos los casos, el resultado es el mismo. Y sí, el archivo de política está en la ruta (veo una Excepción de Parse, cuando escribo declaraciones incorrectas en el archivo de política). Probé varias otras constelaciones "/" y "/" pero no tiene ningún efecto.

Yo uso Eclipse y mis VM-Parameters son así:

-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

Las clases compiladas de interfaz remota y clase de implementación de interfaz (LoginImpl) están en esta ruta: "C: / ProjX / server / serverProj / bin / usermanager /". El método principal, donde instauro y vuelvo a vincular el talón al registro, está en otro paquete y se ve así:

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(); } }

¿Alguien tiene un consejo para mí? Gracias por ayudar.

Entonces la pregunta es la misma (java.rmi.UnmarshalException muestra que cambiar la base de código no es la solución de AccessControlException). Y no: no quiero comprar un plugin "GB" ;-).


La concesión de todos los permisos a todos los códigos es realmente mala. Cualquier cliente de RMI podría hacer lo que quisiera como usuario conectado. En general, intente restringir los permisos tanto como sea razonable, particularmente cuando no sabe de dónde viene el código.

Volver a la pregunta ...

-Djava.rmi.server.codebase=file://C:/ProjX/server/serverProj/bin/usermanager/

Eso debería ser "file:///C:/..." o "file:/C:/..." . Piensa en http. "http://C:/..." refiere a un host llamado C Tenga en cuenta que el mensaje de excepción ha eliminado los dos puntos, porque eso es solo la sintaxis del número de puerto.

La razón por la que obtiene una excepción de seguridad incluso si otorga permisos a todo el código, es que RMI está restringiendo los permisos a los apropiados dado las URL implicadas (utilizando el formulario AccessController doPrivileged dos argumentos).


Creo que la excepción en realidad está saliendo de rmiregistry. Esta parte del rastro de la pila es lo que me hace pensar eso. El apéndice de rmiregistry está recibiendo la excepción y devolviéndola como resultado del intento de volver a enlazar.

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)

Intenta ejecutar rmiregistry con -J-Djava.security.policy=all.policy , donde el archivo de política concede todos los permisos (al menos para que todo -J-Djava.security.policy=all.policy ).

Finalmente, es posible que desee cambiar a una URL de base de código HTTP, solo para que pueda ejecutar clientes en una máquina separada de la de su servidor.


Ok, lo tengo. No fue la propiedad de rmiregistry (funciona sin ningún parámetro). Hubo dos errores en mi Parámetro VM de la base de código:

-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

... debería verse así:

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

=> file: / (solo una barra inclinada) + finalización incorrecta del paquete.

Pero el rastro fue tan confuso, mi primer pensamiento fue, que algo debe estar mal con el archivo de política o la configuración de la política.

Sin embargo: gracias por su ayuda y feliz piratería. ;-)


También puede establecer la propiedad programáticamente java.rmi.server.codebase:

Hello h = null; Properties props = System.getProperties(); System.setProperty("java.rmi.server.codebase", "file:/C:/PROJECTX/bin/"); try { h = new HelloImpl(); Naming.bind("//localhost:1099/HelloService", h); System.out.println("Serwis gotów..."); } catch (RemoteException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (AlreadyBoundException e) { e.printStackTrace(); }

para algún servicio hipotético Hello RMI.


Tengo una pregunta muy breve ...

¿Por qué usa esta ruta: "file: // C: / ProjX / server / serverProj / bin / usermanager" Supongo que está en Windows, y las rutas en las ventanas están escritas en C: / ProjX ...... I pregunto porque también tengo algunos problemas con RMI, pero tengo el archivo de política de esta manera:

grant codebase "file:///C:/Users/anna/Desktop/lab5/Eclipse/ProgramareServer/programare.jar-" { permission java.security.AllPermission; };

¿Está mal?


Simplemente funciona bien cuando arreglé la variable CLASSPATH antes de iniciar el registro de rmi. Creo que la idea es que el Registro de RMI cargue sus stubs remotos y debería tener acceso. Eso fue fácil al poner mis clases en CLASSPATH antes de ejecutar el registro. Por lo tanto, no está relacionado con ninguna otra razón, como JDK 7 o file: / protocol.