CAPÍTULO 7 JAVA 7.1 CARACTERÍSTICAS DA LINGUAGEM



Documentos relacionados
Adriano Reine Bueno Rafael Barros Silva

Invocação de Métodos Remotos

Hardware (Nível 0) Organização. Interface de Máquina (IM) Interface Interna de Microprogramação (IIMP)

Sistemas Distribuídos Capítulos 3 e 4 - Aula 4

SISTEMAS DISTRIBUIDOS

Fundamentos de Java. Prof. Marcelo Cohen. 1. Histórico

Sistemas Operacionais

3 SCS: Sistema de Componentes de Software

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

Sistemas Distribuídos

3 Um Framework Orientado a Aspectos para Monitoramento e Análise de Processos de Negócio

Sistemas Distribuídos

UNIVERSIDADE. Sistemas Distribuídos


IMPLEMENTAÇÃO DE SOCKETS E THREADS NO DESENVOLVIMENTO DE SISTEMAS CLIENTE / SERVIDOR: UM ESTUDO EM VB.NET

Invocação de Métodos Remotos RMI (Remote Method Invocation)

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

4 Estrutura do Sistema Operacional Kernel

Prof. Marcos Ribeiro Quinet de Andrade Universidade Federal Fluminense - UFF Pólo Universitário de Rio das Ostras - PURO

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

MÓDULO 7 Modelo OSI. 7.1 Serviços Versus Protocolos

Um Driver NDIS Para Interceptação de Datagramas IP

Intranets. FERNANDO ALBUQUERQUE Departamento de Ciência da Computação Universidade de Brasília 1.INTRODUÇÃO

Sistemas Distribuídos

APLICAÇÃO REDE APLICAÇÃO APRESENTAÇÃO SESSÃO TRANSPORTE REDE LINK DE DADOS FÍSICA 1/5 PROTOCOLOS DE REDE

CONCEITOS INICIAIS. Agenda A diferença entre páginas Web, Home Page e apresentação Web;

Introdução. à Linguagem JAVA. Prof. Dr. Jesus, Edison O. Instituto de Matemática e Computação. Laboratório de Visão Computacional

Introdução à Linguagem Java

Sistemas Distribuídos

IFPE. Disciplina: Sistemas Operacionais. Prof. Anderson Luiz Moreira

UFG - Instituto de Informática

2 Diagrama de Caso de Uso

1

UNIVERSIDADE. Sistemas Distribuídos

Sistemas Distribuídos

Introdução ao Modelos de Duas Camadas Cliente Servidor

OURO MODERNO Web Designer APOSTILA DE EXEMPLO. (Esta é só uma reprodução parcial do conteúdo)

TRANSMISSÃO DE DADOS Prof. Ricardo Rodrigues Barcelar

ESTUDO DE CASO WINDOWS VISTA

Considerações no Projeto de Sistemas Cliente/Servidor

Entendendo como funciona o NAT

Sistemas Distribuídos RPC x RMI. Edeyson Andrade Gomes

Sistemas distribuídos:comunicação

4. Qual seria o impacto da escolha de uma chave que possua letras repetidas em uma cifra de transposição?

Roteiro para a escrita do documento de Especificação de Requisitos de Software (ERS)

Sistemas Operacionais

Modelos de Camadas. Professor Leonardo Larback

3 SERVIÇOS IP. 3.1 Serviços IP e alguns aspectos de segurança

Teleprocessamento e Redes (MAB-510) Gabarito da Segunda Lista de Exercícios 01/2010

Processos (Threads,Virtualização e Migração de Código)

5 Mecanismo de seleção de componentes

Orientação a Objetos

Desenvolvendo uma Arquitetura de Componentes Orientada a Serviço SCA

Chamadas Remotas de Procedimentos (RPC) O Conceito de Procedimentos. RPC: Programa Distribuído. RPC: Modelo de Execução

REDES DE COMPUTADORES

USO GERAL DOS PROTOCOLOS SMTP, FTP, TCP, UDP E IP

Redes de Computadores II. Professor Airton Ribeiro de Sousa

Linguagem de Programação Orientada a Objeto. Introdução a Orientação a Objetos Professora Sheila Cáceres

Um pouco do Java. Prof. Eduardo

TECNOLOGIA WEB. Principais Protocolos na Internet Aula 2. Profa. Rosemary Melo

Curso Tecnológico de Redes de Computadores 5º período Disciplina: Tecnologia WEB Professor: José Maurício S. Pinheiro V

Java. Marcio de Carvalho Victorino

Capítulo VI CORBA. Common Object Request Broker Architecture. [Cardoso2008] Programação de Sistemas Distribuídos em Java, Jorge Cardoso, FCA, 2008.

INFORMÁTICA FUNDAMENTOS DE INTERNET. Prof. Marcondes Ribeiro Lima

Sistemas Distribuídos

Esta dissertação apresentou duas abordagens para integração entre a linguagem Lua e o Common Language Runtime. O objetivo principal da integração foi

Professor: Macêdo Firmino Disciplina: Sistemas Operacionais de Rede

INE Sistemas Distribuídos

Aspectos técnicos do desenvolvimento baseado em componentes

Capítulo 9 - Conjunto de Protocolos TCP/IP e Endereçamento. Associação dos Instrutores NetAcademy - Julho de Página

3. Explique o motivo pelo qual os protocolos UDP e TCP acrescentam a informação das portas (TSAP) de origem e de destino em seu cabeçalho.

Software de segurança em redes para monitoração de pacotes em uma conexão TCP/IP

REDES DE COMPUTADORES Prof. Ricardo Rodrigues Barcelar

Notas da Aula 15 - Fundamentos de Sistemas Operacionais

Redes de Computadores. Protocolos de comunicação: TCP, UDP

RMI: Uma Visão Conceitual

MODELO CLIENTE SERVIDOR

Arquiteturas de Rede. Prof. Leonardo Barreto Campos

Arquitetura de Rede de Computadores

FBV - Linguagem de Programação II. Um pouco sobre Java

Camadas de Transporte, Sessão & Apresentação. Função. Camadas REDES x TRANSPORTE. Redes de Computadores Prof. Leandro C. Pykosz

Capítulo 7 CAMADA DE TRANSPORTE

Protocolos Hierárquicos

Sistemas Operacionais. Prof. M.Sc. Sérgio Teixeira. Aula 05 Estrutura e arquitetura do SO Parte 2. Cursos de Computação

TCP/IP TCP UDP IP HTTP HTTPS FTP TFTP TELNET POP3 IMAP SMTP SNMP DHCP

Disciplina Fundamentos de Redes. Introdução ao Endereço IP. Professor Airton Ribeiro de Sousa Outubro de 2014

Prof. José Maurício S. Pinheiro UniFOA

SISTEMAS OPERACIONAIS. Maquinas Virtuais e Emuladores

SIMULADOR DE ROTEAMENTO DE PACOTES (V. 3 20/05/2010)

CAPÍTULO 7 NÍVEL DE LINGUAGEM DE MONTAGEM

Comunicando através da rede

Eduardo Bezerra. Editora Campus/Elsevier

SMTP, POP, IMAP, DHCP e SNMP. Professor Leonardo Larback

Desenvolvimento de uma Aplicação de Controle de Créditos Usando a Tecnologia MIFARE

CA Nimsoft Monitor Snap

Transcrição:

CAPÍTULO 7 JAVA Java é uma linguagem orientada a objeto cujo projeto foi desenvolvido pela Sun Microsystems no início de 1991. Ela foi originalmente concebida para ser utilizada na programação de dispositivos de consumo ( consumer devices ). Por volta de 1995, quando houve a explosão no uso da Internet, notou-se que Java era uma linguagem de programação ideal para este tipo de aplicação, uma vez que ela endereçava muitas questões de softwares distribuídos através de redes, tais como: interoperabilidade, portabilidade e segurança (Tilley, 1999). 7.1 CARACTERÍSTICAS DA LINGUAGEM Java é uma linguagem de programação que apresenta uma sintaxe próxima ao C e C++, sendo porém menos complexa que o C++. Estas características a tornam familiar à maioria dos desenvolvedores. Ela provê garbage collection, isto é, torna disponível um mecanismo que se encarrega de desalocar, automaticamentente, da memória todos os objetos que não estão sendo mais referenciados, suporta herança de classe simples e não usa ponteiros (Deitel e Deitel, 1997). Java provê flexibilidade porque as classes são linkadas na medida em que são necessárias para atender as requisições dos clientes, existindo também a possibilidade de ser feito o download dessas classes através da rede. Tal flexibilidade é uma mudança de paradigma na computação que requer todas as funcionalidades instaladas na plataforma do usuário antes da execução de uma aplicação (Tilley, 1999). 187

Ao contrário da maioria das linguagens de programação, o código escrito em Java não é compilado para uma máquina real, mas sim para uma virtual, chamada máquina virtual Java ( Java Virtual Machine JVM), cujas características são mantidas em qualquer tipo de hardware ou sistema operacional (Lemay e Perkins, 1997). Os aplicativos do Java dividem-se em dois grupos: os applets e as aplicações Java. Um applet é um programa escrito em Java que executa em um browser Web compatível com essa linguagem. Ele é carregado e executado ao mesmo tempo em que aparece, na tela do cliente, a apresentação de uma página de visualização. Agora, uma aplicação Java independente ( standalone ) é um programa escrito em Java que executa fora do browser Web, mas apenas onde existir uma JVM disponível. Os passos necessários para a construção de um aplicativo Java são listados a seguir (Lemay e Perkins, 1997): Escrever o código do programa em Java, mantendo um arquivo por classe. Compilar os arquivos com o programa fonte da aplicação para que possam ser executados na JVM. Como resultado, são gerados os arquivos <.class>, conhecidos como bytecodes, representando arquivos prontos para serem interpretados. Bytecode é um conjunto de instruções bastante parecida com alguns códigos de máquina, mas não é específica a nenhum processador. Este bytecode pode ser interpretado por qualquer compilador que possua uma JVM. Utilizar um software com as características JVM para executar os arquivos bytecodes através da emulação, isto é, interpretação dos comandos virtuais para a máquina ou ambiente real. Os arquivos <.class> podem ser carregados ou transferidos entre estações de trabalho e interpretados por qualquer JVM nelas disponível. O bytecode Java 188

provê portabilidade porque não é específico a nenhuma plataformas em particular nem nativo a qualquer processador. Entretanto, antes de serem executados, os bytecodes passam por uma verificação, onde os seguintes aspectos são observados (Lemay e Perkins, 1997): Se o código está de acordo com as especificações Java. Se o código não viola a integridade do sistema. Se o código não causa overflow ou underflow nas operações com pilhas. Se os tipos de parâmetros para os códigos estão corretos. Se não existem conversões ilegais de dados. Se o código não viola direitos de acesso a objetos. Se o código não força a mudança de tipos de objeto. Após passar por todos os testes, o arquivo <.class> poderá ser executado. Existe ainda outros mecanismos de segurança adicionais que fazem parte do núcleo do sistema Java, são eles (Shoffner e Hughes, 1999): o carregador de classes ( class loader ) e o gerenciador de segurança ( security manager ). O Java, atualmente, define três domínios possíveis: o computador local, a rede local onde o computador encontra-se localizado e a Internet. Cada um desses é tratado diferentemente pelo class loader, onde ele nunca permite que uma classe de um domínio menos protegido substitua uma classe de um outro domínio mais protegido. Classes em um domínio não podem recorrer a métodos de classes em outros domínios, a menos que essas classes tenham declarado explicitamente esses métodos como públicos. O gerenciador de segurança é uma classe adicionada recentemente ao Java reunindo, em um só lugar, todas as decisões sobre a política de segurança, isto é, quais aspectos de segurança um sistema deve suportar em relação a execução dos programas. 189

Assim, o gerenciador de segurança regula o acesso às funções sensíveis e o carregador de classes garante a aderência das mesmas às normas de segurança definidas pelo padrão Java. 7.1.1 INTERFACE Java suporta herança simples, isto é, cada classe Java pode ter somente uma superclasse, embora qualquer superclasse possa ter várias subclasses. Em outras linguagens de programação como C++ e Smalltalk as classes podem ter mais de uma superclasse herdando variáveis e métodos combinados dessas superclasses. A herança simples torna o relacionamento entre as classes e a funcionalidade que elas implementam simples de entender e projetar, mas de certa forma restritivo, por exemplo, comportamentos semelhantes precisam ser duplicados ao longo de diferentes ramificações da hierarquia de classes. O Java utiliza, para sanar as restrições de comportamento compartilhado, o conceito de interfaces. Uma interface, para o Java, é uma coleção de nomes de métodos indicando o comportamento de uma classe (Lemay e Perkins, 1997). Embora uma classe Java possa ter somente uma superclasse (herança simples) ela pode implementar qualquer número de interfaces. Uma classe oferece implementações aos métodos definidos na interface. Duas classes A e B diferentes podem implementar a mesma interface, mas o resultado da execução de um dos métodos definido nessa interface obtido através da classe A pode ser diferente do obtido pela classe B. As interfaces no Java suportam o conceito de herança múltipla de interface, passando para as suas filhas somente as descrições dos métodos e não a implementação desses métodos. As interfaces, como as classes, são declaradas em arquivos, sendo um para cada interface. Assim, como as classes elas são compiladas em arquivos <.class>. As interfaces 190

complementam e estendem o poder das classes e as duas podem ser tratadas praticamente da mesma maneira. A diferença é que uma classe pode ser instanciada enquanto uma interface não. Java não utiliza para definir uma interface uma linguagem de definição de interface (IDL) específica, a definição é escrita na própria linguagem de programação Java. 7.1.2 BIBLIOTECAS JAVA Java contém uma série de classes pré-definidas agrupadas em categorias chamadas pacotes. Juntos esses pacotes são referenciados como APIs Java ( Java Application Programming Interfaces ). A seguir são listados os pacotes Java disponíveis (Deitel e Deitel, 1997): java.applet ( Java Applet Package ), esse pacote contém a classe Applet e várias interfaces que habilitam a criação desses applets, assim como, interação entre applets / browsers e applets / audio. java.awt ( Java Abstract Windowing Toolkit Package ), esse pacote contém todas as classes e interfaces necessárias para um usuário criar e manipular interfaces gráficas (GUI). java.awt.image ( Java Abstract Windowing Toolkit Image Package ), esse pacote contém todas as classes e interfaces que habilitam armazenamento e manipulação de imagens num programa. java.awt.peer ( Java Abstract Windowing Toolkit Peer Package ), esse pacote contém interfaces que habilitam a interação dos componentes gráficos do Java em diferentes plataformas. java.io ( Java Input/Output Package ), esse pacote contém classes que manipulam entrada e saída de dados. 191

java.lang ( Java Language Package ), esse pacote é automaticamente importado em todos os programas. Ele contém classes e interfaces básicas necessárias a muitos programas Java. java.net ( Java Networking Package ), esse pacote contém classes que habilitam a comunicação entre programas via Internet e Intranets corporativas. java.util ( Java Utilities Package ), esse pacote contém classes e interfaces de propósito geral como, manipulação de data e hora, armazenamento e processamento de grande quantidade de dados, etc. E mais recentemente, java.rmi ( Java Remote Method Invocation Package ), esse pacote contém classes e interfaces que habilitam a invocação de métodos remotos entre aplicações Java. Applets e aplicações Java, em diferentes máquinas, comunicam-se diretamente através da invocação de seus métodos. java.server ( Java Server Package ), esse pacote contém classes e interfaces que facilitam a criação de servidores Java. java.security ( Java Security Package ), esse pacote contém classes e interfaces que facilitam ao desenvolvedor estabelecer a política de segurança, como por exemplo, o uso de criptografia e assinatura digital. Assim, a Figura 7.1 mostra o ambiente Java. 192

Java Applets Aplicações Java independentes Web browser Applets Java executando em um browser Aplicações Java independentes interagindo com o Sist.Operacional através de um ambiente de execução Ambiente de execução Java (Java Developer s Kit - JDK) -Carregador de classe -Interpretador de bytecode -Java Virtual Machine (JVM) -Biblioteca de Classes Java Compilador JIT (opcional) Compiladores JIT (Just-in-Time) converte de forma otimizada o bytecode Java em código nativo Windows MacOS/ PowerPC UNIX/RISC Outras Plataformas Fig. 7.1 Ambiente Java FONTE: Adaptada de Tilley (1999, p.2) 193

7.2 RMI Sistemas distribuídos necessitam que aplicações, executando em vários espaços de endereçamento, normalmente em diferentes computadores, sejam capazes de se comunicarem. Para um mecanismo de comunicação básico, a linguagem Java suporta o conceito de socket. A seguir, é descrito, brevemente, este conceito. O endereçamento de equipamentos na Internet é baseado em um identificador que independe da tecnologia de rede envolvida, conhecido como endereço IP ( Internet Protocol ), cujo formato é o do exemplo a seguir: 128.32.96.4. Este formato representa um número de 32 bits que, no modo normal de endereçamento da Internet, está associado a um único equipamento. Ele identifica a rede e o seu equipamento nela. Existe um outro modo de endereçamento conhecido como multicasting, onde um endereço IP está associado a um grupo de computadores. O endereço IP permite apenas a localização de um dado equipamento na Internet; para a localização de uma aplicação qualquer executando nesse equipamento, existe um outro identificador conhecido como port. Esta localização é obtida através da associação do port com um dos protocolos de transporte Transmission Control Protocol (TCP) ou User Datagram Protocol (UDP). Essa tríade composta por endereço IP, número de port e protocolo de transporte é conhecida como socket (Cyclades Brasil, 1996). Apesar do socket ser flexível o suficiente para comunicação em geral, ele requer do cliente e do servidor o conhecimento dos protocolos para troca de mensagens, isto é, a codificação e decodificação destas mensagens. O projeto destes protocolos é sempre difícil e susceptível a erros. Assim, o Java suporta o conceito de invocação de método remoto ( Remote Method Invocation RMI) permitindo uma abstração maior ao desenvolvedor que não precisa se preocupar com o mecanismo de comunicação entre cliente e servidor. 194

RMI permite manipular objetos distribuídos utilizando Java. Exemplificando, assim como o CORBA especificou um padrão de comunicação entre cliente e servidor, onde esses podem ser escritos em qualquer linguagem de programação, o padrão RMI foi projetado para ser especialmente integrado à linguagem Java, isto é, clientes escritos em Java se comunicam com objetos escritos em Java através do RMI. Basicamente o RMI é um RPC, que ao invés de realizar chamadas a procedimento remotos realiza chamadas a métodos de um objeto remoto. Um objeto remoto é aquele que se localiza em uma JVM diferente daquela em que se encontra o cliente, potencialmente em outro computador. Um objeto remoto é descrito por uma ou mais interfaces escritas na própria linguagem de programação Java. Por ser tratar de um objeto remoto estas interfaces são chamadas de interfaces remotas. A invocação de um método de um objeto remoto tem a mesma sintaxe que a invocação de um método de um objeto local. O cliente quando invoca um objeto não sabe se esse objeto é local ou remoto em relação a ele. O RMI providencia a: Localização ( binding ) de um método de um objeto remoto. Comunicação através de uma conexão de rede confiável permitindo a transmissão de requisições e respostas, funcionando como um canal entre cliente e servidor. Interface com usuário convertendo uma chamada de método em um bloco de dados (mensagem) que possa trafegar através da conexão e remontando a mesma chamada de método no outro extremo (remoto) a partir desta mensagem. São necessários códigos nos pontos finais da conexão para deixar transparente o uso do RMI pelo usuário. No lado cliente, um stub tem a mesma assinatura (nome, argumentos e tipo de retorno) que o método remoto e sua função é empacotar os argumentos em 195

uma mensagem para ser enviada através do canal de comunicação. Quando uma mensagem contendo os resultados enviados pelo servidor surgir neste canal, o stub extrai o valor de retorno antes de passá-lo para o código que chamou o método. O complemento do stub, localizado no lado do servidor, é chamado de skeleton. Sua função é converter as mensagens que chegam pelo canal de comunicação em argumentos e chamar as implementações dos métodos requisitados. Quando o método termina a execução, o valor de retorno é convertido em uma mensagem que é remetida ao stub do cliente. A arquitetura em que se baseia o RMI consiste de 3 camadas: a camada stub / skeleton, a camada de referência remota ( remote reference ) e a camada de transporte, mostradas na Figura 7.2. Elas são independentes entre si e podem ser substituídas por diferentes implementações sem que umas afetem as outras. Por exemplo, pode-se substituir a camada de transporte implementada em TCP, usando socket Java, por outra baseada em UDP. 196

Interface do objeto Implementação do objeto Call ( ) Call ( ) return return Stubs Referência Remota Skeleton Referência Remota Transporte Transporte Máquina do cliente Máquina Remota Conexão TCP/IP Fig. 7.2 RMI FONTE: Adaptada de Java (1999, p.2) 7.2.1 CAMADA STUB / SKELETON A camada stub / skeleton é a interface entre a aplicação e as outras camadas que compõem o RMI. Esta camada não trata do transporte em si, mas é responsável por transmitir os dados para a camada de referência remota como um stream de dados. Esse stream chamado de marshal stream emprega o mecanismo de serialização de objeto ( object serialization ). Este mecanismo permite que numa invocação (local ou remota) objetos Java possam ser passados como argumentos ou retornados como resultado da execução de 197

métodos. Os objetos Java, transmitidos através deste sistema de serialização de objetos, são passados por cópia entre espaços de endereçamento diferentes, isto é, máquinas diferentes. Caso já sejam objetos remotos, eles serão repassados por referência, onde referência de um objeto remoto é a referência de uma instância desse objeto. A serialização de objeto é específica da linguagem Java, assim, tanto clientes quanto servidores devem estar escritos em Java (Albuquerque, 1998). Quando um cliente invoca um método de um objeto remoto, os parâmetros do método são convertidos em um bloco de dados (mensagem) pelo stub e esta mensagem é enviada a máquina remota utilizando o protocolo, por exemplo, TCP/IP. Quando a mensagem chega na máquina remota, o skeleton transforma esta mensagem em argumentos e chama a implementação do método convertendo o resultado em uma mensagem que é redirecionada a máquina cliente, cujo stub é responsável pela extração do valor de retorno. O stub que se localiza no lado cliente contém todas as interfaces suportadas pela implementação do objeto remoto, sendo responsável por (Java, 1999): Iniciar a chamada do objeto remoto (acionando a camada de referência remota). Fazer o marshaling dos argumentos, utilizando o mecanismo de serialização de objeto, que será enviado para a camada de referência remota. Informar à camada de referência remota que a chamada pode ser invocada. Fazer o unmarshaling do valor de retorno ou exceção obtido. Informar à camada de referência remota que a chamada foi completada. O skeleton que se localiza no lado servidor contém um método que envia as chamadas recebidas do cliente para a implementação do objeto remoto, sendo responsável por (Java, 1999): 198

Fazer o unmarshaling dos argumentos recebidos. Realizar a chamada da implementação do objeto que executará o serviço requerido pelo cliente remoto. Fazer o marshaling do valor de retorno ou da situação de exceção, caso ocorra, utilizando o mecanismo de serialização de objeto que será enviado para a origem da chamada. As classes dos stubs e skeletons apropriadas são determinadas em tempo de execução e carregadas dinamicamente quando necessárias para atender uma requisiçâo do cliente. 7.2.2 CAMADA DE REFERÊNCIA REMOTA A camada de referência remota lida com a interface de transporte de baixo nível por meio de um protocolo. Esse protocolo é independente do stub do cliente e skeleton do servidor. O stub e skeleton desconhecem os diversos tipos de protocolo que um servidor pode utilizar. Existem vários protocolos que podem ser especificados e executados por esta camada, tais como (Java, 1999): Servidores suportam somente invocação ponto-a-ponto, onde um cliente interage com um único objeto. Servidores suportam replicação, onde um número de objetos remotos replicados precisam se manter sincronizados sempre que uma instância é modificada. Objetos remotos não estão continuamente ativos, sendo somente carregados do disco quando um cliente invoca um de seus métodos. Este protocolo pode ser selecionado pelo usuário que escolhe como a camada de referência será utilizada. Atualmente, a implementação da camada de referência está restrita a invocação ponto-a-ponto, onde um cliente interage 199

com um único objeto (não replicado) cuja referência é somente válida quando o processo servidor está executando. A classe que implementa esse protocolo é a java.rmi.server.unicastremoteserver. 7.2.3 CAMADA DE TRANSPORTE A camada de transporte manipula os detalhes da conexão e providencia um canal de comunicação entre as JVMs executando o código cliente e código servidor. O lado cliente deve possuir a interface do objeto remoto para poder referenciá-lo, enquanto o lado servidor possui a implementação do mesmo. Em geral, esta camada é responsável por (Java, 1999): Estabelecer conexões entre espaços de endereçamentos remotos, isto é, entre JVMs diferentes. Gerenciar conexões. Monitorar conexões (se elas existem ou não ( liveness )). Escutar chamadas que estejam sendo recebidas. Manter uma tabela que contém os objetos remotos residentes num determinado espaço de endereçamento. Estabelecer a conexão para as chamadas que estejam sendo recebidas. Localizar o alvo de uma chamada remota passando a conexão para quem a chamou. 7.3 APLICAÇÕES UTILIZANDO RMI O RMI, utilizando a facilidade de nomeação ( rmiregistry ), implementa um objeto servidor de nomes que mantem registrados todos os objetos localizados num host com os seus respectivos nomes, tornando acessível a referência desses objetos ao cliente. Uma aplicação cliente típica para invocar métodos de um objeto remoto deve obter primeiro a referência desse objeto. Essa referência é passada ao servidor que localizará a implementação do 200

objeto. O RMI trata os detalhes de comunicação entre cliente e servidor, assim, o cliente vê a invocação de um método de um objeto remoto como a de um objeto local. RMI (a) Registro Cliente RMI (c) Protocolo URL RMI (b) Servidor Protocolo URL Servidor Web Protocolo URL Fig. 7.3 Aplicações de objetos distribuídos com RMI FONTE: Adaptada de Java (1999, p.2) Na Figura 7.3 um cliente (RMI (a)) utiliza o sistema de registro para obter a referência de um objeto remoto, após obtida, invoca os seus métodos (RMI (b)). Caso seja necessário o RMI pode, se o cliente autorizar, utilizar o servidor web para localizar e carregar objetos remotos, isto é, classes Java em bytecodes. Para o carregamento pode-se utilizar qualquer protocolo Uniform Resource Locator (URL) suportado pelo sistema Java, por exemplo, HTTP, FTP, file, etc. Essas classes podem ser carregadas para serem executadas no servidor ou no cliente. Em aplicações que utilizam RMI, o método é executado na máquina onde se encontra o objeto sobre o qual ele atua. O objeto pode estar tanto em uma máquina diferente daquela onde se encontra o cliente quanto na mesma máquina. 201

7.4 CARREGAMENTO DINÂMICO DE STUB Em sistemas onde se utiliza o RPC, o código do stub deve ser gerado e linkado junto ao cliente antes de sua execução. Este código pode ser linkado estaticamente ou linkado dinamicamente em tempo de execução, utilizando para isso bibliotecas disponíveis localmente ou na rede. Em ambos os casos, o código que realiza o RPC deve estar disponível, na forma compilada, na máquina do cliente. O RMI generaliza essa técnica de carregar o código do stub em tempo de execução. Essa generalização do carregamento dinâmico do stub ( dynamic stub loading ) utiliza-se da capacidade do Java de realizar downloading de código. Tipicamente, o stub é carregado dinamicamente do sistema de arquivos locais, neste caso, o gerenciador de segurança não apresenta restrições. Entretanto, quando ele é carregado da rede, suas classes passam pelo gerenciador de segurança, prevenindo, assim, problemas potenciais de segurança (Java, 1999). O carregamento do stub, de forma dinâmica, é utilizado somente quando um cliente necessita de um determinado stub não disponível. Neste esquema, o código do stub (lado cliente) suporta o mesmo conjunto de interfaces remotas da implementação da classe que o gerou. Esse código do stub, residente num servidor host ou em qualquer outra localização, será enviado ao cliente sob demanda ( downloaded ). Para uma implementação remota, esse código pode ser gerado em tempo real ( on-the-fly ) no lado remoto e enviado para o cliente ou pode ser gerado no lado cliente através de uma lista de interfaces suportadas pela implementação remota. O carregamento dinâmico do stub emprega o carregador de classes do Java, o gerenciador de segurança e a serialização de objeto (Java, 1999). Quando a referência de um objeto remoto for passada como parâmetro ou como 202

resultado de uma chamada de método, o marshal stream, que transmite essa referência, incluirá também a informação de onde carregar a classe do stub para o objeto remoto (o URL, se ele for conhecido). Assim, quando a referência de objeto remoto for unmarshaled no destino, o marshal stream poderá localizar e carregar o código do stub (via carregador de classe e verificado pelo gerenciador de segurança) de tal forma que o cliente tenha disponibilizado o stub correto. 7.5 GARBAGE COLLECTION DE OBJETOS REMOTOS Num sistema distribuído, assim como, num sistema local, é desejável que todos os objetos remotos, não mais referenciados por qualquer cliente, sejam destruídos. Isso libera o desenvolvedor da necessidade de rastrear e finalizar, de maneira apropriada, os objetos remotos utilizados pelos clientes. Para executar a tarefa de coleta de lixo ( garbage collection ) o RMI utiliza-se de um algoritmo que implementa um contador de referência. Em tempo de execução, o RMI mantém, em cada JVM, o rastreamento de todas as referências de objetos vivos, isto é, que estão sendo referenciados por algum cliente naquela JVM. Quando um cliente referencia um objeto o contador é incrementado e quando deixa de referenciá-lo o contador é decrementado. A primeira vez que um objeto é referenciado é enviada uma mensagem de referenciamento para o servidor. No momento em que não existir mais referências vivas, uma mensagem de não referenciamento é enviada para o servidor. Se um objeto remoto não for mais solicitado pelos clientes, o RMI, em tempo de execução, utiliza uma referência fraca ( weak ) para referenciá-lo, permitindo ao coletor de lixo do JVM descartá-lo, caso não exista qualquer referência local a ele. Notar que, se existir partição de rede entre cliente e objeto remoto, é possível a ocorrência de uma remoção prematura deste objeto. Devido a esta 203

possibilidade, referências remotas não garantem integridade referencial, porque ela pode estar associada a um objeto inexistente e, neste caso, ocorrerá uma situação de falha (Java, 1999). 7.6 CONSIDERAÇÕES FINAIS Apesar do ambiente Java, como descrito neste capítulo, suportar as várias exigências de um ambiente de objetos distribuídos, nota-se que o RMI é um mecanismo caracterizado pelo fato do cliente, assim como o servidor serem, necessariamente, escritos em Java, tornando, por exemplo, a integração de sistemas legados, isto é, sistemas já existentes escritos nas mais diversas linguagens de programação, uma tarefa complexa (Curtis, 1998). Como visto nos capítulos anteriores, tem-se sempre um código, isto é, a implementação de um objeto executando numa máquina servidora acessada por um cliente. No Java, o mecanismo de adicionar uma camada extra de interpretação de bytecodes permite cópias e execução de seus códigos nas diversas máquinas onde as cópias estejam presentes. Esse mecanismo possibilita o ganho muito grande de portabilidade, mas, algumas vezes, causa perda de desempenho (Curtis, 1998). Pode-se também questionar, levando em conta a diferença existente na localização do código, a forma de distribuição implementada pelo Java. Tipicamente, um código é executado num servidor onde um cliente tem acesso a todas as suas funcionalidades. No Java, o código é copiado para o cliente como um arquivo e então executado. A aplicação do cliente acessa o código, em execução, localmente e, assim, o que é distribuído é o código Java e não, necessariamente, o dado e nem o processamento utilizado por ele (Grimes, 1997). De forma a ilustrar a utilização do Java/RMI encontra-se no Apêndice A um exemplo de aplicação. 204