Pergunta

Estou tentando usar uma biblioteca Java de terceiros na Oracle. A biblioteca parece compatível com a mesma versão 1.4 da JVM que nosso Oracle 10G Server Hosts, pois funciona bem fora do Oracle, então sinto que devo conseguir que isso funcione. Essa biblioteca acaba fazendo solicitações HTTP baseadas em sabão e recebo erros de resolução de classe quando executar no Oracle.

Aqui está uma linha que mostra a diferença:

Class msgfact = Class.forName("com.sun.xml.messaging.saaj.soap.MessageFactoryImpl");

Tentei registrar essas bibliotecas no Oracle no utilitário loadjava e consegui o que pensei ser um resultado bem -sucedido:

C:\>loadjava -verbose -schema MYUSER -user MYUSER/MYPWD@dbinstance -force saaj-impl.jar

Parece que tudo é carregado, e eu posso ver essa classe MessageFactoryImpl nessa lista. Mas então eu tento executar essa linha de código do Oracle SQL (dentro de outra classe que escrevi e carreguei com loadjava), essa linha lança uma classeNotFoundException (java.lang.classnotfoundException: com/sol/xml/mensagens/saaj/sabão/mensagem ).

Então voltei e tentei adicionar o interruptor "-Resolve" na linha de comando loadjava. Ele age como essas aulas de Saaj estão sendo registradas, mas elas não estão resolvendo corretamente.

Como posso colocar essas aulas de Saaj com sucesso, ou se, por algum motivo, o Oracle já está carregado, como posso convencer meu próprio código a usar com sucesso a classe existente?

FWIW, já tomei as medidas para garantir que as permissões de soquete apropriadas fossem concedidas e meu código possa fazer uma solicitação HTTP genérica para o URL de destino. Ele só tem problemas para usar a pilha de sabão da biblioteca para que isso aconteça.

EDIT: Aqui está uma amostra do meu resultado de Loadjava. Isso parece estar mostrando exatamente o que está falhando, mas estou confuso sobre o motivo pelo qual essas classes em particular não estão sendo resolvidas quando parecem ser tratadas adequadamente nas etapas de pré-resolução. Eu eliminei cerca de 80% do arquivo aqui, mas existem outras classes que mostram os mesmos problemas de resolução de classe.

arguments: '-verbose' '-schema' 'MYSCHEMA' '-user' 'MYSCHEMA/MYSCHEMA@actest' '-resolve' '-force' 'saaj-impl.jar' 
[snip]
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/GifDataContentHandler
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/GifDataContentHandler
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/JpegDataContentHandler
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/JpegDataContentHandler
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
creating : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl
loading  : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl
[snip]
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/AttachmentPartImpl
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/Envelope
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/SOAPPartImpl could not be resolved
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/GifDataContentHandler
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/JpegDataContentHandler
resolving: class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl could not be resolved
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/impl/EnvelopeImpl could not be resolved
errors   : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl$1
    ORA-29534: referenced object MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl could not be resolved
skipping : class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl$2
[snip]
The following operations failed
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/EnvelopeFactory: resolution
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageFactoryImpl: resolution
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl: resolution
    class MYSCHEMA.com/sun/xml/messaging/saaj/soap/MessageImpl$1: resolution
[snip]
exiting  : Failures occurred during processing
Foi útil?

Solução

Primeiro de tudo, verifique fora do Oracle que a classe que você está procurando está na verdade nesse arquivo JAR. Espero que seja, mas não dói verificar.

Em seguida, eu verificaria quais classes foram carregadas e se elas têm status válidos.

SELECT object_name, dbms_java.longname(object_name), status
  FROM user_objects
  WHERE object_type='JAVA CLASS'
  ORDER BY 1

Você pode limitar isso um pouco se houver muitas aulas, por exemplo:

WHERE dbms_java.longname(object_name) LIKE '%MessageFactoryImpl'

Se a classe não estiver lá, ou estiver lá com o nome do pacote errado, o problema está no comando loadjava.

Se a classe estiver lá, mas seu status for inválido, verifique o user_errors para ver quais são os erros. Não me lembro se fiz o carregamento dinâmico de classe dentro do Oracle, mas lembro que a ligação estática daria erros que implicavam que uma classe não existia quando realmente existia, mas tinha erros.

Novas informações após a saída do loadjava postada

A saída Loadjava parece inconsistente com sua tentativa de encontrar a classe no banco de dados. Se estiver sendo carregado, mas não resolvido, ainda deve ser listado, mas com um status inválido.

Eu peguei a jarra e tentei eu mesmo em um esquema vazio. A classe carrega, mas é inválida como esperado:

dev> select object_name, dbms_java.longname(object_name),status
  2  from user_objects
  3  where object_name like '%MessageFactoryImpl';

OBJECT_NAME
--------------------------------------------------------------------------------
DBMS_JAVA.LONGNAME(OBJECT_NAME)
--------------------------------------------------------------------------------
STATUS
-------
/3e484eb0_MessageFactoryImpl
com/sun/xml/messaging/saaj/soap/MessageFactoryImpl
INVALID

Eu então verifiquei o que estava o erro na aula:

dev> alter java class "com/sun/xml/messaging/saaj/soap/MessageFactoryImpl" resolve;
dev> /

Warning: Java altered with compilation errors.

dev> show error
Errors for JAVA CLASS "/3e484eb0_MessageFactoryImpl":

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      ORA-29521: referenced name javax/xml/soap/MessageFactory could
         not be found

0/0      ORA-29521: referenced name javax/xml/soap/SOAPMessage could not
         be found

0/0      ORA-29521: referenced name javax/xml/soap/MimeHeaders could not
         be found

0/0      ORA-29521: referenced name javax/xml/soap/SOAPException could not
         be found

(Esses erros também seriam listados em usuários, assumindo que a resolução foi tentada pelo menos uma vez.)

Claramente, esta classe faz referência a classes da Base Soap Biblioteca. Você teria que carregar isso também - você fez isso?

Para sua informação, quando escrevo algum código para fazer a classe. O que pode parecer contra-intuitivo, pois o objeto de classe existe no esquema. No entanto, uma classe inválida realmente não "existe" do ponto de vista do carregador de classe no Oracle; E para que a classe seja válida, o Oracle deve ser capaz de resolver todas as suas referências a outras classes.

Outras dicas

É a primeira vez que sua execução de Java no banco de dados? Aqui está a implementação do Hello World para garantir que sua JVM Oracle esteja funcionando corretamente e você tenha as permissões necessárias. Você disse "meu esquema de banco de dados, para que eu possa fazer o que eu quiser" -não significa que você tenha os subsídios adequados.

SQL> create or replace and compile java source named "Hello" as 
   public class Hello{ 
      public static String world() { 
         return "Hello World "; 
      } 
   }; 
/ 

Java created. 

Agora a função do invólucro

SQL> create or replace function Hello RETURN VARCHAR2 
     as LANGUAGE JAVA NAME 'Hello.world() return String'; 
     / 

Function created.

Agora teste

SQL> select Hello from dual; 

HELLO 
----------------------------------- 
Hello World 

Fazem isto:

try
{
    System.out.println("Class.forName returned: " + 
        Class.forName("com.sun.xml.messaging.saaj.soap.MessageFactoryImpl"));
}
catch(final Throwable ex)
{
    ex.printStackTrace();
    System.exit(1);
}

Só para ter 100 e 10% de certeza de que não está lançando uma exceção que está de alguma forma oculta e que está realmente retornando nulo. Se ainda for o caso, informe -me (problema interessante se o código acima funcionar, mas retornará nulo).

Experimente # 3 :-) (Eu não uso o Oracle ... mas esse é um problema interessante para depurar ...)

As informações aqui na classe.ForName in Oracle ajudam?

http://download.oracle.com/docs/cd/b14117_01/java.101/b12021/appover.htm#i1006547

Isso apresenta como um problema de carregador de classe, então a solução é da mesma linha que acontece no mundo "real e não oráculo" :-)

Editar ... outra tentativa ...

Ok, olhando para isso um pouco mais ... qual é a saída dos seguintes:

System.out.println("vm vendor:     " + System.getProperty("java.vendor"));
System.out.println("vm version:    " + System.getProperty("java.version"));
System.out.println("class version: " + System.getProperty("java.class.version"));

Gostaria de saber se há um problema na versão do arquivo de classe - os arquivos da classe têm uma versão que não pode ser executada na VM Oracle?

Resolução e carregamento de classe são operações complexas tratadas pela VM. O algoritmo a ser usado por essas duas operações, conforme descrito na especificação, é deixado aberto para implementadores da VM. Meu sentimento é que, no seu caso, a resolução funciona à medida que a operação verifica apenas a disponibilidade da própria classe, enquanto está falhando mais tarde ao tentar carregar efetivamente a classe (provavelmente devido à falta de dependências: ao carregar a classe, a VM precisa para resolver pelo menos todas as referências diretas a outras classes). Você precisará garantir que todas as classes estejam disponíveis para o Oracle e realizando uma rápida pesquisa no Google pelo ORA-29534, mostre toneladas de pessoas com esse problema (e tenho certeza de que alguém descobriu).

./Alex

O SAAJ-IMPL.JAR faz parte do componente SAAJ do pacote de desenvolvedores de serviços da Web. Ele tem dependências de outros frascos que enviam com Saaj, por exemplo, definitivamente depende de saaj-api.jar e ativação.jar, que eu saiba. Obviamente, o saaj-api.jar deve depender de muitos outros potes também.

No que diz respeito ao JWSDP 1.5, você pode encontrar as informações em Notas de liberação do JWSDP 1.5 Ser útil. O JWSDP 1.6 tem frascos diferentes em Saaj I não achei que as notas de lançamento do JWSDP 2.0 fossem particularmente úteis nesse sentido. BTW, o JWSDP 2.0 teria frascos diferentes para serem colocados no caminho de classe; Portanto, o escopo do seu problema eventualmente depende da versão do saaj-impl.jar que você usa.

No caso de você precisar, já está disponível alguma documentação sobre como carregar os frascos do cliente SOAP em um banco de dados Oracle e utilizá -los nas páginas seguintes. Presumo que estes sejam diferentes dos frascos SAAJ que acompanham sua biblioteca.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top