views:

1075

answers:

6

I am in a situation where I need to expose a Java method as a web service, and I need to choose the technology to do so and I am basically a bit bewildered.

The requirements are:

  • Must be runnable in an IBM Java 5.
  • Must be deployable as a web application inside an embedded Jetty (currently version 6)
  • Must be detachable from an IDE (has previously used the XFire in MyEclipse 5, I'd like a stand-alone version)
  • Must be well supported, reasonably fast, and preferrably Open Source.
  • Would be really really nice if it was simple to use.

I've seen a multitude of possibilities, CFX (and XFire), Axis 1 and 2, Netbeans 6 (wants Glassfish), JAX-WS (apparently have features with Java 6 which are nice but probably not an option unless it can be retrocompiled), JDeveloper has something, and Eclipse, and I have a hard time getting enough information to make a decision.

I'd appreciate pointers, experiences, recommendations and warnings.


The chosen approach is to use Metro 1.4 which works well.


I have told others about my experiences with it in http://archive.midrange.com/java400-l/200902/msg00074.html and in more detail on http://archive.midrange.com/java400-l/200904/msg00071.html

The information is valid for any Servlet 2.4 compatible container (this is probably the most important single technological decision taken in the whole Metro project IMHO :) )

+4  A: 

The JAX-WS Metro stack (the same one that ships with J2EE 1.5+ or J2SE 6+) can be downloaded and used independently of Glassfish. It makes it fairly easy to expose services, as it uses the @Webservice annotation.

The Metro site also has a page about using it with Eclipse. I also found a blog post about getting it to work with Jetty... apparently Jetty embedded can still be used with jetty.xml

R. Bemrose
+2  A: 

I'd vote for Apache CXF using JSR-181 web service annotations:

http://cwiki.apache.org/CXF20DOC/a-simple-jax-ws-service.html

Simplest example:

@WebService
public class Hello {
    public String sayHi(String name) {
        return "Hello " + name;
    }
}

You get the ease of use of annotated-based development along with an open source solution that is reasonably lightweight and very portable. If you want to expose a CXF-based service without deploying to a container it has excellent support for using embedded Jetty itself.

cliff.meyers
This was a close contender to the Metro suggestion, but the decisive factor was the attention Sun has given to interoperability with .NET. As I like choice I hope that the annotation approach used in JSR-181 allows me to simply switch Metro out with CXF if the need arises.
Thorbjørn Ravn Andersen
+1  A: 

I'm using Spring web services. They keep me insulated from Axis, XFire, etc.

duffymo
A: 

I prefer a lightweight, control-your-own-destiny approach. If you control both sides of the communication, then pick your own simple, optimized transport. If you don't control both sides, then you are probably stuck with something like the proposals given (XML-based in particular).

I prefer using very lightweight web services, which means NOT using XML and not using a lot of wrapper layers (like SOAP, Axis, etc.). All that you really need is HTTP and a shared data representation.

Regarding HTTP, you should simply do a GET for reading data (no side-effects) and a POST for submitting actions (side effects), with perhaps PUT, DELETE, etc. when appropriate.

As for data representation, keep in mind that all those other approaches to web services presume a lot of requirements and add a lot of complexity. Most of them ignore performance completely (e.g., XML is hell on performance).

If you don't need XML for interoperability with a third-party, then you can save a lot of heartache and recapture performance. HTTP is text-based, so convert your data into simple strings. Since you are in Java, use the properties file format if your data is that complex. If your data is even more complex, such as a complete object graph of a customer's order with details, consider using JSON.

Using JSON is my chosen direction for all future efforts, unless specific requirements force me to SOAP or something else. JSON makes it easy to consume the web service via AJAX, and it is easy to accommodate interoperability across platforms and languages. JSON also handles simple cases well, such as passing a single data value or properties-file-like data (simple set of name/value pairs).

Another option for passing data easily, when you really need performance but also want interoperability and simplicity, is Google's protocol buffers. However, I doubt that your immediate needs fit that option.

Rob Williams
+2  A: 

A requirement like "expose a Java method as a web service" in most cases means that some kind of remote access is desired, not necessarily Web Services, with the bloated SOAP, WSDL that eventually will make the solution more complicated than it need to be. If the goal is to really create a web service than ideally you should start from WSDL (Contract First). Even Spring recommends that.

If you have control over Client and Server side and both are Java, then I would recommend some kind of Remoting. I like Spring Remoting, specially the binary protocols from Cauho. The interoperability is very easy, you'll be working with Pojos and, because the data is transfered in binary form, the performance will also be better than a Web Service with XML.

If you don't have control over the client side, then a Simple XML or JSON over HTTP kind of service would be my choice, since XML provides the interoperability. I have used XStream with success in the past to create a simple XML representation of a Java Object.

Handerson
Thank you for responding. Unfortunately I do not have control over both sides, and I have no idea what the other end may be using. You are right in that the primary feature of WebServices that we need is the Contract as it allows for decoupled development.
Thorbjørn Ravn Andersen
A: 

Thanks to all who have responded.

A different approach is not a good idea. Web Services was chosen for the "WSDL contract" allowing decoupled development between teams (from different vendors), and the various overheads are less relevant here.

After having looked a bit on all the suggestions, I have decided that I like the @WebService approach, and that the first attempt will be getting Metro to work on our scenario. The CFX package has a very large amount of dependencies, and Metro is declared to be servlet 2.4 compatible and should run on Tomcat. Unfortunately Metro requires some classes for some versions of Java 6 to be on the boot classpath, but that should be circumventable in our scenario.


2009-02-19: It turns out that the Metro 1.4 runtime libraries can generate the classes on the fly which previously required "apt" preprocessing and deploying the generated artifacts. It runs very well on an embedded Jetty 6.1 web container as well as Tomcat 6 and Jetty 6 servers in the Eclipse JEE perspective allowing for easy development.

The approach of only deploying the original classes with the WebService and WebMethod annotations is in my mind how to ensure that the source will work unchanged with future implementations of the specification. Hopefully even without a recompilation. Suggestion marked as accepted answer.

Thorbjørn Ravn Andersen
The classes that need to be on the boot classpath are the JAX-WS API. And those are only necessary up to Update 3 or 4 (can't remember which one). Later Releases work just fine without that trick. Good luck.
Joachim Sauer