Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

A primeira vez que acessar o developerWorks, um perfil será criado para você. Informações do seu perfil (tais como: nome, país / região, e empresa) estarão disponíveis ao público, que poderá acompanhar qualquer conteúdo que você publicar. Seu perfil no developerWorks pode ser atualizado a qualquer momento.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

Passando objetos de dados entre ambientes Java CICS: Parte 2: técnicas para passar objetos de dados Java

Dennis Weiand, Client Technical Specialist for CICS, Web, and Java, IBM Technical Sales team, IBM
Photo of Dennis Weiand
Dennis Weiand é Client Technical Specialist em CICS, web e Java na equipe IBM Technical Sales de Dallas, TX. É possível entrar em contato com Dennis pelo email dweiand@us.ibm.com.

Resumo:  Java está se tornando uma linguagem de programação popular para aplicativos CICS. CICS fornece vários ambientes Java, cada um com seus próprios pontos fortes e, portanto, passar objetos de dados entre os diferentes ambientes CICS Java é um tópico importante. Esta série de artigos dividida em três partes fornece os detalhes. A Parte 2 usa um exemplo de classe Java para mostrar como passar objetos de dados Java entre aplicativos em execução em um ambiente de JVM com CICS compartilhado, uma JVM baseada em Axis2, um ambiente de Script Dinâmico CICS e uma JVM com base em CICS OSGi.

Visualizar mais conteúdo nesta série

Data:  02/Fev/2012
Nível:  Intermediário Também disponível em :   Inglês
Atividade:  2635 visualizações
Comentários:  


Introdução

A Parte 1 desta série de três partes descreveu os diferentes ambientes Java™ fornecidos pelo IBM® CICS® :

  • O ambiente de JVM compartilhado tradicional, onde somente uma transação de Java baseada em CICS é executada por vez em uma JVM.
  • O ambiente do servidor CICS JVM, onde várias solicitações de programa Java podem ser despachadas à mesma JVM e ao mesmo tempo. Estes são os ambientes Java fornecidos por CICS que usam o servidor JVM (mas não podem ser combinados em um único servidor JVM):
    • O ambiente baseado em OSGi, que fornece o sistema de módulo dinâmico OSGi com funcionalidades como a adição e remoção dinâmica de classes Java à JVM, fornecimento do registro OSGi, exposição apenas das interfaces para seu módulo Java em vez de todas as classes no módulo e especificação de dependências de módulo para praticamente eliminar problemas ClassNotFound comuns.
    • O mecanismo de serviço da web de software livre Axis2, que permite expor um POJO de forma rápida e fácil usando anotações JAX-WS e escrever manipuladores no estilo Axis2.
    • CICS Dynamic Scripting, que fornece uma maneira rápida de desenvolver aplicativos da web usando as linguagens de script PHP e Groovy. Os intérpretes de PHP e Groovy são implementados em Java e, portanto, há uma ponte Java para permitir que você instancie objetos Java e invoque programas CICS
  • CICS Transaction Gateway, que facilita as comunicações de um programa Java em execução em um ambiente não CICS com um programa CICS TS.

Conforme o esperado, se você estiver trabalhando com classes Java em um único programa Java baseado em CICS, trabalhe com elas normalmente: instancie o objeto e invoque os métodos do objeto. No entanto, quando seu aplicativo é codificado em Java, mas você deseja aproveitar os pontos fortes dos diferentes ambientes Java fornecidos por CICS, ou deseja distribuir as partes de seu aplicativo baseado em Java em diversas regiões do CICS, o uso de uma abordagem parecida com Java para transportar os objetos de dados Java é preferível sobre a abordagem tradicional de série de bytes orientada ao campo para o transporte de dados. Essa abordagem tradicional de passagem de dados é necessária e funciona bem se você estiver usando diversas linguagens de programação, o que é um dos pontos fortes do CICS.

A Parte 1 descreveu a versão do CICS de uma chamada, o comando EXEC CICS LINK, que o permite chamar outro programa escrito com a mesma linguagem de programação, ou com outra diferente, em um ambiente CICS. As instalações arquitetadas por CICS para a passagem de dados entre programas CICS são a área de comunicação e os canais e contêineres. A área de comunicação é um bloco de armazenamento de até 32 KB, enquanto um contêiner é um bloco nomeado de armazenamento sem limite de tamanho. Os contêineres são agrupados em um canal, que pode ser passado de um programa CICS para outro. A área de comunicação e os canais e contêineres são mutuamente exclusivos -- um programa pode receber dados usando somente uma das duas técnicas por vez. Quando você realiza um LINK do programa A para o programa B, o programa A pode passar uma área de comunicação ou um canal, mas não ambos.

A Parte 1 afirmou que se um aplicativo baseado em CICS for escrito somente em Java e você precisar se mover de um ambiente CICS Java para outro, é mais simples permanecer em um paradigma Java e passar objetos de dados Java entre os ambientes Java baseados em CICS. É possível fazer isso serializando um objeto de dados Java em um contêiner CICS, passando o contêiner para outro programa Java em execução em um ambiente CICS Java diferente e desserializando o objeto no programa Java de destino.

Também é possível passar os dados em uma estrutura de série de bytes, orientada ao campo. Porém, passar objetos de dados Java entre os ambientes Java fornecidos por CICS permite que você aproveite os pontos fortes dos diferentes ambientes Java fornecidos por CICS, além de ajudá-lo a evitar:

  • A criação de um layout de copybook COBOL para os dados que serão passados entre os programas Java
  • A execução de utilitários para criar um objeto de dados Java a partir do copybook COBOL
  • A necessidade de o programador Java entender sobre COBOL
  • A necessidade de manter os copybooks COBOL necessários em seu repositório de origem
  • A necessidade de realizar uma rotatividade de produção no copybook COBOL
  • A necessidade de atualizar o copybook COBOL se o conteúdo dos dados passados mudar (e a necessidade de passar pelas atualizações de repositório subsequentes e rotatividade da produção)

Usando uma facha orientada ao objeto sobre o CICS

Este artigo mostra como usar as instalações de passagem de dados do CICS para passar objetos de dados Java entre programas Java em execução nos ambientes Java fornecidos por CICS. É possível fornecer uma fachada orientada ao objeto sobre as instalações de passagem de dados CICS a fim de criar uma forma orientada a Java para passar os objetos de dados Java. Na parte inferior deste artigo, é possível fazer o download de uma classe de amostra que implementa uma fachada e pode ser usada como está ou como a base de sua própria implementação de fachada. Quando você passa objetos de dados Java de um programa Java de origem, em execução em um ambiente Java fornecido por CICS, para um ambiente Java diferente fornecido por CICS, uma fachada permite que você passe objetos de dados Java usando um código como este:

String abc = "Some information to Pass";
Employee emp = new Employee("John Doe");
DDW_CicsObjectTransporter transporter =
    new DDW_CicsObjectTransporter();
transporter.addObject("abc",abc)
    .addObject("emp",emp)
    .execute("TARGET");

// and after the program return

String errorString = (String)transporter.getObject("error");
If (errorString != null) {
    processError();
} else {
    Manager newManager = (Manager)transporter.getObject("mgr");
    // process/display Manager object that was returned
}

Há algumas amostras de código para o programa Java respondente para retornar os dados usando a fachada:

DDW_CicsObjectTransporter transporter = new DDW_CicsObjectTransporter();
Employee emp = (Employee)transporter.getObject("emp");
// work with employee object
transporter.removeObject("abc");    // can remove object in the transporter
Manger mgr = new Manger("Joe Bloggs");
transporter.addObject("mgr",mgr);  // add new or changed objects
return;

As classes Java incluídas neste artigo fornecem uma fachada que permite as interações acima. Você pode usar essas classes como elas estão em seu ambiente, mas leia o restante do artigo para entender o que essas classes fazem e como elas podem afetar o desempenho de seu aplicativo.

Esta série de artigos descreve os ambientes CICS Java disponíveis pelo CICS TS V4.2. A série é voltada para programadores Java que desenvolvem programas para CICS, mas também será benéfica aos programadores de aplicativo em CICS que estão começando a usar Java e também para programadores de sistemas em CICS.

Serialização do objeto Java

A passagem de objetos de dados Java entre ambientes Java fornecidos por CICS exige a serialização do objeto de dados Java. Os conceitos de serialização de objetos são bem entendidos por grande parte dos programadores Java, e há vários artigos de qualidade sobre a serialização de objetos Java, além de vários exemplos do código Java para serialização de objetos na Internet. Portanto, este artigo apenas mencionará alguns destaques da serialização de objetos Java e esses destaques ajudarão se você ler alguns dos artigos sobre a serialização de objetos Java.

Para serializar seu objeto para um array de bytes, observe o método writeObject() de ObjectOuputStream. Para desserializar seu objeto para um array de bytes, observe o método readObject() de ObjectInputStream.

Para um objeto ser serializado, ele precisa implementar a interface java.io.Serializable. Objetos Java, como String e arrays, implementam essa interface, mas java.lang.Object (a mãe de todos os objetos) não implementa. Portanto, dependendo da estrutura de herança dos objetos que você deseja passar, talvez seja necessário que seus objetos implementem a interface Serializável. É possível implementar diversas interfaces em um único objeto Java, portanto, isso não deve ser um problema. Mesmo que seu objeto implemente a interface Serializável, não significa que tudo a que seu objeto fizer referência seja serializado. Convém se certificar de que seu objeto e todos os objetos aos quais ele faz referência (e os objetos aos quais eles fazem referência) implementam a Serializável.

Também será necessário garantir que a mesma versão da classe exista no ambiente CICS JVM que está realizando o LINK e no ambiente CICS JVM que está recebendo o LINK. Como parte da implementação da interface Serializável, inclua um campo definido como longo final estático privado, com um nome de serialVersionUID. Ao alterar seu objeto, também é necessário alterar o serialVersionUID. Quando o serialVersionUID é incluído no objeto, o valor associado a esse campo é armazenado no objeto serializado. Se houver uma tentativa de desserializar um objeto onde a definição da classe local não corresponde ao serialVerisionUID no objeto de serialização, a desserialização falhará, com uma mensagem de erro significativa. O uso do campo serialVersionUID evitará possíveis situações de fora de sincronização que podem causar resultados inesperados. O uso de serialVersionUID é uma prática recomendada ao usar a serialização de objeto.

As classes de transporte de objeto de dados Java fornecidas com este artigo verificam se você forneceu um serialVersionUID no objeto a ser passado, mas as classes de transporte fornecidas não validam se você forneceu um campo serialVersionUID nos objetos referenciados pelo objeto passado. Portanto, é necessário verificar se os objetos referenciados contêm um campo serialVersionUID. Na classe Java fornecida, é possível desativar a verificação de serialVersionUID usando o método setCheckForSerialVersionUIDBeforeSerialization(false) .

Se seu objeto tiver considerações especiais de serialização e a serialização normal de Java não funcionar para ele, especifique como seu objeto será serializado e desserializado implementando os métodos writeObject() e readObject(). Esses dois métodos, ao implementar a interface Serializável, serão invocados se estiverem presentes durante a serialização e desserialização do objeto.

A serialização não é trivial e exige ciclos de CPU. Uma vez que se espera que os aplicativos em execução em um ambiente CICS tenham um tempo de resposta rápido, não serialize e desserialize os objetos sem necessidade. Além disso, você deve fazer referência ao uso de objetos de dados Java serializados para seu aplicativo. O efeito geral da serialização em seu aplicativo dependerá do tamanho, complexidade e número de objetos que estão sendo serializados.

Gravando e lendo objetos Java serializados em canais e contêineres CICS em um ambiente CICS TS Java

Depois de serializar o objeto a ser passado a um array de bytes, é necessário colocar o array de bytes em um contêiner associado a um canal. No programa Java de recebimento, você precisa obter o array de bytes de um contêiner. Para obter ou colocar os dados de e em um contêiner, primeiro você precisa obter uma referência a um canal. Há três maneiras de obter uma referência de canal CICS:

  • Acessar o canal que foi passado a você (também conhecido como o canal atual) com o seguinte comando:
    Channel myChannel = Task.getTask().getCurrentChannel();

  • Criar um canal, que pode ser passado para outro programa, com o seguinte comando:
    Channel myChannel = Task.getTask().createChannel(THECHANNELNAME);

  • Acessar o canal atual ou qualquer canal criado com o nome especificado no nível do link CICS atual:
    Channel myChannel = Task.getTask().getChannel(THECHANNELNAME);

Para os métodos getCurrentChannel() e getChannel(), se a variável myChannel for nula, o canal especificado não existirá nesse nível de link CICS, portanto, será necessário criar um canal para passar o objeto de dados Java serializado.

Se você estiver pensando em adicionar contêineres a um canal (passar objetos serializados para outro programa Java em um ambiente CICS Java diferente), use o canal atual, mas tenha cuidado, pois qualquer coisa que já estiver no canal, além dos contêineres adicionados, será passada para o programa de destino. Se o programa de destino estiver em uma região CICS diferente, todo o conteúdo do contêiner será transmitido para a região CICS que contém o programa de destino (o que poderia aumentar o tempo de resposta do aplicativo). Se os contêineres forem passados para um ambiente Java diferente dentro da mesma região CICS, a passagem do conteúdo do contêiner será uma transferência de memória para memória.

Depois de obter uma referência para um canal, é possível usar o código a seguir para colocar os dados em um contêiner, obter dados dele e excluí-lo. Há dois tipos de contêineres CICS -- CHAR e BIT, e convém usar os contêineres BIT nesse caso. Os nomes do canal e do contêiner podem ter de 1 a 16 caracteres.

byte[] myByteArray = "some bytes".getBytes();   // to be passed
Container myContainer = myChannel.createContainer(containerName);
myContainer.put(myByteArray);                   // this is a BIT container

Container myContainer = myChannel.getContainer(containerName);
byte[] myByteArray = myContainer.get() ;        // get the byte array from the container

myChannel.deleteContainer(containerName);       // delete the container

Ao trabalhar com canais e contêineres em seu programa Java baseado em CICS, diversas exceções podem ser lançadas, portanto, coloque os fragmentos de código acima em blocos try/catch.

Invocando outro programa CICS de um programa Java baseado em CICS

Os programas Java baseados em CICS que usam outros programas Java dentro do mesmo ambiente Java fornecido por CICS, devem usar técnicas Java normais -- instanciar um objeto do tipo apropriado e invocar os métodos apropriados nesses objetos.

Invocar outro programa Java baseado em CICS que executa em um ambiente Java fornecido por CICS diferente do ambiente Java fornecido por CICS atual (ou que execute em um ambiente Java diferente fornecido por CICS sob o controle de uma região CICS diferente) exige o equivalente a um EXEC CICS LINK para o outro programa Java. O equivalente em Java de um comando EXEC CICS LINK é bem direto, como mostra abaixo:

Program aProg = new Program();
aProg.setName(targetProgram);
aProg.link(theChannel);

No fragmento de código acima, targetProgram é uma variável contendo o nome do programa CICS que receberá o LINK. O método link(theChannel) tenta o LINK, passando o canal especificado e todos os contêineres nesse canal. Coloque o fragmento de código acima em um bloco try/catch.

A partir de uma perspectiva teórica, isso é tudo -- basta serializar o objeto em um array de bytes, colocar o array de bytes em um contêiner associado a um canal, aplicar um LINK para o programa de destino e desserializar o array de bytes passado no contêiner em um objeto de dados que possa ser usado por seu programa.

Há tantas etapas que a melhor abordagem é codificar um conjunto de classes genéricas para executar essas etapas para você. Enquanto pesquisávamos os conceitos apresentados neste artigo, escrevemos um conjunto de classes que pode ser usado para ver as etapas e a sintaxe dos comandos, além de ser ampliado para seu próprio uso. (Essas classes Java não foram enviadas para qualquer teste oficial da IBM e são fornecidas "no estado em que se encontram" a fim de ilustrar os conceitos descritos neste artigo.) Embora a abordagem descrita neste artigo facilite a vida do desenvolvedor de aplicativo Java, o desempenho apresentará variações. Portanto, se você usar as técnicas descritas neste artigo, estude seus resultados para ver se seu aplicativo apresenta um desempenho dentro de níveis aceitáveis, ou se, em vez de usar objetos serializados, converta os dados dos objetos de dados Java para uma estrutura de série de bytes orientada ao campo ao passar dados entre seus programas Java (em outras palavras, use a técnica de passagem de dados CICS tradicional, que é necessária ao passar dados para programas baseados em CICS codificados em diversas linguagens e não apenas em Java).

Usando as classes Java fornecidas para passar objetos Java entre programas CICS Java

Ao passar objetos Java entre ambientes JVM baseados em CICS, o ambiente CICS Java de origem será:

  • Aplicativo de script dinâmico CICS
  • Programa wrapper de serviço da web baseado em Axis2
  • Programa cliente CICS Transaction Gateway Java
  • Ambiente OSGi baseado em CICS
  • Ambiente de JVM compartilhado baseado em CICS

Os ambientes de destino JVM baseados em CICS onde o programa de lógica de negócios Java de destino será invocado são:

  • Ambiente OSGi baseado em CICS
  • Ambiente de JVM compartilhado baseado em CICS

Novamente, o ambiente OSGi baseado em CICS é o local estratégico para a lógica de negócios baseada em Java no CICS, pois ele maximiza a flexibilidade de sua lógica de negócios e possibilita a reutilização permitindo que você exponha a lógica de negócios baseada em Java usando várias opções de interoperabilidade de CICS, incluindo serviços da web, interface RESTful, WebSphere MQ e script dinâmico CICS.

O código de origem para o transportador do objeto de amostra deve ajudá-lo a entender a abordagem de passar objetos serializados em um ambiente Java fornecido por CICS. É possível usar o transportador de objeto fornecido ou aprimorar o transportador de objeto a fim de acomodar quaisquer requisitos especiais.

Passando objetos Java de uma JVM compartilhada por CICS, uma JVM baseada em OSGi ou uma Axis2 JVM

Passar objetos Java de uma JVM compartilhada por CICS, uma JVM baseada em OSGi ou uma JVM baseada em Axis2 usando a classe Java fornecida é a mesma coisa, mas a forma como você especifica onde reside a classe Java fornecida é diferente em cada ambiente. O objeto DDW_CicsObjectTransporter fornecido com este artigo permite que você realize um LINK com um programa Java de destino chamado TARGET, passando objetos usando a seguinte abordagem:

String abc = "Some information to Pass";
Employee emp = new Employee("John Doe");
DDW_CicsObjectTransporter transporter =
    new DDW_CicsObjectTransporter();
transporter.addObject("abc",abc).
    addObject("emp",emp).
    execute("TARGET");

// and after the program returns

String errorString = (String)transporter.getObject("error");
If (errorString != null) {
    processError();
} else {
    Manager newManager = (Manager)transporter.getObject("mgr");
    // process/display Manager object that was returned
}

Na classe DDW_CicsObjectTransporter fornecida com este artigo, ao responder ao exemplo de código acima:

  1. A classe DDW_CicsObjectTransporter fornecida (o transportador) usa um nome de canal DDWddwObjTrnsptr. Se o transportador tiver passado um canal com esse nome ou já tiver criado um canal com esse nome, esse canal será usado. Caso contrário, o transportador criará um canal chamado DDWddwObjTrnsptr. Portanto, se você instanciar um segundo transportador, ele usará o mesmo canal chamado DDWddwObjTrnsptr, uma vez que já existirá um da primeira instância de classe.
  2. O método execute() causará uma solicitação de LINK para o programa especificado.
  3. Quando um método addObject(String containerName, Object obj) é invocado, o obj é serializado e colocado e m um contêiner cujo nome é containerName.
  4. O transportador verifica se essa referência do objeto por obj contém um campo chamado serialVersionUID, mas o transportador não verifica se os objetos referenciados por obj contêm um campo serialVerisionUID . Essa verificação consome ciclos de CPU, portanto, se você quiser evitá-la, invoque transporter.setCheckForSerialVersionUIDBeforeSerialization(false).
  5. Se o método getObject(String containerName) for invocado, o array de bytes no contêiner especificado será desserializado e o objeto será retornado. O método getObject() retorna um objeto do tipo Object, portanto, você precisa estereotipar o Object retornado no tipo de objeto que você está esperando.
  6. Se você invocar o método removeObject(String containerName) , o transportador invocará um método deleteContainer(containerName) no canal DDWddwObjTrnsptr a fim de remover o contêiner.
  7. A convenção ao usar canais e contêineres para situações de erro é retornar um contêiner de erro (com algum nome acordado) com uma indicação da causa do erro. Portanto, o programa de lógica de negócio TARGET deverá adicionar um objeto de erro ao transportador caso detecte uma situação de erro (como "cliente não encontrado"). O código de amostra acima testa a existência de um contêiner de erro chamado error. Se ele existir, a solicitação apresentará um erro, que deve ser processado. Se não houver um contêiner error , a solicitação será bem-sucedida.
  8. Se o transportador remoto no programa TARGET apresentar um erro de serialização ou desserialização ou de obtenção, adição ou remoção de contêineres, o DDW_CicsObjectTransporter remoto lançará uma exceção e aplicará um contêiner de erro chamado DDWddwObjTErrorM no canal. Se o transportador local encontrar esse contêiner de erro, qualquer solicitação de método do transportador lançará uma exceção afirmando a causa do erro no transportador remoto.
  9. Igualmente, se o transportador local tiver um problema de serialização ou desserialização de um objeto, ou de obtenção, adição ou remoção de contêineres, o transportador lançará uma exceção afirmando a causa do erro. Quando qualquer erro ocorrer no transportador, qualquer solicitação de método de transportador para o transportador lançará uma exceção afirmando o problema original. Se você não gostar desse comportamento, poderá invocar os métodos
    transporter.checkForTransporterErrorsInChannel(false) e
    transporter.writeTransporterErrorsToChannel(false) .
  10. Algumas das mensagens de erro fornecidas quando a desserialização nativa Java enfrenta um problema para desserializar objetos referenciados por outros objetos não fornecem uma boa indicação com relação à causa do erro. O transportador pode apenas passar as informações que recebe.
  11. Se você tiver problemas com o transportador, use o método transporter.setDebugLevel(9) para que o transportador grave mensagens no destino CSMT Transient Data (especifique 0 se você não quiser mensagens de depuração -- quanto maior o número de depuração, mais detalhada serão as mensagens). Para gravar na saída padrão em vez de gravar em uma fila de TD, use:
    transporter.setPrintToTdQueue(false).
    Se você quiser enviar as mensagens para uma fila de TD que não a CSMT, use:
    transporter.setTdQueueForPring("NAME").
    Também é possível definir o nível de depuração no construtor do transportador para ver as mensagens de inicialização do transportador. Use:
    DDW_CicsObjectTransporter transporter = new
    DDW_CicsObjectTransporter(9);
    .

Seu ambiente Java baseado em CICS necessitará de acesso para a classe DDW_CicsObjectTransporter contida no arquivo com.ibm.ddw.cics.object.transporter.jar fornecido com este artigo:

  • Para um ambiente JVM compartilhado por CICS, adicione o arquivo JAR à variável CLASSPATH_SUFFIX em seu arquivo JVMProfile do CICS Java PROGRAM (PROGRAMs em um ambiente de JVM compartilhado e os arquivos JVMProfile estão descritos na Parte 1 desta série).
  • Para um ambiente Axis2 JVM fornecido por CICS, coloque o pacote com.ibm.ddw.cics.object.transporter com seu aplicativo.
  • Para um ambiente baseado em CICS OSGi, é possível usar três abordagens diferentes para disponibilizar o transportador do objeto para seus pacotes OSGi:
    1. Inclua o código de origem no pacote com.ibm.ddw.cics.object.transporter como um dos pacotes em seu pacote OSGi que usa o transportador.
    2. Adicione o arquivo com.ibm.ddw.cics.object.transporter.jar com seu aplicativo ao diretório raiz de seu pacote e especifique o local do arquivo JAR na opção CLASSPATH do manifesto de seu pacote OSGi.
    3. Coloque o arquivo com.ibm.ddw.cics.object.transporter.jar em um local comum do sistema de arquivos z/OS UNIX System Services e especifique o local do arquivo JAR na opção CLASSPATH do manifesto do pacote OSGi.

A vantagem da Opção 3 é que você sabe que todos seus pacotes OSGi acessarão a mesma versão do código do transportador de objeto, mas se você estiver preocupado com a portabilidade do pacote OSGi, considere uma das duas primeiras opções. Ao decidir entre a Opção 1 ou 2, se você quiser ver o transportador de objeto como uma implementação de caixa preta e não lidar com o código de origem, use a Opção 2.

O pacote com.ibm.ddw.cics.object.transporter não pode ser usado como um pacote OSGi independente e não pode ser incluído no parâmetro OSGI_BUNDLES= no arquivo JVMProfile do OSGi JVMServer, uma vez que as regras de visibilidade de OSGi causarão o recebimento de um ClassNotFoundException pelo transportador de objeto quando ele tentar desserializar objetos. Você poderia importar cada pacote que usará o transportador de objeto no pacote OSGi do transportador de objetos, mas isso é impraticável, pois você teria que mudar constantemente o pacote OSGi do transportador de objeto para cada utilização nova do transportador de objeto. O arquivo JAR com.ibm.ddw.cics.object.transporter inclui os arquivos de origem e .class e está incluído com este artigo.

Passando objetos Java de um ambiente de script dinâmico CICS

Conforme indicado acima, o script dinâmico CICS fornece um interpretador de PHP e Groovy implementado em Java e é executado em um servidor CICS JVM. Uma ponte de PHP-para-Java permite que você instancie e invoque classes e métodos Java. Também é possível instanciar e invocar classes e métodos Java usando o Groovy. Portanto, DDW_CicsObjectTransporter pode ser usado para passar objetos Java de um script PHP ou Groovy para uma JVM compartilhada fornecida por CICS ou baseada em OSGi, permitindo, dessa forma, que você escreva sua lógica de apresentação em PHP ou Groovy e mantenha sua lógica de negócios baseada em Java em um ambiente JVM compartilhado por CICS ou baseado em OSGi.

Embora não seja exibido abaixo, também é possível usar Java como uma linguagem de programação em seu aplicativo de script dinâmico CICS. O uso do transportador de objeto em um programa Java em execução em um ambiente de script dinâmico CICS é parecido com o uso do transportador de objeto em um ambiente JVM compartilhado por CICS, exceto pelo fato de que o arquivo com.ibm.ddw.cics.object.transporter.jar precisa ser colocado no diretório lib de seu aplicativo de script dinâmico CICS, e um zero resolve precisa ser realizado em seu aplicativo.

Veja um exemplo simples de como usar DDW_CicsObjectTransporter a partir de um script PHP simples:

<html>
<head><title>Link to a CICS Java program with objects</title></head>
<body>
<?php
try {
    // create some Java objects using the PHP to Java bridge
    $someString = "some string";
    $myManager = new Java('com.ddw.transporter.test.Manager');
    $myManager->setManagerName('Roy');
    $staffArray = new Java('java.util.ArrayList');
    $aStaff = new Java('com.ddw.transporter.test.Staff', "Dennis");
    $staffArray->add($aStaff);
    $myManager->setStaff($staffArray->toArray());

    // transport objects to/from specified CICS Java program
    $transporter = new
Java('com.ibm.ddw.cics.object.transporter.DDW_CicsObjectTransporter');
    $transporter->addObject("someString", $someString);
    $transporter->addObject("myManager", $myManager);
    $transporter->execute("PROGRAMB");    // invoke CICS Java program
    $responseData = $transporter->getObject("responseData");
    echo $responseData;
} catch (Exception $e1) {
    echo 'Exception: '.$e1->getMessage();
}
?>
</body>
</html>

No exemplo de código acima, a passagem de objetos é parecida com os ambientes Axis2 fornecido por CICS, compartilhados e OSGi.

  • Você está adicionando um array de Staff a um objeto Manager , adicionando o objeto Manager ao transportador e invocando o programa CICS Java chamado PROGRAMB.
  • O bloco try/catch testa a ocorrência de uma exceção, mas o transportador lançará somente um DDW_CicsObjectTransporterException, portanto, você poderia ter testado especificamente para essa exceção.

Para usar DDW_CicsObjectTransporter em seu aplicativo de script dinâmico CICS, adicione com.ibm.ddw.cics.object.transporter.jar ao diretório lib de seu aplicativo e realize um zero resolve.

Recebendo objetos Java em uma JVM compartilhada por CICS ou uma JVMServer baseada em OSGi

É possível usar o seguinte código com DDW_CicsObjectTransporter para receber objetos Java em um programa Java baseado em CICS em execução em uma JVM compartilhada por CICS ou em um servidor JVM baseado em CICS OSGi:

DDW_CicsObjectTransporter transporter =
    new DDW_CicsObjectTransporter();
Employee emp = (Employee)transporter.getObject("emp");
// work with employee object
transporter.removeObject("abc");    // can also remove objects
Manger mgr = new Manger("Joe Bloggs");
transporter.addObject("mgr",mgr);  // add new or changed objects
return;

No exemplo de código acima:

  1. A classe DDW_CicsObjectTransporter fornecida (o transportador) usa um nome de canal DDWddwObjTrnsptr. Nesse caso, como esse programa Java foi invocado por um transportador a partir de um programa Java remoto baseado em CICS, o canal atual (o canal passado para esse programa) tem um nome de DDWddwObjTrnsptr. É possível usar os métodos getObject(), removeObject() e addObject() do transportador.
  2. Quaisquer objetos adicionados ao transportador voltarão ao programa que está realizando o LINK.
  3. Embora seja um pouco confuso, você poderia instanciar um segundo ou terceiro transportador. Todas as instâncias do transportador usariam o canal atual, uma vez que ele tem um nome de DDWddwObjTrnsptr. Não haveriam conflitos.
  4. Embora não seja exibido, você pode usar o método execute() para realizar um LINK com outro programa Java em um outro ambiente Java baseado em CICS.
  5. A convenção ao usar canais e contêineres para situações de erro é retornar um contêiner de erro (com algum nome acordado) com uma indicação da causa do erro. Portanto, o programa que receberá o LINK (este programa) deve adicionar um contêiner de erro ao canal, se um erro tiver sido encontrado. Você poderia adicionar um código como este:
    String error = "The customer named "+theCustomerName+" was not found");
    transporter.addObject("error", error);
    .
    E no programa que realiza o LINK, você acessaria os dados do erro da seguinte maneira:
    String error = (String)transporter.getObject("error");
    // null if no ‘error'if (error != null)
    {// handle the error here or throw new ApplicationException(error);}
  6. Se esse transportador apresentar um erro de serialização ou desserialização ou de obtenção, adição ou remoção de contêineres, ele lançará uma exceção e colocará um contêiner de erro chamado DDWddwObjTErrorM no canal. Se o transportador do programa que está realizando o LINK encontrar esse contêiner de erro, quaisquer solicitações para esse transportador lançará uma exceção afirmando a causa do erro nesse transportador (o remoto).
  7. Se você invocar quaisquer métodos neste transportador após ele ter detectado um problema de serialização ou desserialização, ele lançará uma exceção afirmando o problema original que causou o erro inicial. Se você não gostar desse comportamento, poderá invocar o método
    transporter.checkForTransporterErrorsInChannel(false)
    , e se não quiser passar os erros do transportador de volta ao transportador do programa que está realizando o LINK, invoque o método
    transporter.writeTransporterErrorsToChannel(false) .
  8. Algumas das mensagens de erro fornecidas quando a desserialização nativa Java enfrenta um problema para desserializar objetos referenciados por outros objetos não fornecem uma boa indicação com relação à causa do erro. O transportador pode apenas passar as informações que recebe.
  9. Se você tiver problemas com o transportador, use o método transporter.setDebugLevel(9) para que o transportador grave mensagens no destino CICS CSMT Transient Data. Especifique 0 se você não quiser mensagens de depuração -- quanto maior o número de depuração, mais detalhada serão as mensagens. Para gravar em stdout em de uma fila TD, use:
    transporter.setPrintToTdQueue(false).
    Se você quiser enviar as mensagens para uma fila de TD que não a CSMT, use:
    transporter.setTdQueueForPring("NAME").
    Também é possível definir o nível de depuração no construtor do transportador para ver as mensagens de inicialização do transportador. Use:
    DDW_CicsObjectTransporter transporter = new
    DDW_CicsObjectTransporter(9);

Seu ambiente Java baseado em CICS precisará de acesso à classe DDW_CicsObjectTransporter incluída no arquivo com.ibm.ddw.cics.object.transporter.jar fornecido com este artigo.

  • Para um ambiente JVM compartilhado por CICS, adicione o arquivo JAR à variável CLASSPATH_SUFFIX em seu arquivo JVMProfile do CICS Java PROGRAM (PROGRAMs em um ambiente de JVM compartilhado e os arquivos JVMProfile estão descritos na Parte 1 desta série).
  • Para um ambiente baseado em CICS OSGi, é possível usar três abordagens diferentes para disponibilizar o transportador do objeto para seus pacotes OSGi:
    1. Inclua o código de origem no pacote com.ibm.ddw.cics.object.transporter como um dos pacotes em seu pacote OSGi que usa o transportador.
    2. Adicione o arquivo com.ibm.ddw.cics.object.transporter.jar com seu aplicativo (no diretório raiz de seu pacote) e especifique o local do arquivo JAR na opção CLASSPATH do manifesto de seu pacote OSGi.
    3. Coloque o arquivo com.ibm.ddw.cics.object.transporter.jar em um local comum do sistema de arquivos do z/OS UNIX System Services e especifique o local do arquivo JAR na opção CLASSPATH do manifesto do pacote OSGi.

A vantagem da Opção 3 é que você sabe que todos seus pacotes OSGi acessarão a mesma versão do código do transportador de objeto, mas se você estiver preocupado com a portabilidade do pacote OSGi, considere uma das duas primeiras opções. Ao decidir entre a Opção 1 ou 2, se você quiser ver o transportador de objeto como uma implementação de caixa preta e não lidar com o código de origem, use a Opção 2.

O pacote com.ibm.ddw.cics.object.transporter não pode ser usado como um pacote OSGi independente e não pode ser incluído no parâmetro OSGI_BUNDLES= no arquivo JVMProfile do OSGi JVMServer, uma vez que as regras de visibilidade de OSGi causarão o recebimento de um ClassNotFoundException pelo transportador de objeto quando ele tentar desserializar objetos. Você poderia importar cada pacote que usará o transportador de objeto no pacote OSGi do transportador de objetos, mas isso é impraticável, pois você teria que mudar constantemente o pacote OSGi do transportador de objeto para cada utilização nova do transportador de objeto. O arquivo JAR com.ibm.ddw.cics.object.transporter inclui os arquivos de origem e .class e está incluído com este artigo.

Desempenho

Um dos primeiros comentários dos especialistas no assunto que revisaram este artigo foi relacionado ao desempenho. Há um custo para serializar e desserializar objetos. Ao usar o transportador de objeto fornecido, avalie seu aplicativo logo no início do ciclo de vida de desenvolvimento a fim de verificar se ele tem as características de desempenho que você precisa. Embora a passagem de dados entre programas Java baseados em CICS usando a abordagem tradicional de série de bytes orientada ao campo exija a execução de utilitários adicionais e o conhecimento sobre alguns detalhes de uma linguagem processual, como COBOL ou PL/I, essa abordagem tradicional pode ter um desempenho melhor.

A verificação de erro foi adicionada à amostra de transportador fornecida com este artigo e grande parte da verificação de erro está ativada por padrão. Para melhorar o desempenho do código de amostra do transportador fornecido, é possível usar os métodos listados abaixo para desativar parte da verificação de erro. Além disso, quando são detectados erros de incompatibilidade de versão, um aviso é emitido por padrão e o transportador continua a funcionar. Se você quiser que o transportador seja desativado se um transportador remoto em um nível diferente for detectado, use o método setStopTransporterActivityIfLocalRemoteVersionsDifferent(true) .

setCheckForTransporterErrorsInChannel(false);
   // Don't check for errors from previous requests
setCheckForSerialVersionUIDBeforeSerialization(false);
   // Don't take time to check for serialVersionUID field on objects to be serialized
setCheckTheTransporterLevelWithWhichWeAreCommunicating(false);
   // Don't take time to check if local and remote transporter are at same level

Conforme indicado anteriormente, use o transportador de objetos somente ao se movimentar entre ambientes Java baseados em CICS. Ao permanecer dentro de um único ambiente Java baseado em CICS, use a programação Java normal, instanciando os objetos e invocando os métodos.

A classe DDW_CicsObjectTransporter tem a intenção de implementar uma técnica conhecida do programador de aplicativos em Java e simplificar a passagem de objetos. Como o transportador de objetos é fácil de usar para um programador de aplicativos em Java, será muito fácil ficar bastante descuidado. Se você passar objetos que contêm mais informações do que você precisa passar ou se os objetos que você passar fizerem referência a outros objetos que não precisam ser passados, você perderá tempo serializando dados e transferirá dados extras desnecessariamente; ambas as opções aumentarão seu tempo de resposta sem necessidade.

Depurando problemas de passagem de objeto

É possível configurar o nível da mensagem de depuração nos transportadores de objeto usando um campo int com um valor de 1 a 9 como um argumento para o construtor ou usando o método transporter.setDebugLevel(5) . Quanto maior o número, mais detalhadas serão as mensagens. Se você quiser que as mensagens sejam enviadas para a saída padrão, invoque transporter.setPrintToTdQueue(false) ou a mensagem irá para o destino de dados transientes CSMT. Se você quiser mudar o destino, invoque transporter.setTdQueueForPrint("ABCD").

Também é possível definir o nível de depuração no construtor do transportador para ver as mensagens de inicialização do transportador. Use:
DDW_CicsObjectTransporter transporter = new
DDW_CicsObjectTransporter(9);
.

Distribuição da carga de trabalho

É comum em um ambiente grande de CICS distribuir as solicitações de seu aplicativo em diversas regiões do CICS para obter disponibilidade e escalabilidade. O CICS normalmente executa a distribuição de carga de trabalho por programa. Como as técnicas descritas no artigo fornecem uma maneira fácil de passar objetos para um programa Java baseado em CICS, você poderia usar essas técnicas de passagem de dados Java e ainda fazer com que o CICS execute a distribuição de carga de trabalho de seus programas Java.

Interoperabilidade de linguagem

Um dos pontos fortes do CICS é sua capacidade de interoperar com a lógica de negócios escrita em diversas linguagens de programação. As técnicas neste artigo presumem que você precisa passar dados entre dois programas Java baseados em CICS em execução em dois ambientes Java diferentes fornecidos por CICS. Como as linguagens diferentes de Java não entendem objetos Java serializados, não é possível usar a abordagem do transportador de objetos para interoperar com um programa Assembler, C, C++, COBOL ou PL/I CICS. Em um ambiente CICS, para interoperar entre Java e Assembler, COBOL ou PL/I, você precisa mover os dados em um formato que possa ser entendido pelo programa Assembler, COBOL ou PL/I -- um formato de série de bytes, orientado ao campo.

Serialização do objeto Java

Para conferir uma discussão dos prós e contras ou dos aspectos detalhados da serialização de objeto (serialização Java nativa ou algumas das rotinas de serialização/desserialização de software livre disponíveis), consulte a documentação Java apropriada.

Conclusão

Este artigo descreveu as etapas para passar objetos de dados Java entre programas Java em execução nos diferentes ambientes CICS Java fornecidos pelo CICS:

  • Serializar o objeto de dados Java em um array de bytes.
  • Colocar o array de bytes em um contêiner CICS associado a um canal.
  • Invocar o equivalente ao comando EXEC CICS LINK para passar o canal que detém os contêineres cujo conteúdo esteja nos objetos de dados Java serializado
  • No programa que recebeu o LINK, obtenha o array de bytes do contêiner CICS e desserialize o array de bytes em um objeto de dados Java utilizável.

Finalmente, o artigo descreveu as classes Java fornecidas que implementam as técnicas descritas no artigo. Essas classes Java não foram enviadas para qualquer teste oficial da IBM e são fornecidas "no estado em que se encontram" a fim de ilustrar os conceitos descritos neste artigo. As técnicas descritas neste artigo facilitarão a vida do desenvolvedor de aplicativo Java e, como ocorre em qualquer ambiente, o desempenho apresentará variações. Se você usar essas técnicas, avalie seus resultados para determinar se seu aplicativo apresenta um desempenho com níveis aceitáveis ou se, em vez de usar objetos serializados, você deve converter os dados de objetos de dados Java para uma estrutura de série de bytes, orientada ao campo, ao passar dados entre seus programas Java.

A Parte 3 mostrará como passar objetos de dados Java de um programa cliente CICS Transaction Gateway Java para um ambiente CICS Transaction Server Java.

Agradecimentos

O autor gostaria de agradecer aos seguintes colegas da IBM pela ajuda em revisar este artigo e fornecer sugestões para o conteúdo e aprimoramentos:

  • Steve Fowlkes, Certified IT Specialist, Suporte técnica de CICS, IBM EUA
  • Leigh Compton, Certified IT Specialist, Equipe de qualificações técnicas avançadas de CICS, IBM EUA
  • Mark Cocker, Planejamento e estratégia técnica de CICS, IBM Reino Unido
  • Phil Wakelin, Planejamento e estratégia técnica de CICS, Java e acesso ao CICS, IBM Reino Unido


Download

DescriçãoNomeTamanhoMétodo de download
Code samplecom.ibm.ddw.cics.object.transporter.zip28 KBHTTP

Informações sobre métodos de download


Recursos

Sobre o autor

Photo of Dennis Weiand

Dennis Weiand é Client Technical Specialist em CICS, web e Java na equipe IBM Technical Sales de Dallas, TX. É possível entrar em contato com Dennis pelo email dweiand@us.ibm.com.

Ajuda para Relatar Abuso

Relatar abuso

Obrigado. Esta entrada foi sinalizada para atenção do moderador.


Ajuda para Relatar Abuso

Relatar abuso

Falha no envio do Relatório de abuso. Tente novamente mais tarde.


developerWorks: Registre-se


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Na primeira vez que você efetua sign in no developerWorks, um perfil é criado para você. Informações selecionadas do seu perfil developerWorks são exibidas ao público, mas você pode editá-las a qualquer momento. Seu primeiro nome, sobrenome (a menos que escolha ocultá-los), e seu nome de exibição acompanharão o conteúdo que postar.

Selecione seu nome de exibição

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

(Deve possuir de 3 a 31 caracteres.)


Ao clicar em Enviar, você concorda com os termos de uso do developerWorks.

 


Classificar este artigo

Comentários

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Tecnologia Java, WebSphere
ArticleID=790643
ArticleTitle=Passando objetos de dados entre ambientes Java CICS: Parte 2: técnicas para passar objetos de dados Java
publish-date=02022012