Archive for July, 2007

SCA Assembly vs. Spring + CXF

Sunday, July 22nd, 2007

From Ke Jin’s comment on InfoQ:

The programming objects of so-called “remote-services” in SCA are either their client stubs (for client applications) or server skeletons (for server applications). Both of these classes are merely special cases of POJOs.

As the matter of fact, the so-called SCA assembly model is merely a DSL (domain specific language) that can easily be realized on top of Spring or any decent POJO IoC containers, with few hundreds lines of code and half day of work.

So I’m not the only one who thinks this!

Now, I’m extending on the SCA examples I’ve seen, so this could be a completely wrong example. BUT, is this:

<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <component name="AccountService">
  <implementation.java class="AccountServiceImpl"/>
 </component>
 <service name="accountDataService">
  <interface.java interface="services.accountdata.AccountDataService"/>
  <binding.ws uri="/accountDataService" />
 </service>
 <property name="currency" type="xsd:string">USD</property>
</componentType>

Really that much different from this:

<beans default-autowire="byType"
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
 <bean id="AccountService" class="foo.AccountServiceImpl">
  <property name="currency" value="USD"/>
 </bean>
 <jaxws:client id="accountDataService" class="services.accountdata.AccountDataService"
    address="http://host/accountDataService"/>
</beans>

(In this case the AccountDataService is being wired in as a property on the AccountService)

Someone show me where Ke Jin is wrong and where SCA expands on Spring capabilties. Language independence does NOT count as I consider that a big red herring (that can be another blog entry for when I have more time).

SXC 0.6 Released - XML parser/writer compiler, JAXB accellerator, etc

Wednesday, July 11th, 2007

I’m happy to announce that SXC (yes, it’s pronounced sex-c) 0.6 has been released. SXC is an xml parser/writer compiler. It can build optimized XML parser/writers via an API, for your JAXB classes, and for XPath expressions, resulting in large performance gains.

This release is due completely to the wonderful coding by Kohsuke Kawaguchi. He has implemented several improvements at the API level:

  • Split the core module into a runtime module and a core module. This way if you generate classes they can be used at runtime with a very minimal set of dependencies.
  • Made it possible to just generate a reader or just a writer. You can also control the names of the classes now.
  • Simplification of the API by removing the GeneratedReader/Writer classes
  • Several bug fixes
  • Documentation improvements

Kohsuke has prompted me to renew my dev efforts for SXC, so I’m planning on starting on 0.7 relatively soon. I really want to accomplish two features:

  • Allow pre-compilation of JAXB optimized readers/writers. Ideally you’d be able to add a piece of configuration to your build and then SXC wouldn’t have to compile anything at runtime. This will make JAXB startup and runtime performance faster.
  • Improve our JAXB type support. There are still a few notable missing things, like attributed value types and attachments.

If you’re interested in helping, there are plenty of areas to work on. I’d definitely like to see our XPath support improve significantly sometime soon as well!

In Salt Lake City

Sunday, July 8th, 2007

I’ll be in Salt Lake City this week. If you’re around and are interested in meeting up, send me an email! Hopefully I won’t melt in the 100 degree heat…

Tips for improving Spring’s start up performance

Tuesday, July 3rd, 2007

Someone is blathering on again about how Spring sucks, and so startup performance came up in the conversation. CXF uses Spring under the covers by default (it’s optional, don’t worry). Initially there was some major slowness, but I’ve spent a lot of time profiling/improving CXF’s startup time. I thought I’d share what I learned so you can improve your startup time as well:

  1. Use the latest version of Spring (2.0.5+). The latest version of Spring contains may performance improvements (including one I found while profiling CXF).
  2. Reduce the number of configuration files. More configuration == more XML to parse.
  3. Reduce the number of <bean>s in your configuration. Contrary to popular belief, not every friggin class needs to be a <bean>. Startup time is pretty proportional to the number of beans (if you follow the suggestion in #4).
  4. Don’t use classpath*:*.xml type wildcards. These significantly slow down the starup process as Spring needs to search through all the jars. In some cases it needs to expand them (I think on certain appservers). Doing a classpath:/foo/*.xml search is much better as that can delegate to the JDK. Although further performance gains can be made by removing wildcards together I think.
  5. Reduce your number of beans - just because you can make it a <bean> doesn’t mean you should.
  6. lazy-init=”true” is your friend. Don’t load a <bean> until you need to.
  7. Turn off schema validation (Alternately: anyone want to rewrite Xerces?) - this adds about 20% more time to startup in the CXF case.

If all goes well, you should be able to get the Spring startup time pretty low. At this point its probably other things, like your ORM layer (*cough* Hibernate *cough*), that are slowing things down.

Random tidbit: I was profiling the CXF startup the other day. About 33% of the time is in Introspector.getBeanInfo(), so its really not all Spring’s fault IMO :-). Maybe someone can hack the JDK to be faster there?

Have any more Spring performance tips? Add them to the comments!

Apache CXF 2.0 (incubating) is released!

Tuesday, July 3rd, 2007

Well, its been about one year since we began and today we’ve finally reached our 2.0 release! From the announcement:

The Apache Incubator CXF team is proud to announce the availability of the 2.0 release!

Apache CXF is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS. These
services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.

CXF includes a broad feature set, but it is primarily focused on the following areas:

  • Web Services Standards Support: CXF supports a variety of web service standards including SOAP, the Basic Profile, WSDL, WS-Addressing, WS-Policy, WS-ReliableMessaging, and WS-Security.
  • Frontends: CXF supports a variety of “frontend” programming models. CXF provides a JAX-WS Compliant frontend. It also includes a “simple frontend” which allows creation of clients and endpoints without annotations. CXF supports both contract first development with WSDL and code first development starting from Java.
  • Ease of use: CXF is designed to be intuitive and easy to use. There are simple APIs to quickly build code-first services, Maven plug-ins to make tooling integration easy, JAX-WS API support, Spring 2.0 XML support to make configuration a snap, and much more.
  • Binary and Legacy Protocol Support: CXF has been designed to provide a pluggable architecture that supports not only XML but also non-XML type bindings, such as JSON and CORBA, in combination with any type of transport.

For those who aren’t up on things, CXF is the merge of the XFire and Celtix projects. As such, CXF is really a continuation of the XFire project and can be thought of as XFire 2.0. For all the XFire users out there: have no fear, your services should deploy just fine in CXF. You’ll just need to change your deployment code/xml. Check out our migration guide if you’re interested in more details.

For more information on CXF check out:

Many thanks to all those involved in the whole process. Its been a pleasure to work with so many talented people. Thanks to Debbie Moynihan for helping the whole CXF project get rolling and getting IONA involved. Dan Kulp for continually making CXF more coherent, his incredible eye for detail, TCK work, build maintenance and patience with my build breakage. Andrea Smyth for the great Policy/ReliableMessaging work. Jervis Liu for his work on everything, like the SAAJ stuff which was a giant PITA. Eoghan Glynn for putting up with me and the superb WS-A layer. James Mao for making CXF tooling rock. Christopher Moesel for his MTOM integration. Willem Jiang for fixing things all over and the JCA work. Guillaume Nodet for using XFire, showing me how many things were wrong with it when using it with JBI and then helping develop the CXF JBI code. Freeman Fang for the JBI work. Jeff Genender and Jarek Gawor for their awesome work on the TCK and Geronimo. Jim Ma for the work on the tooling and frontends. Thanks to all the incubator folks for reviewing our releases. Our mentors who guided us in the Apache process, especially Jim Jagielski. (*whew* - I probably missed some people, apologies!)

A special thanks to Tomek Sztelak who has been helping maintain the XFire code more than I have lately and answering a ton of questions on the XFire list. Not only that, but he’s also found time to contribute a set of Maven archetypes to CXF. All this while he’s been working full time AND been in and out of the hospital! Heroic!

The CXF community welcomes involvement and feedback. For more information see how to get involved or the mailing lists.

JBossWS supports CXF as a pluggable WS framework

Monday, July 2nd, 2007

Thomas just announced that JBoss has been working on making their WS layer pluggable. In addition to supporting the native JBossWS framework, CXF and Metro (the project formerly know as the JAX-WS RI + Tango) integration code will be added for the 2.1.0 release as well. Among other things, this should help make it easier for CXF/Metro users to deploy services and create EJB backed web services inside JBoss.

I’m very happy to see this. Its not uncommon for me to visit a customer who is mixing different stacks together. Its part of the promise of open source, you can pick the best technologies (dare I use the marketing term - best of breed), and integrate them together.

Its great to see JBoss/RedHat support this approach.

<horn-tooting>

Coincidentally, why might you want to use CXF within JBoss [1][2]?

  • Spring integration - we have lots of lovely support for the Spring 2.0 syntax. Its trivial to make a Spring bean a web service. Just write a <jaxws:endpoint … /> snippet and you’re done It equally trivial to inject a WS client into your application.
  • JAX-WS frontend - Use the standard JAX-WS APIs to build your services via annotations
  • Simple frontend - CXF supports the building of services with no annotations needed through the simple frontend. It works well in conjunction with the Aegis databinding, which can generate schemas from just about anything - including Map<Foo, Bar> constructs (maybe someday JAXB will support that).
  • RESTful services via annotations
  • WS-* support - including Addressing, Policy, Security, and ReliableMessaging
  • The ability to work with non-XML data like JSON
  • Maven Plugins

</horn-tooting>
1. Important: this is not to imply that the JBossWS Native or Metro does not have any particular one of these features, I just think it is this combination that makes CXF unique.

2. Disclaimer: The JBossWS code is an ongoing effort and the CXF code still isn’t quite ready yet AFAIK. I would encourage you to get involved though if this interests you. Also, CXF can still be run standalone inside JBoss in the mean time - many users do that already.

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!