Tutorial RMI em Java

20
1 Tutorial RMI by lufer, Carlos Castro , Sandra Melo (v.1.1) Este documento resultou do tratamento e compilação de informação vária sobre JAVA RMI, existente em livros da especialidade, acetatos das aulas, URLs da Web e outras fontes. Esta versão teve a colaboração dos alunos Sandra Melo e Carlos Castro do curso de SIG. Referências: Tutorais: http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp http://www.guj.com.br/java.tutorial.artigo.37.1.guj http://www.genady.net/rmi/v20/docs/installation/configure_jdk.html RMI e Bases de Dados: http://java.sun.com/javase/technologies/core/basic/rmi/whitepaper/index.jsp Livro: Java RMI, O´Reilly, ISBN: 9781565924529 JAVA RMI A tecnologia RMI - Remote Method Invocation (Invocação de Métodos Remotos), surge na expectativa de, por um lado acompanhar a força do desenvolvimento apoiado em arquitecturas RPC (Remote Procedure Call), no mundo da Programação Orientada a Objectos, e por outro, suportando o desenvolvimento distribuído em JAVA, herdando o que de melhor estas tecnologia e paradigma oferecem. O JAVA RMI surgiu logo com a versão Java JDK 1.1, e tem vindo a sofrer pequenas alterações à medida que novos pacotes JAVA são lançados. Embora a portabilidade de soluções desenvolvidas não esteja saudavelmente garantida entre versões JAVA (entenda-se, JVM - Máquinas Virtuais JAVA), a arquitectura RMI assenta num padrão de desenvolvimento que se tem respeitado. Apresentação O principal objectivo do JAVA RMI é possibilitar o desenvolvimento de aplicações distribuídas em JAVA, utilizando a sintaxe e semântica usada nos programas não distribuídos. Pretende-se utilizar métodos de objectos remotos a partir de qualquer JVM, residentes ou não na mesma

description

Tutorial de apoia para aplicações distribuidas RMI em JAVA

Transcript of Tutorial RMI em Java

Page 1: Tutorial RMI em Java

1

Tutorial RMI

by lufer, Carlos Castro , Sandra Melo

(v.1.1)

Este documento resultou do tratamento e compilação de informação vária sobre JAVA RMI,

existente em livros da especialidade, acetatos das aulas, URLs da Web e outras fontes. Esta

versão teve a colaboração dos alunos Sandra Melo e Carlos Castro do curso de SIG.

Referências:

Tutorais:

• http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp

• http://www.guj.com.br/java.tutorial.artigo.37.1.guj

• http://www.genady.net/rmi/v20/docs/installation/configure_jdk.html

RMI e Bases de Dados:

• http://java.sun.com/javase/technologies/core/basic/rmi/whitepaper/index.jsp

Livro:

• Java RMI, O´Reilly, ISBN: 9781565924529

JAVA RMI

A tecnologia RMI - Remote Method Invocation (Invocação de Métodos Remotos), surge na

expectativa de, por um lado acompanhar a força do desenvolvimento apoiado em arquitecturas

RPC (Remote Procedure Call), no mundo da Programação Orientada a Objectos, e por outro,

suportando o desenvolvimento distribuído em JAVA, herdando o que de melhor estas

tecnologia e paradigma oferecem.

O JAVA RMI surgiu logo com a versão Java JDK 1.1, e tem vindo a sofrer pequenas alterações

à medida que novos pacotes JAVA são lançados. Embora a portabilidade de soluções

desenvolvidas não esteja saudavelmente garantida entre versões JAVA (entenda-se, JVM -

Máquinas Virtuais JAVA), a arquitectura RMI assenta num padrão de desenvolvimento que se

tem respeitado.

Apresentação

O principal objectivo do JAVA RMI é possibilitar o desenvolvimento de aplicações distribuídas

em JAVA, utilizando a sintaxe e semântica usada nos programas não distribuídos. Pretende-se

utilizar métodos de objectos remotos a partir de qualquer JVM, residentes ou não na mesma

Page 2: Tutorial RMI em Java

2

máquina. Praticamente todas as “virtudes” da tecnologia JAVA são mantidas, como é o caso do

portabilidade, segurança e polimorfismo. Interagir com sistemas legados (via JNI, JDBC, etc.),

com outros objectos existentes, etc., é uma tarefa suportada. Os arquitectos do RMI tentaram

fazer com que o uso dos objectos distribuídos em Java fosse similar ao uso de objectos Java

locais.

A arquitectura RMI define como os objectos se comportam (através de JAVA Interfaces), como

e quando excepções podem ocorrer, como a memória é gerida e como os parâmetros são

passados e retornados entre métodos remotos.

Arquitectura JAVA RMI

A arquitectura RMI é baseada num importante princípio: a definição do comportamento e a

implementação do comportamento são conceitos separados. O RMI permite que o código que

define o comportamento e o código que implementa o comportamento permaneçam separados

e corram em Máquinas Virtuais separadas separadas.

Em RMI, a definição do serviço remoto é codificada através de uma Interface Java, enquanto a

sua implementação (desse mesmo serviço remoto) é codificada numa classe. Logo, a chave

para se entender o RMI é recordar que as Interfaces definem o comportamento e as classes

definem a implementação.

A classe que implementa o comportamento (i.e, os métodos ou serviços que se pretendem

disponibilizar) executa no lado do servidor RMI. A classe que executa no cliente actua como

um Proxy para o serviço remoto, tal como é representado no seguinte diagrama:

O programa cliente faz chamadas de métodos pelo objecto Proxy, o RMI envia a requisição

para a JVM remota e redirecciona para a implementação. Qualquer valor devolvido (return)

pelo servidor é devolvido ao Proxy e depois ao programa cliente.

Um objecto RMI, ao poder ser evocado remotamente, tem de ser implementado seguindo as

seguintes especificações RMI:

• Extende UnicastRemoteObject

Page 3: Tutorial RMI em Java

3

• Possui métodos públicos distribuídos que lidam com (throw) RemoteException

• Possuem um construtor que lida com RemoteException

• Possuem um interface separado que descreve a assinatura dos métodos remotos e

extende java.rmi.Remote.

Implementação

A implementação do RMI é essencialmente feita em três camadas de abstracção. A primeira

camada contém os Stub e Skeleton (equivalentes aos stubs da especificação RPC - esta

camada intercepta as chamadas de métodos feitas pelo cliente), depois a classe que

implementa a Interface redirecciona essas chamadas para o serviço RMI remoto.

A próxima camada é a Remote Reference Layer. Esta camada sabe como interpretar e gerir as

referências feitas dos clientes para os objectos no serviço remoto. A conexão do cliente ao

servidor é Unicast (uma-para-um).

A camada de transporte é baseada em conexões TCP/IP.

Cada uma das camadas pode ser facilmente melhorada ou substituída sem afectar o resto do

sistema. Por exemplo, a camada de transporte poderia ser substituída por uma camada que

implemente conexões UDP/IP, sem afectar as camadas superiores.

Nome dos Objectos Remotos

Como um cliente “descobre” o serviço remoto RMI?

Os clientes encontram os serviços remotos usando o serviço de nomeação ou directório

(naming or directory). Isto parece um pouco redundante, mas o serviço de nomeação ou

directório funciona como um endereço bem formado (host:port).

O RMI pode usar diferentes tipos de serviços de directório, incluindo o JNDI (Java Naming and

Directory Interface). O próprio RMI inclui um simples serviço, chamado RMI Registry (no JDK

>=4.0 corresponde ao programa rmiregistry) que executa em cada máquina que hospeda o

serviço remoto, por defeito, na porta 1099.

Page 4: Tutorial RMI em Java

4

Numa máquina host, o servidor cria o objecto que implementa um dado serviço remoto

pretendido. Depois regista-o no RMI Registry, com um nome público.

No lado do cliente o RMI Registry é acedido através da classe estática Naming. Ela possui,

entre outros métodos, o método lookup( ), que o cliente usa para procurar o registro. Esse

método aceita a URL que especifica o nome do servidor e o nome do serviço desejado. O

método retorna uma referência remota para o objecto do serviço. A URL tem o seguinte

aspecto:

rmi://<host_name>[:port_number]/<service_name>

“Receita” para programar RMI

Para este tópico vamos utilizar o exemplo Mensageiro (também analisado nas aulas e cujo

código se encontra na página da disciplina), utilizado pelos tutoriais Java na demonstração de

vários processos de desenvolvimento. Para isso não necessitamos obrigatoriamente de duas

máquinas distintas ou com IP distintos. O exemplo pode ser executado na mesma máquina,

pois o RMI sabe como lidar com isso, mesmo que o host e o cliente sejam no mesmo local.

Um sistema RMI é composto de várias partes:

• Definição das interfaces para os serviços remotos

• Implementações dos serviços remotos

• Ficheiros de Stub e Skeletons

• Um servidor para hospedar os serviços remotos

• Um serviço de RMI Naming que permite ao cliente encontrar os serviços remotos

• Um provedor de ficheiros de classes (servidor http ou ftp)

• Um programa cliente que necessita dos serviços remotos

É possível sugerir uma notação capaz de orientar melhor a escrita de código. Assim, no nosso

exemplo, vamos ter:

Nome Exemplo Objectivo

Sem sufixo Mensageiro.java Código do Interface

Sufixo Impl MensageiroImpl.java Implementa os métodos (regras)

Sufixo Server MensageiroServer.java Servidor: cria objectos

Sufixo Client MensageiroClient.java Programa cliente

Page 5: Tutorial RMI em Java

5

Sufixo _stub e

skel

MensageiroImpl_Stub.class

MensageiroImpl_Skel.class

Classes que mapeiam os métodos no

cliente e no servidor

Um exemplo RMI

Vamos criar um sistema teste que implemente o RMI, utilizando um programa cliente e um

programa servidor. Não vai ser utilizado um servidor FTP ou http e os programas estão

alojados na mesma máquina com a mesma estrutura de directórios.

Os passos a serem seguidos agora são:

• Definir a Interface

• Escrever e compilar o código Java da interface

• Escrever e compilar o código Java das implementações das classes

• Gerar as classes Stub e Skeleton das classes de implementação

Antes de se criarem os Stub e Skeleton, a estrutura de ficheiros necessários terá a seguinte

forma embora seja possível, mas não recomendável, juntar num único módulo o Interface e a

sua implementação):

– Servidor

• MensageiroImpl.java (implementação)

• Mensageiro.java (interface)

• StoreServer.java (main)

• Outras classes

– Cliente

• MensageiroClient.java

• Mensageiro.java

Crie agora um directório para guardar todos os ficheiros deste exemplo.

Interface

O primeiro passo, deverá ser então a criação da interface e compilá-la. A interface define todas

as funcionalidades remotas oferecidas pelo serviço. Nomeie o ficheiro como Mensageiro.java.

import java.rmi.Remote;

import java.rmi.RemoteException;

Page 6: Tutorial RMI em Java

6

public interface Mensageiro extends Remote {

public void enviarMensagem( String msg ) throws RemoteException;

public String lerMensagem() throws RemoteException;

}

Anote que esta interface extende a classe Remote, e cada assinatura de método ao declarar as

funcionalidades do serviço, prevê a existência de serem geradas excepções RemoteException.

Guarde este ficheiro no seu directório e compile, com a seguinte linha de comando:

javac Mensageiro.java

Implementação do interface

Agora é necessário implementar cada um dos serviços remotos, ou seja, o código a ser

executado no ambiente remoto. Nomeie o ficheiro como MensageiroImpl.java.

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

public class MensageiroImpl extends UnicastRemoteObject implements Mensageiro {

public MensageiroImpl() throws RemoteException {

super();

}

public void enviarMensagem( String msg ) throws RemoteException {

System.out.println( msg );

}

public String lerMensagem() throws RemoteException {

return "This is not a Hello World! message";

}

}

Guarde este ficheiro no seu directório e compile, com a seguinte linha de comando:

Page 7: Tutorial RMI em Java

7

javac MensageiroImpl.java

Observe que a classe utiliza (extende) a classe UnicastRemoteObject para linkar com o

sistema RMI. Neste exemplo a classe extende a classe UnicastRemoteObject directamente.

Quando uma classe extende a classe UnicastRemoteObject, ela deve disponibilizar um

construtor que declare que ele pode lançar uma excepção RemoteException, pois quando o

método super( ) é chamado, ele activa o código em UnicastRemoteObject, que executa o link

RMI e a iniciação do objecto remoto.

Gerar os Stub e Skeleton

Gere os ficheiros Stub e Skeleton da classe de implementação que corre no servidor. Para isso

execute o comando rmic, compilador RMI do JDK1 (segundo o JRMP – Java Remote Method

Protocol).

rmic MensageiroImpl

Existem contudo outras formas de gerar os stubs, dependendo da versão JAVA a utilizar:

– Com a versão JDK5.0, os stubs passam a ser gerados automaticamente

– Com a versão JDK1.2, os stubs são gerados com:

– rmic –v1.2 MensageiroImpl

– Antes de JDK1.2, stubs e skeletons são criados com

– rmic –v1.1 MensageiroImpl

Após a execução deste comando, você deverá ver no seu directório os ficheiros

Mensageiro_Stub.class, Mensageiro_Skeleton.class. Todas as classes devem ser compiladas

(com javac) antes da utilização do rmic.

Assim, após a geração de stubs, a estrutura típica de ficheiros de uma aplicação RMI ficará:

– Servidor

• MensageiroImpl.java (implementação)

• Mensageiro.java (interface)

• StoreServer.java (main)

1 http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/rmic.html

Page 8: Tutorial RMI em Java

8

• Outras classes

• MensageiroImpl_Stub.class

– Cliente

• MensageiroClient.java

• Mensageiro.java

• MensageiroImpl_Stub.class

Servidor

O serviço remoto RMI deve ser hospedado num processo servidor. A classe MensageiroServer

é um servidor bem simples, que implementa somente os serviços pretendidos. Guarde o

ficheiro como MensageiroServer.java.

import java.rmi.Naming;

public class MensageiroServer {

public MensageiroServer() {

try {

Mensageiro m = new MensageiroImpl();

Naming.rebind("rmi://localhost:1099/MensageiroService", m);

}

catch( Exception e ) {

System.out.println( "Trouble: " + e );

}

}

public static void main(String[] args) {

new MensageiroServer();

}

}

Guarde este ficheiro (MensageiroServer.java) no seu directório e compile, com a seguinte linha

de comando:

javac MensageiroServer.java

Cliente

O código fonte para o cliente é o seguinte. Guarde o ficheiro como MensageiroClient.java.

Page 9: Tutorial RMI em Java

9

import java.rmi.Naming;

import java.rmi.RemoteException;

import java.rmi.NotBoundException;

import java.net.MalformedURLException;

public class MensageiroClient {

public static void main( String args[] ) {

try {

Mensageiro m = (Mensageiro) Naming.lookup( "rmi://localhost/MensageiroService" );

System.out.println( m.lerMensagem() );

m.enviarMensagem( "Hello World!" );

}

catch( MalformedURLException e ) {

System.out.println();

System.out.println( "MalformedURLException: " + e.toString() );

}

catch( RemoteException e ) {

System.out.println();

System.out.println( "RemoteException: " + e.toString() );

}

catch( NotBoundException e ) {

System.out.println();

System.out.println( "NotBoundException: " + e.toString() );

}

catch( Exception e ) {

System.out.println();

System.out.println( "Exception: " + e.toString() );

}

}

}

Nota:

Para que o cliente “descubra” o servidor, é utilizada a instrução

Naming.lookup( "nome_servidor" )

Neste caso é procurado, por omissão, na porta 1099, no localhost. A sintax mais adequada

deverá ser contudo,

Page 10: Tutorial RMI em Java

10

Naming.lookup(“rmi://host:port/name”);

Neste caso é possível indicar o IP da máquina e a porta disponibilizada para tal. No nosso

exemplo poderia então ser, por exemplo:

Naming.lookup( "rmi://127.0.0.1:99/MensageiroService" );

Se pretender conhecer todos os servidores registados no registry, a classe Naming possui o

método list, usado com a seguinte sintax:

String[] bindings = Naming.list(“<url do registry>”);

Guarde este ficheiro (MensageiroClient.java) no seu directório e compile, com a seguinte linha

de comando:

javac MensageiroClient.java

Testar a aplicação RMI

Para testar um exemplo de RMI, talvez o melhor seja utilizar três consolas diferentes do MS-

DOS.

Numa das consolas vai executar o programa servidor, numa outra execute o RMI Registry e na

última execute o Cliente.

Inicie o RMI Registry. Você deve estar no mesmo directório em que estão gravados os

ficheiros. Execute a seguinte linha de comando:

start rmiregistry

Page 11: Tutorial RMI em Java

11

Aparecerá então uma consola DOS na qual está a ser executado o RMI registry.

Na segunda consola vamos executar o programa servidor. Você deve estar no mesmo

directório em que estão gravados os ficheiros para executar o aplicativo. Execute o seguinte

comando:

java MensageiroServer

Este comando inicia o servidor, carrega a sua implementação na memória e espera pela

conexão com o cliente.

Na última consola, execute o programa cliente. Você deve estar no mesmo directório em que

estão gravados os ficheiros. Para isso execute o seguinte comando:

java MensageiroClient

Se tudo correr bem, nas consolas 2 (servidor) e 3 (cliente) deverão ocorrer as seguintes

mensagens.

Na consola 2 (servidor):

“Hellow World!”

Na consola 3 (cliente):

“This is not a Hello World! Message”

Tratamento de segurança

Tratando-se de um sistema que pretende aceder a processos que correm em máquinas

diferentes, é importante considerar questões de permissões de acessos e outras, relacionadas

com segurança.

Este processo, embora não muito simples, foca-se na análise das classes que gerem a

segurança do JAVA, neste caso essencialmente a classe System.setSecurityManager. Para

isto, o código no processo Cliente deverá conter a seguinte instrução

System.setSecurityManager(new RMISecurityManager());

Para que consiga ser executado, as condições de acesso e permissão poderão ser

definidasem ficheiros externos (policy files) e referidos na altura da execução dos processos. O

comando seguinte refere um ficheiro (policy.all) no qual estarão definindo todas as regras de

Page 12: Tutorial RMI em Java

12

segurança pretendidas (convém aprofundar mais este assunto, lendo sobre “Implementação de

segurança em aplicações Java”).

java –Djava.security.policy=policy.all MensageiroClient

Outro exemplo RMI

Interface

public interface myRMIInterface extends java.rmi.Remote { public java.util.Date getDate() throws java.rmi.RemoteException; public int sum(int x, int y) throws java.rmi.RemoteException; }

Classe que implementa o Interface

import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class myRMIImpl extends UnicastRemoteObject implements myRMIInterface { public myRMIImpl(String name) throws RemoteException { super(); try { Naming.rebind(name, this); } catch(Exception e) { System.out.println("Exception occurred: " + e); } } public java.util.Date getDate() { return new java.util.Date(); } public int sum(int x, int y) { return (x+y); } }

Servidor implementado como instância da classe que implementa o interface (myRMIImpl)

import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class myRMIServer

Page 13: Tutorial RMI em Java

13

{ public static void main(String[] argv) { System.setSecurityManager(new RMISecurityManager()); try { myRMIImpl implementation = new myRMIImpl("myRMIImplInstance"); System.out.println("Servidor escuta..."); } catch (Exception e) { System.out.println("Exception occurred: " + e); } } }

Cliente

import java.rmi.*; import java.rmi.registry.*; import java.rmi.server.*; import java.util.Date; public class myRMIClient { public static void main(String[] argv) { System.setSecurityManager(new RMISecurityManager()); if (argv.length != 1) { System.out.println("usage: java myRMIClient <IP address of host running RMI server>"); System.exit(0); } String serverName = argv[0]; try { //bind server object to object in client myRMIInterface myServerObject = (myRMIInterface) Naming.lookup("rmi://"+serverName+"/myRMIImplInstance"); //invoke method on server object Date d = myServerObject.getDate(); System.out.println("Date on server is " + d); int x = myServerObject.sum(2,3); System.out.println("Soma de 2 com 3 = :" + x); } catch(Exception e) { System.out.println("Exception occured: " + e); System.exit(0); } System.out.println("RMI connection successful"); }

Page 14: Tutorial RMI em Java

14

}

Repare-se que neste último caso a classe main() do Servidor está definida, não na classe que

implementa o interface mas sim na classe instância.

Repare-se também que neste exemplo é possível indicar, na altura da execução do cliente, o

IP da máquina onde está a executar o servidor.

Desenvolver aplicações RMI com Eclipse 2

Caso queiras utilizar o IDE Eclipse para escrever o código JAVA, segue um pequeno tutorial de

como instalar o plugin necessário.

Configurar o JDK no Eclipse

a) Antes de tudo é fundamental configurar correctamente o JAVA no IDE Eclipse.

Obviamente que terá de instalar uma das versões do JDK (JDK 1.4.2 ou JDK 1.5.0 ou

mesmo J2SE v1.4.2_12 SDK")3.

b) Supondo que optou pela instalação do JDK5.0, na pasta “C:\Program

Files\Java\jdk1.5.0_09“.

c) Inicie o Eclipse e aceda ao serviço Preferences (Window -> Preferences...) (Figura 1)

2 Capítulo criado com a colaboração do aluno Carlos Castro ( 3º ano de SIG) 3 Não confunda JDK com JRE. Este último refere-se somente à máquina virtual

Page 15: Tutorial RMI em Java

15

Figura 1

d) Aceda à página referente a "Java->Installed JREs". (Figura 2)

Figura 2

Tem de verificar que a localização da a máquina virtual (JRE) deverá corresponder à PATH

onde instalou o JDK.

Page 16: Tutorial RMI em Java

16

e) Se tiver de alterar a localização, por defeito, do JRE, seleccione o registo corrente

(checkbox) e click em “Edit…”. (Figura 3)

Figura 3

f) Escreva o correspondente à versão que instalou ("jdk-1.5.0", por exemplo) no campo

“JRE name” e defina "C:\Program Files\Java\jdk1.5.0_09" a PATH

correspondente ao local onde instalou o JDK, no campo "JRE home directory". Click

em "OK" para terminar.

Nota:

Por vezes a portabilidade JAVA fica comprometida sempre que estejam várias versões JDK ou

mesmo JRE instaladas. Isto pode acontecer, por exemplo, se compilar com uma versão (com

javac) e for executar (com java) com outra versão distinta…para evitar isto, certifique-se que

todas as variáveis de ambiente estão devidamente configuradas: PATH, CLASSPATH e

JAVA_HOME.

Configuração do Plugin

• Download do plugin RMI em http://www.genady.net/rmi/v20/downloads.html

• Colocar o conteúdo da pasta features e plugins dentro das respectivas com o mesmo

nome na directoria do eclipse.

Page 17: Tutorial RMI em Java

17

Utilização

• Criar um novo projecto JAVA como se tratasse de uma aplicação Java normal. Uma

boa prática neste caso é criar Packages para agrupar classes. Sendo assim, criamos

(por exemplo) 3 Packages, Cliente, Servidor e Interface.

• Antes de compilar a aplicação, clicar com o botão direito do rato por cima do nome do

projecto no Package Explorer, escolher RMI e depois Enable Stubs Generation (isto

para activar a geração automática do Stub - "rmic")

• Para compilar e correr a aplicação, basta clicar com o botão direito novamente sobre o

nome do projecto, depois escolher Run As, e finalmente RMI Application. Irá surgir uma

mensagem em que se pede que seja escolhida uma classe main (escolhemos a classe

que contem o servidor). De seguida fazemos um Run novamente mas seleccionamos a

classe Cliente.

• Se for necessário introduzir parâmetros na invocação da classe cliente por exemplo,

quando fazemos Run, surgem vários submenus antes da confirmação final e aí é

possível introduzir alguns dados entre os quais os parâmetros da invocação.

Desenvolver aplicações RMI sem IDE

Trata-se de desenvolver aplicações RMI sem a ajuda de qualquer IDE específico mas somente

através de um editor de texto (situação comum para ambientes linux ou mesmo os menos

adeptos ao Windows).

Neste caso, uma sugestão de organização de ficheiros e criação de scripts é apresentado nos

seguintes tópicos:

Organização de ficheiros:

Uma estrutura indicada pode ser a apresentada na figura seguinte:

onde, na pastas:

• server são colocados o código JAVA do interface, as classes que o implementam e o

código da aplicação servidor.

Page 18: Tutorial RMI em Java

18

no nosso caso:

• client é colocado o código JAVA da aplicação cliente

no nosso caso

• build são colocadas todas as classes resultantes da compilação

no nosso caso

Batch Files:

Para facilitar a compilação poderão ser criadas algumas batch files (ou scripts) tais como se

apresentam a seguir:

build.bat

usada para compilar todo o código

@rem preparar exemplo de RMI @by lufer @rem Set up de variáveis locais setlocal set pwd=E:\Users\work\Ipca\2006-2007\ISI\RMI\Exemplos\Exemplo2 set class_dir=%pwd%\build\classes set int_dir=%pwd%\server set impl_dir=%pwd%\server set client_dir=%pwd%\client @rem criar directorias auxiliares mkdir build mkdir build\classes copy policy.all build\classes @rem compilar tudo javac -classpath %class_dir% -d %class_dir% %int_dir%\*.java javac -classpath %class_dir% -d %class_dir% %impl_dir%\*.java javac -classpath %class_dir% -d %class_dir% %client_dir%\*.java @rem executar rmic para gerar stub e skeleton rmic -classpath %class_dir% -d %class_dir% MensageiroImpl

Page 19: Tutorial RMI em Java

19

endlocal

server.bat

usada para iniciar o rmiregistry e a aplicação servidor

@rem executa o servidor. cd build\classes @rem inicia o rmiregistry start rmiregistry @rem corre o servidor start java -Djava.security.policy=policy.all MensageiroServer cd ..\..

client.bat

usada para iniciar a aplicação cliente

@rem Run the SampleServer client cd build\classes java -Djava.security.policy=policy.all MensageiroClient cd ..\..

Conclusão

Se tudo correu bem, acabou de criar um sistema utilizando a tecnologia RMI. Apesar de ter

executado os programas na mesma máquina, o RMI usa a pilha de rede TCP/IP para

comunicar entre as três diferentes instâncias da JVM.

Resumindo, algumas das vantagens de um sistema RMI.

• Orientado a Objectos: objectos como parâmetros e devolução de tipos complexos

• Comportamento “Móvel”: a classe que implementa o Interface pode ser transferida do

cliente para o servidor e vice-versa4;

• Desenvolvimento via Design Patterns: a arquitectura RMI é respeitada

• Segura e Portável: garantido pelo próprio JAVA

• Fácil de programar e de usar

• Integra-se bem com sistemas legados: via JNI, JDBC, etc.

• Write Once, Run Anywhere: com os devidos cuidados, a portabilidade é garantida

• Garbage Collection distribuída: garantido pelo JAVA

• Admite computação paralela: pois pode recorrer a JAVA threads

4 Mais informação em http://java.sun.com/javase/technologies/core/basic/rmi/whitepaper/index.jsp

Page 20: Tutorial RMI em Java

20

• Para concluir, é fácil de programar e é robusta.

Esta tecnologia compete directamente com a especificação CORBA e com a tecnologia Web

Services.

Quiçá uma das desvantagens, entre outras, seja a dependência exclusiva do JAVA.

Luís Ferreira, Sandra Melo, Carlos Castro

Março, 2007