Ejecutar los Programas de Ejemplo

Una Nota sobre la Seguridad

El modelo de seguridad del JDK 1.2 es más sofisticado que el modelo utilizado en el JDK 1.1. Contiene ampliaciones para seguridad de grano fino y requiere código que permita los permisos específicos para realizar ciertas operaciones.

En el JDK 1.1, todo el código que haya en el path de clases se considera firmado y puede realizar cualquier operación, el código descargado está gobernado por las reglas del controlador de seguridad instalado. Si ejecutamos este ejemplo en el JDK 1.2 necesitaremos especificar un fichero de policía cuando ejecutemos el servidor y el cliente. Aquí tenemos un fichero de policía general que permite al código descargado desde cualquier codebase, hacer dos cosas:

grant {
    permission java.net.SocketPermission "*:1024-65535", 		
        "connect,accept";
    permission java.net.SocketPermission "*:80", "connect";
};
Si hacemos nuestro código disponible mediante URLs HTTP, deberíamos ejecutar el fichero de policía anterior cuando ejecutemos este ejemplo. Sin embargo, si utilizarámos un fichero de URLs en su lugar, podemos utilizar el fichero de policía siguiente. Observa que en entornos windows, la barra invertida necesita ser representada con dos barras invertidas en el fichero de policía:
grant {
    permission java.net.SocketPermission "*:1024-65535", 		
        "connect,accept";
    permission java.io.FilePermission 
        "c:\\home\\ana\\public_html\\classes\\-", "read";
    permission java.io.FilePermission 
        "c:\\home\\jones\\public_html\\classes\\-", "read";
};
Este ejemplo asume que el fichero de policía se llama java.policy y contiene los permisos apropiados. Si ejecutamos este ejemplo en el JDK 1.1, no necesitamos un fichero de policía ya que el RMISecurityManager proporciona toda la protección que necesitamos.

Arrancar el Servidor

Antes de arrancar el motor de cálculo, necesitamos arrancar el registro de RMI con el comando rmiregistry. Como explicamos en páginas anteriores el registro RMI es una facilidad de nombrado que permite a los clientes obtener una referencia a un objeto remoto.

Observa que antes de arrancar el rmiregistry, debemos asegurarnos de que el shell o ventana en la que ejecutaremos rmiregistry no tiene la variable de entorno CLASSPATH, o si la tiene ésta no incluye el path a ninguna clase, incluyendo los stubs de nuestras clases de implementación de los objetos remotos, que querramos descargar a los clientes de nuestros objetos remotos.

Si arrancamos el rmiregistry y éste puede encontrar nuestras clases stub en el CLASSPATH, no recordará que las clases stub cargadas pueden ser cargadas desde el codebase de nuestro servidor (que fue especificado por la propiedad java.rmi.server.codebase cuando se arrancó la aplicación servidor). Como resultado, el rmiregistry no enviará a los clientes un codebase asociado con las clases stub, y consecuentemente, nuestros clientes no podrán localizar y cargar las clases stub (u otras clases del lado del servidor).

Para arrancar el registro en el servidor, se ejecuta el comando rmiregistry. Este comando no produce ninguna salida y normalmente se ejecuta en segundo plano.


Detalles Específicos de la Plataforma: Arrancar el Registro en el Puerto por Defecto

Windows (utilizar javaw si no está disponible start):

unset CLASSPATH
start rmiregistry

UNIX:

unsetenv CLASSPATH
rmiregistry &

Por defecto el registro se ejecuta sobre el puerto 1099. Para arrancar el registro sobre un puerto diferente, se especifica el número de puerto en la línea de comandos. No olvidemos borrar el CLASSPATH.


Detalles Específicos de la Plataforma: Arrancar el Registro en el Puerto 2001

Windows:

start rmiregistry 2001

UNIX:

rmiregistry 2001 &

Una vez arrancado el registro, podemos arrancar el servidor. Primero, necesitamos asegurarnos de que el fichero compute.jar y la implementación del objeto remoto (que es lo que vamos a arrancar) están en nuestro path de clases.


Detalles Específicos de la Plataforma - Seleccionar la variable CLASSPATH

Windows:

set CLASSPATH=c:\home\ana\src;c:\home\ana\public_html\classes\compute.jar

Unix:

setenv CLASSPATH /home/ana/src:/home/ana/public_html/classes/compute.jar

Cuando arrancamos el motor de cálculo, necesitamos especificar, utilizando la propiedad java.rmi.server.codebase, donde están disponibles las clases del servidor. En este ejemplo, las clases del lado del servidor disponibles son el stub de ComputeEngine y los interfaces Compute y Task disponibles en el directorio public_html\classes de ana.


Detalles Específicos de la Plataforma: Arrancar el Motor de Cálculo

Windows:

java -Djava.rmi.server.codebase=file:/c:\home\ana\public_html\classes/
     -Djava.rmi.server.hostname=zaphod.east.sun.com
     -Djava.security.policy=java.policy
         engine.ComputeEngine

UNIX:

java -Djava.rmi.server.codebase=http://zaphod/~ana/classes/
     -Djava.rmi.server.hostname=zaphod.east.sun.com
     -Djava.security.policy=java.policy
         engine.ComputeEngine

El comando java anterior define varias propiedades:

La clase stub de ComputeEngine se carga dinámicamente en la máquina virtual del cliente sólo cuando la clase no está disponible localmente y la propiedad java.rmi.server.codebase ha sido configurada apropiadamente, para la localización de la clase stub, cuando se arrancó el servidor. Una vez cargada la clase stub no necesitamos recargarla más veces para referencias adicionales a objetos ComputeEngine.

Arrancar el Cliente

Una vez que el registro y el motor se están ejecutando, podemos arrancar el cliente, especificando:

Primero seleccionamos el CLASSPATH para ver el cliente de jones y el fichero JAR que contiene los interfaces. Luego se arranca el cliente de esta forma:


Detalles Específicos de la Plataforma: Arrancar el Cliente

Windows:

set CLASSPATH c:\home\jones\src;c:\home\jones\public_html\classes\compute.jar
java -Djava.rmi.server.codebase=file:/c:\home\jones\public_html\classes/
     -Djava.security.policy=java.policy
        client.ComputePi localhost 20

UNIX:

setenv CLASSAPTH /home/jones/src:/home/jones/public_html/classes/compute.jar
java -Djava.rmi.server.codebase=http://ford/~jones/classes/
     -Djava.security.policy=java.policy 
        client.ComputePi zaphod.east.sun.com 20

Después de arrancar el cliente, deberíamos ver la siguiente salida en nuesta pantalla:

3.14159265358979323846
La siguiente figura muestra de dónde obtienen las clases el rmiregistry, el servidor ComputeEngine y el cliente ComputePi durante la ejecución del programa:

Cuando el servidor ComputeEngine coloca su referencia al objeto remoto en el registro, éste descarga el ComputeEngine_Stub, y también los interfaces Compute y Task de los que la clase stub depende. Estas clases son descargadas del servidor web del ComputeEngine (o del sistema de ficheros, dado el caso).

El cliente ComputePi también carga ComputeEngine_Stub, desde el servidor web de ComputeEngine, como resultado de la llamada a Naming.lookup. Como el cliente tiene los dos intefaces disponibles en su path de clases, estas clases son cargadas desde allí, no de la localización remota.

Finalmente, la clase Pi se carga en la máquina virtual de ComputeEngine cuado el objeto Pi es pasado en la llamada al método remoto executeTask del objeto ComputeEngine. La clase Pi se carga desde la página web del cliente.


Ozito