Um Estudo de Caso de Chamada Remota de Procedimento: JAVA RMI Por: Thaís Batista O conteúdo deste documento foi retirado do livro: Gregory R. Andrews Foundations of Multithreaded, Parallel and Distributed Programming Addison Wesley, 2000 Visão Geral: A linguagem Java oferece suporte para Chamada Remota de Procedimento através de um mecanismo chamado Java RMI (Remote Method Invocation) uma vez que operações em objetos Java são chamadas de métodos. Duas bibliotecas são utilizadas para programação com Java RMI: java.rmi e java.rmi.server. Uma aplicação que usa invocação remota de método (RMI) tem três componentes: • Uma Interface com declarações dos métodos • Uma classe Servidor que implementa os métodos declarados na interface • Um ou mais Clientes que realizam chamadas remotas Um serviço de registro é um programa especial que mantém uma lista de nomes de servidores registrados em um host. Ele é inicializado em background em uma máquina servidora executando o comando rmiregistry port &. Um programa servidor também pode oferecer seu próprio serviço de registro usando o pacote java.rmi.registry. A interface para o serviço de registro é fornecida por um objeto Naming que tem dois métodos. O método bind é usado para registrar um nome e o método lookup para recuperar um servidor associado a um nome. Os seguintes passos devem ser seguidos para desenvolvimento dos programas acima citados: 1. Escreva uma interface Java que estenda a interface Remote (que é definida no pacote java.rmi). 2. Escreva um servidor que estende a interface UnicastRemoteObject e que implemente os métodos na interface 3. Escreva um código para criar uma instância do servidor e registrar seu nome no serviço de registro. Este código pode estar dentro do método main do servidor. 4. Escreva uma classe cliente que interage com o servidor. O cliente deve primeiro habilitar o gerenciador de segurança do RMI para protegê-lo. Isto é feito através da chamada System.setSecurityManager(new RMISecurityManage()). Em seguida o cliente deve chamar o método Naming.lookup para obter no serviço de registro, a referência para o objetos servidor. 5. O cliente já pode chamar os métodos remotos. Exemplo: A seguir mostraremos um exemplo simples do uso de Java RMI. Inteface: A interface BDremoto define os métodos métodos que o servidor implementa: ler e escreve. Como estes métodos serão chamados remotamente pelo cliente, eles são declarados usando o RemoteException. public interface BDremoto extends Remote { public int ler() throws RemoteException; public void escreve(int value) throws RemoteException; } Servidor: A classe servidor, Bdremotoserver, implementa a interface. O banco dados propriamente dito é simplesmente uma variável inteira protegida. O método main, no servidor, cria uma instância do servidor, registra seu nome e imprime uma linha no host do servidor para indicar que ele está em operação. A máquina e porta usado por este programa é baltazar:9999 import java.rmi.*; import java.rmi.server.*; class Bdremotoserver extends UnicastRemoteObject implements BDremoto protected int data = 0; /* o banco de dados */ public int ler() throws RemoteException { return data; } public void escreve(int value) throws RemoteException { data = value; System.out.println(“novo valor e’: “+ data); } // construtor necessario devido a clausula throws public Bdremotoserver() throws RemoteException { super(); } public static void main(String[] args) { try { // cria um objeto banco de dados remoto RemoteDatabaseServer server = New RemoteDatabaseServer(); // registra o nome e inicia o serviço String name = “rmi://baltazar:9999/bancodados”; Naming.bind(name, server); System.out.println(name + “está executando”); } catch (Exception e) { System.err.println(e); } } } Cliente: A classe Cliente define o cliente. Ela consiste do método main que pode ser inicializado em qualquer máquina. Um cliente primeiro seta o RMI security manager para protegê-lo contra erros do servidor. Em seguida, o cliente procura pelo nome do servidor e obtém a referência para o servidor. O restante do código do cliente chama os métodos ler e escreve. Class Client { public static void main(String[] args) { try { // seta o standard RMI security manager System.setSecurityManager(new RMISecurityManager()); // recupera o objeto remoto String name = “rmi://baltazar:9999/bancodados”; BDremoto bd = (Bdremoto) Naming.lookup(name); // ler o argumento da linha de comando e acessa o banco de dados int value, rounds = Integer.parseInt(args[0]); for (int i = 0; i < rounds; i++) { value = bd.ler(); System.out.println(“ler: “+ value); bd.escreve(value+1); } } catch (Exception e) { System.err.println(e); } } } O cliente é inicializado em uma máquina executando java Client rounds Ambas as partes deste programa necessitam ser armazenadas em um único arquivo chamado BDremoto.java pois este é o nome da interface. Executando os seguintes comandos no host baltazar, o programa será compilado, os stubs serão criados e o servidor inicializado: javac BDremoto.java rmic Bdremotoserver rmiregistry 9999 & java BDremotoserver