Sistemas Distribuidos, desenvolvendo aplicações com Java RMI.

Segundo a definição do site Wikipédia RMI ou Remote Method Invocation é uma tecnologia  utilizada para criar aplicações distribuídas na linguagem Java. Possibilitando ao programador invocar métodos remotos de outras Java Virtual Machines (Maquinas virtuais Java), que podem ou não existir em diferentes host. Outra característica do RMI é que ele usa serialização de objetos para ordenar os parâmetros e não precisa truncar os dados, podendo utilizar o real polimorfismo orientado a objetos.

O objetivo desse post é de criar um programa que seja capaz de efetuar cálculos de forma remota usando RMI. O programa deve ser composto de duas partes, uma parte cliente e uma servidora. O Cliente deve ser capaz de efetuar chamada a um método calcular localizada em um Servidor da seguinte forma: calcular(operacao, valor1, valor2).

Sendo que “operacao” é a operação que se deseja fazer( + – * /) e valor1, valor2 são inteiros. O retorno do método é um número real.
Ou seja, se for invocado da seguinte forma calcular(“/”, 3,2)  o retorno deve ser 1.5

Na classe Cliente encontrasse o menu e a chamada remota do método do servidor.
Para compilar você poderá usar uma IDE como o NetBeans ou poderá usar a linha de comando chamando o compilador java como no exemplo:
“javac Cliente.java” (Lembre-se que deve ser sem as aspas).

/*********************************
Autor: Fernando Krein Pinheiro
Data: 18/03/2011
Linguagem: JAVA

========= IMPORTANTE ===========
O código esta livre para usar,
citar e compartilhar desde que
mantida sua fonte e seu autor.
Obrigado.
*********************************/
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import javax.swing.JOptionPane;

public class Cliente {

    public static void main(String[] args)
    {
        try {
               int val1 = Integer.parseInt(JOptionPane.showInputDialog("Entre com o primeiro valor"));
               String opcao[] = {"+", "-", "*", "/"};

               int operacao = JOptionPane.showOptionDialog(null, "Escolha uma das operacoes", "Tipo de operacao",
               0, JOptionPane.INFORMATION_MESSAGE, null, opcao, opcao[0]);

               int val2 = Integer.parseInt(JOptionPane.showInputDialog("Entre com o segundo valor"));

               InterfaceCalculoRemoto objCalculoRemoto = (InterfaceCalculoRemoto)
               Naming.lookup("rmi://localhost:1099/InterfaceCalculoRemoto");

               System.out.println("Servidor fala: O resultado é = " + objCalculoRemoto.metodo_calcular(val1, val2, operacao));
               objCalculoRemoto.mensagemServidor("Recebi a Resposta");
             }

        	catch (MalformedURLException e)
        	{
                    System.out.println("Erro:" + e.toString());
                    e.printStackTrace();
        	}
        	catch (RemoteException e)
        	{
                    System.out.println("Erro:" + e.toString());
                    e.printStackTrace();
                }
        	catch (NotBoundException e)
        	{
                    System.out.println("Erro:" + e.toString());
                    e.printStackTrace();
                }
        	catch (Exception e)
        	{
            		JOptionPane.showMessageDialog(null, "Entrada inválida", e.getMessage(), JOptionPane.ERROR_MESSAGE);
            		System.exit(-1);
        	}
    }
}

Classe Servidor: Contem o endereço para o registro do serviço RMI e uma chamada para o método da Classe ImplementacaoCalculoRemoto. A compilação deve ser feita da mesma forma que a da classe cliente.

import java.rmi.Naming;
import java.rmi.RemoteException;

public class Servidor
{
    public Servidor() throws RemoteException
    {
        String localServico = "rmi://localhost:1099/InterfaceCalculoRemoto";
        InterfaceCalculoRemoto objServidorRemoto = new ImplementacaoCalculoRemoto();

        try
        {
             Naming.rebind(localServico, objServidorRemoto);
        }
        catch (Exception e)
        {
             e.printStackTrace();
        }
     }

        public static void main(String[] args) throws RemoteException
        {
              Servidor objServidor = new Servidor();
        }
}

Classe InterfaceCalculoRemoto: foi definida uma interface por causa das extensões que são feitas na classe ImplementacaoCalculoRemoto

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface InterfaceCalculoRemoto extends Remote
{
        public double metodo_calcular(int val1, int val2, int operacao) throws RemoteException;
        public void mensagemServidor(String mensagem) throws RemoteException;
}

Classe ImplementacaoCalculoRemoto: responsável pelo calculo a ser feitos sobre os dados enviados pelo cliente, é a implementação da InterfaceCalculoRemoto.

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ImplementacaoCalculoRemoto extends UnicastRemoteObject implements InterfaceCalculoRemoto
{
    public ImplementacaoCalculoRemoto() throws RemoteException
    { }

public void mensagemServidor(String mensagem) throws RemoteException
{
      System.out.println("Cliente fala: " + mensagem);
}

public double metodo_calcular(int val1, int val2, int op) throws RemoteException
{
   double v1 = Double.valueOf(String.valueOf(val1));
   double v2 = Double.valueOf(String.valueOf(val2));

      if (op == 0)
      {
          return (v1 + v2);
      }
      else
          if (op == 1)
          {
              return (v1 - v2);
          }
          else
              if (op == 2)
              {
                  return (v1 * v2);
              }
              else
                   if (op == 3)
                   {
                       return (v1 / v2);
                    }
     return 0;
  }
}

Compilando as classe.

Siga a ordem:

1 -Primeiro compile a Classe InterfaceCalculoRemoto, entre em um terminal e digite: javac InterfaceCalculoRemoto
2 – Agora compile a implementação da interface: javac ImplementacaoCalculoRemoto
3 – Vamos gerar os Stubs e Skeletons para isso digite: rmic ImplementacaoCalculoRemoto
4 – Agora compile a Classe Servidor: javac Servidor.java
5 – E por fim a Classe Cliente: javac Cliente

6 – Após a compilação dos arquivos vamos iniciar o serviço RMI, para isso digite no terminal: rmiregistry
7 – Agora abra outro terminal para executar o Servidor, digite: java Servidor
8 – E por ultimo vamos executar o Cliente, para isso abra outro terminal e digite: java Cliente

Agora só faça os teste e confira os resultados.

Anúncios
por ferpinheiro Postado em Java

5 comentários em “Sistemas Distribuidos, desenvolvendo aplicações com Java RMI.

  1. Sinceramente, o melhor tutorial RMI q achei na net toda!
    Parabéns, só uma dúvida: tá dando erro na hora de compilar o Servidor!
    Tenho q mudar alguma coisa no código?? OBS: Sou bem iniciante! rsrs

    • Consegui consertar o erro!! Muito obrigado!! Ótimo post! Só uma dúvida:
      Como rodar o Servidor em outra máquina??

  2. Nao consegui rodar o servidor, aparece os seguintes erros:
    Erro:java.rmi.NotBoundException: InterfaceCalculoRemoto
    java.rmi.NotBoundException: InterfaceCalculoRemoto
    at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:106)
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:386)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Naming.java:84)
    at rmi.Cliente.main(Cliente.java:35)
    CONSTRUÍDO COM SUCESSO (tempo total: 6 segundos)

    O QUE PODERIA SER, ALGUEM SABE?

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s