Oracle vs Java

Bruno Braga on July 1st, 2008

Atualmente estou atuando em um projeto onde é necessário a integração do Oracle com Java. Ou seja: é necessário executar código Java dentro do Oracle para uma determinada funcionalidade.

Esse projeto faz parte de um treinamento/consultoria sobre Websphere MQ (antigamente chamado de MQSeries) para um cliente, e vai ser o primeiro tema / “puxão de orelha” depois da reformulação do blog.

Puxão de orelha porque alguns itens referentes a integração do Oracle com Java não são legais. Mas para entender o problema e o funcionamento da integração vamos a um rápido cenário do aplicativo:

Além do treinamento de Websphere MQ o cliente solicitou que fosse desenvolvido um conector MQ em Java para posteriormente ser utilizado pelo sistema deles. Então optamos por desenvolver o conector MQ usando JMS e abstrair toda a complexidade da comunicação. Ele iria enviar mensagens com um comando e receber mensagens com um comando a partir do aplicativo Java. Até esse ponto estava excelente.

A dificuldade começou quando o cliente solicitou que o Conector MQ fosse executado dentro do Oracle através de uma trigger já que o Oracle suportava Java. Realmente o Oracle suporta Java, mas não tão bem como era esperado.
Somente para deixar claro: classes Java simples (recursos nativos da JVM) rodam muito bem no Oracle, isso foi um ponto bem positivo. O problema é executar uma aplicação ou conector que tem vários jars como API.

Objetivamente seguem detalhes sobre pontos problemáticos do Oracle versão 10.2:

  • ele não aceita jar’s externos. Todos os jar’s devem ser carregados para o banco usando o comando loadjava.
  • o comando loadjava carrega as classes do jar mas deixa todas com status INVALID !?!?… a maneria de resolver isso é usar o comando loadjava com o parâmetro “-resolve”.
  • o problema do parâmetro “-resolve” é que ele tenta “re-compilar” todas as classes do jar (sendo que um jar já é algo pronto para utilizar). Para cada classe o Oracle solicita as dependências (classes que estão no import). Então para incluir um jar de um driver do MQ preciso de N outros jars para satisfazer as dependências de compilação;
  • uma forma de resolver o problema acima podemos até utilizar o parâmetro “-genmissing” do comando loadjava, ele vai gerar uma classe fake para cada dependência e evita problemas de compilação, mas é obvio que se a classe fake for usada em qualquer ponto do processo (direta ou indiretamente) vai dar erro (ORA-29532: Java call terminated by uncaught Java exception: java.lang.NoClassDefFoundError:
    !!!ERROR!!! generated by genmissing) – então o genmissing não é muito útil, somos obrigados a ter as dependências para compilar / resolver quase tudo usando o “-resolve”;
  • o Oracle carrega para dentro do banco a classe que queremos importar + todos os jars necessários para execução + todas as dependências. Então temos um excesso de classes desnecessariamente;

Por causa dessas limitações a integração do Oracle com Java não é tão transparente. Não acredito que isso tenha um tratamento melhor no Oracle 11. Apesar do banco Oracle não ser um Application Server, poderia pelo menos seguir a arquitetura Java e ler as libs de um CLASSPATH. A parte de ter que carregar os jar para dentro do Oracle e re-compilar matou parte do suporte a Java do banco. Esse trabalho todo não vale a pena :)

Então esse foi o puxão de orelha, e todos esses problemas foram suportados pelo suporte oficial Oracle (http://metalink.oracle.com).

Mas em tempo, o SQLJ é bastante poderoso: podemos escrever uma classe Java (usando recursos nativos) e em determinados pontos utilizar #sql() (querys) com váriaveis Java. Então considerando somente esta necessidade a utilização é válida.

4 Responses to “Oracle vs Java”

  1. Bruno no fim vc conseguiu resolver esse problema ??? Fiz um carinha acessando o http de um server, mas hj preciso conectar no MQ e nao to conseguindo nem a pau fazer o o loadjava dos libs.(até diz q funciona) mas nao to conseguindo fazer na compilação da classe q o Oracle enxerger esse jar externo. De qq forma obrigado

  2. Augusto, ler o jar externo não dá mesmo.
    Eu conseguia ler uma jar interno importado com o loadjava.

    Mas no meu caso eram muitos arquivos jar. Muitas libs para o meu código funcionar então essa funcionalidade não funciona bem para isso.

    Eu era obrigado a usar o loadjava -resolve e isso me obrigava ater todos os jar que eram as dependencidas para recompilar. Então não estava legal.

    Precisava de tanta dependência que chegou uma hora que não dava mais. Era quase um loop infinito.

    O que eu fiz no meu caso foi criar uma classe Java dentro do Oracle com pouca dependência (basicamente só dependia do JDK que é nativo, não dependia de nenhum jar).

    E nessa classe eu executei um comando no Java no S.O via Runtime, tipo java -cp /path/meupacote.jar MinhaClasse

    Então a parte de enviar para o MQ eu deixei no S.O e só “chamei” ela de dentro do Oracle.

    Apesar de usar uma chamada externa, ela pode ser controlada com o waitFor() para aguardar o processamento e ter um controle de erros. Então contornei essas limitações do Oracle com esse workaround.

  3. Ola Bruno,
    Seguinte, eu estou no mesmo problema, ja tentei de tudo quanto é jeito fazer a chamada ao MQ de dentro do Oracle sem sucesso, não consigo carregar os jars la de nenhum jeito. Tirando o problema de ter muitas dependencias, voce alguma vez conseguiu fazer esta chamada?
    Outra coisa é sobre o seu workaround, eu estou tentando fazer a chamada a uma classe no SO como vc fez, mas quando faço a chamada de dentro ro Oracle, a JVM do Oracle não encontra minha classe, vc teve algum problema parecido? Estou passando o caminho da minha classe no -cp e mesmo assim ele diz que nao encontrou a classe.
    Grato,

  4. Bruno, boa tarde !

    Você já experimentou utilizar-se do Oracle AQ ?
    É uma solução interessante pois, trata-se de JMS nativo do Oracle e pode ser configurado como uma Bridge para outros Brokens JMS.
    Veja mais sobre isto neste link:
    http://download.oracle.com/doc.....qintro.htm

    Mais sobre integração com Websphere MQ você encontra neste link:
    http://www.ibm.com/developerwo....._tuli.html

    Recentemente eu necessitei usar isto e acho que serve ao seu caso.

    Abs

Trackbacks/Pingbacks

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>