8/28/2003
José Alves Marques
Métodos em Objectos Remotos
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Invocação de Métodos em Objectos Remotos
• Um sistema de objectos distribuídos é uma extensão ao
conceito de RPC
• Um objecto invoca um método noutro objecto localizado
remotamente.
• Num sistema de objectos o RPC designa-se normalmente
Remote Method Invocation ou RMI
• A IDL é uma linguagem orientada aos objectos
tipicamente baseada em C++, Java, ou C#.
8/28/2003
José Alves Marques
m4 m5 m6Interface
Remota
m1 m2 m3Código
dos
métodos
Dados
Objecto remoto
Invocação de Objectos Remotos
Departamento de Engenharia Informática
Diferenças Relevantes
• Granularidade
– Mais fina do que em servidores que tipicamente disponibilizam
interfaces para programas com alguma complexidade
• Invocação dinâmica
– Sistemas cliente-servidor ligação é forte (tightly coupled):
• Clientes não podem invocar serviços para os quais não tenham os
stubs (estabelecidos quando IDL foi compilada)
– Sistemas de objectos
desenvolvimento incremental / loosely
coupled
• Permitem um objecto invocar dinamicamente outros de que obtém a
interface em tempo de execução
8/28/2003
José Alves Marques
Principais Sistemas de Objectos Remotos
• Corba
• RMI (Java / J2EE)
• Remoting (C# / .NET)
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
CORBA
• Tem origem no Object Management Group
(OMG) criado em 1989
• Modelo Conceptual é uma síntese entre o modelo
cliente –servidor e as arquitecturas de objectos
• A proposta original do Corba - Object
Management Architecture foi publicada em 1990 e
continha:
– Serviços de suporte ao ciclo de vida dos objectos
– Object request broker
8/28/2003
José Alves Marques
Object Request Broker
• Novo paradigma: consiste num serviço que auxilia a
invocação de objectos remotos
• O papel do ORB é localizar o objecto, activá-lo se
necessário, enviar o pedido do cliente ao objecto
ORB
Aplicação
Cliente
Serviço
Remoto
(objecto)
Activar serviço
Localizar objecto
(serviço)
Estabelecer
ligação
Comunic.
Departamento de Engenharia Informática
CORBA
•
CORBA 2.0 publicado em 1996
•
Os principais elementos da plataforma são:
– IDL – linguagem object oriented com suporte para herança
– Arquitectura – define o ambiente de suporte aos objectos, à invocação, ao
ciclo de vida
– GIOP – General Inter Orb Protocol – protocolo de invocação remota entre
Orb de fabricantes diferentes
– IIOP - Internet Inter Orb Protocol – implementação do GIOP sobre
protocolos TCP/IP
•
Actualmente
– Actividade de normalização reduzida
– Vários produtos disponíveis
• Visigenic/Visibroker
• IONA
8/28/2003
José Alves Marques
Modelo de Objectos
•
Um objecto CORBA implementa uma interface descrita na IDL
CORBA
•
Um objecto CORBA pode ser invocado remotamente através de uma
referência remota
•
Os objectos CORBA residem no servidor,
•
os clientes podem ser objectos ou programas que enviam as mensagens
correctas para os objectos
•
Os objectos não têm de ser implementados numa linguagem Object
Oriented podem ser em Cobol, C, etc.
•
Os objectos remotos são transferidos por referência.
– Ou seja permanecem no servidor e apenas é enviada uma referência que
permite invocá-los
– Alternativa (usada para os tipos primitivos): passagem por valor. Quais as
diferenças?
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Referências Remotas
• Para invocar uma operação remota é necessário que o
objecto invocador tenha uma referência remota para o
objecto
• As referências remotas podem ser passadas como
argumentos ou como resultados de invocações remotas
• Analogia com o binding handle dos RPC
IDL interface type name
Protocol and address details
Object key
interface repository
identifier
IIOP
host domain
name
port number
adapter name
object name
IOR
8/28/2003
José Alves Marques
CORBA IDL
• A interface é escrita em OMG IDL
– A interface é object-oriented com sintaxe muito
semelhante ao C++
• A herança é suportada
– Especifica um nome de uma interface e um conjunto de
métodos que os clientes podem invocar
– Descreve os parâmetros e o respectivo sentido in, out,
inout
– Os métodos podem ter excepções
Departamento de Engenharia Informática
module Accounts
{
interface Account
{
readonly attribute string number;
readonly attribute float balance;
exception InsufficientFunds (string detail);
float debit (
in float amount) raises (insufficientFunds);
float credit (
in float amount);
}
interface InterestAccount : Account
{
readonly attribute float rate;
}
}
8/28/2003
José Alves Marques
Arquitectura
Implementation repository interface repository Client program Proxy for A ORB coreclient
or dynamic skeleton
o b je c t a d a p te r ORB coreserver
s k e le to n Servant ARequest
Reply
Or dynamic invocation
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Elementos da Arquitectura
•
ORB – núcleo – run-time da invocação remota, conjunto de funções
residentes quer no cliente quer no servidor
– Implementa a infra-estrutura de comunicação
– O ORB tem funções para ser inicializado e parado
•
Servidor
– Object adapters - rotina de despacho que recebe as mensagens e invoca os
stubs apropriado
• O nome do object adapter faz parte da referência remota e permite a sua
invocação
• Despacha cada invocação via um skeleton para o método apropriado
– Skeletons
• Funções de adaptação que fazem a conversão dos parâmetros de entrada e saída
e o tratamento das excepções
•
Client proxies
– Para as linguagens Object-oriented
8/28/2003
José Alves Marques
Invocação
• A invocação do método tem por omissão uma semântica
at-most-once
• A heterogeneidade é resolvida com a conversão para CDR –
Common Data Representation
– Inclui 15 tipos básicos
– Receiver makes it right
Departamento de Engenharia Informática
index in
sequence of bytes
notes
on representation
0-3
4-7
8-11
12-15
16-19
20-23
24-27
5
“Smit”
“h____”
6
“Lond”
“on____”
1934
4 bytes
length of string “Smith” length of string London unsigned longStruct Pessoa {
string Nome;
string Lugar;
unsigned long Ano;
};
Representa a struct Person com os valores: {‘Smith’, ‘London’, 1934}
8/28/2003
José Alves Marques
Elementos da Arquitectura
• Interface repository
– Dá informação sobre as interfaces registadas
– Para uma interface pode dar a informação dos métodos
e dos respectivos parâmetros
– O compilador de IDL atribui um número único a cada
tipo IDL que compila
– Esta facilidade permite a invocação dinâmica em
CORBA. Se um cliente recebe uma referência remota
para um novo objecto CORBA de que não tem um
proxy, pode ir buscar esta informação ao Interface
repository
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
CORBA – Invocação Dinâmica
•
Para dinamicamente invocar um objecto em tempo de execução existe
a invocação dinâmica
•
O cliente não precisa de ter os proxies
– As invocações remotas são construídas dinamicamente
– Novos servidores podem ser usados por clientes já existentes
•
Funcionamento
– O Cliente usa o Interface Repository para obter a informação sobre os
métodos e argumentos.
– Cria a mensagem de acordo com a especificação da interface, e envia o
pedido para o respectivo objecto.
Account_ptr acc = ...; // Obter ref para objecto Account
acc->deposit( 100 ); // Invoc. estática
CORBA::Object_ptr obj = ...;
CORBA::Request_ptr req = obj->_request( "deposit" );
req->add_in_arg( "amount" ) <<= (CORBA::ULong) 100;
req->invoke();
8/28/2003
José Alves Marques
Invocação
dinâmica
Departamento de Engenharia Informática
8/28/2003
José Alves Marques
RMI
• Remote Method Invocation: mecanismo de chamada
remota a métodos Java
• Utilizado para RPCs entre objectos Java distribuídos
– Mantém a semântica de uma chamada local, para objectos distantes
– Efectua automaticamente o empacotamento e desempacotamento
dos parâmetros
– Envia as mensagens de pedido e resposta
– Faz o agulhamento para encontrar o objecto e o método pretendido
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Java RMI
• O RMI Java pressupõe que se utiliza um ambiente
Java de linguagem única, pelo que não se colocam
alguns dos problemas que o CORBA pretende
resolver.
• Apesar do ambiente uniforme um objecto tem
conhecimento que invoca um método remoto
porque tem de tratar RemoteExceptions
• A interface do objecto remoto por sua vez tem de
ser uma extensão da interface Remote
8/28/2003
José Alves Marques
Java RMI
• No Java RMI os parâmetros de um método assumem-se
como entradas (input) e o resultado do método como
parâmetro de saída (output)
• Quando o parâmetro é um objecto remoto (herda de
java.rmi.Remote)
– é sempre passado como uma referência para um objecto remoto
• Quando o parâmetro é um objecto local (caso contrário)
– é serializado e passado por valor. Quando um objecto é passado
por valor uma nova instância é criada remotamente
– Tem de implementar java.io.Serializable
– Todos os tipos primitivos e objectos remotos são serializáveis.
(java.rmi.Remote descende de java.io.Serializable)
Departamento de Engenharia Informática
Java RMI
• Quando um objecto pode ocorrer que o receptor não tenha
a classe respectiva. Por exemplo?
• Problema: Como “des-serializar” o objecto?
• Solução: quando um objecto é serializado, é enviado
(juntamente com a informação sobre a sua classe) a
localização da classe (URL) de onde é feito o seu
carregamento dinâmico.
8/28/2003
José Alves Marques
import java.rmi*;
import java.util.Vector;
public interface Shape extends
Remote {
int getVersion() throws
RemoteException;
GraphicalObject getAllState() throws
RemoteException;
}
public interface ShapeList extends
Remote {
Shape newShape(GraphicalObject g) throws RemoteException;
Vector allShapes() throws
RemoteException;
int getVersion() throws
RemoteException;
}
Remote interfaces de Shape e ShapeList
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
JNDI
Java Naming and Directory Interface
• Mecanismo de nomes do J2EE
• Utilizado para associar nomes a recursos e
objectos de forma portável
– Identificação, localização, partilha
• Mapeia nomes em referências para objectos
• Uma instância do registry deve executar-se em
todos servidores que têm objectos remotos.
• Os clientes têm de dirigir as suas pesquisas para o
servidor pretendido
8/28/2003
José Alves Marques
Funções do registry
•
void rebind (String name, Remote obj)
– Usado pelos servidores para registar a associação entre o objecto e o seu nome.
•
void bind (String name, Remote obj)
– Igual ao anterior mas lança excepção se já existe a associação.
•
void unbind (String name, remote obj)
– Retira uma associação existente.
•
Remote lookup (String name)
– Usado pelos clientes para localizar um objecto remoto pelo seu nome. Retorna a
referência para o objecto remoto.
•
String [ ] list ( )
– Retorna um vector de strings com os nomes presentes no registry.
Departamento de Engenharia Informática
import java.rmi.*;
public class ShapeListServer{
public static void main(String args[]){
System.setSecurityManager(new RMISecurityManager());
try{
ShapeList aShapeList = new ShapeListServant();
Naming.rebind(“ShapeList”, aShapeList );
System.out.println(“ShapeList server ready” );
}catch(Exception e) {System.out.println(“ShapeList
server main” + e.getMessage());}
}
}
classe ShapeListServer com o método main
Criar um gestor de segurança
para evitar problemas com classes
que são carregadas a partir de
outros sites.
8/28/2003
José Alves Marques
Implementação do Servidor em Java
• A implementação dos métodos da interface remota é uma
classe “servant”
• No exemplo seguinte o método newShape pode ser
chamado uma factory porque permite ao cliente criar
objectos remotos.
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
Import java.util.Vector;
public class ShapeListServant extends UnicastRemoteObject implements ShapeList {
private Vector theList; //contains the list of Shapes private
int version;
public ShapeListServant()throws
RemoteException{...}
public Shape newShape(GraphicalObject g) throws
RemoteException {
version++;
Shape s = new ShapeServant( g, version);
theList.addElement(s);
return s;
}
public Vector allShape()throws RemoteException{...}
public int getVersion() throws RemoteException{...}
}
Classe ShapeListServant implementa a interface
ShapeList
8/28/2003
José Alves Marques
import java.rmi.*;
import java.rmi.server.*;
import java.util.Vector;
public class ShapeListClient{
public static void main(String args[]){
System.setSecurityManager(new RMISecurityManager());
ShapeList aShapeList = null;
try{
aShapeList = (ShapeList)
Naming.lookup(“//host/ShapeList”);
Vector sList = aShapeList.allShapes();
}catch(RemoteException e) {System.out.println(e.getMessage());
}catch(Exception e){System.out.println(“Client:”+e.getMessage());}
}
}
Cliente da classe ShapeList
Departamento de Engenharia Informática
Java RMI – mecanismo de Reflexão
• A reflexão é usada para passar informação nas mensagens
de invocação sobre o método que se pretende executar
• API de reflexão permite, em run-time:
– Determinar a classe de um objecto.
– Obter informação sobre os métodos / campos de uma classe /
interface
– Criar uma instância de uma classe cujo nome é desconhecido antes
da execução
8/28/2003
José Alves Marques
Reflexão no RMI – como usar
• Visão de 10,000 pés:
– Obter instâncias das classes genéricas “Class” e “Method”
– Cada instância de Method representa as características de um
método (classe, tipo dos argumentos, valor de retorno, e
excepções)
– Invocar métodos remotos com o método “invoke” da classe
“Method”. Requer dois parâmetros:
• O primeiro é o objecto a invocar
• O segundo é um vector de Object contendo os argumentos
• Mais detalhes em
http://java.sun.com/docs/books/tutorial/reflect/
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Contexto: J2EE
• Até agora vimos arquitecturas cliente-servidor
– Simples, mas…
– difícil de fazer evoluções
– difícil de reutilizar a lógica de negócio ou de
apresentação
• J2EE é uma plataforma para desenvolver e
executar aplicações distribuídas multi-nível
8/28/2003
José Alves Marques
Páginas HTML dinâmicas
Páginas JSP
Enterprise Beans
Base de Dados
Aplicação J2EE Multi-nível
Cliente
Servidor
J2EE
Servidor de
Base de Dados
Camada cliente
Camada Web
Camada de negócio
Camada EIS
Departamento de Engenharia Informática
Tecnologias Principais do J2EE
• Servlets
• Java Server Pages (JSP)
• Enterprise Java Beans (EJB)
• Java Database Connectivity (JDBC)
• Remote Method Invocations (RMI)
• XML
8/28/2003
José Alves Marques
Arquitectura J2EE
8/28/2003
José Alves Marques
8/28/2003
José Alves Marques
.NET Remoting
• Equivalente ao RMI para C# / Plataforma .NET
• Semelhante ao RMI. Vamo-nos concentrar nas novas
opções fornecidas
Departamento de Engenharia Informática
Objectos Remotos
• Qualquer objecto pode ser usado remotamente derivando-o de
MarshalByRefObject ou de MarshalByValObject
• MarshallByValue
– Objectos serializáveis, são copiados para o cliente
– Pode ser muito ineficiente
• MarshallByRef
– Quando o cliente recebe uma referência de um objecto remoto ele está
efectivamente a receber uma referência a um objecto proxy local criado
automaticamente pelo .NET Remoting.
– Esse proxy é encarregue de passar as chamadas dos métodos para o
servidor.
8/28/2003
José Alves Marques
Utilização de Objectos Remotos
• Requer a respectiva activação
• Dois modos:
• Singleton
– Apenas uma instância em cada instante
– Criada aquando da primeira invocação
– Requer sincronização no acesso a estado partilhado
• SingleCall
– Uma nova instância é criada para cada pedido.
– Após a execução de uma chamada, a próxima chamada será
servida por outra instância.
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Tempo de Vida dos Objectos
• Tempo de vida dos objectos Singleton
determinado por sistema de leases.
– Ao expirar um lease, este deve ser renovado, caso
contrário a memória ocupada pelo objecto é recuperada
pelo garbage collector.
– Java RMI escolheu solução mais complexa: contagem
de referência distribuída. Problema: falhas na rede e nos
servidores?
8/28/2003
José Alves Marques
Canais
•
A comunicação entre dois processos
distintos é realizada através de canais,
cuja função é:
– Empacotar a informação de acordo com
um tipo de protocolo
– Enviar esse pacote a outro computador.
•
Dois tipos pré-definidos:
– TcpChannel (que envia os dados por TCP
em formato binário).
– HttpChannel (que utiliza o protocolo
HTTP em formato XML).
•
Maior flexibilidade do que no RMI na
escolha dos mecanismos de serialização
e protocolos de transmissão
Departamento de Engenharia Informática
Resumo das Opções
• MarshallByRef vs. MarshallByValue
• Canais – TcpChannel vs. HttpChannel vs. Custom
• Activação – Singleton vs. Single Call
8/28/2003
José Alves Marques
Exemplo: Interface
public interface i_ola {
string MetodoOla();
}
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
Exemplo: Servidor
class ser {
static void Main() {
TcpChannel chan1 = new TcpChannel(8086);
ChannelServices.RegisterChannel(chan1);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(c_ola),
“Ola", WellKnownObjectMode.Singleton);
System.Console.WriteLine("<enter> para sair...");
System.Console.ReadLine();
}
}
public class c_ola : MarshalByRefObject, i_ola
{
public string MetodoOla() {
return “ola!”;
}
8/28/2003
José Alves Marques
Exemplo: Cliente
class cl {
static void Main() {
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
i_ola obj = (i_ola) Activator.GetObject(typeof(i_ola),
"tcp://localhost:8086/Ola");
if (obj == null)
System.Console.WriteLine("Could not locate server");
else
Console.WriteLine(obj.MetodoOla());
}
}
Departamento de Engenharia Informática
Comparação – IDL
package SimpleStocks; import java.rmi.*; import java.util.*;
public interface StockMarket
extends java.rmi.Remote {
float get_price( String symbol ) throws RemoteException; } module SimpleStocks { interface StockMarket {
float get_price( in string symbol ); }; }; using System; namespace SimpleStocks {
public interface StockMarket { float get_price(string symbol); }
Java/RMI -Interface definition CORBA -IDL
8/28/2003
José Alves Marques
// // StockMarketClient // // importjava.rmi.*; import java.rmi.registry.*; import SimpleStocks.*; public classStockMarketClient{
public static void main(String[] args)throws Exception { if(System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } StockMarket market = (StockMarket)Naming.lookup("rmi://local host/NASDAQ");
System.out.println( "The price of MY COMPANY is "
+ market.get_price("MY_COMPANY") ); } } // // StockMarketClient // // importorg.omg.CORBA.*; import org.omg.CosNaming.*; import SimpleStocks.*; public classStockMarketClient
{
public static void main(String[] args)
{ try {
ORB orb = ORB.init(); NamingContext root = NamingContextHelper.narrow( orb.resolve_initial_references("NameS ervice") );
NameComponent[] name = new NameComponent[1] ; name[0] = new NameComponent("NASDAQ",""); StockMarket market = StockMarketHelper.narrow(root.resolve (name)); System.out.println("Price of MY COMPANY is " +
market.get_price("MY_COMPANY")); } catch( SystemException e ) { System.err.println( e ); } } } // // StockMarketClient // // namespace SimpleStocks {
public classStockMarketClient
{
static void Main() { try { StockMarket market = (StockMarket)Activator.GetObject( typeof(StockMarket), “tcp://localhost:8086/NASDAQ”); System.Console.WriteLine("The price of MY COMPANY is " +
market.get_price("MY_COMPANY") ); }
}
8/28/2003
José Alves Marques
Departamento de Engenharia Informática
// // // StockMarketServer // // package SimpleStocks; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; public class StockMarketImplextends UnicastRemoteObjectimplements StockMarket{
public float get_price( String symbol )
{
float price = 0;
for( int i = 0; i < symbol.length(); i++ )
{
price += (int) symbol.charAt( i ); }
price /= 5; return price; }
public StockMarketImpl( String name ) throws RemoteException
{ try {
Naming.rebind( name, this );
} catch( Exception e ) { System.out.println( e ); } } } // // // StockMarketServer // // import org.omg.CORBA.*; import SimpleStocks.*;
public class StockMarketImpl extends _StockMarketImplBase
{
public float get_price( String symbol ) { float price = 0; for(int i = 0; i < symbol.length(); i++) {
price += (int) symbol.charAt( i ); }
price /= 5; return price; }
public StockMarketImpl( String name ) { super( name ); } } // // // StockMarketServer // // using System.Runtime.Remoting;
public class StockMarketImpl : MarshalByRefObject, SimpleStocks.StockMarket
{
public float get_price( string symbol )
{
float price = 0;
for( int i = 0; i < symbol.length(); i++ )
{
price += (int) symbol.charAt(i); }
price /= 5; return price; }
}
Java/RMI - Server implementation CORBA - Server implementation
8/28/2003
José Alves Marques
// // StockMarketServer Main // // using System.Runtime.Remoting; class StockMarketServer {static void Main(string[] args) {
TcpChannel chan1 = new TcpChannel(8086); ChannelServices.RegisterChannel (chan1); RemotingConfiguration.RegisterWel lKnownServiceType(typeof(StockMar ket),“NASDAQ",WellKnownObjectMode .Singleton); System.Console.WriteLine("<enter> para sair..."); System.Console.ReadLine(); } } // // StockMarketServer Main // // importjava.rmi.*; import java.rmi.server.UnicastRemoteObject; import SimpleStocks.*;
public class StockMarketServer {
public static voidmain(String[] args) throws Exception { if(System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); }
StockMarketImpl stockMarketImpl = new StockMarketImpl("NASDAQ"); } } // // StockMarketServer Main // // importorg.omg.CORBA.*; import org.omg.CosNaming.*; import SimpleStocks.*; public class StockMarketServer {
public static voidmain(String[] args) {
try {
ORB orb = ORB.init(); BOA boa = orb.BOA_init();
StockMarketImpl stockMarketImpl = new StockMarketImpl("NASDAQ"); boa.obj_is_ready( stockMarketImpl ); org.omg.CORBA.Object object = orb.resolve_initial_references("NameSer vice"); NamingContext root = NamingContextHelper.narrow( object ) ; NameComponent[] name = new
NameComponent[1];
name[0] = new NameComponent("NASDAQ", ""); root.rebind(name, stockMarketImpl); boa.impl_is_ready(); } catch( Exception e ) { e.printStackTrace(); } } }