Today's blog goes over a bunch of web service stuff I learned for a project at work. A web service implementation was desirable because of the potential for interoperability. However, we wanted to send images and have support alerts. None of us really knew about the recent advancements in web services, so I spent a week or two doing a feasibility study. I ended up learning a lot about JAX-WS, Asynchronous Callbacks, and MTOM. So, I'm going to share what I've learned. This entry was written 1/18/2007, so it may not be all that accurate today. Don't blame me, blame our every changing technology.
-- Web Service Study --
Web services have developed a lot between 2004 and 2006. Many new features and capabilities have been added to the tools, which has also made creating and using web services more complex. The technology is still very new and although there are people using it, there isn't much documentation about it. This makes it very difficult to find information about it, especially to the depth that I wanted. At this point, I have a "pretty good" idea about what is out there and how it works. Which means that I can use the APIs and create services, but as for how it really works... I'm basically making educated guesses.
There are at least four different Java web service implementations that support asynchronous callbacks and MTOM out there:
1. JAX-WS (big name): https://jax-ws.dev.java.net/
2. Axis 2 (big name): http://ws.apache.org/axis2/
3. xFire (claims excellent performance): http://xfire.codehaus.org/
4. JibxSoap: http://jibx.sourceforge.net/jibxsoap/index.html
-- JAX-WS --
I only focused on, and will only be discussing, the JAX-WS 2.0 approach. JAX-WS 2.0 is the successor to JAX-RPC. There are two major reasons for this decision.
Firstly, JAX-WS 2.0 is included in Java 6. This means applications using it will require no third party software dependencies or additional jar files for supporting web services. Unfortunetely, the ant tasks to build web services are not included with Java 6, so we as developers still need to get a separate special JAX-WS jar for the development side. The needed classes are the ant versions of the apt and wsimport tools. However, as far as running the client goes, only Java 6, the application, and possibly some client side xml will be necessary. I have verified using a JAX-WS developed application with only JDK 6.
Secondly, JAX-WS also seems to be the most determined to follow specifications, although I'm not sure how standard or widely adopted these specifications are. JAX-WS seems to concentrate on the WS-I standards, which has no track record of adoption. JAX-WS seems to be trying to ensure interoperability with Microsoft's Indigo platform. Going beyond the interoperability provided by JAX-WS itself, the JAX-WS project also provides the foundation for the Web Services Interoperability Technology (WSIT) that provides enterprise features that interoperate with Microsoft Windows Communication Foundation. The WSIT software works as documented, but is known to be incomplete and contain known bugs at this time
JAX-WS currently claims to support:
JAX-WS 2.0
WS-I Basic Profile 1.1
WS-I Attachments Profile 1.0
WS-I Simple SOAP Binding Profile 1.0
The JAX-WS team claims that the next release (JAX-WS 2.1) will support:
WS-Addressing - This standard defines a mechanism for callbacks where the client sends an address the server can send alerts to.
[Selected Relevant Links]
JAX-WS Homepage: https://jax-ws.dev.java.net/
Web Services in Java: http://www-128.ibm.com/developerworks/java/library/ws-java1.html
-- Using JAX-WS --
I'm going to briefly describe how to create a web service and a client to access that web service using JAX-WS. Coding web service server/client applications in JAX-WS requires very specfic design decisions and code annotations. While they aren't very hard to write once you learn them, they take a fair amount of time to learn. And once you get the code running, there may still be a significant amount of effort deploying the service and debugging interoperability problems.
JAX-WS allows (actually, I think forces) you to use annotations to define a web service. Defining a web service would look like this:
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService(name = "StockQuote", serviceName = "StockQuoteService")
public class StockQuoteImpl {
@WebMethod(operationName = "getQuote")
public double getQuote(String ticker) {
double result = 0.0;
if (ticker.equals("GOOG")) {
result = 320.0;
}
return result;
}
}
Once the code is written, you need to run the apt tool on it, which provides a facility for programmatically processing the annotations added to Java. If you want to use this in an ant build, you would want to download the JAX-WS jar which includes com.sun.tools.ws.ant.apt. After you've run apt, then you need to create your war file using the war tool and a custom xml file. Deploy the war file and your web service will be ready to use.
Then, you can write some client code to use this service.
public class StockQuoteClient {
public static void main(String[] args) {
StockQuote port = new StockQuoteService().getStockQuotePort();
double result = port.getQuote("GOOG");
System.out.printf("The stock price of %s is $%f.\n", ticker, result);
}
}
Then you must use wsimport, which generates JAX-WS portable artifacts. If you want to use this in an ant build, you would want to download the JAX-WS jar, which includes com.sun.tools.ws.ant.wsimport. wsimport works by getting the wsdl and creating all the artifacts needed to use this service. In this case, it would generate the JAXB 2.0 binding classes GetQuote, GetQuoteResponse, package-info, and ObjectFactory. Furthermore, it creates the service endpoint interface StockQuote, which provides the client view of the service, and the class StockQuoteService, which allows a client to interact with the client runtime. A point to note here is that, even though the wsimport is from the RI, the artifacts it generates are portable.
With the artifacts created, you can now compile the client. Then you can run the client. Supporting asynchronous callbacks or mtom, which are addressed in the following sections, will add complexity on top of what has been described here.
[More Detailed Tutorial]
JAX-WS Example: http://today.java.net/pub/a/today/2006/06/13/web-services-with-jax-ws-2.0.html
-- Web Service Asynchronous Callbacks and JAX-WS --
Asynchronous web services still imply a request-response protocol. However, asynchronous web services allow the application to do other things while it is waiting for a response from the server. So instead of a blocking operation, you have a non-blocking operation.
In the JAX-WS implementation, you tell the client application to asynchonously use web services through a combination of code and xml. The xml is actually WSDL bindings. This does not mean that the WSDL file on the server side needs special JAX-WS specific bindings that will effect interoperability. Instead it is optional and you may specify client-side xml to merge with the server obtained WSDL. Of course, this means that a .NET client accessing the service would somehow need to know to use asynchronous calls. There isn't any mechanism for that yet.
On the JAX-WS website, it is claimed that "the connection is kept open until the response is received. After that, the callback is called. client/server side handlers do not affect this behaviour." As this implies, using a web service asynchronously is implemented entirely by the client. I believe that when you make an asynchronous request to a web service, JAX-WS creates a new thread that waits for the response so that there is no blocking unless you need the returned data to continue. There isn't any massive polling, just a waiting for a response. Like I said before, the syntax for coding this isn't complicated, but it takes a lot of time to learn and the interoperability may be difficult.
There are two ways to use asynchronous services, which are polling and callback. Each approach definitely has its own benefits and disadvantages.
The polling approach allows you to poll an object that is created when you make the web service request about whether or not a response has been recieved from the server. If it has received a response, you can then request the data response from that object. As I said before, I do not believe that this actually polls the server.
The callback approach allows you to define a callback method when you make the web service request. When the response is received, the callback method is automatically executed. There is no need for you to do anything after making the request, although you can still check if the response has been received yet.
From what I understand, in all implementations, asynchronous web services is completely done on the client side and does not require the implementation to follow any standards. Using the TCPMon tool, I looked into the SOAP messages sent by a test application I developed and verified that there was no change between using the web service synchronously and asynchronously. Asynchronous callbacks are implemented by all the major web service platforms. There is no standardized way to suggest that the web service be used asynchronously, but it won't be impossible.
Java 6 also includes an embedded http server. What this means is that an endpoint can be embedded in client via the JAX-WS API. So using this, the client can send its address to the server, and the server can push information whenever anything is available to a service on the client's server. For this kind of callback, WS-Adressing has a specification about how this should work. JAX-WS does not follow this, but they say that they plan to for the next release. Oh yeah, the embedded server appears to randomly refuse requests if it receives many requests.
[Examples of Use]
JAX-WS Asynchronous Callback Example: http://today.java.net/pub/a/today/2006/09/19/asynchronous-jax-ws-web-services.html
Endpoints in Mustang Example: http://weblogs.java.net/blog/jitu/archive/2006/01/web_service_end.html
-- Attachments and JAX-WS --
The built-in support for Binary Attachments in JAX-WS is MTOM (Message Transmission and Optimization Mechanism). MTOM is a method of efficiently sending binary data to and from web services. It uses XOP (XML-binary Optimized Packaging) to transmit binary data and is intended to replace both MIME and DIME attachments.
The SOAP Message Transmission Optimization Mechanism, paired with the XML-binary Optimized Packaging [XOP], was proposed to address the inefficiencies related to the transmission of binary data in SOAP documents. This solution proposes a method in which XML messages are dissected in order to transmit binary blobs as MIME attachments in a way that is transparent to the application. Since an attachment is not really part of the XML payload, binary data does not need to be base64 encoded, thus reducing its size and increasing its processing speed.
MTOM is supported by the JAX-WS API and is transparent to the user and developer. MTOM is also supported by Microsoft .NET starting in WSE 3.0. The other web service alternative is encoding the data (such as base64 conversion), which is much more inefficient. Unfortunetely, MTOM still doesn't seem all that fast.
[References]
MTOM W3C Recommendation: http://www.w3.org/TR/soap12-mtom/
MTOM and JAX-WS: http://java.sun.com/webservices/docs/2.0/jaxws/mtom-swaref.html
MTOM Performance and Description: http://weblogs.java.net/blog/spericas/archive/2006/04/mtom_performanc.html
JAX-WS MTOM Usage Example: http://blogs.sun.com/milan/entry/using_web_service_to_send
-- From the Web Browser --
As for the web browser, there really hasn't been any outstanding development in that field. People have done funny things to allow callbacks (like using transfers for embedded video for the html requests). The methods were unreliable and very unlikely to really be adopted. Polling still seems like the best way, although it could be heavy on bandwidth.
- SOAP Thoughts -
To end off, I want to rant about SOAP:
SOAP is bloated and you can't find many people that actually like it. Sure, some businesses/people are using it, but the implementations don't work like they're supposed to. SOAP is confusing. It isn't easy to figure out what the standards are or what the standards are trying to say. Microsoft and Sun claim to be working off the same standards, but I'm not convinced they interpret them the same way. SOAP is complicated. You need compatible generation tools, WSDL files, SOAP web applications, and web clients for anything to even work. The interoperability it's designed for still isn't quite there because there are many different standards out there or the implementations of SOAP don't follow the standards correctly. I'm not convinced that it will remain popular for very long. SOAP services are incredibly difficult to create unless you have tools to do most of the work for you. If you have the right tools, it's not too hard to write applications, but the learning curve is pretty steep if you actually want to know what's going on. And you will need to know what's going on if you're writing anything more complicated than a stock-quote example. And it will be very difficult to troubleshoot any problems. SOAP still isn't very mature. A lot about it has changed in the past year and there's not much to suggest that it won't radically change in the next year.
I wonder if some of the other stuff (REST or something else altogether) will eventually replace it. I am impressed with how much web services have developed, but a lot of this development has added a lot of complexity. Web Services are easier to make (thanks to the tools) and more official standards are taking form, but they are more complicated than ever to understand and make by hand (which means they are not easy to debug.) Of course, none of this means that SOAP won't gain popularity and become increasingly important. It seems like the most in-use, buzzed up thing right now, which is good for lastibility.
[A Fun Read]
SOAP dialogue: http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/
- Conclusion -
And that's it. Sorry if it's fragmented sounding, I hope you were able to learn something useful. Like to look into REST. For more fun, look into the latest javascript advancements, as well as Adobe Flex.
Friday, August 03, 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment