WSDL to web service code in Weblogic 10
lukas
Weblogic 10 web services runtime uses JAX-WS and JAXB for web service generation. Following the preferred contract-first (or wsdl-first) design approach one can use the wsdlc Ant task to generate all web services artifacts (Impl file, proxy classes and java bean types and their xml serializers & deserializers) from a WSDL file and associated xsd schemas.
(Note: Before starting, make sure Weblogic 10 is correctly installed. Also, the web service generation relies on annotations so Java 5 must also be installed. Note that you need the JDK - not just the JRE - as the WSDL generation required tools.jar which comes with the JDK only)
WSDLC takes a WSDL file as parameter and uses custom JAXB binding files to configure the generation of Java files. Although this process is much more complicated than the simple package to namespace mapping file (NStoPkg.properties) used by Apache Axis it is also much more configurable. For example the JAXB binding files allow you to also specify things such as the name of the generated Impl file, names of operations, parameters as well as configure SOAP handlers. It’s basically a one-stop-shop for the configuration of the web service.
I use the JAXB binding files mainly to generate the the correct package structure of the various Java artifacts.
My WSDL and accompanying schema structure is something like this:
/JobMaintenanceService.wsdl > defines services /jobmaintenance/JobMaintenanceService.xsd > defines main types used in the service /enterprise_schemas/assignment/*.xsd > defines types from the assignment functional area /enterprise_schemas/common/*.xsd > defines various common types reused by all other schemas etc..
It is important to note that JobMaintenanceService imports JobMaintenanceService.xsd which in turn imports other schemas which in turn may import or include other schemas as required. See my previous post on the difference between import vs. include.
The package structure I wanted from the above schemas was as follows:
com.mycompany.myapp.ws.client > to hold service client classes - proxy, etc. com.mycompany.myapp.ws.service > to hold JobMaintenanceService impl class com.mycompany.myapp.ws.dto > to hold JobMaintenanceService schema files com.mycompany.myapp.ws.types.assignment > to hold types from the assignment schemas com.mycompany.myapp.ws.types.common > to hold types from common enterprise schemas etc..
The following is the Ant target to generate the webservice code. The wsdlc ant task comes with Weblogic 10 (weblogic.wsee.tools.anttasks.WsdlcTask) and is actually a wrapper around Sun’s wsimport task so don’t be surprised if you get warnings or errors referring to wsimport.
build.xml:
<property name="bea.home" value="C:/apps/bea10" /> <property name="jdk.home" value="${bea.home}/jdk150_06" /> <property name="weblogic.home" value="${bea.home}/wlserver_10.0" /> <property name="src.dir" value="src"/> <property name="wsdl.file.name" value="JobMaintenanceService"/> <target name="run-wsdlc"> <path id="compile.classpath"> <fileset dir="${jdk.home}"> <include name="lib/tools.jar" /> </fileset> <fileset dir="${weblogic.home}"> <include name="server/lib/weblogic.jar"/> </fileset> </path> <taskdef name="wsdlc" classname="weblogic.wsee.tools.anttasks.WsdlcTask" classpathref="compile.classpath" /> <mkdir dir="${src.dir}"/> <property name="binding.declaration.file" value="schema-jobmaintenance.xjb,wsdl-jobmaintenance.xjb"/> <wsdlc type="JAXWS" srcWsdl="etc/job_maint/${wsdl.file.name}.wsdl" destJwsDir="${src.dir}/jws" destImplDir="${src.dir}/impl" explode="true" failonerror="true" > <binding dir="etc" includes="${binding.declaration.file}"/> <classpath> <path refid="compile.classpath"/> </classpath> </wsdlc> </target>
The above will generate all required java files into the correct package structure. Here is an excerpt from the schemas binding file showing the mappings of the common and assignment namespaces.
schema-jobmaintenance.xjb:
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" > <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" schemaLocation="job_maint/enterprise_schemas/common/Common.xsd" node="/xs:schema" > <jxb:schemaBindings> <jxb:package name="com.mycompany.myapp.ws.types.common"/> </jxb:schemaBindings> </jxb:bindings> <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" schemaLocation="job_maint/enterprise_schemas/assignment/Assignment.xsd" node="/xs:schema" > <jxb:schemaBindings> <jxb:package name="com.mycompany.myapp.ws.types.assignment"/> </jxb:schemaBindings> </jxb:bindings> .... </jxb:bindings>
Some notes:
- The wsdlc Ant task configures namespace to package mappings using custom JAXB binding files - schema-jobmaintenance.xjb and wsdl-jobmaintenance.xjb - one to map schema types and the other to map definitions from the wsdl.
- Do NOT use the wsdlc option “packageName” in the Ant wsdlc task - this will override any custom bindings made in the jaxb config files.
- Make sure you do NOT have Apache Axis and related jars in your classpath - they interfere with the weblogic ones from above and results in the binding files not being read!
- I don’t think you can mix bindings for jaxws (for wsdl) and jaxb (for schema) in the same binding file - I spent quite a bit of time on it but could not get all my bindings to be read from a single binding file - if you know whether this is possible and how this is done please let me know!
- I could not get nested bindings to work correctly for schemas (e.g. you’re supposed to be able to nest bindings for your imported schemas within bindings for the encompassing schema as in one of the example articles further below but that didn’t work for me - it seemed like the xpath expression with the namespace does not get evaluated correctly). I therefore created separate binding entries for each XSD of a particular namespace.
- The only item I could NOT generate in it’s correct location was the JWS file (service Impl skeleton file). I tried many things but it just would not pick up the package from the binding file. I also stumbled on a WL10 support case that had this logged as an issue so maybe it is a true bug in this release of WL. Fortunately this is not too big of a deal as it is only a single file - and the one you have to manually edit anyway - to complete the web service implementation.
- I recommend using an “copy” Ant task to only copy the *.java files into your src project structure as “wsdlc” automatically compiles the java src in the target directory:
<copy todir="dest/dir"> <fileset dir="${src.dir}"> <exclude name="**/*.class"/> </fileset> </copy>
Finally here is a list of links I recommend to get more information on some of the above:
Wsdlc ant task reference on BEA’s Edocs website
Iterative Development of Weblogic 10 webservices from BEA
The following 2 awesome articles from dev2dev:
Using JAX-WS & JAXB with Weblogic 10
JAX-WS customization binding
Best of luck! If you have any questions or comments please feel free to post below.
Posted in xml, programming |
No Comments »
While we are living & working overseas (currently in Canada) we are renting out our home back in New Zealand so as to at least cover the interest on our mortgage.