Download org.omg.CORBA.Object - Tecgraf JIRA / Confluence - PUC-Rio

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Desenvolvendo uma
aplicação CORBA utilizando
Java
Tecgraf PUC-Rio
maio de 2011
Exemplo passo-a-passo
• Veremos um exemplo, passo-a-passo, de
desenvolvimento de aplicações CORBA
usando Java
• Para desenvolver a aplicação, usaremos o
Jacorb como ORB tanto para o cliente quanto
para o servidor, já que ambos serão
desenvolvidos em Java
Passo 1: Jacorb e SDK
• A última versão do Jacorb pode ser obtida de:
• http://www.jacorb.org
• Precisaremos também do JDK 1.5 ou superior
• Para fazer build do exemplo, usaremos o Ant:
– http://ant.apache.org/
Libs do Jacorb
•
•
•
•
•
•
•
•
antlr-2.7.2.jar
avalon-framework-4.1.5.jar
backport-util-concurrent.jar
idl.jar
jacorb-2.3.0.jar
logkit-1.2.jar
picocontainer-1.2.jar
wrapper-3.1.0.jar
Passo 2: Escrevendo a IDL
// StockMarket.idl
// O módulo StockMarket consiste das definições
// úteis para desenvolvimento de aplicações
// que lidam com mercado de ações.
module StockMarket {
// O tipo StockSymbol é usado para representar os
// identificadores das ações
typedef string StockSymbol;
// Um StockSymbolList é uma sequência de StockSymbols.
typedef sequence<StockSymbol> StockSymbolList;
// A interface StockServer é a interface que fornece
// as informações sobre as ações do mercado.
interface StockServer {
// getStockValue() retorna o valor de uma
// determinada ação do marcado identificada por um
// StockSymbol fornecido como parâmetro de entrada.
// Se o StockSymbol dado for desconhecido, o resultado
// é indefinido. Depois veremos como usar uma exceção
// para sinalizar essa condição.
float getStockValue(in StockSymbol symbol);
};
};
// getStockSymbols() retorna uma sequência com todos os
// StockSymbols conhecidos pelo servidor do mercado de
// ações.
StockSymbolList getStockSymbols();
Passo 3: Compilando a IDL
• Para compilar a IDL, usaremos o Ant e o
compilador IDL do Jacorb:
<!-- =================================================== -->
<!-Inicializacao
-->
<!-- ==================================================== -->
<target name="init" description="Inicia as propriedades">
<property name="lib" value="lib"/>
<property name="idl" value="idl"/>
<property name="generated" value="generated"/>
<property name="jacorb" value="jacorb"/>
</target>
<!-- ==================================================== -->
<!-IDL compiler
-->
<!-- ==================================================== -->
<target name="idl" depends="clean" description="Compila as idls">
<delete dir="${generated}"/>
<java classname="org.jacorb.idl.parser" fork="yes">
<classpath>
<pathelement location="${lib}/${jacorb}/idl.jar"/>
<pathelement location="${lib}/${jacorb}/logkit-1.2.jar"/>
</classpath>
<arg line="-d ${generated} ${idl}/StockMarket.idl"/>
</java>
</target>
Arquivos gerados na compilação da IDL
• Todas as classes estão dentro do pacote StockMarket
– StockServer.java
– StockServerOperations.java
– StockServerHelper.java
– StockSymbolHelper.java
– StockSymbolListHelper.java
– StockServerHolder.java
– StockSymbolListHolder.java
– StockServerPOA.java
– StockServerPOATie.java
– _StockServerStub.java
}
}
}
}
Interface Files
Helper Files
Holder Files
Stubs e Skeleton Files
Interface Files
• A interface IDL StockServer é mapeada para:
– uma interface java de assinatura StockServer.java
– uma interface java de operações
StockServerOperations.java
• A interface de assinatura possui o mesmo nome da
interface IDL, estende outras interfaces CORBA e é
usada como o tipo referenciado em outras interfaces.
• A interface de operações possui o nome da interface IDL
junto com o sufixo Operations e é uma interface “java
pura”, ou seja, possui apenas as declarações das
operações e atributos definidos na interface IDL
StockServerOperations.java
package StockMarket;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 19, 2010 5:47:22 PM
*/
public interface StockServerOperations
{
/* constants */
/* operations */
float getStockValue(java.lang.String symbol);
java.lang.String[] getStockSymbols();
}
StockServer.java
package StockMarket;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 19, 2010 5:47:22 PM
*/
public interface StockServer
extends StockServerOperations,
org.omg.CORBA.Object,
org.omg.CORBA.portable.IDLEntity
{
}
org.omg.CORBA.Object: é a interface raiz para todas as referências a objetos
CORBA na linguagem Java, análogo a interface java.rmi.Remote para os objetos remotos
RMI.
org.omg.CORBA.portable.IDLEntity: interface de “marcação” cuja finalidade é
apenas indicar que a classe que implementa essa interface é um tipo IDL que possui uma
classe de Helper correspondente.
Stub e Skeleton Files
• A compilação da IDL StockServer produz a
classe _StockServerStub.java que atua como stub
do cliente e as classes StockServerPOA.java e
StockServerPOATie.java que servem de skeleton
do servidor.
• Veremos depois que o uso das classes de
skeleton POA ou POATie depende da
estratégia adotada para implementação do
servidor: por herança ou por delegação
_StockServerStub.java
package StockMarket;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 25, 2010 3:50:57 PM
*/
public class _StockServerStub
extends org.omg.CORBA.portable.ObjectImpl
implements StockMarket.StockServer {
...
public float getStockValue(java.lang.String symbol) {
...
}
public java.lang.String[] getStockSymbols() {
...
}
}
StockServerPOA.java
package StockMarket;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 25, 2010 3:50:57 PM
*/
public abstract class StockServerPOA
extends org.omg.PortableServer.Servant
implements org.omg.CORBA.portable.InvokeHandler,
StockMarket.StockServerOperations
{
...
}
StockServerPOATie.java
package StockMarket;
import org.omg.PortableServer.POA;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 25, 2010 3:50:57 PM
*/
public class StockServerPOATie
extends StockServerPOA
{
...
private StockServerOperations _delegate;
public StockServerPOATie(StockServerOperations delegate)
{
_delegate = delegate;
}
public float getStockValue(java.lang.String symbol)
{
return _delegate.getStockValue(symbol);
}
}
public java.lang.String[] getStockSymbols()
{
return _delegate.getStockSymbols();
}
Helper Files
• A compilação da IDL StockServer produz as
classes de Helper StockServerHelper.java,
StockSymbolHelper.java e
StockSymbolListHelper.java
• As classes de Helper oferecem diversos
métodos estáticos úteis na manipulação do
tipo correspondente:
–
–
–
–
inserir e extrair um objeto do tipo em Any
obter o repository id
ler de um stream e escrever para um stream
…
Helper Files
• A classe de Helper gerada a partir de uma
interface IDL, também inclui operações
de narrow para converter o tipo genérico
org.omg.CORBA.Object para o tipo
específico.
• A exceção IDL CORBA::BAD_PARAM é lançada
se a conversão do narrow falhar devido a
inconsitência do tipo da referência do objeto.
StockSymbolHelper.java
package StockMarket;
/*
* Generated from IDL alias "StockSymbol".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 19, 2010 5:47:22 PM
*/
public final class StockSymbolHelper {
...
}
public static void insert (org.omg.CORBA.Any any, java.lang.String s) {
...
}
public static java.lang.String extract (final org.omg.CORBA.Any any) {
...
}
public static String id() {
return "IDL:StockMarket/StockSymbol:1.0";
}
public static java.lang.String read (
final org.omg.CORBA.portable.InputStream _in) {
...
}
public static void write (
final org.omg.CORBA.portable.OutputStream _out, java.lang.String _s) {
...
}
StockServerHelper.java
package StockMarket;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 19, 2010 5:47:22 PM
*/
public final class StockServerHelper {
// Todos os métodos estáticos insert, extract, type, id, read e write
// e mais os métodos de conversão narrow
...
public static StockMarket.StockServer narrow(final org.omg.CORBA.Object obj)
{
...
}
public static StockMarket.StockServer unchecked_narrow(
final org.omg.CORBA.Object obj)
{
...
}
}
Holder Files
• Os métodos definidos nas interfaces IDL que
tem passagem de parâmetros nos modos out
e inout, requerem o uso de classes de
Holder.
– Todos os tipos primitivos da IDL possuem as
classes de Holder disponíveis no pacote
org.omg.CORBA package
– O compilador IDL gera as classes de Holder para
todos os tipos definidos pelo desenvolvedor
• A compilação da IDL StockServer produz as
classes de Holder StockServerHolder.java e
StockSymbolListHolder.java
StockSymbolListHolder.java
package StockMarket;
/**
* Generated from IDL alias "StockSymbolList".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 19, 2010 5:47:22 PM
*/
public final class StockSymbolListHolder
implements org.omg.CORBA.portable.Streamable
{
public java.lang.String[] value;
public StockSymbolListHolder () { }
}
public StockSymbolListHolder (final java.lang.String[] initial)
{
value = initial;
}
public org.omg.CORBA.TypeCode _type ()
{
return StockSymbolListHelper.type ();
}
public void _read (final org.omg.CORBA.portable.InputStream in)
{
value = StockSymbolListHelper.read (in);
}
public void _write (final org.omg.CORBA.portable.OutputStream out)
{
StockSymbolListHelper.write (out,value);
}
StockServerHolder.java
package StockMarket;
/**
* Generated from IDL interface "StockServer".
*
* @author JacORB IDL compiler V 2.3-beta-2, 14-Oct-2006
* @version generated at Oct 19, 2010 5:47:22 PM
*/
public final class StockServerHolder
implements org.omg.CORBA.portable.Streamable{
public StockServer value;
public StockServerHolder() { }
}
public StockServerHolder (final StockServer initial)
{
value = initial;
}
public org.omg.CORBA.TypeCode _type()
{
return StockServerHelper.type();
}
public void _read (final org.omg.CORBA.portable.InputStream in)
{
value = StockServerHelper.read (in);
}
public void _write (final org.omg.CORBA.portable.OutputStream _out)
{
StockServerHelper.write (_out,value);
}
Passo 4: Compilando o código java
• Para compilar o código Java gerado pela
IDL, usaremos o Ant e o compilador javac
<!-- ====================================================
<!-Java Compiler
<!-- ====================================================
<target name="javac" depends="idl" description="Compila o
<!-- Cria o diretorio para compilacao -->
<mkdir dir="${build}" />
<!-- Compila os fontes do src e do gerenerated -->
<javac destdir="${build}"
debug="on"
encoding="iso-8859-1">
<src path="${generated}"/>
<src path="${src}"/>
</javac>
</target>
-->
-->
-->
codigo java">
Passo 5: Implementando o Servant
• O Servant que implementa a interface
definida na IDL StockServer pode ser uma
classe que estende a classe abstrata
StockServerPOA ou pode ser uma classe
simples cuja instância é passada para a classe
de delegação StockServerPOATie.
• Para compilar o Servant, o compilador java
deve ter no classpath as classes de skeleton,
as classes de interface e as classes Helper e
Holder geradas pelo compilador IDL.
Estratégias de implementação
• CORBA suporta dois mecanismos para
implementação da IDL por uma classe Servant
– por herança
– por delegação
• A diferença principal entre os dois mecanismos é
que, pelo mecanismo de delegação, a classe de
implementação da IDL não precisa derivar de uma
classe em particular
Usando herança
package StockMarket;
/*
* StockServerImpl implementa a interface IDL StockServer
*/
public class StockServerImpl extends StockServerPOA {
// As ações com seus respectivos valores
private Map<String, Float> myStock;
public StockServerImpl() {
myStock = new HashMap<String,Float>();
// Inicializa as ações com nomes e valores
// atribuídos randomicamente
...
}
public float getStockValue(String symbol) {
if (myStock.containsKey(symbol)) {
// Simbolo encontrado; retorna seu valor
return myStock.get(symbol);
} else {
// Simbolo não foi encontrado
return 0f;
}
}
}
public String[] getStockSymbols() {
return myStock.keySet().toArray(new String[0]);
}
Usando delegação
package StockMarket;
/**
* StockServerImpl implementa a interface IDL StockServer usando
* o mecanismo de delegação
*/
public class StockServerTieImpl implements StockServerOperations {
// As ações com seus respectivos valores
private Map<String, Float> myStock;
public StockServerTieImpl () {
myStock = new HashMap<String,Float>();
// Inicializa as ações com nomes e valores
// atribuídos randomicamente
...
}
public float getStockValue(String symbol) {
if (myStock.containsKey(symbol)) {
// Simbolo encontrado; retorna seu valor
return myStock.get(symbol);
} else {
// Simbolo não foi encontrado
return 0f;
}
}
}
public String[] getStockSymbols() {
return myStock.keySet().toArray(new String[0]);
}
Passo 6: Implementando o servidor
• O programa servidor se encarrega de:
–
–
–
–
inicializar o ORB
criar o objeto Servant StockServerImpl
exportar o Servant para o POA
aguardar que o cliente envie requisições
• Para compilar o servidor, o compilador java
deve ter no classpath as classes de interface, a
classe do skeleton, as classes Helper e Holder
geradas pelo compilador IDL e, a classe do
Servant.
Inicializa o ORB
Properties orbProps = new Properties();
orbProps.setProperty("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
orbProps.setProperty("org.omg.CORBA.ORBSingletonClass",
"org.jacorb.orb.ORBSingleton");
ORB orb = ORB.init(args, orbProps);
init
public static ORB init(String[] args,
Properties props)
Creates a new ORB instance for a standalone application. This method may be called from
applications only and returns a new fully functional ORB object each time it is called.
Parameters:
args - command-line arguments for the application's main method; may be null
props - application-specific properties; may be null
Returns:
the newly-created ORB instance
Cria o Servant que implementa a IDL
• Se o Servant tiver adotado a estratégia de
implementação por herança:
Servant stockServer = new StockServerImpl();
• Se o Servant tiver adotado a estratégia de
implementação por delegação:
Servant stockServer = new StockServerPOATie(new StockServerTieImpl ());
Cria o Servant que implementa a IDL
• Note que, até aqui, temos apenas um objeto
Java instanciado.
• Precisamos agora tornar esse objeto um
objeto CORBA, capaz de receber as
requisições dos clientes.
• Usaremos, para isso, o POA.
Exporta o Servant para o POA
POA poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
poa.the_POAManager().activate();
org.omg.CORBA.Object o = poa.servant_to_reference(stockServer);
• Obtém uma referência para uma instância do
POA
• Após fazer narrow da referência, é necessário
ativar o POA (seu estado inicial é on-holding)
• Registra o Servant no POA
Bloqueia a thread corrente para o ORB
orb.run();
• Bloqueia a thread corrente até o ORB terminar
Exemplo do servidor do StockServer
package StockMarket;
import java.io.*;
import org.omg.CORBA.ORB;
import org.omg.PortableServer.*;
public class StockServerMain {
public static void main(String args[]) {
try {
// Inicializa o ORB.
Properties orbProps = new Properties();
orbProps.setProperty("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
orbProps.setProperty("org.omg.CORBA.ORBSingletonClass",
"org.jacorb.orb.ORBSingleton");
ORB orb = ORB.init(args, orbProps);
// Cria o Servant StockServerImpl que implementa a IDL
Servant stockServer = new StockServerImpl();
// Obtém uma referência para o POA e registra o Servant nesse POA
POA poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
poa.the_POAManager().activate();
org.omg.CORBA.Object o = poa.servant_to_reference(stockServer);
// Escreve no arquivo a referência para o objeto CORBA
PrintWriter ps = new PrintWriter( new FileOutputStream(
new File( args[0] )));
ps.println(orb.object_to_string( o ));
ps.close();
// Bloqueia a thread corrente até o ORB finalizar
orb.run();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Passo 7: Implementando o cliente
• O programa cliente se encarrega de:
– inicializar o ORB
– obter a referência para o objeto CORBA
StockServer
– fazer chamadas aos métodos definidos pela IDL
do StockServer
• O módulo cliente deve ter no classpath a classe de
stub _StockServerStub, a classe de assinatura
StockServer e as classes Helper e Holder geradas
pelo compilador IDL
Exemplo do cliente do StockServer
package StockMarket;
import java.io.*
import org.omg.CORBA.ORB;
public class StockServerClient {
public static void main(String args[]) {
try {
// As propriedades que informam o uso do JacORB como ORB.
Properties orbProps = new Properties();
orbProps.setProperty("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
orbProps.setProperty("org.omg.CORBA.ORBSingletonClass",
"org.jacorb.orb.ORBSingleton");
// Inicializa o ORB.
ORB orb = ORB.init(args, orbProps);
// Lê o IOR do arquivo cujo nome é passado como parâmetro
BufferedReader reader =
new BufferedReader(new InputStreamReader(new FileInputStream(args[0])));
String ior = reader.readLine();
// Obtém a referência para objeto CORBA
org.omg.CORBA.Object obj = orb.string_to_object(ior);
StockServer myStock = StockServerHelper.narrow(obj);
// Executa as chamadas ao objeto CORBA
StockServerClient stockClient = new StockServerClient(myStock);
stockClient.run();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
Exemplo do cliente do StockServer
package StockMarket;
public class StockServerClient {
private StockServer myStock;
public StockServerClient(StockServer myStock) {
this.myStock = myStock;
}
public void run() {
try {
System.out.println(”Ações de mercado obtidas do StockServer:");
// Obtém os símbolos de todos as ações
String[] stockSymbols = myStock.getStockSymbols();
// Mostra as ações com seus respectivos valores
for (int i = 0; i < stockSymbols.length; i++) {
System.out.println(stockSymbols[i] + " "
+ myStock.getStockValue(stockSymbols[i]));
}
}
catch (org.omg.CORBA.SystemException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
...
}
Passo 8: Executando o servidor
java -cp ./build:
lib/jacorb/antlr-2.7.2.jar:
lib/jacorb/avalon-framework-4.1.5.jar:
lib/jacorb/backport-util-concurrent.jar:
lib/jacorb/idl.jar:lib/jacorb/jacorb-2.3.0.jar:
lib/jacorb/logkit-1.2.jar:
lib/jacorb/picocontainer-1.2.jar:
lib/jacorb/wrapper-3.1.0.jar
StockMarket.StockServerMain ior
Saída da execução do servidor
mjulia$ ./runserver
Ações do mercado criadas:
UION: 18.192759
LGBA: 46.23733
ZZSP: 48.71345
KLVV: 57.355362
ZDZR: 41.779728
UFTH: 74.87004
DNKS: 80.69647
AQVS: 99.87545
AZHM: 72.27951
PEMR: 35.293213
Passo 9: Executando o cliente
java -cp ./build:
lib/jacorb/antlr-2.7.2.jar:
lib/jacorb/avalon-framework-4.1.5.jar:
lib/jacorb/backport-util-concurrent.jar:
lib/jacorb/idl.jar:lib/jacorb/jacorb-2.3.0.jar:
lib/jacorb/logkit-1.2.jar:
lib/jacorb/picocontainer-1.2.jar:
lib/jacorb/wrapper-3.1.0.jar
StockMarket.StockServerClient ior
Saída da execução do cliente
mjulia$ ./runclient
Ações de mercado obtidas do StockServer:
UION 18.192759
LGBA 46.23733
ZZSP 48.71345
KLVV 57.355362
ZDZR 41.779728
UFTH 74.87004
DNKS 80.69647
AQVS 99.87545
AZHM 72.27951
PEMR 35.293213