T. D. S. I. PARA WEB
Prof. Emmanuel Nolêto
Java RMI
Objetivos
• Permitir que um método de uma classe
Java em execução em uma máquina
virtual JVM chame um método de um
objeto (instância de uma classe Java)
situado em outra máquina virtual JVM,
usando a mesma sintaxe e com a mesma
facilidade de se chamar um método local.
• Transparência de acesso e de localização.
Esquema geral
JVM servidor
objeto da
classe S
JVM cliente
método f
da classe C
em execução
método g
chamada
remota
Remote Method
Invocation
• Facility to call methods remotely
• Similar to RPC - Remote Procedure Call
• High-level communication abstraction
• The RMI mechanism provides:
• control transfer between caller and called
• parameters cans be exchanged
• class definitions can be exchanged
• RMI support in Java provides:
• A specific API
• compilation support tools
• runtime support
General scenario
naming service
Registry
object
reference is
published
1
get an object
reference
2
perceived
Server
Skeleton
Client
actual
3
communication
Stub
Componentes em
execução
cliente
servidor
f de C
g de S
cria
chamda remota de g
main
S_Stub
S_Skel
bind
lookup
Socket
Cliente
Socket
Servidor
Socket
Cliente
Socket
Servidor
Naming
Naming
Registry
Hierarquia de classes e
interfaces
Interface Remote
Classe UnicastRemoteObject
extends
extends
Interface R
assinatura de g
Classe S
implementação de g
implements
Compilação
S.java
C.java
javac
javac
S.class
C.class
rmic
S_Skel.class
S_Stub.class
Exemplo de RMI
•
•
•
•
•
Definição das interfaces para os serviços remotos
Implementações dos serviços remotos
Arquivos de Stub e Skeletons
Um servidor para hospedar os serviços remotos
Um serviço de RMI Naming que permite o cliente
achar os serviços remotos
• Um provedor de arquivos de classes (servidor http
ou ftp)
• Um programa cliente que necessita os serviços
remotos
Aplicativo com RMI
• 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, criar um
diretório para salvar todos os seus
arquivos de projeto.
Interfaces
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Mensageiro extends Remote {
public void enviarMensagem( String msg ) throws
RemoteException;
public String lerMensagem() throws RemoteException;
}
Interfaces
• O primeiro passo, como dito, será criar a
interface e compilá-la. A interface define
todas as funcionalidades remotas
oferecidas pelo serviço. Nomeio o arquivo
como: Mensageiro.java.
Interfaces
• Perceba que esta interface estende a
classe Remote, e cada assinatura de
método declara as funcionalidades do
serviço, e que podem gerar uma exceção
RemoteException. Salve este arquivo
(Mensageiro.java) no seu diretório e
compile, com a seguinte linha de
comando:
– javac Mensageiro.java
Implementação
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";
}
}
Implementação
• Agora, você deverá escrever a
implementação para o serviço remoto, ou
seja, o código a ser executado no
ambiente remoto. Nomeia o arquivo como:
MensageiroImpl.java.
• Salve este arquivo (MensageiroImpl.java)
no seu diretório e compile, com a seguinte
linha de comando:
– javac MensageiroImpl.java
Implementação
• Observe que a classe se utiliza (estende) da classe
UnicastRemoteObject para linkar com o sistema RMI. Neste
exemplo a classe estende a classe UnicastRemoteObject
diretamente. Isto não é realmente necessário, mas essa discusão
fica para uma próxima etapa. Quando uma classe estende a classe
UnicastRemoteObject, ele deve prover um construtor que declare
que ele pode lançar uma exceção RemoteException, pois quando o
método super( ) é chamado, ele ativa o código em
UnicastRemoteObject, que executa o link RMI e a iniciação do
objeto remoto.
• Stubs e Skeletons
• Gere os arquivos Stubs e Skeletons da classe de implementação
que roda no servidor. Para tanto, execute o comando rmic,
compilador RMI do JDK.
– rmic MensageiroImpl
Implementação
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();
}
}
Implementação
• Salve este arquivo
(MensageiroServer.java) no seu diretório e
compile, com a seguinte linha de
comando: > javac MensageiroServer.java
• Cliente
– O código fonte para o cliente é o seguinte.
Salve o arquivo como: MensageiroClient.java.
Implementação
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();
Implementação
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() );
}
}
}
Implementação
• Salve este arquivo
(MensageiroClient.java) no seu diretório e
compile, com a seguinte linha de
comando:
– javac MensageiroClient.java
Rodando o sistema
RMI
• Agora que todos os arquivos do projeto de exemplo
foram criados e devidamente compilados, estamos
prontos para rodar o sistema! Você precisará abrir três
diferentes consoles do MS-DOS no seu Windows, ou
outro, caso utilize um diferente sistema operacional.
• Em um dos consoles vai rodar o programa servidor, no
outro o cliente e no terceiro o RMI Registry. Inicie com o
RMI Registry. Você deve estar no mesmo diretório em
que estão gravados seus arquivos para rodar o
aplicativo. Execute a seguinte linha de comando:
– rmiregistry
Rodando o sistema
RMI
• Isso irá iniciar o RMI Registry e rodá-lo.
No segundo console vamos executar o
programa servidor. Você deve estar no
mesmo diretório em que estão gravados
seus arquivos para rodar o aplicativo.
Execute o seguinte comando:
– java MensageiroServer
Rodando o sistema
RMI
• Isso irá iniciar, carregar a implementação
na memória e esperar pela conexão
cliente. No último console, rode o
programa cliente. Você deve estar no
mesmo diretório em que estão gravados
seus arquivos para rodar o aplicativo.
Excute o comando:
– java MensageiroClient
Rodando o sistema
RMI
• Se tudo correr bem, que é o que
esperamos e o que deveria acontecer, a
seguinte saída será gerada nos consoles
2 (servidor) e 3 (cliente). No console 2
(servidor):
– Hellow World!
• No console 3 (cliente):
– This is not a Hello World! message
Rodando sistema RMI
• É isso aí. Você acabou de criar um
sistema utilizando a tecnologia RMI.
Apesar de você ter rodado os programas
na mesma máquina, o RMI usa a pilha de
rede TCP/IP para se comunicar entre as
três diferentes instâncias da JVM. Espero
que tenham gostado e aprendido com
esse pequeno exemplo de como se usar o
RMI.
Download

Remote - ebaixar - Emmanuel Nolêto