Enterprise Integration Zone is brought to you in partnership with:

Senior Software Engineer at Parexel International .Experienced in middle tier development using JEE technologies.I get easily influenced by the buzz words in java ecosystem and likes to experiment with them.Apart from job,loves skiing,biking and other outdoor activities. Ramsundar is a DZone MVB and is not an employee of DZone and has posted 5 posts at DZone. View Full User Profile

Two big reason why chose Apache CXF over Metro WS

05.17.2010
| 17588 views |
  • submit to reddit

 

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.       

Published at DZone with permission of Ramsundar Kuppusamy, author and DZone MVB.

(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

I dont think these reasons are really "blockers". But ok. Its something.

Witold Szczerba replied on Wed, 2010/05/19 - 2:19am

Why would you like to extract interface from JAX-RS class representing a resource? You say it would be nice to package API and implemenatation of web services, but what would you need such interface for?

Christophe Hamerling replied on Wed, 2010/05/19 - 2:22am

Completely agree with point 1, this is really boring to have to annotate the implementation. For point 2, I never use Metro but what about exposing the service in REST and SOAP with CXF? Can you do it in one single operation or do you need to publish endpoint 2 times?

Ramsundar Kuppusamy replied on Wed, 2010/05/19 - 8:34am in response to: Witold Szczerba

Its a good practise to code to interface and not expose your implementation class.

Ramsundar Kuppusamy replied on Wed, 2010/05/19 - 8:53am in response to: Christophe Hamerling

yes..you need to publish 2 endpoints one for REST and one for SOAP. But if you are using spring,you can avoid writing any code to publish the endpoints and all you have to do is define two beans in spring xml for the two formats.

Ramsundar Kuppusamy replied on Wed, 2010/05/19 - 9:05am in response to: Lukas Zapletal

think of a scenario like there are 100 different implementations for your service but everything implementing just one interface.would you like to add/modify the webservice annotations at 100 different places or just one interface?if you think about writing a maintainable code,then this scenario should be of very high concern.

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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.