AULA PRÁTICA SOBRE JAVA RMI
Desenvolver uma aplicação cliente/servidor em Java RMI consistindo de:
• Servidor: programa que implementa alguns objetos remotos representando contas bancárias.
Estes objetos devem possuir um método obterSaldo(), o qual retorna o saldo atual de uma
conta.
• Cliente: programa que lê o número de uma conta bancária e executa uma chamada remota ao
método obterSaldo() desta conta.
Observações:
• Todos os arquivos desta aplicação deverão ser digitados no Bloco de Notas. No entanto, é
comum que o Bloco de Notas acrescente a extensão .txt a cada arquivo salvo através do
mesmo. Assim, após salvar seus arquivos, certifique-‐se de que os mesmos possuem a extensão
correta . Caso eles tenham sido salvos com a extensão .txt, você deverá então renomeá-‐los.
• Os arquivos serão compilados usando o Sun JDK (Java Development Kit),
• Inicialmente, tanto cliente como servidor executarão na mesma máquina. Em seguida, como
exercício, você deverá distribuir cliente e servidor em máquinas diferentes.
IMPLEMENTAÇÃO DO SERVIDOR:
1. Definição da interface dos objetos remotos:
Digite o arquivo abaixo no Bloco de Notas e o salve com o nome
Conta.java
:
// arquivo Conta.java import java.rmi.Remote; import java.rmi.RemoteException;
public interface Conta extends Remote {
public float obterSaldo () throws RemoteException; }
Este arquivo descreve a interface (cabeçalho dos métodos) do objeto remoto a ser ativado no
servidor. Como usual em Java RMI, esta interface deve estender a interface pré-‐definida
2. Implementação do Servidor:
Digite o arquivo abaixo no Bloco de Notas e o salve com o nome
ContaImpl.java
. Analise o
código deste arquivo, verificando que ele implementa a classe do objeto remoto. Como usual
em Java RMI, esta classe implementa a interface remota definida no passo 1 e estende a classe
pré-‐definida UnicastRemoteObject. Além disso, essa classe possui o método main do servidor,
o qual cria três objetos remotos e os registra com nomes Conta10, Conta20, Conta30.
// arquivo ContaImpl.java import java.rmi.*; import java.rmi.server.*;
// Classe ContaImpl implementa a interface remota Conta
public class ContaImpl extends UnicastRemoteObject implements Conta { private int numero; // numero da conta
private float saldo; // saldo da conta
public ContaImpl (int n, float s) throws RemoteException // Construtora { super(); // chama construtora da classe base numero= n;
saldo= s; }
public float obterSaldo () throws RemoteException // Metodo remoto { System.out.println ("Conta " + Integer.toString (numero)
+ "::saldo= " + Float.toString(saldo) ); return saldo;
}
public static void main (String[] args) { // função main
try {
// Cria 3 objetos remotos
Conta c1= new ContaImpl (10, 1000); Conta c2= new ContaImpl (20, 2000); Conta c3= new ContaImpl (30, 3000);
// Registra objetos na Registry com os nomes de “Conta10”, “Conta20” e “Conta30” Naming.rebind ("Conta10", c1);
Naming.rebind ("Conta20", c2); Naming.rebind ("Conta30", c3);
System.out.println ("Objetos das contas de numero 10, 20 e 30 inseridos na registry"); System.out.println ("Servidor em execução, esperando chamadas remotas ...");
} catch (Exception e) {
System.out.println ("Erro no servidor: " + e.getMessage()); }
} }
3. Compilação do servidor
Compile e execute o servidor usando o JDK (Java Development Kit) da Sun. Para tanto, abra uma
janela DOS e digite os seguintes comandos:
set CLASSPATH=
.
<enter> // existe um ponto após o sinal de igualjavac ContaImpl.java <enter>
rmic ContaImpl <enter>
Deverão ser gerados os seguintes arquivos em seu diretório:
• ContaImpl.class
// bytecode do servidor
• ContaImpl_Skel.class
// bytecode do skeleton (stub do servidor)
Nas versões mais novas do JD, o stub é gerado dinamicamente, por meio de reflexão.
4. Execução do servidor
Em uma nova janela DOS, certifique-‐se de que o diretório corrente é aquele onde encontram-‐
se gravados os arquivos do passo anterior e então, neste diretório, digite os seguintes
comandos:
set CLASSPATH=
.
<enter> // existe um ponto após o sinal de igual
rmiregistry
<enter>
O RMIRegistry entrará em execução, ficando em um loop infinito esperando registro de
objetos remotos (por parte de servidores) e consultas de referências para objetos remotos
(por parte de clientes). Esta janela DOS deverá ser então minimizada, pois deverá ficar
executando indefinidamente.
Em uma nova janela DOS, ative o servidor digitando o seguinte comando no mesmo diretório
onde estão gravados os arquivos:
java ContaImpl <enter>
Caso o servidor execute corretamente, deverá ser exibida a seguinte mensagem:
Veja que o servidor permanecerá executando, em um loop infinito, esperando requisições dos
clientes.
IMPLEMENTAÇÃO DO CLIENTE
O cliente deverá possuir uma interface como a mostrada abaixo:
1. Código do Cliente
Digite o arquivo abaixo no Bloco de Notas e o salve com o nome
Cliente.java
. Veja que o
OnClick do botão OK do formulário criado por este arquivo realiza uma chamada remota ao
método ObterSaldo da conta cujo número foi informado.
// arquivo Cliente.java import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.rmi.*; import java.rmi.server.*;
public class Cliente extends JFrame { JLabel jLabel1 = new JLabel();
JTextField jTextField1 = new JTextField();
JToggleButton jToggleButton1 = new JToggleButton(); JTextField jTextField2 = new JTextField();
public Cliente() { enableEvents(AWTEvent.WINDOW_EVENT_MASK); try { jbInit(); }
catch(Exception e) { e.printStackTrace(); }
}
private void jbInit() throws Exception { // desenha interface
jLabel1.setText("Conta");
jLabel1.setBounds(new Rectangle(21, 44, 41, 17)); this.getContentPane().setLayout(null);
this.setSize(new Dimension(340, 203)); this.setTitle("Aula de Java RMI -‐ Cliente"); jTextField1.setText(""); jTextField1.setBounds(new Rectangle(121, 42, 104, 25)); jToggleButton1.setText("Saldo"); jToggleButton1.setBounds(new Rectangle(21, 90, 77, 25)); jToggleButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) { jToggleButton1_actionPerformed(e); } }); jTextField2.setText(""); jTextField2.setBounds(new Rectangle(121, 88, 105, 27)); this.getContentPane().add(jLabel1, null); this.getContentPane().add(jToggleButton1, null); this.getContentPane().add(jTextField2, null); this.getContentPane().add(jTextField1, null); }
protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if(e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } }
void jToggleButton1_actionPerformed(ActionEvent e) { // OnClick do botao Saldo Conta c;
float saldo;
try {
// consulta o registry para obter referencia para objeto remoto c= (Conta) Naming.lookup ("Conta" + jTextField1.getText().trim());
// chama operacao obterSaldo() do objeto remoto saldo= c.obterSaldo();
jTextField2.setText (Float.toString(saldo));
} catch (Exception exception) { // trata excecoes ocorridas no bloco try System.out.println ("Erro no cliente: " + exception.getMessage()); }
}
public static void main (String[] args) { Cliente cliente= new Cliente(); cliente.setVisible (true); }
}
2. Compilação e Execução do Cliente
Em uma janela DOS, digite os seguintes comandos:
set CLASSPATH=
.
<enter> // existe um ponto após o sinal de igualjavac Cliente.java <enter>
java Cliente <enter>