Desenvolvendo uma aplicação CORBA utilizando Java

Propaganda
Desenvolvendo uma
aplicação CORBA utilizando
Java
Tecgraf PUC-Rio
fevereiro 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
a 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
(exceto aqueles definidos por typedef)
•  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 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]);
}
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 StockServerImpl());!
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;!
import java.io.*!
import org.omg.CORBA.ORB;!
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
Download