Java: sin administrador de seguridad: cargador de clases RMI desactivado [duplicado]


Esta pregunta ya tiene una respuesta aquí:

Hola tengo la aplicación RMI y ahora intento invocar algunos métodos en el servidor desde mi cliente. Tengo el siguiente código:

public static void main(final String[] args) {
    try {
        //Setting the security manager

        System.setSecurityManager(new RMISecurityManager());
        IndicatorsService server = (IndicatorsService) Naming
                .lookup("rmi://localhost/" + IndicatorsService.SERVICE_NAME);
        DataProvider provider = new OHLCProvider(server);
        server.registerOHLCProvider(provider);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (NotBoundException e) {
        e.printStackTrace();
    }
}

El servidor está cargado correctamente, pero cuando estoy tratando de llamar server.registerOHLCProvider(provider); Recibo estos errores:

     java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:336)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
    at sk.fri.statistics.service.impl.IndicatorsServiceImpl_Stub.registerOHLCProvider(Unknown Source)
    at sk.fri.statistics.service.Client.main(Client.java:61)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:296)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
    at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
    at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
    at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:290)
    ... 9 more

He agregado mi archivo de política como argumento VM, así es como se ve:

grant {
    permission java.security.AllPermission;
}

Sigue diciendo algo sobre la carga de clases deshabilitada, así que supongo que el problema está en algún lugar ... ¡Gracias!

Author: Mark, 2011-06-12

4 answers

La carga remota de clases puede ser complicada.

El post original no incluye ninguna información sobre el código base. Puede ser que la configuración de seguridad del cliente sea correcta, pero no tiene acceso al código remoto. Las clases son cargadas directamente desde el "código base" por el cliente. No son presentados al cliente por el servicio a través de la conexión RMI. El servicio simplemente hace referencia a una fuente externa para las clases.

El servidor debe especificar la propiedad del sistema java.rmi.server.codebase. El valor debe ser una URL que sea accesible para el cliente, desde la que se puedan cargar las clases necesarias. Si se trata de una URL file:, el sistema de archivos debe ser accesible para el cliente.

Y al revés: Si el servidor debe poder cargar clases desde el cliente (como aquí), el cliente debe establecer la propiedad code base en una URL que sea accesible para el servidor.

 23
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-14 19:58:33

Cada vez que invoca un método en un proxy dinámico RMI,MarshalInputStream ( que se extiende ObjectInputStream para anular resolveClass y resolveProxyClass) delegados a LoaderHandler buscar en 3 lugares el ClassLoader a utilizar:

  1. El cargador de clases del proxy que se está invocando (técnicamente, utiliza un hack llamado latestUserDefinedLoader(): camina por la pila, buscando el primer método en la pila que no es parte de JRE).
  2. Hilo-local contextClassLoader del llamante
  3. Base de código ClassLoader si SecurityManager está habilitado
    1. Si la propiedad del sistema java.rmi.server.useCodebaseOnly=false, entonces el codebase ClassLoader usa URLs en el control remoto java.rmi.server.codebase. Tenga en cuenta que el valor predeterminado de useCodebaseOnly cambiado en JDK 7u21 por lo que la base de código remota ya no se utiliza a menos que lo cambie!
    2. De lo contrario, el codebase ClassLoader usa URLs en el local java.rmi.server.codebase.

Así que hay algunas razones posibles por las que obtendrías un {[11]]} al invocar un método remoto:

  • Si stack contiene "no security manager: RMI class loader disabled", asegúrese de establecer un SecurityManager como lo describen otros si necesita cargar clases remotas para ambos lados para obtener todas las interfaces remotas y clases serializables.
  • Si está utilizando la carga remota de clases y dejó de funcionar cuando actualizó a JRE 7u21, establezca -Djava.rmi.server.useCodebaseOnly=true para que coincida con el comportamiento anterior, o establezca -Djava.rmi.server.codebase en una lista de direcciones URL separadas por espacios en tanto el lado local como el remoto. Y asegúrese de que la computadora pueda acceder a esas URL.
  • Si está utilizando un ClassLoader personalizado localmente cuyo classloader padre define algunas interfaces remotas, asegúrese de llamar a Thread.setContextClassLoader(ClassLoader) para que RMI use ese ClassLoader. (Este era mi problema: tenía un SwingWorker que estaba programado en un hilo de trabajo que se creó antes de que el contextClassLoader se configurara en el EventDispatchThread). Por ejemplo, A y C pertenecen a su costumbre ClassLoader pero B pertenece al padre ClassLoader, entonces cuando se llama a. getB ().getC (), la llamada getB() utilizará el classloader personalizado, pero la llamada getC () no podrá encontrar C en el ultistUserDefinedClassLoader y tendrá que recurrir al contextClassLoader.

Todo esto es una advertencia sobre el pobre diseño de API de ObjectInputStream. ObjectInputStream debería haber requerido que pasaras un parámetro de ClassLoader, no intentar encontrar uno al azar usando latestUserDefinedLoader, contextClassLoader y codebase.

 7
Author: yonran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-29 18:29:12

Necesita el administrador de seguridad en el lado del servidor, no solo en el lado del cliente.

Sin esto, el motor RMI del servidor se niega a cargar clases desde el cliente, ya que no puede garantizar que estas no hagan cosas malas en el servidor.

¿Necesita cargar la clase RMI? ¿No podría el servidor ya tener las clases que el cliente intenta enviar?

 4
Author: Paŭlo Ebermann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-14 18:18:53

Sé por qué sucede. por ejemplo, se inicia el servidor en el proyecto A, pero se utiliza el Cliente en el proyecto B para solicitar este servidor, esto está mal. Por lo tanto, debe poner el servidor y el cliente en el mismo proyecto.

 -3
Author: user3556213,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-21 11:09:58