문제

Oracle 내에서 타사 Java 라이브러리를 사용하려고 합니다.라이브러리는 Oracle 10g 서버가 호스트하는 jvm의 동일한 1.4 버전과 호환되는 것 같습니다. Oracle 외부에서도 잘 실행되기 때문에 이 라이브러리를 작동시킬 수 있어야 한다고 생각합니다.이 라이브러리는 SOAP 기반 http 요청을 생성하게 되며 Oracle에서 실행할 때 클래스 확인 오류가 발생합니다.

차이점을 보여주는 줄은 다음과 같습니다.

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

나는 loadjava 유틸리티를 사용하여 이러한 라이브러리를 Oracle에 등록하려고 시도했으며 성공적인 결과를 얻었습니다.

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

모든 것이 로드된 것처럼 보이며 해당 목록에서 이 MessageFactoryImpl 클래스를 볼 수 있습니다.그러나 Oracle SQL(loadjava로 작성하고 로드한 다른 클래스 내부)에서 이 코드 줄을 실행하려고 하면 이 줄에서 ClassNotFoundException(java.lang.ClassNotFoundException:com/sun/xml/messaging/saaj/soap/MessageFactoryImpl).

그런 다음 돌아가서 loadjava 명령줄에 "-resolve" 스위치를 추가하려고 했습니다.이러한 saaj 클래스가 등록되는 것처럼 작동하지만 제대로 해결되지 않습니다.

이러한 saaj 클래스를 Oracle에 성공적으로 가져오려면 어떻게 해야 합니까? 또는 어떤 이유로 Oracle이 이미 이러한 클래스를 로드한 경우 내 코드가 기존 클래스를 성공적으로 사용하도록 어떻게 설득할 수 있습니까?

FWIW, 적절한 소켓 권한이 부여되었고 내 코드가 대상 URL에 대한 일반 http 요청을 성공적으로 만들 수 있는지 확인하는 단계를 이미 수행했습니다.단지 이를 실현하기 위해 라이브러리의 SOAP 스택을 사용하는 데 문제가 있을 뿐입니다.

편집하다:다음은 내 loadjava 결과 샘플입니다.이는 정확히 무엇이 실패하고 있는지 보여주는 것 같지만 이러한 특정 클래스가 해결 전 단계에서 제대로 처리되는 것처럼 보이는데 왜 해결되지 않는지 혼란스럽습니다.여기에서는 파일의 약 80%를 제거했지만 동일한 클래스 해결 문제를 보여주는 다른 클래스도 있습니다.

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
도움이 되었습니까?

해결책

우선, 찾고 있는 클래스가 실제로 해당 jar 파일에 있는지 Oracle 외부에서 확인하십시오.그럴 것으로 예상하지만 확인해 보는 것도 나쁘지 않습니다.

그런 다음 어떤 클래스가 로드되었는지, 유효한 상태인지 확인합니다.

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

클래스가 많은 경우 이를 다소 제한할 수 있습니다. 예:

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

클래스가 없거나 잘못된 패키지 이름으로 존재하는 경우 문제는 loadjava 명령에 있습니다.

클래스가 있지만 상태가 INVALID인 경우 USER_ERRORS를 확인하여 오류가 무엇인지 확인하세요.Oracle 내에서 동적 클래스 로딩을 수행했는지는 기억나지 않지만, 정적 링크를 사용하면 클래스가 실제로 존재했는데 오류가 있었음에도 클래스가 존재하지 않았음을 암시하는 오류가 발생했다는 것을 기억합니다.

loadjava 출력 이후의 새로운 정보가 게시되었습니다.

loadjava 출력이 데이터베이스에서 클래스를 찾으려는 시도와 일치하지 않는 것 같습니다.로드 중이지만 해결되지 않은 경우에도 목록에 표시되지만 INVALID 상태가 됩니다.

JAR을 가져와서 빈 스키마에서 직접 시도해 보았습니다.클래스가 로드되지만 예상대로 유효하지 않습니다.

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

그런 다음 수업에 어떤 오류가 있는지 확인했습니다.

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

(해결 방법이 한 번 이상 시도되었다고 가정하면 이러한 오류는 USER_ERRORS에도 나열됩니다.)

따라서 이 클래스는 기본 SOAP 라이브러리의 클래스를 참조하는 것이 분명합니다.그것도 로드해야 합니다. 그렇게 했나요?

참고로 Class.forName() 호출을 수행하는 코드를 작성할 때 ClassNotFoundException이 발생합니다.클래스 객체가 스키마에 존재하기 때문에 반직관적으로 보일 수 있습니다.그러나 유효하지 않은 클래스는 Oracle의 클래스 로더 관점에서 실제로 "존재"하지 않습니다.클래스가 유효하려면 Oracle은 다른 클래스에 대한 모든 참조를 확인할 수 있어야 합니다.

다른 팁

데이터베이스에서 Java를 처음 실행하시나요?Oracle JVM이 제대로 실행되고 있고 필요한 권한이 있는지 확인하기 위한 hello world 구현은 다음과 같습니다."내 데이터베이스 스키마이므로 내가 원하는 것은 무엇이든 할 수 있습니다"라고 말씀하셨는데, 이는 적절한 권한을 부여받았다는 의미는 아닙니다.

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

Java created. 

이제 래퍼 기능

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

Function created.

이제 테스트해보세요

SQL> select Hello from dual; 

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

이 작업을 수행:

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);
}

어쨌든 숨겨져 있는 예외를 발생시키지 않고 실제로 null을 반환한다는 것을 100% 및 10% 확신하기 위해서입니다.그래도 문제가 지속된다면 알려주시기 바랍니다(위 코드가 작동하지만 null을 반환하는 경우 흥미로운 문제가 발생함).

# 3을 시도해 보세요 :-) (저는 Oracle을 사용하지 않습니다...하지만 이것은 디버깅하기 좋은 문제입니다...)

Oracle의 Class.forName에 대한 정보가 도움이 됩니까?

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

이는 ClassLoader 문제로 나타나므로 솔루션이 "실제 Oracle이 아닌" 세계에서 발생하는 것과 동일한 라인을 따르기를 바랍니다. :-)

편집하다...또 다른 시도...

알았어 좀 더 살펴봐...다음의 결과는 무엇입니까?

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"));

클래스 파일 버전에 문제가 있는지 궁금합니다. 클래스 파일에 Oracle VM에서 실행할 수 없는 버전이 있습니까?

클래스 확인 및 로드는 VM에서 처리하는 복잡한 작업입니다.사양에 설명된 대로 이 두 가지 작업에서 사용되는 알고리즘은 VM 구현자에게 공개되어 있습니다.내 생각에는 귀하의 경우 작업이 클래스 자체의 가용성만 확인하므로 해결 방법이 작동하는 반면 나중에 클래스를 효과적으로 로드하려고 할 때 실패합니다(대부분 종속성 누락으로 인해 발생함).클래스를 로드할 때 VM은 최소한 다른 클래스에 대한 모든 직접 참조를 확인해야 합니다.모든 클래스가 Oracle에서 사용 가능한지 확인해야 하며 ORA-29534에 대한 빠른 Google 검색을 수행하면 수많은 사람들이 이 문제를 겪고 있음을 알 수 있습니다(누군가가 이를 알아냈을 것이라고 확신합니다).

./알렉스

saaj-impl.jar은 웹 서비스 개발자 팩의 SAAJ 구성 요소의 일부입니다.예를 들어 SAAJ와 함께 제공되는 다른 JAR에 대한 종속성이 있습니다. 제가 아는 한 saaj-api.jar 및 activate.jar에 확실히 종속됩니다.물론, saaj-api.jar은 다른 많은 JAR에도 의존하게 됩니다.

JWSDP 1.5에 관한 한 다음에서 정보를 찾을 수 있습니다. JWSDP 1.5 릴리스 노트 유용합니다.JWSDP 1.6에는 SAAJ에 다른 JAR이 있습니다. JWSDP 2.0 릴리스 노트가 이와 관련하여 특히 유용하다고 생각하지 않습니다.그런데 JWSDP 2.0에는 클래스 경로에 배치할 다른 JAR이 있습니다.따라서 문제의 범위는 결국 사용하는 saaj-impl.jar 버전에 따라 달라집니다.

필요할 경우를 대비해 SOAP 클라이언트 JAR을 Oracle 데이터베이스에 로드하고 이를 활용하는 방법에 대한 일부 문서가 다음 페이지에 이미 제공되어 있습니다.나는 이것이 라이브러리와 함께 제공되는 SAAJ JAR과 다를 것으로 추정합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top