Wednesday, February 25, 2009

Getting JAX-WS to work with WebLogic 9.2

I spent several hours at work today troubleshooting problems related to getting JAX-WS (as included with Apache CXF) working in a Java web application running under BEA (Oracle) WebLogic 9.2.  This post contains a summary of the errors I encountered, and their resolutions -- hopefully this will save someone some of the troubleshooting time that I spent today.

Background

Some brief background: I was building some new SOAP web service integrations into one of our internal Java applications, which runs on WebLogic server.  This application was the client side of the integration.  I used Spring, Apache CXF, and JAX-WS to build the integrations.

I first coded the SOAP integrations into a simple stand-alone Java application, and that worked fine.  However, when I plugged my code and the CXF .jar files into the "real" application running on my local WebLogic server, I ran into a couple of errors.

Error #1: "java.lang.NoSuchMethodError: javax.jws.WebMethod.exclude"

Upon running my application under WebLogic 9.2, I got this error in the WebLogic server log file:

org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'internalBeanName': Instantiation of bean failed;
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public java.lang.Object org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create()]
threw exception; nested exception is java.lang.NoSuchMethodError: javax.jws.WebMethod.exclude()Z

This error turned out to be caused by the fact that in addition to the javax.jws.WebMethod class included in the geronimo-ws-metadata_2.0_spec-1.1.2.jar file included in the distribution of CXF that I downloaded, another (apparently older) implementation of that class is also included in the weblogic.jar file included with WebLogic 9.2.  WebLogic by default assigned priority to classes from its own weblogic.jar file over classes included with my application; as a result, WebLogic tried to use the older implementation of the javax.jws.WebMethod class, which does not include the exclude() method, and the NoSuchMethodError occurred when the other JAX-WS code tried to access that method.

To fix this, I modified my weblogic.xml and weblogic-application.xml files, to instruct WebLogic to give priority to the JAX-WS implementation in my own supplied .jar files rather than its own JAX-WS implementation. 

In my weblogic.xml, I added:

<container-descriptor>
  <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>

For more on this weblogic.xml change, see documentation on a similar issue affecting Apache Axis.

In my weblogic-application.xml, I added:

<prefer-application-packages>
    <package-name>org.apache.xerces.*</package-name>
    <package-name>javax.jws.*</package-name>
</prefer-application-packages>

For more on this weblogic-application.xml change, see the WebLogic configuration documentation in the CXF documentation.

Error #2: "Your JAXP provider [...] does not support XML Schema"

Having resolved the NoSuchMethodError, I re-deployed my application, and got this error upon running the app:

org.springframework.beans.factory.BeanDefinitionStoreException: Parser configuration exception parsing XML from class path resource [mySpringContext.xml]; nested exception is javax.xml.parsers.ParserConfigurationException: Unable to validate using XSD: Your JAXP provider [org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@nnnnnnn] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? Upgrade to Apache Xerces (or Java 1.5) for full XSD support.

The problem here was that there was an an old (2003) xerces.jar file present in my Java project, which contained an old JAXP provider class which did not support XSD. 

To fix this, I deleted the old xerces.jar file, and redeployed the project.  (I also needed to delete WebLogic's cache, located on my machine at \bea\user_projects\domains\mydomain\servers\myserver\tmp, to completely get rid of the old cached xerces.jar file.)

6 comments:

  1. Jon, have you played with Axis (http://ws.apache.org/axis/) at all? That is what we're primarily using for our Java web services (at least so far!)

    ReplyDelete
  2. Hi Chris! I have not played with Axis personally; it was one of my co-workers that went through the obligatory "we decided we want to do x; now let's do an evaluation to figure out which library/framework that implements x we want to use" process (where x is SOAP in this case)!

    ReplyDelete
  3. Jon, the same day you wrote your article I found myself in the same situation as you did. Luckily CXF has the documentation on it's main page and I could resolve it without many problems.
    Small world hug??...
    Regarding Axis, i've used Axis - Xfire and CXF (Xfire evolution) and I can say by experience that CXF way more fast than Axis regarding databinding (JAXB) as well as simplicity due to generated code and spring integration.

    ReplyDelete
  4. Alternatively, make a copy of geronimo-ws-metadata in the server lib directory and add it to the CLASSPATH (e.g. PRE_CLASSPATH) so that geronimo will be loaded before weblogic.jar.

    I had to do this is because forcing weblogic to use applicaiton libraries somehow messes up loading one of my other libraries.

    ReplyDelete
  5. Thanks from Chile !!!

    ReplyDelete
  6. can I use weblogic-application.xml without EAR deployment?

    ReplyDelete

Hi spammers! No need to waste your time here; comments are heavily moderated, so if you like, you can save us both a little time and just move on to the next site. :-)

For everyone else: Thanks for visiting! Your comments are more than welcome!