Carga dinámica de clases

De ChuWiki
Saltar a: navegación, buscar

Carga dinámica de clases

En rmi puede ser que los métodos de un objeto remoto admitan como parámetros a otras clases y devuelvan clases. Por ejemplo, puede ser un método así

public InterfaceResultado dameResultado (InterfaceParametro parametro) throws java.rmi.RemoteException
{
   ...
}

Para que esto funcione, tanto InterfaceParametro como InterfaceResultado deben, al menos, heredar de Serializable.

Si no hemos instalado ningún RMISecurityManager, tanto el servidor como el cliente deben tener sus propias copias de las clases que implementen estas interfaces. Es decir, si ClaseResultado implementa InterfaceResultado y ClaseParametro implementa InterfaceParametro, tanto el cliente como el servidor deben tener en su CLASSPATH los ficheros ClaseResultado.class y ClaseParametro.class.

Si instalamos un RMISecurityManager, se habilita la carga dinámica de clases. De esta forma el servidor no necesita tener una copia de ClaseParametro.class ni el cliente una copia de ClaseResultado.class. Es más, el cliente ni siquiera necesita tener el ObjetoRemoto_Stub.class del que hablabamos en Conceptos básicos de rmi.

Instalando el RMISecurityManager, debemos poner también un fichero java.policy que restrinja los permisos de estas clases.

Para que la carga dinámica de clases funcione, además debe definirse la propiedad java.rmi.server.codebase. Esta propiedad en el cliente es un String con formato URL de dónde está su ClaseParametro o cualquier otra clase que quiera enviar al servidor y este no tenga ya en su CLASSPATH local, de forma que el servidor pueda encontrarla y descargarla. La misma propiedad en el servidor debe ser un String con formato URL indicando dónde están las clases del servidor ClaseResultado y ObjetoRemoto_Stub

La carga dinámica de clases es útil para ampliar la funcionalidad de un servidor desde un cliente sin necesidad de recompilar y arrancar el servidor, ya que ponemos nuevas clases a su disposición. También es útil para actualizar los clientes en tiempo de ejecución, ya que pueden obtener nuevas clases que tenga el servidor. Por ejemplo, un cliente rmi puede pedirle al servidor la ventana que debe mostrar. Si en un momento decidimos cambiar la ventana, bastará con decirle al servidor que devuelve un nuevo tipo de ventana. Los clientes se actualizarán sobre la marcha, según se vayan arrancando.

Un problema de seguridad

Al cargar clases dinámicamente, debemos protegernos de código malicios. Por ejemplo, un cliente puede hacerse su propia versión de ClaseParametroMala con código malicioso y enviarla al servidor como parámetro de ese método remoto.

Una forma segura de que se ejecute este código malicioso es redefinir en ClaseParametroMala el método readObject(), que es el que se ejecuta en el momento de reconstruir la clase en el servidor.

El fichero java.policy que mencionamos anteriormente nos ayuda a restringir estos accesos. En él podemos configurar los permisos de acceso a disco, sockets, etc para cada clase.


Enlaces