Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override JAX-WS version used by Weblogic 10 - Dynamic WSDL with inline schemas

Has anyone successfully updated the JAX-WS version used by Weblogic 10.3.3?

I've been trying to do what's described in the accepted answer from here for hours with no luck.

I'm using Maven to resolve my dependencies and I've tried with combinations of the following libraries in my WAR module (Web service project):

    <dependency>
        <groupId>javax.xml.ws</groupId>
        <artifactId>jaxws-api</artifactId>
        <version>2.2.8</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>2.2.7</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.jws</artifactId>
        <version>3.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.metro</groupId>
        <artifactId>wsit-api</artifactId>
        <version>2.2.1-1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.metro</groupId>
        <artifactId>wsit-impl</artifactId>
        <version>2.2.1-1</version>
    </dependency>

That is basically to ship a newer version of JAX-WS with my application.

In my EAR module I've played with the weblogic-application.xml file overriding different packages:

    <package-name>javax.jws.*</package-name>
    <package-name>javax.xml.ws.*</package-name>
    <package-name>javax.xml.bind.*</package-name>
    <package-name>javax.xml.soap.*</package-name>
    <package-name>com.sun.xml.*</package-name>

That is to indicate Weblogic to use my classes instead of the classes it has in itself.

Currently my Weblogic 10.3.3 is using JAX-WS 2.1.5 and when I deploy a web service it dynamically generates a wsdl file, the generated wsdl is importing xsds (schemas) and I would like to tell Weblogic to generate the wsdl with inline schemas, that's why I'm trying to override the used JAX-WS version hoping a more recent version uses inline schemas.

Another option would be to generate the wsdl with inline schemas during development and somehow tell Weblogic to use that one instead of generating a dynamic version, do anyone know how to do that? is it putting it in a specific path on the WAR? what about the wsdlLocation attribute on the @WebService annotation?

Thanks in advance!

like image 351
Adolfo Avatar asked Oct 03 '12 20:10

Adolfo


2 Answers

I was able to get JaxWs 2.2.6 running in Weblogic 10.3.5 I know your are working on 10.3.3 but this solution should also work.

I followed the steps from this METRO discussion: http://www.java.net/node/695058#comment-772902

Not all steps from there are really required. So here is the description what I have done.

Steps for war file

1) Package your webservice as war file

2) in the war file you need a sun-jaxws.xml file under WEB-INF directory (for detailed information look here: http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/2.0/jaxws/jaxws-war.html)

3) place the wsdl and xsd file under WEB-INF/wsdl

4) register WSServlet and WSServletContextListener in your web.xml
(for some help look here http://java.dzone.com/articles/jax-ws-deployment-five-minute)

<listener>
  <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
  <servlet-name>MyWebService</servlet-name>
  <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
  <load-on-startup>1</load-on-startup> 
</servlet>

<servlet-mapping>
  <servlet-name>MyWebService</servlet-name>
  <url-pattern>/MyWebService</url-pattern>
</servlet-mapping>

5) Place at least one service file under WEB-INF/classes/META-INF/services

i used javax.xml.ws.spi.Provider
and as content in the file (impl class of the provider): com.sun.xml.ws.spi.ProviderImpl
you can get this file from jaxws-rt.jar
place also other service files here (for example for different XeceresParserFactory)

reason: Weblogic generates at runtime a file called: _wl_cls_gen.jar . And here it looks for service files in the first place. When weblogic founds a service file there all other files are loaded from from jar files as espected. at least it behaves like this

6) Create a weblogic.xml set <prefer-web-inf-classes>false</prefer-web-inf-classes> to false

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd      http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd">
  <context-root>/LogisticsWebservice</context-root>
  <container-descriptor>
    <prefer-web-inf-classes>false</prefer-web-inf-classes>        
  </container-descriptor>
</weblogic-web-app>

Structure of war file:

WEB-INF
|-> classes
    |-> META-INF
        |-> services
            |-> javax.xml.ws.spi.Provider
|-> lib
    |-> alle projektspezifischen jars außer die Abhängigkeiten für JaxWS
|-> wsdl
    |-> MyWebService.wsdl
    |-> MyObjects.xsd
|-> sun-jaxws.xml
|-> web.xml
|-> weblogic.xml

Steps for ear file

1) Pack your war file in an ear file

2) Place a JaxWs Service Finder class under APP-INF/classes you can use the existing class files from JaxWs-rt.jar

3) Place jaxws-rt, all dependencies and xerces-2.9.1 and xalan-2.7.1 under APP-INF/lib

4) Create an application.xml file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" "http://java.sun.com/dtd/application_1_3.dtd">
<application>
  <display-name>MyWebService</display-name>
  <module id="MyWebService">
    <web>
      <web-uri>MyWebService.war</web-uri>
      <context-root>/MyWebService</context-root>
    </web>
  </module>
</application>

5) Create an weblogic-application.xml file

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://xmlns.oracle.com/weblogic/weblogic-application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-application http://xmlns.oracle.com/weblogic/weblogic-application/1.2/weblogic-application.xsd">

  <application-param>
    <param-name>webapp.encoding.default</param-name>
    <param-value>UTF-8</param-value>  
  </application-param>

  <prefer-application-packages>
    <package-name>com.ctc.*</package-name>
    <package-name>com.sun.xml.*</package-name>
    <package-name>com.sun.istack.*</package-name>
    <package-name>com.sun.msv.datatype.*</package-name>
    <package-name>com.sun.msv.driver.*</package-name>
    <package-name>com.sun.msv.grammar.*</package-name>
    <package-name>com.sun.msv.reader.*</package-name>
    <package-name>com.sun.msv.relaxns.*</package-name>
    <package-name>com.sun.msv.scanner.*</package-name>
    <package-name>com.sun.msv.util.*</package-name>
    <package-name>com.sun.msv.verifier.*</package-name>
    <package-name>com.sun.msv.writer.*</package-name>
    <package-name>com.sun.org.apache.xml.internal.*</package-name>
    <package-name>com.sun.wsit.*</package-name>
    <package-name>javax.jws.*</package-name>
    <package-name>javax.xml.bind.*</package-name>
    <package-name>javax.xml.soap.*</package-name>
    <package-name>javax.xml.stream.*</package-name>
    <package-name>javax.xml.ws.*</package-name>
    <package-name>javax.xml.activation.*</package-name>
    <package-name>javax.xml.annotation.*</package-name>
    <package-name>javax.xml.mail.*</package-name>
    <package-name>javax.xml.security.*</package-name>
    <package-name>javax.xml.registry.*</package-name>
    <package-name>javax.xml.rpc.*</package-name>
    <package-name>javax.xml.crypto.*</package-name>
    <package-name>org.apache.xerces.*</package-name>
    <package-name>javanet.staxutils.*</package-name>
    <package-name>jp.gr.xml.*</package-name>
    <package-name>org.codehaus.stax2.*</package-name>
    <package-name>org.glassfish.gmbal.*</package-name>
    <package-name>org.iso_relax.*</package-name>
    <package-name>org.jcp.xml.dsig.*</package-name>
    <package-name>org.jvnet.*</package-name>
    <package-name>org.relaxng.*</package-name>

  </prefer-application-packages>

  <prefer-application-resources>
    <resource-name>META-INF/services/*</resource-name>
  </prefer-application-resources>
</weblogic-application>    

Attention: jars which are in ear file under APP-INF/lib should not be in war file under WEB-INF/lib

Structure of ear file:

|-> APP-INF
    |-> classes
        |-> com
            |-> sun
                |-> xml
                    |-> ws
                        |-> util
                            |-> ServiceFinder.class
                            |-> ServiceFinder$1.class
                            |-> ServiceFinder$ComponentExWrapper.class
                            |-> ServiceFinder$CompositeIterator.class
                            |-> ServiceFinder$LazyIterator.class
    |-> lib
        |-> activation-1.1.jar
        |-> gmbal-api-only-3.1.0-b001.jar
        |-> ha-api-3.1.8.jar
        |-> istack-commons-runtime-2.4.jar
        |-> javax.annotation-3.1.1.jar
        |-> jaxb-api-2.2.4.jar
        |-> jaxb-impl-2.2.5.jar
        |-> jaxws-api-2.2.8.jar
        |-> jaxws-rt-2.2.6.jar
        |-> jsr181-api-1.0-MR1.jar
        |-> management-api-3.0.0-b012.jar
        |-> mimepull-1.8.jar
        |-> policy-2.3.1.jar
        |-> relaxngDatatype-20020414.jar
        |-> resolver-20050927.jar
        |-> saaj-api-1.3.4.jar
        |-> saaj-impl-1.3.18.jar
        |-> serializer-2.7.1.jar
        |-> stax-api-1.0-2.jar
        |-> stax-ex-1.7.jar
        |-> stax2-api-3.1.1.jar
        |-> streambuffer-1.4.jar
        |-> txw2-20110809.jar
        |-> woodstox-core-asl-4.1.2.jar
        |-> xalan-2.7.1.jar
        |-> xercesImpl-2.9.1.jar
        |-> xml-apis-1.3.04.jar
|-> META-INF
    |-> application.xml
    |-> weblogic-application.xml
|-> MyWebService.war

Now deploy your ear file to weblogic.

when you open your wsdl file http://localhost:7001/MyWebService/MyWebService?wsdl you should see this comment:

<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.6b21  svn-revision#12959. -->

hope this how-to is/was somehow usefull.

for some debug informations I added this to my ServiceImpl class:

private static String getImplementationInfo(String componentName, @SuppressWarnings("rawtypes") Class componentClass)
{
  CodeSource source = componentClass.getProtectionDomain().getCodeSource();
  return MessageFormat.format(
      "{0} implementation: {1} loaded from: {2}",
      componentName,
      componentClass.getName(),
      source == null ? "Java Runtime" : source.getLocation());
}


public MyWebServiceResponse sayHello(MyWebServiceRequest request) throws MyWebServiceFault
  if (LOG.isDebugEnabled())
  {
    com.sun.xml.ws.util.Version jaxwsVersion = com.sun.xml.ws.util.Version.RUNTIME_VERSION;
    LOG.debug("JaxWS major=" + jaxwsVersion.MAJOR_VERSION + "; buildVersion=" + jaxwsVersion.BUILD_VERSION + "; buildId="
        + jaxwsVersion.BUILD_ID + "; svnRev" + jaxwsVersion.SVN_REVISION);
    LOG.debug(getImplementationInfo("JaxWS", com.sun.xml.ws.util.Version.class));
    LOG.debug(getImplementationInfo("JaxB", com.sun.xml.bind.Util.class));
    LOG.debug(getImplementationInfo("DocumentBuilderFactory", DocumentBuilderFactory.newInstance().getClass()));
    LOG.debug(getImplementationInfo("XPathFactory", XPathFactory.newInstance().getClass()));
    LOG.debug(getImplementationInfo("TransformerFactory", TransformerFactory.newInstance().getClass()));
    LOG.debug(getImplementationInfo("SAXParserFactory", SAXParserFactory.newInstance().getClass()));
  }

  // do something

  return myWebServiceResponse;
}

regards Alex

PS: As a new user i#m only allowed to post 2 hyperlinks, please excuse this...

like image 116
Alex Avatar answered Nov 06 '22 00:11

Alex


I used this solution and was able to get this working... But the problem is that I need to send proper client certificate so I created a custom SSLSocketFactory that I assigned to the binding: bp.getRequestContext().put(JAXWSProperties.SSL_SOCKET_FACTORY, fact.getSSLSocketFactory());

Problem is that weblogic doesn't use it. It uses its own HTTPsConnection with standard factory. I tried to implement a weblogic SSLSocketFactory but the put into the binding complains rightfully that it is not the sun class.

After a lot of time wasted I created a template of the call (by running my code as standalone), then I use XML to replace/update nodes (+ action in http header). It works nicely and I got rid of all those changes that where required. I know it is a bit radical, but honestly to implement a call it works very well.

like image 37
user2678835 Avatar answered Nov 06 '22 00:11

user2678835