Two big reason why chose Apache CXF over Metro WS
Apache CXF and Metro WS are two very popular webservice frameworks(which fully implements JAX-WS specification).Both are equally popular and widely used. Metro WS project has been receiving lot of attention, thanks to some good advertising and promotions by Sun Microsystem(now Oracle).Based on my experiences with the two frameworks,the following are two major reasons why i would prefer CXF over Metro.
Metro forces you to expose the implementing class
In a real world application one prefers to just expose the interface and hide the actual implementation class.For eg: you might want to do something like the below code,
@WebService
public interface HelloWorldService {
@WebMethod
public String sayHello(String input);
}
public class HelloWorldServiceImpl {
public String sayHello(String input)
{
return "hello world"+input;
}
}
When you try to execute the above code with Metro,you will get this exception
saying "JAXB can't handle interfaces".
Metro forces you to add the JAX-WS annotations on implementing class(HelloWorldServiceImpl)
even if you had already annotated the
interface.You cannot just annotate interfaces and hope subclasses will
be "annotated".
Many a times you might have something similar to jaxb-api.jar and jaxb-impl.jar,where API's are packaged seperately from the actual implementation.In such cases you don't want the developers writing the implementations to worry about exposing web services or JAX-WS annotations.CXF handles this pretty well and lets you add all those JAX-WS annotations just at the interface level.
CXF supports both jax-ws and jax-rs very well
CXF supports usage of both JAX-WS and JAX-RS annotations together without any trouble.It means,one can expose any interface in both SOAP and REST format and still keep the implementing class ignorant of all this.
@Path("/helloWorldService/")
@WebService(serviceName = "HelloWorld", name = "HelloWorldService")
public interface HelloWorldService {
@WebMethod
@GET
@Path("/")
HelloWorld sayHello();
}As you can see in the above example,HelloWorldService interface has both SOAP and REST annotations and it works with CXF framework. For some reason,Sun maintains two separate projects Metro and Jersey to support SOAP and REST (Metro for SOAP and Jersey for REST).It is possible to get Metro and Jersey working together but might require some plumbing work to be done.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Lukas Zapletal replied on Wed, 2010/05/19 - 1:50am
Witold Szczerba replied on Wed, 2010/05/19 - 2:19am
Christophe Hamerling replied on Wed, 2010/05/19 - 2:22am
Ramsundar Kuppusamy replied on Wed, 2010/05/19 - 8:34am
in response to:
Witold Szczerba
Ramsundar Kuppusamy replied on Wed, 2010/05/19 - 8:53am
in response to:
Christophe Hamerling
Ramsundar Kuppusamy replied on Wed, 2010/05/19 - 9:05am
in response to:
Lukas Zapletal
Artur Karazniewicz replied on Sun, 2010/06/20 - 1:18am
Ramsundar
Both frameworks are great and have their strengths. I personally prefer CXF a little bit more because of its ground-up integration with Spring, better portability, and great community support. Metro on the other hand has much better WS-* support, is more robust and mature and has much better interoperability foundation through WSIT project. However choosing right tool base on hello world examples is pretty unreasonable.
Your first example is actually invalid in every non trivial, real-life scenario. You have to annotate implementation anyhow. JAX-WS SEI and endpoint implementation maps directly to WSDL architecture: SEI reassembles abstract WSDL part (portType, bindigs) and service endpoint implementation reassembles WSDL non-abstract part (service) accordingly. Now some annotations make sense only on implementation (namely javax.jws.WebService.portName and javax.jws.WebService.serviceName) and cannot be applied to SEI. Sure, if You won't annotate endpoint implementation, JAX-WS stack will generate some implementation specific names for You. While it's convenient it's dangerous because it emits fragile contract (usually portName and serviceName are derived from implementation class name; thus refactoring breaks Your contract).
Also, bridging JAX-WS and JAX-RS stuff in one implementation seems unreasonable in practice. First of all REST has actually quite different architecture. Usually SOAP endpoint is fundamentally different from REST resource. I cannot see single reason, except 'we can done this', to put this stuff together. In reality, You will end up with messy REST or SOAP or both. I would better avoid this approach. However here is one, much more important reason. In any non trivial resource You have to put XmlElementRoot annotation on it (if not - You will end up with this). And XmlRootElement won't work well with SOAP, especially with request/response wrappers and doc/literal wrapped style.
http://blog.restfusion.com
Artur Karazniewicz