Spring 2.0 introduces a set of JMS remoting classes which makes the proposed system much simpler to program and use.
Basically the client and server share the same service interface. The client codes to the interface and the server code implements it.
In your spring config file on the client you create a factory bean of JmsInvokerProxyFactoryBean, you give this bean the service interface, the well named queue and connection factory to the JMS Server. Spring creates a dynamic proxy which translates your code into JMS messages with reply-to and temp queues created properly.
On the server side you create a JmsInvokerServiceExporter bean which has a reference to your bean which actually implements the service interface. You then set up a message listener container which has a reference to the JmsInvokerServiceExporter. The service exporter handles converting the message into an api call on your interface and responding back to the caller on the reply-to queue.
This approach is really beneficial because the code you write NEVER interacts with the actual JMS api. This allows you to easily test the system, change the underlying transport layer (spring offers similar services for RMI/Hessian/Burlap/WebServices), and so on. You can also use this to break apart a useful service from a singular process and expose it remotely to the entire system.
Personally I think the temp queue request-reply approach is a great alternative to an RMI/stateless session bean approach. The layer of indirection afforded by the JMS server is huge. You can easily move the server process to different hosts without worrying about client configurations. If your service is truely stateless you can bring up several server processes consuming off the same queue and distribute your work seemlessly.