Você está na página 1de 26

Java - RMI

Edvar Oliveira

UFPA - 2004
Objetivo

 Introduzida no Java, no JDK versão 1.1


 O principal objetivo do RMI é facilitar a
programação distribuída em Java com a
mesma sintaxe e semântica usada em
programas não-distribuídos.
Arquitetura RMI
 A arquitetura RMI é baseada em um
importante princípio: a definição do
comportamento e a implementação do
comportamento
 RMI permite que o código que define o
comportamento e o código que implementa o
comportamento permanecerem separados e
rodarem em JVMs separadas
Arquitetura RMI
 Interface: definição do serviço remoto
 implementação do serviço remoto é
codificada em uma classe

A chave para se entender o RMI é lembrar que as interfaces


definem o comportamento e as classes definem a
implementação.
Arquitetura RMI
 A classe que implementa o comportamento
roda do lado do servidor RMI. A classe que
roda no cliente atua como um Proxy para o
serviço remoto.
Camadas do RMI
 A implementação do RMI é feita em 3
camadas de abstrações
 Stub e Skeletons
 Remote Reference Layer
 Camada de transporte
Stubs e Skeletons
 Esta camada intercepta as chamadas
de métodos feitas pelo cliente para que
a variável de referência da interface
redirecione essas chamadas para o
serviço RMI remoto
Remote Reference Layer
 Esta camada interpreta e gerencia as
referências feitas dos clientes para os
objetos do serviço remoto.
 A conexão do cliente ao servidor é
Unicast (uma-para-um).
Camada de transporte
 é baseada nas conexões TCP/IP
Aplicação
 Nomeando Objetos Remotos: Os clientes acham os
serviços remotos usando o serviço de nomeação ou
diretório (naming or directory)
 O RMI pode usar diferentes tipos de serviços de
diretório
 RMI Registry, roda na porta 1099
 Um programa servidor cria um serviço remoto,
primeiramente criando o objeto que implemente aquele
serviço. Em seguida ele exporta aquele objeto para o
RMI. Quando o objeto é exportado o RMI cria um
serviço que aguarda as conexões do cliente. O
servidor registra o objeto no RMI Registry, com um
nome público.
Aplicação
 Cliente: o RMI Registry é acessado através
da classe estática Naming. Ela provém o
método lookup( ), que o cliente usa para
requisitar 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 objeto do serviço.
Aplicação
 Formatação da URL
rmi://<host_name>[:port_number]/<service_name>
Desenvolvendo a nossa
primeira aplicação
 Um sistema RMI é composto de várias
partes:
 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
Desenvolvendo a nossa
primeira aplicação
 Passos para criar um programa 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
 A Criação da interface

// Mensagem.java
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Mensagem extends Remote {

String exibeMensagem() throws RemoteException;

int[] bubble(int vet[], int tamanho) throws RemoteException;


}
 A interface estende a classe Remote
 Cada assinatura de método declara as
funcionalidades do serviço, e que podem
gerar uma exceção RemoteException.
 Compilar o arquivo:

javac Mensagem.java

 Desenvolver a Implementação para o


serviço remoto
// MensagemImpl.java
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
public class MensagemImpl extends UnicastRemoteObject implements Mensagem{

public MensagemImpl() throws RemoteException {


super();
}
public String exibeMensagem() {
return "Teste de RMI";
}

public static String mostraVetor(int vetor[]) {


int tamanho=vetor.length;
String output = "";
for (int j = 0; j < tamanho; j++) {
output += vetor[j] + " ; ";
}
return output;
}
public int[] bubble(int vet[], int tamanho) {
double bubbleSortInicio;
double bubbleSortFim;
int aux, i,j;
bubbleSortInicio = System.currentTimeMillis();
System.out.println("Chegou Aqui.");
for (i = 0; i <= tamanho - 2; i++) {
for (j = 0; j <= tamanho - 2 - i; j++) {
if (vet[j] > vet[j + 1]) {
aux = vet[j];
vet[j] = vet[j + 1];
vet[j + 1] = aux;
}
}
}
System.out.println(mostraVetor(vet)+ "\n");
bubbleSortFim = System.currentTimeMillis();
System.out.println("Bubble Sort:" + (bubbleSortFim - bubbleSortInicio) / 1000);
return vet;
}
public static void main(String args[]) {
/*Criacao do security manager*/
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}

try {
MensagemImpl obj = new MensagemImpl();
/*nomeia a instancia do objeto como MensagemServer*/
Naming.rebind("MensagemServer", obj);

System.out.println("Mensagem Server rodando.");


} catch (Exception e) {
System.out.println("Erro: " + e.getMessage());
e.printStackTrace();
}
}
}
 Compilar o arquivo:
javac MensagemImpl.java

 A classe estende da classe


UnicastRemoteObject para linkar com o
sistema RMI
 Gere os arquivos skeleton e stubs
rmic MensagemImpl
 Observe se foram criados os stubs e
skeletons na mesma pasta.
Cliente
import javax.swing.JOptionPane;
import java.util.*;
import java.rmi.Naming;
import java.rmi.RemoteException;
public class MensagemCliente extends javax.swing.JFrame {

/** Variáveis Globais */


String mensagem = "sem resposta";
int vetor2[], vetor[];

/** Creates new form MensagemCliente */


public MensagemCliente() {
initComponents();
}
private void BrmiActionPerformed(java.awt.event.ActionEvent evt) {
Mensagem obj = null;
String saida = "Vetor Ordenado \n";
double LbubbleSortInicio;
double LbubbleSortFim;

try {
// obj = (Mensagem)Naming.lookup("//" + getCodeBase().getHost() +
"/MensagemServer");
obj = (Mensagem)Naming.lookup("//10.57.1.192/MensagemServer");
// pego o inicio e o fim da transferencia do vetor ordenado
LbubbleSortInicio = System.currentTimeMillis();
vetor2 = obj.bubble(vetor, vetor.length);
LbubbleSortFim= System.currentTimeMillis();
mensagem = obj.exibeMensagem();
for (int i = 0; i < vetor2.length; i++) {
saida+= vetor2[i] + " ";
}
saida+= "\n Tempo de envio + ordenação + reposta do servidor =" +
(LbubbleSortFim-LbubbleSortInicio)/1000;
Tvetor.setText(saida);
} catch (Exception e) { System.out.println("Erro: " + e.getMessage());
}}
 Compilar o arquivo:
javac MensagemCliente.java

 Criar o arquivo de segurança policy


grant{
permission java.security.AllPermission;
};
 Inicializar o rmiregistry
rmiregistry
Dicas de compilação
 Obs: setar no classpath o caminho do
pasta com os fontes do rmi
 java -
Djava.rmi.server.codebase=file:///diretó
rio/dos/fontes/ -
Djava.security.policy=file:///diretório/do
/policy/policy
rmi.exemplo.MensagemImpl