Archive for the 'Javercising' Category

Working with Non XML formats in CXF Interceptors

Sunday, July 1st, 2007

Most web service frameworks provide some way for you to intercept and work with the raw messages that it receives. In JAX-WS this comes in the form of Handlers. Through these handlers you can either work with the raw protocol message (i.e. the XML DOM) or the logicial message (i.e. the databound objects).

In CXF, this comes in the form of Interceptors. Nearly all CXF functionality is built on interceptors. When a transport receives a message, it does as little work as possible, creates a Message object, and then sends that Message off through an InterceptorChain.

One of the things that I think is unique about CXF’s Interceptor support is its ability to make working with low level I/O streams and non XML formats easy for the developer. I want to explore that momentarily and show how you can easily create a GZip Interceptor.

An Interceptor in it’s rawest form is simply a handleMessage() method. There are some other support methods, but we can focus on just the important stuff by extending AbstractPhaseInterceptor:

public class MyInterceptor extends AbstractInterceptor {
 public MyInterceptor() {
  super(Phase.USER_STREAM);
 }
 public void handleMessage(Message message) throws Fault {
  System.out.println("Hello World!");
 }
}

When an endpoint receives a message, this interceptor will run in the USER_STREAM phase and print out “Hello World.” Now how do we work with the low level InputStream?

InputStream stream = message.getContent(InputStream.class);
GZIPInputStream gzip = new GZIPInputStream(stream);
message.setContent(InputStream.class, gzip);

The CXF Message stores multiple content formats which you can easily access via the “T getContent(Class<T> type)” API. An InputStream is one. XMLStreamReader, List
<Object>, SAAJMessage.class, etc are all other possibilities at well. Its perfectly valid for their to be multiple valid formats at once. For instance, we can have both an XML document and a List of databound objects at late points in the chain.

In the final line of the above example, we can replace the InputStream that was set by the transport with our new GZIPInputStream. Its all pretty simple. So whats the big deal?

Well most web service frameworks (including XFire), only provide an XML document to their message processing engine. In CXF, ALL the binding specific details, including transport level details like recognizing attachments and finding the most appropriate data format, are handled in Interceptors. This ultimately makes the transports much cleaner and more flexible. You don’t need a SOAP specific HTTP transport or a RESTful HTTP specific transport. You just have an HTTP transport and all the protocol details get handled by the Interceptors supplied by the bindings.

It also makes several things possible which weren’t before with XFire. One of these things is working with non-XML data. Another important use case is message routing. Since CXF is just a generic message handling framework, you can route based on some criteria (i.e. SOAP or HTTP headers) and copy the message to its destination without parsing the whole thing.

P.S. CXF 2.0 final is being voted on now… Hopefully we’ll have an announcement soon!

CXF is JAX-WS certified in Geronimo 2.0-M6-RC1!

Tuesday, June 5th, 2007

The Apache Geronimo team just announced that they’re JEE certified as of today with their 2.0-M6-RC1 release. This is especially good news from a CXF point of view as Geronimo used CXF for JAX-WS certification!

A big congratulations to everyone on the Geronimo and CXF teams. Some people that deserve an especially large thanks for helping certify CXF inside G include Dan Kulp, Jarek Gawor, Jeff Genender, Jervis Liu,  Jim Ma, and I’m sure many others as well. (I’m pretty sure that I’ll be permanently remembered as the guy who kept breaking the Geronimo build in an effort to add some of the missing features, so I’m lucky these people are still talking to me ;-)).

JavaOne 2007 Wrap-up

Tuesday, May 15th, 2007

I know this is just a few days late, but Gregor just got his out, so at least I’m in good company.

I spent a lot of time this year manning the Envoi booth with Paul. Paul’s entry captures most of my thoughts, but its worth just recapping some things.

The booth was a good chance to talk to people about their needs and how they’re using CXF & XFire. Conversations ranged from educating people about our open source involvement to talking about WebLogic issues to discussing advanced product integration to whats next for CXF. It was also a good chance to educate people about our business. As Paul mentioned, it is easy to have your work in open source get disconnected from the company you work for. Conferences seem to be a good way to help establish that connection.

I was very unimpressed with the start up booths this year. They tried a new layout that resulted in us getting comparatively little traffic. While they admitted it was a mistake, they were were pretty unapologetic about it and tried very little to fix it.

The nighttime parties were a lot of fun this year (as always). While I sufferred from a cold the whole week, I did manage to stay out late a fair amount (which probably didn’t help). The new restaurant of the week was the Town Hall. Highly recommended. Other highlights included visiting the Slanted Door yet again, the RedMonk unconference, the Tangosol party, and a visit to the “place of leaky abstractions.”

The disappointments of the week included being randomly bitten (hard) in a bar by some drunk woman and the Google party at the W.

(Updated to move the letter to Google to a separate post and also add mention to the RedMonk unconference. Random question: is everyone a RedMonk customer these days? Crikey - they’re everywhere.)

CXF 2.0 RC is released!

Sunday, May 6th, 2007

I’m very happy to announce that the CXF team has produced a 2.0 release candiate! This release has some real quality stuff in it:

  • A JAX-WS implementation - although we aren’t quite TCK compliant yet.
  • Built in support for WS-Addressing, WS-Policy, WS-RM, and WS-Security
  • Really good Spring 2.0 integration
  • Support for building web services from POJOs - i.e. no annotations
  • HTTP, JMS, and local (in-JVM) transports
  • RESTful services support - including JSON services

If you’re currently an XFire user, I would suggest you take a look. I think there is a lot to benefit from:

  • Improved WSDL support
  • Improved JAX-WS support
  • Improved JMS transport
  • Maven plugins
  • Spring 2.0 syntax support
  • Improved WS-* support
  • Cleaned up APIs for building services
  • Easier to use extension points
  • RESTful support
  • Support for a “bare” XML binding, which doesn’t include a SOAP envelope

Most XFire services that you have written should be compatabile out of the box with CXF. You will however have to change your deployment code or xml configuration to take advantage of the improved APIs and improved XML format. See the XFire migration guide for some more details.

There has been a question or two about why we are announcing a release candidate as people don’t often announce RCs. There are a couple reasons. First, we’re attempting to finish the JAX-WS TCK testing before we release 2.0 final - although that may wait until 2.0.1. So we wanted to give people a release to use in the meantime. Second, while we’ve had many users testing CXF, we’re sure there are a few bugs out there yet (people have already pointed out a couple which we’re working on fixing). We’d like to throw the release out to the wider community to run through the gauntlet before we declare 2.0 final.

WS-Policy with Apache Neethi

Thursday, April 26th, 2007

At Dim’s suggestion, I’d like to spend a few moments going over one of the underlying components of our policy framework in CXF - Apache Neethi.

Neethi provides an object model for working with Policy expressions. In some sense its the WSDL4J equivalent in the policy world. It provides a common model for both 1.2 and 1.5 policy expressions. For instance, here is a snippet which creates a Policy which says that MTOM is optional:

Policy policy = new Policy();
ExactlyOne exactlyOne = new ExactlyOne();
All all1 = new All();
Assertion a = new PrimitiveAssertion(
new QName("http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization",
"OptimizedMimeSerialization"));
all1.addPolicyComponent(a);
exactlyOne.addPolicyComponent(all1);
exactlyOne.addPolicyComponent(new All());

ExactlyOne and All are policy components which contain other components. ExactlyOne states that ONE of it’s policy components MUST be matched for a particular message/invocation. An All component states that ALL of it’s policy components MUST be matched for a particular message/invocation.

The first policy component that we set up here (all1) contains an MTOM Policy Assertion. The Assertion class represents this, provides Neethi with the assertion QName, and is able to normalize/serialize itself. The PrimitiveAssertion class is an implementation of the Assertion interface which resides in CXF. Its a very simple class which just creates an assertion around a particular QName. In essence, it just represents the XML <mtom:OptimizedMimeSerialization>.

The second policy component is an All with no assertions. Since both of the Alls reside in the ExactlyOne, the net effect is a Policy which says that MTOM is optional:

<Policy>
<ExactlyOne>
<All>
<mtom:OptimizedMimeSerialization/>
</All>
<All/>
</ExactlyOne>
</Policy>

This seems rather verbose, and it is. Luckily there is a way to shorten this:

<wsp:Policy>
<mtom:OptimizedMimeSerialization wsp:Optional="true"/>
</wsp:Policy>

And this leads us to the concept of normalization. The first Policy snippet is a normalized version of the second one. Whenever an Optional=”true” attribute is encountered that means that the particular policy assertion that is optional can be transformed into two <All>s in an <ExactlyOne>. While its more verbose, its a bit more machine friendly when you’re trying to look through and figure out if any of the Policies were met.

Neethi also includes an AssertionBuilder class which builds these assertions from AXIOM elements. As we’re trying to reduce the amount of dependencies needed for CXF, we opted to create our own version of the AssertionBuilder class which uses DOM elements instead. We have a few implementations of the AssertionBuilder floating around, but one of the most interesting is probably the JaxbAssertionBuilder. This builder can build an assertion from a JAXB object. This makes it trivial to add new assertions. Just write your schema, generate your JAXB beans, and tell CXF to look for the new assertion builder.

All in all, I’m pretty pleased with the model Neethi has given us. If I could change one thing though, I would separate out the AXIOM dependant interfaces into a separate package. And similarly with the DOM implementations that we’ve written. However at this point (post 2.0 release), I don’t think its really possible so I haven’t brought it up.

CXF, Spring, and WS-Policy Internals

Monday, April 23rd, 2007

As we near our CXF 2.0-RC release (we’re cutting it today hopefully!), I want to spend a bit more time on my blog talking about CXF, some of the unique things I think we’ve done, and why you should consider it for your projects. Consider this part 1 of n :-).

In CXF we’ve taken the philosophy that we want to leverage the containers and appservers that are out there. Our primary container that we support is Spring. We can also run without Spring, but then you miss out on some of the features.

One of the big new things in Spring 2 is its support for custom XML snippets, meaning we can mix and match any XML types inside a spring config. We’ve added support for configuring clients and servers via this mechanism. Here’s an example of what configuring a JAX-WS endpoint looks like:

<jaxws:endpoint id="helloWorld" class="com.acme.HelloWorld" addressing="http://localhost/helloworld"/>

We expanded this functionality to support various “features” which you can plugin to your service. Features are simply classes which can customize your Server/Client at load time. For instance, I wrote a simple logging feature:

<jaxws:endpoint id="helloWorld" class="com.acme.HelloWorld" addressing="http://localhost/helloworld">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
</jaxws:endpoint>

Notice that you can easily mix & match the Spring syntax and our own jaxws:endpoint syntax. This helps the user as they can leverage the Spring syntax they already know. It also helps developers as it makes creating extensions pretty easy - no XML parsing needed and no schemas need to be written.

CXF and WS-Policy
Before we continue, I’d like to explain a little bit about CXF supports WS-Policy. With WS-Policy I can assert various policies on my service - like that it needs to be using WS-Addressing or it should be using WS-ReliableMessaging. Within CXF there are two things associated with each type of assertion - an AssertionBuilder and a PolicyInterceptorProvider. The AssertionBuilder is responsible for building Assertions classes from XML. The Assertion class is from the Apache Neethi project which provides us with a nice API for working with WS-Policy.

The PolicyInterceptorProvider is where the magic comes in. It allows you to supply interceptors to the CXF message processing chain for whenver your policy is active. For instance, say you are writing support for the <UsingAddressing/> assertion. Then you can have a PolicyInterceptorProvider which provides WS-Addressing Interceptors which get added dynamically to the chain if the policy is active. This means you only have to configure WS-Policy - you don’t have to also configure your service’s interceptors for WS-Addressing.

Bringing together WS-Policy and Spring

The above lays a foundation for simple configuration via WS-Policy. All that you need to do is simply write an assertion for your service and it will get configured correctly (that is, the assertion’s interceptors will be added to interceptor chain).

This merges really well with the Feature framework. We wrote a WSPolicyFeature which understands <Policy> documents embedded inside your <jaxws:endpoint> definition.

<jaxws:endpoint id="helloWorld" class="com.acme.HelloWorld" addressing="http://localhost/helloworld">
<jaxws:features>
<wsp:Policy xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
xmlns:wsam="http://www.w3.org/2007/01/addressing/metadata">
<wsam:Addressing>
<wsp:Policy />
</wsam:Addressing>
</wsp:Policy>
</jaxws:features>
</jaxws:endpoint>

Since this is still Spring, the <Policy> element becomes a WSPolicyFeature Spring bean which you can reference anywhere else inside your code. We simply use the Id attribute on the Policy. This makes it very easy to share Policy configurations across endpoints inside a spring file:

<jaxws:endpoint id="helloWorld" class="com.acme.HelloWorld" addressing="http://localhost/helloworld">
<jaxws:features>
<ref bean="AddressingPolicy"/>
</jaxws:features>
</jaxws:endpoint>


<wsp:Policy wsu:Id="AddressingPolicy"
xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsam="http://www.w3.org/2007/01/addressing/metadata">
<wsam:Addressing>
<wsp:Policy />
</wsam:Addressing>
</wsp:Policy>

You can of course do policy attachments and what not as well, but I’m just focusing on the Spring part of things for now.

More Spring Configuration Coolness
One of the other cool things about this is that we can also apply this configuration to an Endpoint I’ve created via the API through Spring’s AOP mechanisms. For instance, when you create a JAX-WS Endpoint, interally CXF calls into Spring and configures your Endpoint. It finds the appropriate <endpoint> definition using the service’s name. Here’s a sample of a configuration that could be applied to your service:

<jaxws:endpoint id="{http://my.service.namespace}ServicePort" createdFromAPI="true">
<jaxws:features>...</jaxws:features>
</jaxws:endpoint>

Closing Thoughts
All in all, this makes me much more likely to use WS-Policy than I ever thought I would be predisposed to before. I don’t have to write extra XML files and WS-Policy automatically configures features like Addressing, RM, and soon MTOM as well. Much of the credit here goes to Andrea Smyth for doing the WS-Policy layer the AOP configuration stuff. It all looks very cool!

Sonatype Launches

Wednesday, April 18th, 2007

Jason van Zyl announces in his blog:

Since my departure from Mergere I’ve been quietly and steadily working to help start a Maven related company that I’m proud to say I’m a part of. No grandiose launch, no marketing hype, no VCs, haven’t talked to a single analyst, and we hope that you can actually understand what we do by looking at our website. The company’s name is Sonatype and I’m finally happy with the people involved and the direction we’re headed in. We are focused on facilitating the adoption of Maven through our partners network, providing training, and delivering Maven related products for software development.

I’m excited to see an open source business that is as strongly focused on their customers and their business as I know these guys are. They’re great people, and great companies can’t help but come from great people.

Envoi Solutions is proud to be one of Sonatype’s partners. We’re in the process of working on various solutions to help people develop web service/SOA projects more effectively - including a set of archetypes around CXF/XFire.

Congratulations to Jason, Neel, John, Kenney, Eric and the many others involved!

Dodgy Benchmarks Indeed

Thursday, February 8th, 2007

I’ve been meaning to post a follow up to the WSO2 benchmarks for some time. I was hoping to have my own ready, but since InfoQ is carrying them today I would like to respond and with an important point (this is slightly modified from my InfoQ comment).

After looking at their benchmarks I think the latest claim about Axis2 being 2.5% faster than XFire with JiBX is not really true. I noticed that they added in a <soap:Header/> to every message. XFire is optimized for the non header case as that is what most clients will send. Sending a Header will trigger the creation of a JDOM Document to hold the headers in. This is why XFire looks slower in their benchmarks for small messages. For at least 90% of the people out there, XFire will in fact be faster. This also applies to many of the benchmarks in their first posting comparing ADB & JAXB as well.

If WSO2 wants to look at scenarios that use headers, like WS-Addressing or user headers, thats great, and Axis2 might win out there, but this benchmark seems to be about the performance of moving data around without the bells and whistles.

Update: I removed my snippy comments about Axis2 as I don’t know that they were called for. Also, I want to elaborate on the case of headers since Paul Downey raised it in the comments. When there are actual headers in the document, and you are executing logic based on these headers, the document creation time will probably not matter as much. Regardless though, this is a difference of a few percent either way. 5% simply doesn’t matter for web services as your service logic will most likely take more time than that. Now if someone can show me something that doubles performance, that would be noteworthy. However that will be quite tricky to achieve because now the limiting factor in web service performance is probably not XFire or Axis2, its going to be your XML parser, HTTP provider, and/or your data-binding implementation.

Jettison 1.0-beta-1 is released!

Saturday, February 3rd, 2007

I am happy to announce the availbility of Jettison 1.0-beta-1. Jettison is a StAX implementation which reads and writes JSON. It was designed for usage in CXF and XFire to allow easy creation of JSON services side by side with your XML services. For more information about Jettison and downloads see the Jettison website, CXF documentation on JSON, or my earlier blog entry on how to build RESTful services with CXF and Jettison!

For those interested in the change log, this release is primarily focused around bug fixes and small features. The following improvements were included:

  • Element names with “.” are now supported
  • getLocation() no longer returns null
  • Created a switch to allow serialization of attributes without an “@” symbol
  • Fixed a bug in writeCharacters()
  • Several other bug fixes

ApacheCon EU talks

Sunday, January 28th, 2007

Much to my surprise, it seems that somehow I managed to get two talks accepted to ApacheCon EU (May 1-4) this year. The best part is that they're on completely different sides of the spectrum.

The first talk is Navigating WS-death^H^H^H^H^H*. (It seems not everyone liked the name, so that may be changed - feel free to give feedback in the comments). There are many WS specs out there with many different versions (like WS-Addressing). When should I as a user consider using them? What benefits will they bestow on my project? How interoperable is a particular specification? What does the spec roadmap look like?

The second is entitled Building scalable, reliable, and secure RESTful services. This talk is intended to be practical advice on how to build RESTful services. I am to illustrate scalability, reliability, and security through a series of practical examples using different toolkits/frameworks.

Hope to see many of you in Amsterdam this year, I'm sure it'll be a great time!