We have seen that Spring supports a wide variety of remoting strategies: from the slim HTTP-based protocol twins Hessian and Burlap over Spring's own HTTP invoker to standard RMI and JAX-RPC. It brings the Spring values of consistency and simplicity, without sacrificing power, to a wide variety of remoting scenarios.
As much as possible, Spring offers a common configuration style for all of those strategies. Proxies can consistently use plain Java business interfaces and throw Spring's unchecked RemoteAccessException, although there is also the option of exposing traditional RMI service interfaces for RMI and JAX-RPC services. As a special feature, an existing RMI-style service can also be proxied with a plain Java business interface, delegating each method call to the underlying RMI service stub.
On the server side, the export mechanism depends on the actual protocol. The lightweight HTTP-based protocols Hessian, Burlap, and HTTP invoker all allow for exposing an existing Spring-managed bean as a remote service, through defining an exporter for a specific protocol. It is also straightforward to expose the same service instance through multiple protocols at the same time, simply defining multiple exporters for the same target bean and binding them to different URLs.
Using Spring's RMI exporter is usually a seamless process, too — provided that there is no conflicting RMI infrastructure in place. It is in general not advisable to use the RMI exporter in a process that also runs an EJB container, as this might lead to conflicts. Exporting a service via RMI works nicely in a J2EE web container such as Tomcat, Jetty, or Resin, though, and is a particularly convincing option for a process that does not run in a J2EE container.
Exporting a Web Service through JAX-RPC is significantly more complex than exporting a service through one of the other protocols. It involves tool-specific deployment of a special endpoint implementation. Delegation to an existing Spring-managed bean can be achieved, but only through writing a thin endpoint adapter for each service. Accessing a Web Service basically follows Spring style, but requires more configuration than Hessian or HTTP invoker.
This flexibility poses the question: which protocol to choose for which scenario? As outlined, the protocol choice is not an either/or decision with Spring, as the same service can be exported through multiple protocols at the same time. Nevertheless, there has to be a choice of protocol per client. The basic recommendation is as follows:
Java-to-Java remoting: If all you need is remote calls from one Java process to another Java process, we strongly recommend that you avoid a cross-platform protocol such as SOAP. Instead, choose a binary strategy such as Hessian, HTTP invoker, or RMI invoker. The former allows for loose coupling without strictly matching codebases, while the latter two impose the restrictions of Java serialization on your objects. Even if your server has to expose a SOAP endpoint for other clients, let your Java clients talk to a (more efficient) Hessian or HTTP invoker endpoint instead.
Cross-platform remoting: If non-Java clients need to talk to your server, SOAP via JAX-RPC is an obvious choice, in particular for platforms such as .NET and Delphi, which include native support for SOAP. This is where the configuration complexity of Web Services will pay off, in contrast to a Java-to-Java remoting scenario. However, there is still an alternative: If there is a Hessian or Burlap implementation for the platform in question, you could choose one of them as a lighter alternative to SOAP. Even implementing your own Hessian or Burlap client can be feasible, in particular for platforms without native SOAP support.
A further important criterion is whether you need client-server remoting or intra-server remoting. For the former, an HTTP-based protocol is preferable, to avoid firewall issues and to be able to communicate over the Internet. However, for an intra-server scenario, a non-HTTP solution such as RMI would be appropriate, too, although Hessian and HTTP invoker are roughly equivalent in terms of efficiency (despite being HTTP-based). Most importantly, do not choose SOAP for communication between Java-based servers unless absolutely necessary.
To a large degree, the protocol choice becomes a configuration matter with Spring. Neither client objects nor service implementations are tied to a specific protocol or remoting API. In many cases, the protocol can indeed be switched at deployment time: for example, from RMI invoker to HTTP invoker if facing firewall limitations in a concrete environment. Some of the protocols have specific requirements for serializable objects, but in general even switching between different serialization mechanisms — for example, between Hessian and HTTP invoker — is rather smooth.
Of course, as with any infrastructure that you depend on, test your application with the remoting protocols of your choice, and test it thoroughly. All deployment scenarios for your application need to be tested, including all potential remoting protocols. Once you have made sure that a certain set of remoting protocols works for your requirements, the actual deployment choice becomes a configuration matter with Spring.