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.

Subscribe to this blog's RSS feed