Sistemas
Distribuídos
Marcelo Lobosco
DCC/UFJF
Comunicação em
Sistemas Distribuídos
Aula 06
Agenda

Modelo Cliente-Servidor (cont.)
 Invocação
Remota de Método (Remote
Method Invocation – RMI)
Visão Geral
 Criando aplicações distribuídas com RMI
 Escrevendo código do servidor
 Escrevendo código do cliente
 Compilando e executando o exemplo

Visão Geral

RMI provê suporte para comunicação
remota entre programas escritos na
linguagem de programação Java
 Java
RMI permite que um objeto executando
em uma Máquina Virtual Java (MVJ) invoque
métodos de um objeto executando em uma
segunda MVJ

Aplicações RMI geralmente consistem de
dois programas separados
 Cliente
e servidor
Visão Geral



Típico programa servidor cria algum(ns) objeto(s)
remoto(s), torna a(s) referência(s) a este(s)
objeto(s) acessível(ies) e aguarda o(s) cliente(s)
invocarem métodos neste(s) objeto(s)
Típico programa cliente obtêm uma referência
remota para um ou mais objetos remotos em um
servidor e então invoca métodos neste(s)
RMI provê o mecanismo pelo qual clientes e
servidores se comunicam e passa informações
de um lado para o outro
Visão Geral
 Tais
aplicações algumas vezes chamadas
sistemas de objetos distribuídos (OD).
 Ações necessárias em um sistema de OD:
 Localizar
os objetos remotos
 Comunicar com objetos remotos
 Ler definições de classes para objetos que são
passados como parâmetro / retorno
Visão Geral
Localizar
objetos remotos
 Vários
mecanismos podem ser utilizados para
obter referência de objetos remotos
Aplicação pode registrar seus objetos remotos em
um serviço especial de registro de nomes, RMI
registry
 Referências remotas podem ser passadas /
retornadas como parte de invocações remotas

Comunicar
com objetos remotos
 Detalhes
da comunicação com objetos
remotos são tratados por RMI

Para programador, comunicação remota similar a
invocação tradicional de métodos
Visão Geral

Ler definições de classes para objetos que
são passados como parâmetro / retorno
 RMI
permite que objetos sejam passados
como parâmetro / retorno
 RMI provê mecanismos para ler definição da
classe de um objeto

Java é uma linguagem dinâmica
 RMI
provê mecanismos para transmitir estado
de um objeto
Visão Geral
Visão Geral

Figura ilustra aplicação RMI distribuída que
usa registro para obter referência para
objeto remoto
 Servidor
chama registro para associar (ou ligar
– bind) um nome a um objeto remoto
 Cliente procura por objeto remoto pelo seu
nome no registro do servidor e então invoca
um método neste objeto
 Webserver pode ser usado por sistema RMI
para ler definição de classes para objetos
necessários

Tanto do lado do cliente quanto do servidor
Visão Geral

Interfaces, objetos e métodos remotos
 Como
qualquer aplicação Java, aplicação
distribuída composta de classes e interfaces
Interfaces declaram métodos
 Classes implementam métodos declarados na
interface, podendo declarar métodos adicionais

 Em
uma aplicação distribuída, implementações
podem residir em máquinas virtuais distintas
 Objetos com métodos que podem ser
invocados por diferentes MVJ são chamados
de objetos remotos
Visão Geral

Objeto torna-se remoto quando implementa
um interface remota, que possui as
seguintes características:
 Uma
interface remota estende a interface
java.rmi.Remote
 Cada método da interface declara
java.rmi.RemoteException em sua cláusula
throws, em adição a qualquer exceção
específica da aplicação
Visão Geral

RMI trata objetos remotos de forma distinta dos
objetos locais quando o objeto é passado de uma
MVJ para outra
 Ao
invés de copiar na MVJ o objeto de
implementação invocado, RMI passa um stub
remoto para um objeto remoto



Stub age como representante local (proxy) do objeto
remoto
Basicamente stub é, para o cliente, a referência remota
Cliente invoca método no stub local, que é responsável
por repassar a chamada para o objeto remoto
Visão Geral

Stub para um objeto remoto implementa o
mesmo conjunto de interfaces remotas que
o objeto remoto implementa
 Somente
métodos definidos na interface
remota podem ser chamadas pela MVJ onde
clientes executam
cliente
Máquina do cliente
stub
servid
or
Máquina do servidor
Criando Aplicações Distribuídas
com RMI

Passos gerais para desenvolver aplicação
distribuída com RMI:
 Projetar
e implementar os componentes de sua
aplicação distribuída
 Compilar os fontes
 Tornar as classes acessíveis via rede
 Iniciar a aplicação
Criando Aplicações Distribuídas
com RMI

Projetar e implementar os componentes de
sua aplicação distribuída
 Inicialmente,
determine a arquitetura de sua
aplicação, definindo componentes locais e
componentes acessíveis remotamente:

Defina as interfaces remotas: especifica métodos
que podem ser invocados remotamente por um
cliente


Defina tipos dos parâmetros e retorno dos métodos
Implemente os objetos remotos: objetos remotos
devem implementar uma ou mais interfaces

Podem incluir implementações de interfaces e métodos
disponíveis apenas localmente
Criando Aplicações Distribuídas
com RMI

Projetar e implementar os componentes de sua
aplicação distribuída (cont)


Implemente o(s) clientes
Compile os fontes
qualquer programa java, use javac para
compilar os programas fonte
 Como


Declarações de interfaces remotas, suas
implementações, outras classes de serviço, clientes
Versões anteriores a JSE 5.0 necessitam do rmic
Criando Aplicações Distribuídas
com RMI

Tornar as classes acessíveis via rede
 Neste
passo, torne certas definições de
classes acessíveis via rede
Como definições para interfaces remotas e seus
tipos associados, e definições de classes que
precisam ser acessadas por clientes e servidores
 Geralmente tornam-se acessíveis através de um
servidor web


Iniciar a aplicação
 Inclui,
além do cliente e do servidor, o serviço
de registro de nomes, rmiregistry
Criando Aplicações Distribuídas
com RMI

Passagem de parâmetros
 Qualquer
tipo primitivo, objeto remoto ou
objeto local, pode ser passado como
parâmetro em chamadas RMI
No caso de objeto local, além de acessível via
rede, deve ser também serializável
 Para objeto ser considerado “serializável”, sua
classe deve implementar a interface
java.io.Serializable

Exemplo de Aplicação:
Calculadora Distribuída

Servidor oferece serviços de uma calculadora
 Funcionalidade
simples: soma, subtração,
multiplicação e divisão com dois inteiros

Cliente faz uso dos serviços
 Faz
invocação, passando parâmetros e
imprimindo resultado

Objetivo: ilustrar o funcionamento de RMI
 Naturalmente
aplicação real

que overhead proibitivo para
Serviço muito simples
Calculadora Distribuída:
Interface

Primeiro passo: projetar interface remota
 Que
serviços serão oferecidos?
 Quais os parâmetros necessários?
 Quais os tipos dos valores retornados?
 Quais exceções podem ocorrer?
Calculadora Distribuída:
Interface
package exemplo;
import java.rmi.Remote;
import java.rmi.RemoteException;
import exemplo.divisaoPorZero;
public interface Calculadora extends Remote {
float som (float a, float b) throws
java.rmi.RemoteException;
float sub (float a, float b) throws
java.rmi.RemoteException;
float mul (float a, float b) throws
java.rmi.RemoteException;
float div (float a, float b) throws
DivisaoPorZero,
java.rmi.RemoteException;
}
Calculadora Distribuída:
Interface

Ao estender a interface java.rmi.Remote, a
interface Calculadora identifica-se como uma
interface que pode receber requisições de
outras MVJ
 Qualquer
classe que implemente esta interface pode
produzir objetos remotos

Métodos da interface Calculadora podem ser
executados remotamente
 Logo
devem ser capazes de sinalizar exceção
java.rmi.RemoteException
 Sinaliza ocorrência de falha de comunicação ou
erro de protocolo
Calculadora Distribuída:
Implementação da Interface

De modo geral, classe que implementa
interface remota deve seguir, no mínimo,
os seguintes passos:
 Declarar
as interfaces remotas sendo
implementadas
 Definir o construtor para cada objeto remoto
 Prover uma implementação para cada
método remoto declarado nas interfaces
remotas
Calculadora Distribuída:
Implementação da Interface

Programa servidor RMI deve:
 Criar
os objetos remotos e
 Exportá-los para o sistema runtime do RMI


Sistema runtime torna-os aptos a receber invocações remotas
Este processo de configuração pode ser:
 Encapsulado
em um método da implementação da
interface remota ou
 Incluído completamente em outra classe

Roteiro do processo de configuração:
 Criar
e instalar um gerente de segurança
 Criar e exportar um ou mais objetos remotos
 Registrar ao menos um objeto remoto no registro de
nomes do RMI (ou outro serviço de nomes)
Calculadora Distribuída:
Implementação da Interface
package exemplo;
import
import
import
import
import
import
java.rmi.RemoteException;
java.rmi.registry.LocateRegistry;
java.rmi.registry.Registry;
java.rmi.server.UnicastRemoteObject;
exemplo.Calculadora;
exemplo.divisaoPorZero;
public class CalculadoraImpl implements Calculadora{
public CalculadoraImpl() {
super();
}
Calculadora Distribuída:
Implementação da Interface
public float som (float a, float b) {
return a+b;
}
public float sub (float a, float b) {
return a-b;
}
public float mul (float a, float b) {
return a*b;
}
public float div (float a, float b) throws
divisaoPorZero {
if (b == 0) throw new divisaoPorZero();
return a/b;
}
Calculadora Distribuída:
Implementação da Interface
public static void main(String[] args) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new
SecurityManager());
}
try {
String name = "Calculadora";
Calculadora calc = new CalculadoraImpl();
Calculadora stub = (Calculadora)UnicastRemoteObject.exportObject(calc,0);
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
System.out.println("Calculadora registrada!");
} catch (Exception e) {
System.err.println("Ocorreu excecao: ");
e.printStackTrace();
}
}
}
Calculadora Distribuída:
Implementação da Interface

Declarando a interface remota sendo
implementada:
public class CalculadoraImpl implements Calculadora
 Podemos
criar objetos remotos da classe
CalculadoraImpl
 Alguns dos seus métodos, entretanto, só
podem ser invocados localmente

Construtor e método main
Calculadora Distribuída:
Implementação da Interface

Definindo o construtor para o objeto
remoto
public CalculadoraImpl() {
super();
}
 Em
nosso caso, apenas invoca construtor da
classe ancestral

Apesar de não ser necessário, foi adicionado por
questões de clareza de código
Calculadora Distribuída:
Implementação da Interface

Provendo implementações para cada método
remoto
 Classe
provê implementações para todos os
métodos declarados na interface


som, sub, mul, div
Passagem de parâmetros em Java segue as
seguintes regras
 Objetos
remotos passados por referência
 Objetos locais passados por cópia


Todos os campos, exceto declarados estáticos ou
transientes
Desde que serializáveis e classes acessíveis (por
exemplo, via servidor web)
Calculadora Distribuída:
Implementação da Interface

Implementação do método main
 Primeira
tarefa: instalar o gerente de
segurança

Protege o acesso aos recursos do sistema


Determina, por exemplo, se código pode ter acesso ao
sistema local de arquivos ou realizar qualquer outra
ação privilegiada
Receita de bolo:
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
Calculadora Distribuída:
Implementação da Interface

Implementação do método main
 Segunda
tarefa: tornar os objetos remotos
disponíveis para o cliente
Instanciar objeto
 Exportar objeto, com
UnicastRemoteObject.exportObject, de forma
que ele possa receber chamadas remotas:

Calculadora stub = (Calculadora)UnicastRemoteObject.exportObject(calc,0);

Segundo parâmetro indica número da porta TCP a
ser ouvida
 Zero indica porta anônima
 Porta real escolhida por SO ou RMI
Calculadora Distribuída:
Implementação da Interface

Implementação do método main
Método exportObject retorna stub para
objeto remoto exportado

Observe que tipo do stub deve ser da interface, e
não da implementação
 Antes
do cliente invocar um objeto em um
objeto remoto, deve primeiro obter referência
para objeto remoto
Registro faz esse papel
 Serviço de nomes, que fornece uma referência
para objeto remoto, dado um nome

Calculadora Distribuída:
Implementação da Interface

Servidor registra nome no serviço de
nomes
String name = "Calculadora";
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
Rebind faz chamada remota para registro
localizado na máquina do servidor
 Como qualquer chamada remota, pode
retornar exceção, que deve ser tratada
 Bloco try/catch faz tratamento

Calculadora Distribuída:
Implementando o Cliente
package exemplo;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class CalculadoraClnt {
public static void main(String args[]) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
Calculadora Distribuída:
Implementando o Cliente
try {
String name = "Calculadora";
Registry registry = LocateRegistry.getRegistry(args[0]);
Calculadora calc = (Calculadora) registry.lookup(name);
System.out.println("2 + 2 = " + calc.som(2,2));
} catch (Exception e) {
System.err.println("Calculadora exception:");
e.printStackTrace();
}
}
}
Calculadora Distribuída:
Implementando o Cliente

Assim como servidor, começamos declarando gerente
de segurança

Necessário se cliente fizer download de código do servidor a
partir do servidor web
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}

Próximo passo: localizar referência para objeto remoto
String name = "Calculadora";
Registry registry = LocateRegistry.getRegistry(args[0]);
Calculadora calc = (Calculadora) registry.lookup(name);
Calculadora Distribuída:
Implementando o Cliente

Passo final: usar as funcionalidades do objeto
remoto, através de seus métodos, da mesma
forma que usaríamos as funcionalidades de um
objeto local
System.out.println("2 + 2 = " + calc.som(2,2));
Calculadora Distribuída:
Compilação e Execução

Para compilar:
 Compilar
com javac *.java
 Criar arquivo jar com classes relacionadas ao
servidor: jar cvf server.jar Calculadora.class
CalculadoraImpl.class divisaoPorZero.class
 Caso código do servidor seja acessado
através de servidor web, disponibilizar arquivo
jar em pasta acessível via rede
 Caso alguma classe do cliente seja acessada
pelo servidor, deve-se criar jar e disponibilizálo através da rede
Calculadora Distribuída:
Compilação e Execução

Antes de executar:
 Criar
arquivo contendo políticas de segurança
 Neste exemplo, daremos todas as
permissões de acesso:
grant {
permission java.security.AllPermission;
};
Calculadora Distribuída:
Compilação e Execução

Para executar:
 Iniciar
rmiregistry (rmiregistry&)
 Iniciar servidor: java -Djava.security.policy=f:\
calc\exemplo\secpolicy
-Djava.rmi.server.codebase=file:\f:calc\exempl
o\server.jar CalculadoraImpl
 Iniciar cliente: java
-Djava.security.policy=f:\calc\exemplo\secpoli
cy CalculadoraClnt localhost
 Resultado: 2 + 2 = 4.0
Próxima Aula...

Remote Procedure Call (cont.)
 Questões
de Implementação
 Problemas
Download

Avaliação de Desempenho de Sistemas Computacionais