我正在尝试在Oracle内使用第三方Java库。该库似乎与Oracle 10G服务器主机的JVM相同的1.4版本兼容,因为它在Oracle之外运行良好,因此我觉得我应该能够使其工作。该库最终会提出基于肥皂的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类。 But then I try to run this line of code from Oracle SQL (inside another class I wrote and loaded with loadjava), this line throws a ClassNotFoundException (java.lang.ClassNotFoundException: com/sun/xml/messaging/saaj/soap/MessageFactoryImpl )。

然后,我回去尝试在LoadJava命令行中添加“ - 溶解”开关。它的作用就像这些SAAJ课程正在注册,但它们无法正确解决。

我如何成功将这些SAAJ类进入Oracle,或者如果由于某种原因Oracle已经加载了这些类别,我该如何说服自己的代码成功使用现有类?

FWIW,我已经采取了步骤来确保授予适当的套接字权限,并且我的代码可以成功地向目标URL提出通用的HTTP请求。它只是使用图书馆的肥皂堆栈来实现它遇到麻烦。

编辑:这是我的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
有帮助吗?

解决方案

首先,验证您要寻找的类的Oracle外面实际上是在该JAR文件中。我希望是,但是检查没有什么坏处。

然后,我将检查已加载哪些类以及它们是否具有有效状态。

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命令。

如果该类在那里,但其状态无效,请检查user_errors以查看错误。我不记得我是否在Oracle内完成了动态类加载,但是我记得静态链接会产生错误的错误,暗示该类是在真正存在但存在错误时不存在的。

LoadJava输出发布后的新信息

LoadJava输出似乎与您尝试在数据库中找到类的尝试不一致。如果已加载但未解决,则仍应列出它,但状态无效。

我得到了罐子,用空的模式自己尝试。该类负载,但无效,如预期的那样:

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中列出。)

因此,很明显,该类参考基础肥皂库中的类。您也必须加载 - 您做到了吗?

仅供参考,当我编写一些代码进行class.forname()调用时,我确实会获得classNotFoundException。由于架构中确实存在类对象,因此似乎是违反直觉的。但是,从Oracle中的类加载程序的角度来看,无效的类并不是真正的“存在”。为了使课程成为有效的甲骨文,必须能够解决其对其他类的所有参考。

其他提示

这是您第一次在数据库上执行Java吗?这是Hello World实施,以确保您的Oracle JVM运行正常,并且您拥有必要的权限。您说:“我的数据库模式,所以我可以做任何我想做的事 - 并不意味着您拥有适当的赠款。

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

只是要使100AND10%确定它不会抛出以某种方式隐藏的例外,并且确实返回了空。如果仍然是这种情况,请告诉我(如果上述代码有效,但返回null)。

尝试#3 :-)(我不使用Oracle ...但这是一个整洁的问题...)

class.forname Oracle中的信息是否有帮助?

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

这是一个班级加载程序问题,因此,解决方案与“真实的,非轨道”世界中发生的事情相同。

编辑...另一个尝试...

好的,再看一些...以下输出是什么:

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需要VM。至少解决所有直接引用其他类)。您必须确保Oracle所有类都可以使用,并对ORA-29534的Google进行快速搜索,显示了大量有这个问题的人(我很确定有人知道了)。

./alex

Saaj-impl.jar是Web Services开发人员包的SAAJ组件的一部分。据我所知,它对与Saaj一起发货的其他罐子具有依赖性,这绝对取决于saaj-api.jar和activation.jar。当然,Saaj-api.jar一定会依靠许多其他罐子。

就JWSDP 1.5而言,您可以在 JWSDP 1.5发行说明 有用。 JWSDP 1.6在Saaj I中有不同的罐子,发现JWSDP 2.0发行说明在这方面特别有用。顺便说一句,JWSDP 2.0将有不同的罐子要放置在类路径中;因此,问题的范围最终取决于您使用的saaj-impl.jar版本。

以防万一您可能需要它,在以下页面中,已经有一些文档可用于将肥皂客户罐加载到Oracle数据库中并利用它们。我认为这些与您的图书馆随附的SAAJ罐有所不同。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top