• Nenhum resultado encontrado

Capítulo 2: A Plataforma J2EE e Limitações em Relação ao Provimento de Confiança no

2.6 Java Remote Method Invocation

Através do RMI, uma aplicação cliente em Java pode utilizar um objeto instanciado em uma máquina virtual diferente da sua e possivelmente executando em um outro computador da rede. Na especificação RMI, qualquer objeto cujos métodos podem ser invocados de uma outra máquina virtual é chamado de “objeto remoto” [Roman 99]. A localização física dos objetos remotos e dos clientes que os utilizam é irrelevante nessa tecnologia. Essa característica permite que o objeto remoto possa ser utilizado da mesma maneira tanto por objetos clientes da sua própria máquina virtual quanto por objetos em execução em um ponto distinto da rede. O RMI surgiu para oferecer um nível maior de abstração para aplicações que precisam trocar informações pela rede. No lugar de enviar mensagens utilizando diretamente o protocolo de rede, a aplicação pode invocar métodos de um objeto localizado em uma máquina virtual diferente da sua da mesma maneira que invoca qualquer outro objeto.

2.6.1 Arquitetura

Para permitir que um objeto possa ser referenciado a partir de uma outra máquina virtual, o desenvolvedor deve criar uma interface que herde de java.rmi.Remote. Nessa interface, devem ser declarados todos os métodos que poderão ser invocados remotamente. Na Figura 2.12, está definida a interface remota para um objeto remoto que irá somar dois valores.

import java.rmi.Remote;

import java.rmi.RemoteException

public interface Calculador extends Remote {

public int adicionar(int n1, int n2) throws RemoteException; }

Figura 2.12 Exemplo de interface remota

Definida a interface remota, o desenvolvedor deve criar uma classe que implemente essa interface, provendo o código dos métodos nela definidos. Essa classe, normalmente, herda algumas funcionalidades básicas do serviço RMI de outras classes, como por exemplo da classe java.rmi.server.UnicastRemoteObject. A implementação do objeto remoto para o exemplo proposto é ilustrada na Figura 2.13.

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

public class CalculadorImpl extends UnicastRemoteObject implements Calculador

{

public int adicionar(int n1, int n2) throws RemoteException {

return n1 + n2; }

}

Figura 2.13 Exemplo de implementação do objeto remoto

Uma das grandes vantagens da tecnologia RMI é que todo o processo de comunicação entre os objetos fica transparente para os desenvolvedores do objeto remoto e do cliente. Dessa forma, a implementação do objeto remoto consiste apenas na lógica da aplicação. Para que isso seja possível, a infra-estrutura do RMI oferece objetos auxiliares que irão permitir que uma invocação de método feita pelo objeto cliente seja recebida pelo objeto remoto através do protocolo de rede [Campione et al. 98]. Um desses objetos auxiliares é o stub que age como uma “referência remota” à instância do objeto remoto. Este objeto (gerado a partir da compilação da interface remota e da implementação do objeto remoto) residirá na máquina virtual do cliente e irá interceptar as chamadas aos objetos remotos. O stub será responsável por interagir diretamente com o protocolo de rede para enviar as requisições (contendo a invocação do método) para a implementação do objeto remoto e receber desta a resposta do método com ilustrado na Figura 2.14.

Figura 2.14 Comunicação entre o cliente e o objeto remoto

Para que o objeto remoto possa ser invocado por objetos clientes em execução em outras máquinas virtuais, ele deve ser registrado em um serviço de nomes como o RMIRegistry ou JNDI [SUN 99]. Esse registro consiste em associar um nome à instância do objeto remoto, para que os objetos clientes possam obter uma referência remota para esse objeto a partir desse nome. Quando um objeto cliente deseja utilizar um objeto remoto, em primeiro lugar é estabelecida uma sessão com o serviço de nomes. Em seguida, a aplicação cliente consulta o serviço de nomes informando o nome do objeto remoto desejado e o resultado dessa consulta é o stub do objeto remoto. A partir daí, os métodos que o cliente invocar serão enviados pelo stub para a instância real do objeto remoto para serem processados. Um exemplo de invocação ao objeto remoto criado está ilustrado na Figura 2.15.

import javax.naming.Context;

import javax.naming.InitialContext;

public class Cliente {

public static void main(String[] args) throws Exception {

//Conexão com o serviço de nomes JNDI Context ctx = new InitialContext();

//Obtém uma referência remota ao objeto Calculador com

//base no nome com o qual ele foi registrado

Calculador objetoRemoto = (Calculador)ctx.lookup(“Calc”); //Invocação do método remoto

int resultado = objetoRemoto.adicionar(2, 2); }

}

Figura 2.15 Exemplo de invocação do objeto remoto

JVM 3 CalculadorImpl JVM 1 Cliente Stub JVM 2 Cliente Stub adicionar(2, 2) adicionar(1, 1) Rede

Como o stub obtido é um objeto que implementa a mesma interface remota implementada pelo objeto remoto, o objeto cliente tem a “ilusão” de estar referenciado o objeto remoto, o que torna a utilização do stub transparente para o cliente.

2.6.2 Limitações

Através dos stubs, as aplicações clientes podem acessar os objetos remotos instanciados em máquinas virtuais diferentes da sua como se fossem objetos locais. Entretanto, de acordo com a especificação RMI, estes objetos auxiliares não possuem mecanismos para detectar a falha das instâncias referenciadas de forma automática e transparente. De uma maneira geral, é possível que, após o cliente obter uma referência remota para o objeto, a máquina virtual do objeto remoto apresente uma falha. Na próxima vez que o cliente invocar um método, ele receberá do stub uma exceção indicando um problema de comunicação com o objeto remoto. Isso irá obrigar a aplicação cliente a recuperar novamente uma referência a um objeto remoto em outra máquina virtual. Este tratamento extra por parte do cliente é devido ao fato de que os objetos stubs só podem referenciar uma instância em uma determinada máquina virtual, mesmo havendo outras instâncias em pontos distintos da rede.