SlideShare uma empresa Scribd logo
1 de 11
Baixar para ler offline
Introdução á Computação Distribuída com RMI


A tecnologia RMI - Remote Method Invocation (Invocação de Métodos Remotos), foi
primeiramente introduzida no Java, no JDK versão 1.1, elevando a programação para
redes em um patamar mais elevado. Apesar do RMI ser relativamente fácil, ele põe o
desenvolvedor Java frente à um novo paradigma, o mundo da computação de objectos
distribuídos.




Este guia prático vai lhe introduzir à esta tecnologia versátil, que melhorou muito desde
sua primeira versão.




O principal objectivo para os criadores (designers) do RMI era permitir os
programadores a desenvolverem programas distribuídos em Java com a mesma sintaxe
e semântica usada em programas não-distribuídos. Para isso, eles tiveram que mapear
cuidadosamente como classes Java e objectos trabalham em uma única Java Virtual
Machine (JVM) para um novo modelo de como as classes e objectos trabalhariam num
ambiente distribuído de computação (múltiplas JVMs). Os arquitectos do RMI tentaram
fazer com que o uso dos objectos distribuídos em Java fosse similar ao uso de objectos
Java locais.




Esta secção introduz a arquitectura RMI da perspectiva dos objectos Java remotos
distribuídos, e explora as diferenças de comportamento com objectos locais. A
arquitectura RMI define como os objectos se comportam, como e quando excepções
podem ocorrer, como a memória é gerida e como os parâmetros são passados e
retornados de métodos remotos.


A arquitectura RMI estende a segurança e robustez da arquitectura Java para o mundo
da computação distribuída.




A arquitectura RMI é baseada em um importante princípio: a definição do
comportamento e a implementação do comportamento são conceitos separados. RMI
permite que o código que define o comportamento e o código que implementa o
comportamento permanecerem separados e rodarem em JVMs separadas.


Em RMI, a definição do serviço remoto é codificada usando uma interface Java. A



                                                                             Página 1 de 11
implementação do serviço remoto é codificada em uma classe. Logo, a chave para se
entender o RMI é lembrar que as interfaces definem o comportamento e as classes
definem a implementação.




A classe que implementa o comportamento roda do lado do servidor RMI. A classe que
roda no cliente actua como um Proxy para o serviço remoto. Veja o seguinte diagrama:




O programa cliente faz chamadas de métodos pelo objecto Proxy, o RMI envia a
requisição para a JVM remota e redirecciona para a implementação. Qualquer valor
retornado pela implementação é devolvido ao Proxy e então ao programa cliente.


Com o entendimento da arquitectura RMI num alto nível, vamos dar uma breve olhada
na sua implementação.




A implementação do RMI é essencialmente feita de três camadas de abstracção. A
camada Stub e Skeleton está abaixo dos olhos do desenvolvedor. Esta camada
intercepta as chamadas de métodos feitas pelo cliente para que a variável de referência
da interface redirecione essas chamadas para o serviço RMI remoto.


A próxima camada é a Remote Reference Layer. Esta camada sabe como interpretar e
gerir referências feitas dos clientes para os objectos do serviço remoto. A conexão do
cliente ao servidor é Unicast (uma-para-um).


A camada de transporte é baseada nas conexões TCP/IP entre as maquinas em uma
rede.


Usando essa arquitectura de camadas, cada uma das camadas poderia ser facilmente



                                                                          Página 2 de 11
melhorada ou substituída sem afectar o resto do sistema. Por exemplo, a camada de
transporte poderia ser substituída por uma camada que implemente conexões UDP/IP,
sem afectar as camadas superiores.




Como um cliente acha o serviço remoto RMI?


Os clientes acham os serviços remotos usando o serviço de nomeação ou directório
(naming or directory). Isso parece um pouco redundante, mas o serviço de nomeação
ou directório roda como um endereço bem formado (host:port).


O RMI pode usar diferentes tipos de serviços de directório, incluindo o JNDI. O próprio
RMI inclue um simples serviço, chamado de RMI Registry. O RMI Registry roda em cada
maquina que hospeda o serviço remoto, por definição na porta 1099.


Numa máquina host, um programa servidor cria um serviço remoto, primeiramente
criando o objecto que implemente aquele serviço. Em seguida ele exporta aquele
objecto para o RMI. Quando o objecto é exportado o RMI cria um serviço que aguarda
as conexões do cliente. O servidor registra o objecto no RMI Registry, com um nome
público.


No lado do cliente o RMI Registry é acedido através da classe estática Naming. Ela
provém o método lookup( ), que o cliente usa para requisitar o registro. Esse método
aceita a URL que especifica o nome do servidor e o nome do serviço desejado. O
método retorna uma referência remota para o objecto do serviço. A URL é formada
como seguinte:


rmi://<host_name>[:port_number]/<service_name>




                                                                          Página 3 de 11
Agora vamos trabalhar com um sistema que realmente implementa um sistema com
RMI. Vamos criar um aplicativo simples, cliente e servidor, que executa métodos do
objecto remoto.


Para tanto não necessitamos de duas máquinas distintas ou com IP distintos. O exemplo
pode ser rodado na mesma máquina, pois o RMI sabe como trabalhar com isso, mesmo
que o host e o cliente sejam na mesma localidade.




Um sistema RMI é composto de várias partes:


• Definição das interfaces para os serviços remotos
• Implementações dos serviços remotos
• Arquivos de Stub e Skeletons
• Um servidor para hospedar os serviços remotos
• Um serviço de RMI Naming que permite o cliente achar os serviços remotos
• Um provedor de arquivos de classes (servidor http ou ftp)
• Um programa cliente que necessita os serviços remotos




Agora iremos, de fato, criar um sistema que implemente o RMI, utilizando-se de um
programa cliente e um programa servidor. Não utilizaremos um servidor FTP ou HTTP,
no entanto utilizaremos os programas na mesma máquina e uma mesma estrutura de
directórios.


Os passos a serem seguidos agora são:


• Escrever e compilar o código Java da interface
• Escrever e compilar o código Java das implementações das classes
• Gerar as classes Stub e Skeleton das classes de implementação


Crie um directório para salvar todos os seus arquivos de projecto.


Você pode fazer o download do código fonte usado nesse tutorial.


O primeiro passo, como dito, será criar a interface e compilá-la. A interface define todas
as funcionalidades remotas oferecidas pelo serviço. Nomeio o arquivo como:
Mensageiro.java.



                                                                           Página 4 de 11
1   import java.rmi.Remote;
2   import java.rmi.RemoteException;
3
4   public interface Mensageiro extends Remote {
5
6        public void enviarMensagem( String msg ) throws RemoteException;
7        public String lerMensagem() throws RemoteException;
8   }




Perceba que esta interface estende a classe Remote, e cada assinatura de método
declara as funcionalidades do serviço, e que podem gerar uma excepção
RemoteException.


Salve este arquivo (Mensageiro.java) no seu directório e compile, com a seguinte linha
de comando:


javac Mensageiro.java




Agora, você deverá escrever a implementação para o serviço remoto, ou seja, o código
a ser executado no ambiente remoto. Nomeia o arquivo como: MensageiroImpl.java.




01   import java.rmi.RemoteException;
02   import java.rmi.server.UnicastRemoteObject;
03
04   public class MensageiroImpl extends UnicastRemoteObject implements Mensageiro {
05
06        public MensageiroImpl() throws RemoteException {
07            super();
08        }
09
10        public void enviarMensagem( String msg ) throws RemoteException {
11            System.out.println( msg );
12        }
13
14        public String lerMensagem() throws RemoteException {
15            return "This is not a Hello World! message";
16        }
17   }




Salve este arquivo (MensageiroImpl.java) no seu directório e compile, com a seguinte
linha de comando:



                                                                         Página 5 de 11
javac MensageiroImpl.java




Observe que a classe se utiliza (estende) da classe UnicastRemoteObject para ligar com
o sistema RMI. Neste exemplo a classe estende a classe UnicastRemoteObject
directamente. Isto não é realmente necessário, mas essa discussão fica para uma
próxima etapa.


Quando uma classe estende a classe UnicastRemoteObject, ele deve prover um
construtor que declare que ele pode lançar uma exceção RemoteException, pois quando
o método super( ) é chamado, ele activa o código em UnicastRemoteObject, que
executa a ligação RMI e a iniciação do objecto remoto.




Gere os arquivos Stubs e Skeletons da classe de implementação que roda no servidor.
Para tanto, execute o comando rmic, compilador RMI do JDK.


rmic MensageiroImpl




Após a execução deste comando, você deveria ver no seu diretório os arquivos
Mensageiro_Stub.class, Mensageiro_Skeleton.class.


Servidor


O serviço remoto RMI deve ser hospedado em um processo servidor. A classe
MensageiroServer é um servidor bem simples, que provê serviços essenciais. Salve o
arquivo como: MensageiroServer.java.




01 import java.rmi.Naming;
02
03 public class MensageiroServer {
04
05     public MensageiroServer() {
06         try {
07             Mensageiro m = new MensageiroImpl();
08             Naming.rebind("rmi://localhost:1099/MensageiroService", m);



                                                                        Página 6 de 11
09           }
                10           catch( Exception e ) {
                11               System.out.println( "Trouble: " + e );
                12           }
                13      }
                14
                15      public static void main(String[] args) {
                16          new MensageiroServer();
                17      }
                18 }




                Salve este arquivo (MensageiroServer.java) no seu diretório e compile, com a seguinte
                linha de comando:


                > javac MensageiroServer.java


                O código fonte para o cliente é o seguinte. Salve o arquivo como:
                MensageiroClient.java.




01   import   java.rmi.Naming;
02   import   java.rmi.RemoteException;
03   import   java.rmi.NotBoundException;
04   import   java.net.MalformedURLException;
05
06   public class MensageiroClient {
07
08       public static void main( String args[] ) {
09           try {
10               Mensageiro m = (Mensageiro) Naming.lookup( "rmi://localhost/MensageiroService" );
11               System.out.println( m.lerMensagem() );
12               m.enviarMensagem( "Hello World!" );
13           }
14           catch( MalformedURLException e ) {
15               System.out.println();
16               System.out.println( "MalformedURLException: " + e.toString() );
17           }
18           catch( RemoteException e ) {
19               System.out.println();
20               System.out.println( "RemoteException: " + e.toString() );
21           }
22           catch( NotBoundException e ) {
23               System.out.println();
24               System.out.println( "NotBoundException: " + e.toString() );
25           }
26           catch( Exception e ) {
27               System.out.println();
28               System.out.println( "Exception: " + e.toString() );
29           }
30       }
31   }




                                                                                        Página 7 de 11
Salve este arquivo (MensageiroClient.java) no seu diretório e compile, com a seguinte
linha de comando:


javac MensageiroClient.java




Agora que todos os arquivos do projeto de exemplo foram criados e devidamente
compilados, estamos prontos para rodar o sistema! Você precisará abrir três diferentes
consoles do MS-DOS no seu Windows, ou outro, caso utilize um diferente sistema
operacional.


Em um dos consoles vai rodar o programa servidor, no outro o cliente e no terceiro o
RMI Registry.


Inicie com o RMI Registry. Você deve estar no mesmo diretório em que estão gravados
seus arquivos para rodar o aplicativo. Execute a seguinte linha de comando:


rmiregistry




Isso irá iniciar o RMI Registry e rodá-lo.


No segundo console vamos executar o programa servidor. Você deve estar no mesmo
directório em que estão gravados seus arquivos para rodar o aplicativo. Execute o
seguinte comando:


java MensageiroServer




Isso irá iniciar, carregar a implementação na memória e esperar pela conexão cliente.


No último console, rode o programa cliente. Você deve estar no mesmo directório em
que estão gravados seus arquivos para rodar o aplicativo. Execute o comando:


java MensageiroClient




                                                                         Página 8 de 11
Se tudo correr bem, que é o que esperamos e o que deveria acontecer, a seguinte saída
será gerada nos consoles 2 (servidor) e 3 (cliente).
No console 2 (servidor):


Hellow World!




No console 3 (cliente):


This is not a Hello World! message



É isso aí. Você acabou de criar um sistema utilizando a tecnologia RMI. Apesar de você
ter rodado os programas na mesma máquina, o RMI usa a pilha de rede TCP/IP para se
comunicar entre as três diferentes instâncias da JVM.

Exercício:

    1. Defina a Interface Remota
        import java.rmi.Remote;
        import java.rmi.RemoteException;
        import java.math.BigInteger;


        public interface Operator extends Remote {
          BigInteger add(BigInteger b1, BigInteger b2) throws RemoteException;
          BigInteger subtract(BigInteger b1, BigInteger b2) throws RemoteException;
          BigInteger divide(BigInteger b1, BigInteger b2) throws RemoteException;
          BigInteger multiply(BigInteger b1, BigInteger b2) throws RemoteException;
        }

    2. Compile a Interface
       Javac Operator.java

    3. Implementer a Interface Remota

        import   java.rmi.RemoteException;
        import   java.math.BigInteger;
        import   java.rmi.server.UnicastRemoteObject;
        import   java.rmi.Naming;

        public class OperatorServer extends UnicastRemoteObject implements Operator
        {
          public OperatorServer() throws RemoteException { }
          public BigInteger add(BigInteger b1, BigInteger b2) throws RemoteException {
            return b1.add(b2);
          }




                                                                        Página 9 de 11
public BigInteger subtract(BigInteger b1, BigInteger b2) throws
   RemoteException {
       return b1.subtract(b2);
     }
     public BigInteger divide(BigInteger b1, BigInteger b2) throws RemoteException
   {
       return b1.divide(b2);
     }
     public BigInteger multiply(BigInteger b1, BigInteger b2) throws
   RemoteException {
       return b1.multiply(b2);
     }
    public static void main(String []args) {
       String name = "//localhost/OperatorServer";
       try {
         OperatorServer os = new OperatorServer();
         Naming.rebind(name,os);
         System.out.println(name + " bound");
       } catch (Exception e) {
         System.err.println("OperatorServer exception: " + e.getMessage());
         e.printStackTrace();
       }
     }
   }


4. Compile a classe servidor
   javac OperatorServer.java

5. Crie o Stub e o Skeleton
   rmic OperatorServer

6. Verifique se as seguintes classes estão criadas

   OperatorServer.class
   OperatorServer.java
   OperatorServer_Skel.class
   OperatorServer_Stub.class

7. Crie a classe cliente

   import java.rmi.Naming;
   import java.math.BigInteger;

   public class OperatorClient {

     public static void main(String args[]) {
      String name = "//localhost/OperatorServer";
      try {
      Operator o = (Operator)Naming.lookup (name);

      BigInteger b1 = new BigInteger("1234567");
      BigInteger b2 = new BigInteger("1");
      BigInteger b3 = o.add(b1, b2);
      System.out.println("b3: " + b3);

      } catch( Exception e) {
        System.out.println(e); e.printStackTrace();
      }




                                                                  Página 10 de 11
}
   }

8. Compile a classe cliente
   Javac OperatorClient.java

9. Abra um consola do MS DOS
    rmiregistry
10. Abra a 2ª consola do MS DOS – execução da aplicação servidor
    java OperatorServer

    Vais mostrar: //localhost/OperatorServerbound
11. Abra a 3ª consola do MS DOS – execução da aplicação cliente
    java OperatorClient

   Vais mostrar: 1234568




                                                                   Página 11 de 11

Mais conteúdo relacionado

Mais procurados

05 - Sincronização de Threads - I
05 - Sincronização de Threads - I05 - Sincronização de Threads - I
05 - Sincronização de Threads - IFabio Moura Pereira
 
Microsoft Community Launch 2010: .NET Framework 4
Microsoft Community Launch 2010: .NET Framework 4Microsoft Community Launch 2010: .NET Framework 4
Microsoft Community Launch 2010: .NET Framework 4Rogério Moraes de Carvalho
 
Programação Concorrente - Gerenciamento de Threads - Parte II
Programação Concorrente - Gerenciamento de Threads - Parte IIProgramação Concorrente - Gerenciamento de Threads - Parte II
Programação Concorrente - Gerenciamento de Threads - Parte IIFabio Moura Pereira
 
1089335456 paper 4 sockets em java
1089335456 paper 4   sockets em java1089335456 paper 4   sockets em java
1089335456 paper 4 sockets em javajosealcides2005
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)Helder da Rocha
 
Objetos distribuídos e invocação remota - CORBA
Objetos distribuídos e invocação remota - CORBAObjetos distribuídos e invocação remota - CORBA
Objetos distribuídos e invocação remota - CORBAWagner Bonfim
 
Phalcon FrameWork - Considerações Iniciais
Phalcon FrameWork - Considerações IniciaisPhalcon FrameWork - Considerações Iniciais
Phalcon FrameWork - Considerações IniciaisPauloRobertoBolsanel
 
php orientado_a_objetos
php orientado_a_objetosphp orientado_a_objetos
php orientado_a_objetosFer Nando
 
40 php orientado a objetos
40 php orientado a objetos40 php orientado a objetos
40 php orientado a objetosFrancisco Santos
 
Concorrência na Linguagem de Programação
Concorrência na Linguagem de ProgramaçãoConcorrência na Linguagem de Programação
Concorrência na Linguagem de ProgramaçãoAlexsandro Pereira
 
The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...
The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...
The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...Rogério Moraes de Carvalho
 
Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO,
Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO, Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO,
Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO, Vinicius Pulgatti
 

Mais procurados (19)

servlet-introducao
servlet-introducaoservlet-introducao
servlet-introducao
 
RMI em Java
RMI em JavaRMI em Java
RMI em Java
 
05 - Sincronização de Threads - I
05 - Sincronização de Threads - I05 - Sincronização de Threads - I
05 - Sincronização de Threads - I
 
Apostila de C# & Asp.Net
Apostila de C# & Asp.NetApostila de C# & Asp.Net
Apostila de C# & Asp.Net
 
Microsoft Community Launch 2010: .NET Framework 4
Microsoft Community Launch 2010: .NET Framework 4Microsoft Community Launch 2010: .NET Framework 4
Microsoft Community Launch 2010: .NET Framework 4
 
A linguagem java
A linguagem javaA linguagem java
A linguagem java
 
Programação Concorrente - Gerenciamento de Threads - Parte II
Programação Concorrente - Gerenciamento de Threads - Parte IIProgramação Concorrente - Gerenciamento de Threads - Parte II
Programação Concorrente - Gerenciamento de Threads - Parte II
 
1089335456 paper 4 sockets em java
1089335456 paper 4   sockets em java1089335456 paper 4   sockets em java
1089335456 paper 4 sockets em java
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)
 
Objetos distribuídos e invocação remota - CORBA
Objetos distribuídos e invocação remota - CORBAObjetos distribuídos e invocação remota - CORBA
Objetos distribuídos e invocação remota - CORBA
 
Phalcon FrameWork - Considerações Iniciais
Phalcon FrameWork - Considerações IniciaisPhalcon FrameWork - Considerações Iniciais
Phalcon FrameWork - Considerações Iniciais
 
php orientado_a_objetos
php orientado_a_objetosphp orientado_a_objetos
php orientado_a_objetos
 
40 php orientado a objetos
40 php orientado a objetos40 php orientado a objetos
40 php orientado a objetos
 
Concorrência na Linguagem de Programação
Concorrência na Linguagem de ProgramaçãoConcorrência na Linguagem de Programação
Concorrência na Linguagem de Programação
 
RMI (Remote Method Invocation)
RMI (Remote Method Invocation) RMI (Remote Method Invocation)
RMI (Remote Method Invocation)
 
The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...
The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...
The Developer's Conference (TDC) 2013 - São Paulo: Programação assíncrona com...
 
Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO,
Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO, Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO,
Apresentação Java, SOA, MICROSERVICE, HTTP, HTTPS, VERSIONAMENTO DE CONTRATO,
 
Java 13
Java 13Java 13
Java 13
 
Aula Tratamento de Exceções
Aula Tratamento de ExceçõesAula Tratamento de Exceções
Aula Tratamento de Exceções
 

Semelhante a Introdução RMI Java

Sistemas Distribuídos - Aula 06
Sistemas Distribuídos - Aula 06Sistemas Distribuídos - Aula 06
Sistemas Distribuídos - Aula 06Arthur Emanuel
 
Sistemas Distribuidos Java
Sistemas Distribuidos JavaSistemas Distribuidos Java
Sistemas Distribuidos Javalimadavi
 
Sistemas Distribuídos - Comunicação Distribuída - Socket
Sistemas Distribuídos - Comunicação Distribuída - SocketSistemas Distribuídos - Comunicação Distribuída - Socket
Sistemas Distribuídos - Comunicação Distribuída - SocketAdriano Teixeira de Souza
 
Webservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHPWebservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHPFlávio Lisboa
 
Apresentação Sistemas Distribuídos - Conceito
Apresentação Sistemas Distribuídos - ConceitoApresentação Sistemas Distribuídos - Conceito
Apresentação Sistemas Distribuídos - ConceitoThiago Marinho
 
JustJava 2005: Web Services em Java com o JWSDP 1.5
JustJava 2005: Web Services em Java com o JWSDP 1.5JustJava 2005: Web Services em Java com o JWSDP 1.5
JustJava 2005: Web Services em Java com o JWSDP 1.5Helder da Rocha
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Strutseduan
 
Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5Lucas Augusto Carvalho
 
Mvc model view controller - java para desenvolvimento web
Mvc   model view controller - java para desenvolvimento webMvc   model view controller - java para desenvolvimento web
Mvc model view controller - java para desenvolvimento webValdir Junior
 
Web Sphere Application Server
Web Sphere Application ServerWeb Sphere Application Server
Web Sphere Application ServerFabricio Carvalho
 
Curso de Java (Parte 7) Web Application
Curso de Java (Parte 7) Web ApplicationCurso de Java (Parte 7) Web Application
Curso de Java (Parte 7) Web ApplicationMario Sergio
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Rafael Benevides
 

Semelhante a Introdução RMI Java (20)

Funmentos de Objetos Remotos
Funmentos de Objetos RemotosFunmentos de Objetos Remotos
Funmentos de Objetos Remotos
 
6-RMI.pdf
6-RMI.pdf6-RMI.pdf
6-RMI.pdf
 
XML-RPC.pdf
XML-RPC.pdfXML-RPC.pdf
XML-RPC.pdf
 
Sistemas Distribuídos - Aula 06
Sistemas Distribuídos - Aula 06Sistemas Distribuídos - Aula 06
Sistemas Distribuídos - Aula 06
 
Sistemas Distribuidos Java
Sistemas Distribuidos JavaSistemas Distribuidos Java
Sistemas Distribuidos Java
 
Sistemas Distribuídos - Comunicação Distribuída - Socket
Sistemas Distribuídos - Comunicação Distribuída - SocketSistemas Distribuídos - Comunicação Distribuída - Socket
Sistemas Distribuídos - Comunicação Distribuída - Socket
 
Webservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHPWebservices e Computação em Nuvem com PHP
Webservices e Computação em Nuvem com PHP
 
Apresentação Sistemas Distribuídos - Conceito
Apresentação Sistemas Distribuídos - ConceitoApresentação Sistemas Distribuídos - Conceito
Apresentação Sistemas Distribuídos - Conceito
 
JustJava 2005: Web Services em Java com o JWSDP 1.5
JustJava 2005: Web Services em Java com o JWSDP 1.5JustJava 2005: Web Services em Java com o JWSDP 1.5
JustJava 2005: Web Services em Java com o JWSDP 1.5
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Struts
 
Apostila de-vb-net
Apostila de-vb-netApostila de-vb-net
Apostila de-vb-net
 
Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5Palestra - Symfony Framework MVC PHP 5
Palestra - Symfony Framework MVC PHP 5
 
Mac5700
Mac5700Mac5700
Mac5700
 
Mvc model view controller - java para desenvolvimento web
Mvc   model view controller - java para desenvolvimento webMvc   model view controller - java para desenvolvimento web
Mvc model view controller - java para desenvolvimento web
 
Web Sphere Application Server
Web Sphere Application ServerWeb Sphere Application Server
Web Sphere Application Server
 
Curso de Java (Parte 7) Web Application
Curso de Java (Parte 7) Web ApplicationCurso de Java (Parte 7) Web Application
Curso de Java (Parte 7) Web Application
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007
 
Web service
Web serviceWeb service
Web service
 
Rmi (remote method invocation)
Rmi (remote method invocation)Rmi (remote method invocation)
Rmi (remote method invocation)
 
Iniciando com realm
Iniciando com realmIniciando com realm
Iniciando com realm
 

Mais de Portal_do_Estudante_SD (11)

Sistemas operativos distribuidos e de redes
Sistemas operativos distribuidos e de redesSistemas operativos distribuidos e de redes
Sistemas operativos distribuidos e de redes
 
Sd capitulo01
Sd capitulo01Sd capitulo01
Sd capitulo01
 
Modelos de estruturação de sistemas distribuídos
Modelos de estruturação de sistemas distribuídosModelos de estruturação de sistemas distribuídos
Modelos de estruturação de sistemas distribuídos
 
Jdbc
JdbcJdbc
Jdbc
 
Corbawebserves
CorbawebservesCorbawebserves
Corbawebserves
 
Conceitos basicos
Conceitos basicosConceitos basicos
Conceitos basicos
 
Caracterizacao de sistemas distribuidos
Caracterizacao de sistemas distribuidosCaracterizacao de sistemas distribuidos
Caracterizacao de sistemas distribuidos
 
Aula sd 2008_02aspectosprojectosds
Aula sd 2008_02aspectosprojectosdsAula sd 2008_02aspectosprojectosds
Aula sd 2008_02aspectosprojectosds
 
Atividade sd
Atividade sdAtividade sd
Atividade sd
 
Arquitectura e modelos de sistemas distribuidos
Arquitectura e modelos de sistemas distribuidosArquitectura e modelos de sistemas distribuidos
Arquitectura e modelos de sistemas distribuidos
 
Sistemas operativos distribuidos
Sistemas operativos distribuidosSistemas operativos distribuidos
Sistemas operativos distribuidos
 

Introdução RMI Java

  • 1. Introdução á Computação Distribuída com RMI A tecnologia RMI - Remote Method Invocation (Invocação de Métodos Remotos), foi primeiramente introduzida no Java, no JDK versão 1.1, elevando a programação para redes em um patamar mais elevado. Apesar do RMI ser relativamente fácil, ele põe o desenvolvedor Java frente à um novo paradigma, o mundo da computação de objectos distribuídos. Este guia prático vai lhe introduzir à esta tecnologia versátil, que melhorou muito desde sua primeira versão. O principal objectivo para os criadores (designers) do RMI era permitir os programadores a desenvolverem programas distribuídos em Java com a mesma sintaxe e semântica usada em programas não-distribuídos. Para isso, eles tiveram que mapear cuidadosamente como classes Java e objectos trabalham em uma única Java Virtual Machine (JVM) para um novo modelo de como as classes e objectos trabalhariam num ambiente distribuído de computação (múltiplas JVMs). Os arquitectos do RMI tentaram fazer com que o uso dos objectos distribuídos em Java fosse similar ao uso de objectos Java locais. Esta secção introduz a arquitectura RMI da perspectiva dos objectos Java remotos distribuídos, e explora as diferenças de comportamento com objectos locais. A arquitectura RMI define como os objectos se comportam, como e quando excepções podem ocorrer, como a memória é gerida e como os parâmetros são passados e retornados de métodos remotos. A arquitectura RMI estende a segurança e robustez da arquitectura Java para o mundo da computação distribuída. A arquitectura RMI é baseada em um importante princípio: a definição do comportamento e a implementação do comportamento são conceitos separados. RMI permite que o código que define o comportamento e o código que implementa o comportamento permanecerem separados e rodarem em JVMs separadas. Em RMI, a definição do serviço remoto é codificada usando uma interface Java. A Página 1 de 11
  • 2. implementação do serviço remoto é codificada em uma classe. Logo, a chave para se entender o RMI é lembrar que as interfaces definem o comportamento e as classes definem a implementação. A classe que implementa o comportamento roda do lado do servidor RMI. A classe que roda no cliente actua como um Proxy para o serviço remoto. Veja o seguinte diagrama: O programa cliente faz chamadas de métodos pelo objecto Proxy, o RMI envia a requisição para a JVM remota e redirecciona para a implementação. Qualquer valor retornado pela implementação é devolvido ao Proxy e então ao programa cliente. Com o entendimento da arquitectura RMI num alto nível, vamos dar uma breve olhada na sua implementação. A implementação do RMI é essencialmente feita de três camadas de abstracção. A camada Stub e Skeleton está abaixo dos olhos do desenvolvedor. Esta camada intercepta as chamadas de métodos feitas pelo cliente para que a variável de referência da interface redirecione essas chamadas para o serviço RMI remoto. A próxima camada é a Remote Reference Layer. Esta camada sabe como interpretar e gerir referências feitas dos clientes para os objectos do serviço remoto. A conexão do cliente ao servidor é Unicast (uma-para-um). A camada de transporte é baseada nas conexões TCP/IP entre as maquinas em uma rede. Usando essa arquitectura de camadas, cada uma das camadas poderia ser facilmente Página 2 de 11
  • 3. melhorada ou substituída sem afectar o resto do sistema. Por exemplo, a camada de transporte poderia ser substituída por uma camada que implemente conexões UDP/IP, sem afectar as camadas superiores. Como um cliente acha o serviço remoto RMI? Os clientes acham os serviços remotos usando o serviço de nomeação ou directório (naming or directory). Isso parece um pouco redundante, mas o serviço de nomeação ou directório roda como um endereço bem formado (host:port). O RMI pode usar diferentes tipos de serviços de directório, incluindo o JNDI. O próprio RMI inclue um simples serviço, chamado de RMI Registry. O RMI Registry roda em cada maquina que hospeda o serviço remoto, por definição na porta 1099. Numa máquina host, um programa servidor cria um serviço remoto, primeiramente criando o objecto que implemente aquele serviço. Em seguida ele exporta aquele objecto para o RMI. Quando o objecto é exportado o RMI cria um serviço que aguarda as conexões do cliente. O servidor registra o objecto no RMI Registry, com um nome público. No lado do cliente o RMI Registry é acedido através da classe estática Naming. Ela provém o método lookup( ), que o cliente usa para requisitar o registro. Esse método aceita a URL que especifica o nome do servidor e o nome do serviço desejado. O método retorna uma referência remota para o objecto do serviço. A URL é formada como seguinte: rmi://<host_name>[:port_number]/<service_name> Página 3 de 11
  • 4. Agora vamos trabalhar com um sistema que realmente implementa um sistema com RMI. Vamos criar um aplicativo simples, cliente e servidor, que executa métodos do objecto remoto. Para tanto não necessitamos de duas máquinas distintas ou com IP distintos. O exemplo pode ser rodado na mesma máquina, pois o RMI sabe como trabalhar com isso, mesmo que o host e o cliente sejam na mesma localidade. Um sistema RMI é composto de várias partes: • Definição das interfaces para os serviços remotos • Implementações dos serviços remotos • Arquivos de Stub e Skeletons • Um servidor para hospedar os serviços remotos • Um serviço de RMI Naming que permite o cliente achar os serviços remotos • Um provedor de arquivos de classes (servidor http ou ftp) • Um programa cliente que necessita os serviços remotos Agora iremos, de fato, criar um sistema que implemente o RMI, utilizando-se de um programa cliente e um programa servidor. Não utilizaremos um servidor FTP ou HTTP, no entanto utilizaremos os programas na mesma máquina e uma mesma estrutura de directórios. Os passos a serem seguidos agora são: • Escrever e compilar o código Java da interface • Escrever e compilar o código Java das implementações das classes • Gerar as classes Stub e Skeleton das classes de implementação Crie um directório para salvar todos os seus arquivos de projecto. Você pode fazer o download do código fonte usado nesse tutorial. O primeiro passo, como dito, será criar a interface e compilá-la. A interface define todas as funcionalidades remotas oferecidas pelo serviço. Nomeio o arquivo como: Mensageiro.java. Página 4 de 11
  • 5. 1 import java.rmi.Remote; 2 import java.rmi.RemoteException; 3 4 public interface Mensageiro extends Remote { 5 6 public void enviarMensagem( String msg ) throws RemoteException; 7 public String lerMensagem() throws RemoteException; 8 } Perceba que esta interface estende a classe Remote, e cada assinatura de método declara as funcionalidades do serviço, e que podem gerar uma excepção RemoteException. Salve este arquivo (Mensageiro.java) no seu directório e compile, com a seguinte linha de comando: javac Mensageiro.java Agora, você deverá escrever a implementação para o serviço remoto, ou seja, o código a ser executado no ambiente remoto. Nomeia o arquivo como: MensageiroImpl.java. 01 import java.rmi.RemoteException; 02 import java.rmi.server.UnicastRemoteObject; 03 04 public class MensageiroImpl extends UnicastRemoteObject implements Mensageiro { 05 06 public MensageiroImpl() throws RemoteException { 07 super(); 08 } 09 10 public void enviarMensagem( String msg ) throws RemoteException { 11 System.out.println( msg ); 12 } 13 14 public String lerMensagem() throws RemoteException { 15 return "This is not a Hello World! message"; 16 } 17 } Salve este arquivo (MensageiroImpl.java) no seu directório e compile, com a seguinte linha de comando: Página 5 de 11
  • 6. javac MensageiroImpl.java Observe que a classe se utiliza (estende) da classe UnicastRemoteObject para ligar com o sistema RMI. Neste exemplo a classe estende a classe UnicastRemoteObject directamente. Isto não é realmente necessário, mas essa discussão fica para uma próxima etapa. Quando uma classe estende a classe UnicastRemoteObject, ele deve prover um construtor que declare que ele pode lançar uma exceção RemoteException, pois quando o método super( ) é chamado, ele activa o código em UnicastRemoteObject, que executa a ligação RMI e a iniciação do objecto remoto. Gere os arquivos Stubs e Skeletons da classe de implementação que roda no servidor. Para tanto, execute o comando rmic, compilador RMI do JDK. rmic MensageiroImpl Após a execução deste comando, você deveria ver no seu diretório os arquivos Mensageiro_Stub.class, Mensageiro_Skeleton.class. Servidor O serviço remoto RMI deve ser hospedado em um processo servidor. A classe MensageiroServer é um servidor bem simples, que provê serviços essenciais. Salve o arquivo como: MensageiroServer.java. 01 import java.rmi.Naming; 02 03 public class MensageiroServer { 04 05 public MensageiroServer() { 06 try { 07 Mensageiro m = new MensageiroImpl(); 08 Naming.rebind("rmi://localhost:1099/MensageiroService", m); Página 6 de 11
  • 7. 09 } 10 catch( Exception e ) { 11 System.out.println( "Trouble: " + e ); 12 } 13 } 14 15 public static void main(String[] args) { 16 new MensageiroServer(); 17 } 18 } Salve este arquivo (MensageiroServer.java) no seu diretório e compile, com a seguinte linha de comando: > javac MensageiroServer.java O código fonte para o cliente é o seguinte. Salve o arquivo como: MensageiroClient.java. 01 import java.rmi.Naming; 02 import java.rmi.RemoteException; 03 import java.rmi.NotBoundException; 04 import java.net.MalformedURLException; 05 06 public class MensageiroClient { 07 08 public static void main( String args[] ) { 09 try { 10 Mensageiro m = (Mensageiro) Naming.lookup( "rmi://localhost/MensageiroService" ); 11 System.out.println( m.lerMensagem() ); 12 m.enviarMensagem( "Hello World!" ); 13 } 14 catch( MalformedURLException e ) { 15 System.out.println(); 16 System.out.println( "MalformedURLException: " + e.toString() ); 17 } 18 catch( RemoteException e ) { 19 System.out.println(); 20 System.out.println( "RemoteException: " + e.toString() ); 21 } 22 catch( NotBoundException e ) { 23 System.out.println(); 24 System.out.println( "NotBoundException: " + e.toString() ); 25 } 26 catch( Exception e ) { 27 System.out.println(); 28 System.out.println( "Exception: " + e.toString() ); 29 } 30 } 31 } Página 7 de 11
  • 8. Salve este arquivo (MensageiroClient.java) no seu diretório e compile, com a seguinte linha de comando: javac MensageiroClient.java Agora que todos os arquivos do projeto de exemplo foram criados e devidamente compilados, estamos prontos para rodar o sistema! Você precisará abrir três diferentes consoles do MS-DOS no seu Windows, ou outro, caso utilize um diferente sistema operacional. Em um dos consoles vai rodar o programa servidor, no outro o cliente e no terceiro o RMI Registry. Inicie com o RMI Registry. Você deve estar no mesmo diretório em que estão gravados seus arquivos para rodar o aplicativo. Execute a seguinte linha de comando: rmiregistry Isso irá iniciar o RMI Registry e rodá-lo. No segundo console vamos executar o programa servidor. Você deve estar no mesmo directório em que estão gravados seus arquivos para rodar o aplicativo. Execute o seguinte comando: java MensageiroServer Isso irá iniciar, carregar a implementação na memória e esperar pela conexão cliente. No último console, rode o programa cliente. Você deve estar no mesmo directório em que estão gravados seus arquivos para rodar o aplicativo. Execute o comando: java MensageiroClient Página 8 de 11
  • 9. Se tudo correr bem, que é o que esperamos e o que deveria acontecer, a seguinte saída será gerada nos consoles 2 (servidor) e 3 (cliente). No console 2 (servidor): Hellow World! No console 3 (cliente): This is not a Hello World! message É isso aí. Você acabou de criar um sistema utilizando a tecnologia RMI. Apesar de você ter rodado os programas na mesma máquina, o RMI usa a pilha de rede TCP/IP para se comunicar entre as três diferentes instâncias da JVM. Exercício: 1. Defina a Interface Remota import java.rmi.Remote; import java.rmi.RemoteException; import java.math.BigInteger; public interface Operator extends Remote { BigInteger add(BigInteger b1, BigInteger b2) throws RemoteException; BigInteger subtract(BigInteger b1, BigInteger b2) throws RemoteException; BigInteger divide(BigInteger b1, BigInteger b2) throws RemoteException; BigInteger multiply(BigInteger b1, BigInteger b2) throws RemoteException; } 2. Compile a Interface Javac Operator.java 3. Implementer a Interface Remota import java.rmi.RemoteException; import java.math.BigInteger; import java.rmi.server.UnicastRemoteObject; import java.rmi.Naming; public class OperatorServer extends UnicastRemoteObject implements Operator { public OperatorServer() throws RemoteException { } public BigInteger add(BigInteger b1, BigInteger b2) throws RemoteException { return b1.add(b2); } Página 9 de 11
  • 10. public BigInteger subtract(BigInteger b1, BigInteger b2) throws RemoteException { return b1.subtract(b2); } public BigInteger divide(BigInteger b1, BigInteger b2) throws RemoteException { return b1.divide(b2); } public BigInteger multiply(BigInteger b1, BigInteger b2) throws RemoteException { return b1.multiply(b2); } public static void main(String []args) { String name = "//localhost/OperatorServer"; try { OperatorServer os = new OperatorServer(); Naming.rebind(name,os); System.out.println(name + " bound"); } catch (Exception e) { System.err.println("OperatorServer exception: " + e.getMessage()); e.printStackTrace(); } } } 4. Compile a classe servidor javac OperatorServer.java 5. Crie o Stub e o Skeleton rmic OperatorServer 6. Verifique se as seguintes classes estão criadas OperatorServer.class OperatorServer.java OperatorServer_Skel.class OperatorServer_Stub.class 7. Crie a classe cliente import java.rmi.Naming; import java.math.BigInteger; public class OperatorClient { public static void main(String args[]) { String name = "//localhost/OperatorServer"; try { Operator o = (Operator)Naming.lookup (name); BigInteger b1 = new BigInteger("1234567"); BigInteger b2 = new BigInteger("1"); BigInteger b3 = o.add(b1, b2); System.out.println("b3: " + b3); } catch( Exception e) { System.out.println(e); e.printStackTrace(); } Página 10 de 11
  • 11. } } 8. Compile a classe cliente Javac OperatorClient.java 9. Abra um consola do MS DOS rmiregistry 10. Abra a 2ª consola do MS DOS – execução da aplicação servidor java OperatorServer Vais mostrar: //localhost/OperatorServerbound 11. Abra a 3ª consola do MS DOS – execução da aplicação cliente java OperatorClient Vais mostrar: 1234568 Página 11 de 11