`
zhang_zling
  • 浏览: 96415 次
  • 性别: Icon_minigender_2
  • 来自: 济南
社区版块
存档分类
最新评论

SAAJ Problem

阅读更多
SAAJ Problem
Leave a Comment Posted by azagozdzinski on February 15, 2011

Last days I was struggling trying to find out the reason for error we were receiving occasionaly. The problem was that we couldn’t find the conditions under the error was happening, except that the error was thrown by our WEB_APP. First main suspect was corrupted JDK, but when the same happened on the other server that idea died (how many corrupted JDK can you have? ;) ). So I started digging …

The error message was:

1.  java.lang.NoClassDefFoundError: Could not initialize class com.sun.xml.internal.ws.api.BindingID

That class is included in rt.jar – that ’s why the first suspect was JDK.

Lucky for me we had historical logs so I could trace last error occurences. The finding was that the error above is sometimes preceded with another one:

2.  java.lang.IllegalArgumentException: com.sun.xml.messaging.saaj.soap.LocalStrings != com.sun.xml.internal.messaging.saaj.soap.LocalStrings

It was not always a rule, but it looked like there was at least one occurence of error [2] followed by many errors [1]. So I decided to investigate the second one.

That error is thrown by java.util.logging.Logger.getLogger(String paramString1, String paramString2) method where paramString2 is resource bundle name.

Implementation:

/*      */   public static synchronized Logger getLogger(String paramString1, String paramString2)
/*      */   {
/*  308 */     LogManager localLogManager = LogManager.getLogManager();
/*  309 */     Logger localLogger = localLogManager.demandLogger(paramString1);
/*  310 */     if (localLogger.resourceBundleName == null)
/*      */     {
/*  312 */       localLogger.setupResourceInfo(paramString2);
/*  313 */     } else if (!(localLogger.resourceBundleName.equals(paramString2))) {
/*  314 */       throw new IllegalArgumentException(localLogger.resourceBundleName + " != " + paramString2);
/*      */     }
/*      */
/*  317 */     return localLogger;
/*      */   }

In our case that means that there is an attempt to create new logger with resource bundle ‘com.sun.xml.internal.messaging.saaj.soap.LocalStrings’, while there is already another one created for the same class, but with resource bundle ‘com.sun.xml.messaging.saaj.soap.LocalStrings’.

I digged into libraries and found that the logger is being created by implementation class SAAJMetaFactoryImpl.

That class can be found in (at least) two places:

   1. rt.jar:               com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl

protected static final Logger log = Logger.getLogger("javax.xml.messaging.saaj.soap", com.sun.xml.internal.messaging.saaj.soap.LocalStrings");

   1. saaj-impl-X.X.jar:    com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl

protected static final Logger log = Logger.getLogger("javax.xml.messaging.saaj.soap", "com.sun.xml.messaging.saaj.soap.LocalStrings");

First one is a part of JDK installation while second one is part of one of our applications EAR (saaj-impl-1.3.2.jar). For this description sake, let’s call it OUR_SERVICE_APP.

I had another, closer look on stack traces and the puzzles started to fit.

First error stack looks as follows:

Caused by: java.lang.ExceptionInInitializerError
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at javax.xml.soap.FactoryFinder.newInstance(FactoryFinder.java:59)
at javax.xml.soap.FactoryFinder.find(FactoryFinder.java:186)
at javax.xml.soap.SAAJMetaFactory.getInstance(SAAJMetaFactory.java:79)
at javax.xml.soap.MessageFactory.newInstance(MessageFactory.java:148)
at com.sun.xml.internal.ws.api.SOAPVersion.<init>(SOAPVersion.java:167)
at com.sun.xml.internal.ws.api.SOAPVersion.<clinit>(SOAPVersion.java:72)
at com.sun.xml.internal.ws.api.BindingID.<clinit>(BindingID.java:324)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parseBinding(RuntimeWSDLParser.java:413)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parseWSDL(RuntimeWSDLParser.java:310)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:135)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:254)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:217)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:165)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:93)
at javax.xml.ws.Service.<init>(Service.java:56)
at our.web_app.webserviceclient.ClientService.<init>(ClientService.java:xx)
... 13 more
Caused by: java.lang.IllegalArgumentException: com.sun.xml.messaging.saaj.soap.LocalStrings != com.sun.xml.internal.messaging.saaj.soap.LocalStrings
at java.util.logging.Logger.getLogger(Logger.java:314)
at com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl.<clinit>(SAAJMetaFactoryImpl.java:41)
... 51 more

That means that our WEB_APP invocation for ClientService encounters problem while trying to init class SAAJMetaFactoryImpl  because there is the same logger with different resource bundle in memory already. Logger created by SAAJMetaFactoryImpl class as ‘side effect’ of OUR_SERVICE_APP is static and final, so it considered as constant object kept in memory since SAAJMetaFactoryImpl class has been initiated by OUR_SERVICE_APP.

Anyway, the stack trace above shows that the RuntimeWSDLParser.parseBinding method tries to init class BindingID which in turn initiates number of other classes. Finally it tries to obtain implementation for SAAJMetaFactory interface and finds com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl that in turn throws an exception while getting static Logger object reference.

That means that it fails on initialization of BindingID class.

RuntimeWSDLParser.parseBinding(RuntimeWSDLParser.java:413) source code:

Line 413:                   binding.setBindingId(BindingID.SOAP11_HTTP);

Where BindingID.SOAP11_HTTP is constant that represents SOAP1.1/HTTP.

And here we are with the second error:

java.lang.NoClassDefFoundError: Could not initialize class com.sun.xml.internal.ws.api.BindingID
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parseBinding(RuntimeWSDLParser.java:413)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parseWSDL(RuntimeWSDLParser.java:310)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:135)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:254)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:217)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:165)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:93)
at javax.xml.ws.Service.<init>(Service.java:56)
at our.web_app.webserviceclient.ClientService.<init>(ClientService.java:xx)
{…}

Initialization of BindingID class failed at first error so this class definition has been unloaded from memory. Result: JVM (or class loader) throwing NoClassDefFoundError.

The open question is why it is working sometimes without such collision. What we know is that problem takes place when OUR_SERVICE_APP has been invoked before our WEB_APP. My hints here are:

-          It can be specific feature implemented in OUR_SERVICE_APP service that calls com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl implementation and loads static Logger object in memory. That feature can be rarely used, so there are shorter or longer periods of time where WEB_APP could be used without problems.

-          Even if the Logger has been loaded – Garbage Collector removes it after some time from memory. WEB_APP can be invoked again…

-          If WEB_APP has been invoked as first – classes from rt.jar are loaded into ‘clean’ memory without problems. OUR_SERVICE_APP uses then classes that JVM / class loader has loaded already, so implementation from saaj-impl-1.3.2.jar included in service’s EAR is not used. Both applications are working fine.

-          If OUR_SERVICE_APP has been invoked first – it loads classes from saaj-impl-1.3.2.jar library and if Garbage Collector didn’t unload them, WEB_APP invocation leads to an error.

Anyway – the solution is to get rid of saaj-impl-1.3.2.jar and saaj-api-1.3.jar libraries from OUR_SERVICE_APP and ‘force’ it to use rt.jar / JDK implementations instead.
Troubleshooting BindingID, com.sun.xml.internal.messaging.saaj.soap.LocalStrings, com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl, com.sun.xml.internal.ws.api.BindingID, com.sun.xml.messaging.saaj.soap.LocalStrings, com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl, java.lang.IllegalArgumentException: com.sun.xml.messaging.saaj.soap.LocalStrings != com.sun.xml.internal.messaging.saaj.soap.LocalStrings, java.lang.NoClassDefFoundError: Could not initialize class com.sun.xml.internal.ws.api.BindingID, javax.xml.messaging.saaj.soap, saaj-api-1.3.jar, saaj-impl-1.3.2.jar
分享到:
评论

相关推荐

    saaj.jar saaj.jar

    saaj.jar saaj.jar saaj.jar saaj.jar

    saaj.jar SAAJ包

    saaj.jar SAAJ包,Java项目常用Jar

    saaj访问web服务

    ### 使用SAAJ访问Web服务及文件上传的知识点 #### 一、SAAJ概述 SAAJ (SOAP with Attachments API for Java) 是一个重要的Java API,主要用于处理SOAP消息,特别是那些带有附件的消息。它是由JCP (Java Community ...

    saaj.jar,saaj.jar

    saaj.jar,saaj.jar,saaj.jar,saaj.jar,saaj.jar

    用SAAJ解决SOA集成问题

    【SAAJ(SOAP with Attachments API for Java)】是Java平台上的一个API规范,用于在松散耦合的软件系统中处理基于SOAP协议的XML消息传递,特别适合支持带有附件的SOAP消息。SAAJ提供了创建、发送、接收和处理SOAP...

    saaj.jar包

    **saaj.jar包详解** 在Java开发中,`saaj.jar`是一个至关重要的库,它全称为SOAP with Attachments API for Java,是Java平台上的一个标准API,用于处理SOAP(Simple Object Access Protocol)消息和相关的附件。...

    saaj-api-1.3.jar

    saaj-api-1.3.jar saaj-api-1.3.jar

    使用SAAJ 和JAXM的 SOAP客户端及服务

    SAAJ(SOAP with Attachments API for Java)和JAXM(Java API for XML Messaging)是Java平台上的两个重要工具,它们分别用于处理SOAP消息和XML消息的发送与接收。本文将深入探讨如何利用SAAJ和JAXM来构建SOAP...

    SAAJ-API包jar

    SAAJ-API包jarSAAJ-API包jarSAAJ-API包jarSAAJ-API包jar

    JAVA6开发WebService (四)——SAAJ调用WebService

    在本篇主题“JAVA6开发WebService(四)——SAAJ调用WebService”中,我们将探讨如何使用Java API for XML Messaging (SAAJ)来与WebService进行交互。SAAJ是Java平台中用于处理SOAP消息的API,它提供了创建、解析和...

    saaj-api.jar.zip_saaj-api_saaj-api-1.3.jar_saaj-api.jar

    标题"saaj-api.jar.zip_saaj-api_saaj-api-1.3.jar_saaj-api.jar" 提到了几个关键元素:'saaj-api.jar.zip' 是压缩文件的名称,暗示了里面包含的文件与SAJJ(SOAP消息抽象API)有关。'saaj-api' 是一个重复出现的...

    saaj-impl-1.3.jar

    saaj-impl-1.3.jar saaj-impl-1.3.jar

    saaj-api.jar

    还在为找不到jar文件烦心吗,不用了到我空间来有你想要的,持续更新。。。 saaj-api.jar

    axis的saaj.jar

    Axis本质上就是一个SOAP引擎,提供创建服务器端、客户端和网关SOAP操作的基本框架。Axis目前版本是为Java编写的,不过为C++的版本正在开发中。但Axis并不完全是一个SOAP引擎,它还是一个独立的SOAP服务器和一个嵌入...

    axis.jar,axis-saaj-1.4.jar

    标题中的"axis.jar"和"axis-saaj-1.4.jar"是两个重要的Java库文件,它们在Web服务开发中扮演着核心角色。本文将详细介绍这两个库以及它们与Web服务的关系。 首先,让我们深入了解Axis。Axis是Apache软件基金会的一...

    saaj-soap(需要的jar)

    saaj-soap(需要的jar)

    saaj-impl.jar.zi

    【标题】"saaj-impl.jar.zi" 是一个压缩文件,它包含了 "saaj-impl.jar" 这个Java档案。"SAAJ" 是"SOAP(Simple Object Access Protocol)API for Java"的缩写,它是Java平台上的一个标准接口,用于处理SOAP消息。这...

    axis-saaj-1.3.jar

    官方版本,亲测可用

Global site tag (gtag.js) - Google Analytics