Tuesday, July 29, 2008

Paper Accepted for UKOUG'08: "How the Oracle JDeveloper team test JDeveloper"

My learned workmate Geoff Waymark, also know as Geoff the tester, will be joining me for this presentation. We are going to cover our usage of Abbot for Swing testing and Selenium to automate testing of web applications. Expect demos, failed demos*, and fireworks!

See how you can use both tools to test your own applictions, for free.

I am also told I am to have a guest role in a presentation to be given by Susan Duncan; but more on that later!.

* Anybody who has done any automation testing will know that a test watched by a crowd never, ever, runs.

Working round xsd:choice binding issue with JAX-B 2.x

While JAX-B is pretty good most of the time it will fall over when trying to bind an xml schema that contains certain types of choice element. For example take the following snippet take from the XACML 2.0 standard schema:

<xs:element name="Policy" type="xacml:PolicyType" />
  <xs:complexType name="PolicyType">
  <xs:sequence>
    <xs:element ref="xacml:Description" minOccurs="0" />
    <xs:element ref="xacml:PolicyDefaults" minOccurs="0" />
    <xs:element ref="xacml:CombinerParameters" minOccurs="0" />
    <xs:element ref="xacml:Target" />
    <xs:choice maxOccurs="unbounded">
      <xs:element ref="xacml:CombinerParameters" minOccurs="0" />
      <xs:element ref="xacml:RuleCombinerParameters" minOccurs="0" />
      <xs:element ref="xacml:VariableDefinition" />
      <xs:element ref="xacml:Rule" />
    </xs:choice>
    <xs:element ref="xacml:Obligations" minOccurs="0" />
  </xs:sequence>
  <xs:attribute name="PolicyId" type="xs:anyURI" use="required" />
  <xs:attribute name="Version" type="xacml:VersionType" default="1.0" />
  <xs:attribute name="RuleCombiningAlgId" type="xs:anyURI" use="required" />
  </xs:complexType>
</xs:element>

If you try to run either the xjc or any of the web service import tools on this then then build will fail with the following message: 'Element "CombinerParameters" shows up in more than one properties.'. You will notice that in some cases of the choice the "CombinerParameters" property is duplicated.

Now one workaround is to refactor the schema to do this using sequences rather than choices; but of course you might not have control over the web service you are trying to use. Fortunately some-one at sun figure this out and there is a customization directive that will cause something sensible to be generated. This is called <xjc:simple> and while it is offically a vendor extension nearly everybody uses the sun implementation so there is not that much to worry about.

The examples linked above all uses embedded customizations; but of course you would never pollute your wsdl with java specific stuff information. So will use a binding file that looks like:

<?xml version="1.0" encoding="US-ASCII" ?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              jxb:extensionBindingPrefixes="xjc">
  <jxb:globalBindings>
        <xjc:simple />
  </jxb:globalBindings>
</jxb:bindings> 

Problem solved you can now create a web service proxy for this type, hopefully this will be folded into a later version of JAXB.

Thursday, July 24, 2008

So I want to use the JAX-WS RI with JDK 6, so I need the endorsed directory right?

So JDK6u4 comes with JAX-WS RI 2.1.3 so you don't really need to worry about downloading and instally the RI? Right, well there is some slight confusion in that the sun extensions to the JAX-WS standard, for example WSBinding, are repackaged into a different package path for inclusion into the JDK. Any server is going to use the RI version of these classes without the "internal" in the package path.

You can't just add the RI classes to the source path and have it work as the javax.xml.ws.spi.Provider is hard coded to use the "internal" jdk version of the RI. So lets look at the following options:

1. JDK 6_u4

In this case the provider uses the value of the constant javax.xml.ws.spi.Provider.DEFAULT_JAXWSPROVIDER which is "com.sun.xml.internal.ws.spi.ProviderImpl".

2. JDK 6_u4 + JAX-WS RI in endorsed

In this case the provider uses the value of the constant javax.xml.ws.spi.Provider.DEFAULT_JAXWSPROVIDER in endorsed version of the jar which is "com.sun.xml.ws.spi.ProviderImpl".

This is what the RI documentation tells you; but you only need to do this if the RI version doesn't match that of the JDK.

3. JDK 6_u4 + META-INF/services/javax.xml.ws.spi.Provider

If you are using something like weblogic that there will be an entry on the classpath, for example in weblogic.jar, that contains an service entry with the above path. In the weblogic case the first services contains the text "weblogic.wsee.jaxws.spi.WLSProvider". This extends "normal" RI classes so you get the classes you expect.

This does present a workaround if you want the RI; but can't control the endorsed directories (Perhaps with WebStart). You can simply create the service entry on the classpath in your own jars with the "com.sun.xml.ws.spi.ProviderImpl" class as its only content. This will force the external RI implementation to be used.

Finally it is worth saying that there is nothing wrong with using the RI classes in the JDK, I just find it tidier to use the same set of package names in all cases.

Tuesday, July 8, 2008

Updated Asynchronous Web Service slides from Jazoon'08

It contain a whole bunch of updates from the JavaOne'08 version. In particular a section on rolling your own version of part of the @AsyncWebService proposal using the RI.