Jetty - stand alone WebSocket server - websocket

in these days I try to implement a WebSocket server by using Jetty.
I've created a Jetty project called "WebSocketServer" as demo-base in the distribution of Jetty 9.2.0.v20140526.
After that, I write some codes to implement the WebSocket mechanism and export all codes to a war file to push it to the webapps folder of "WebSocketServer". When I java -jar ..<jetty.home>/start.jar, it is all workable. But, after I create a new connection to this WebSocket project, there are some error codes happened.
java.lang.ClassCastException: org.eclipse.jetty.server.HttpConnection cannot be cast to org.eclipse.jetty.server.HttpConnection
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:175)
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:148)
at org.eclipse.jetty.websocket.servlet.WebSocketServlet.service(WebSocketServlet.java:151)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:199)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98)
at org.eclipse.jetty.server.Server.handle(Server.java:461)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
at java.lang.Thread.run(Thread.java:744)
I have no idea what's going on? The following codes are what I write to build a simple WebSocket server.
Servlet:
#SuppressWarnings("serial")
public class XYZWebSocketServlet extends WebSocketServlet{
#Override
public void configure(WebSocketServletFactory factory) {
factory.getPolicy().setIdleTimeout(600000);
factory.register(XYZWebSocketEvent.class);
}
}
Event:
#WebSocket
public class XYZWebSocketEvent {
private Session session;
#OnWebSocketConnect
public void onConnect(Session sess) {
session = sess;
// Get parameters while client connect to server
Map<String,List<String>> parameters = session.getUpgradeRequest().getParameterMap();
String encyptedID = parameters.get("ID").get(0);
System.out.println("Connect: " + session.getRemoteAddress().getPort());
try {
session.setIdleTimeout(600000);
session.getRemote().sendString("Hello!");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
#OnWebSocketMessage
public void onMessage(String message) {
try {
session.getRemote().sendString("Message: " + message);
}
catch (Exception ex) {
}
}
#OnWebSocketClose
public void onClose(int statusCode, String reason) {
try {
session.getRemote().sendString("Close: statusCode=" + statusCode + ", reason=" +reason);
}
catch (Exception ex) {
}
}
#OnWebSocketError
public void onError(Throwable t) {
System.out.println("Error: " + t.getMessage());
}
public Session getSession() {
return this.session;
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>WebSocket application</display-name>
<servlet>
<servlet-name>XYZWebSocketServlet</servlet-name>
<servlet-class>com.newKinpo.servlet.XYZWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XYZWebSocketServlet</servlet-name>
<url-pattern>/events/*</url-pattern>
</servlet-mapping>
</web-app>
Is there something wrong? Thanks for your attention.

I had similiar problem and I have found the cause and the solution. Embeded jetty server is loaded by SUN class loader (will call it system class loader later) after webapp directory is scanned my app is loaded by WebApp class loader and when it comes to WebSocketServerFactory it is loaded by WebApp. However org.eclipse.jetty.server.HttpConnection object obtained from the request is loaded by the system class loader.
According to https://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading jetty websocket package is treated as system class package and shouldn't be loaded by the WebApp if already loaded by the system.
The solution is to force loading of the package org.eclipse.jetty.websocket at the time jetty server is initialized.
I just create dummy instance of WebSocketHandler for example. There are many options to force package loading but they are irrelevant to this question.

Related

Spring Boot multiple WAR files in 1 Tomcat

we are developing a multi-mandator shop solution for multiple countries, like Sweden, Netherlands, Germany etc. We aim to have 1 WAR file for each mandator and would like to have all of them running in 1 tomcat. Is it possible to have this integrated into Spring-Boot's embedded tomcat?
If the Mandators are different webapps/war files then you can add wars/web apps to the EmbeddedServletContainer(Tomcat), using the tomcat.addWebapp method.
In your spring-boot main class add the following bean.
#Bean
public EmbeddedServletContainerFactory servletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory() {
#Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
// Ensure that the webapps directory exists
new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs();
try {
Context context = tomcat.addWebapp("/Sweden","Sweden.war");
tomcat.addWebapp("/Netherlands","Netherlands.war");
tomcat.addWebapp("/Germany","Germany.war");
context.setParentClassLoader(getClass().getClassLoader());
} catch (ServletException ex) {
throw new IllegalStateException("Failed to add webapp", ex);
}
return super.getTomcatEmbeddedServletContainer(tomcat);
}
};
}

Jetty websocket class loading issue

I have implemented a basic websocket server in Jetty(Standalone mode).
MyWebSocketServlet.java
public class MyWebSocketServlet extends WebSocketServlet {
#Override
public void configure(WebSocketServletFactory webSocketServletFactory){
webSocketServletFactory.getPolicy().setIdleTimeout(1000 * 10 * 60);
webSocketServletFactory.setCreator(new MyWebSocketFactory());
}
}
MyWebSocketFactory.java
public class MyWebSocketFactory implements WebSocketCreator {
public Object createWebSocket(
ServletUpgradeRequest servletUpgradeRequest
, ServletUpgradeResponse servletUpgradeResponse) {
return new MyWebSocketListener();
}
}
MyWebSocketListener.java
public class MyWebSocketListener implements WebSocketListener {
private Session sessionInstance;
public void onWebSocketBinary(byte[] bytes, int i, int i1) {
ByteBuffer data = ByteBuffer.wrap(bytes, i, i1);
try {
sessionInstance.getRemote().sendBytes(data);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onWebSocketClose(int i, String s) {
}
public void onWebSocketConnect(Session session) {
sessionInstance = session;
}
public void onWebSocketError(Throwable throwable) {
throwable.printStackTrace(System.err);
}
public void onWebSocketText(String s) {
try {
sessionInstance.getRemote().sendString(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
metadata-complete="false"
version="3.1">
<servlet>
<servlet-name>WsEcho</servlet-name>
<servlet-class>org.test.sanket.MyWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WsEcho</servlet-name>
<url-pattern>/echo/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HttpEcho</servlet-name>
<servlet-class>org.test.sanket.MyHttpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpEcho</servlet-name>
<url-pattern>/httpecho/*</url-pattern>
</servlet-mapping>
</web-app>
Instead of using a Standalone Jetty if I use embedded jetty and programatically configure the server and add the Servlets then this sample runs fine.
But if I am packaging the same as a war, and then deploying the same in a standalone jetty instance I am having the following observation:
I am able to hit the HttpServlet , i.e. MyHttpServlet and receive a response
But when I try to hit the websocket servlet, i.e. MyWebSocketServlet, I am seeing the following error:
exception
java.lang.ClassCastException: org.eclipse.jetty.server.HttpConnection cannot be cast to org.eclipse.jetty.server.HttpConnection
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:175)
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:148)
at org.eclipse.jetty.websocket.servlet.WebSocketServlet.service(WebSocketServlet.java:151)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
I did come across the following link:
Jetty - stand alone WebSocket server
From the above link it seems to be a class loading issue, because jetty websocket package is treated as system class package and shouldn't be loaded by the WebApp if already loaded by the system.
So as referenced in the above link, I looked into the details suggested at:
http://www.eclipse.org/jetty/documentation/9.2.10.v20150310/jetty-classloading.html
From this link, one of the ways to get around this issue is to call the org.eclipse.jetty.webapp.WebAppContext.setSystemClasses(String Array) or org.eclipse.jetty.webapp.WebAppContext.addSystemClass(String) to allow fine control over which classes are considered System classes.
So for being able to do that, I should be able to get an Instance of WebAppContext, when Jetty is initializing and add the WebSocket classes as system classes.
I tried searching for how one would be able to achieve the same but no luck so far ? Can anybody kindly point me to a reference implementation as to how this can be achieved ?
Java Version: OpenJDK 7(latest)
Jetty: 9.2.10.v20150310
Operating System: Ubuntu 14.04
Thanks in advance!
If you have followed this link to setup the Jetty Standalone Instance, then you might have run the following command:
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging
If so, then when you try to hit the websocket servlet you will see the exception that you are noticing.
All you need to do is, instead of that command, you as well need to initialize the websocket module as shown below:
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging,websocket
Hope this helps!
Don't include the org.eclipse.jetty.* classes in your war's WEB-INF/lib or WEB-INF/classes directories.

Test case using SpringJunitRunner

I want to write junit test case for the below code with springJunitRunner.
the below piece of code is one service in a class.
#Component
#Path(/techStack)
public class TechStackResource {
#Autowired
private transient TechStackService techStackService;
#GET
#Path("/{id}")
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getTechStackById(final #PathParam("id") Integer technicalstackid) {
final TechStackResponse response = new TechStackResponse();
int statusCode = Constants.HTTP_STATUS_OK_200;
try {
TechStackModel techStackModel = techStackService.findObjectById(technicalstackid);
response.setGetTechStackDetails(GetTechStackDetails.newBuilder().technicalStack(techStackModel).build());
if (techStackModel == null) {
statusCode = Constants.HTTP_STATUS_ERROR_404;
}
} catch (EmptyResultDataAccessException erde) {
} catch (Exception e) {
LOGGER.error("Exception occured in TechStackResource.getTechStackById(technicalstackid) ", e);
throw new APMRestException(
"Exception while executing TechStackResource.getTechStackById(technicalstackid) ",
Constants.UNKNOW_ERROR, e);
}
return Response.status(statusCode).entity(response).build();
}
}
the configuration in web.xml for servlet is
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
Since you are using Jersey as well as Spring, you can use the SpringJunitRunner only to wire-up TechStackResource with its dependency TechStackService.
In order to test your REST handler method getTestStackById, you could go the POJO approach and invoke it directly. Alternatively, you can use Jersey's own MockWeb environment. To find out more about this, I recommend looking at the Jersey example sources, e.g. HelloWorld.

MDB to listen queue and put message into another queue

I'm new to J2EE - MDB but I'm trying to create a Message Driven Bean (MDB) that simply listens to a queue (read the messages), then process that message and push it to a different queue. I have found several working examples on Google to achieve these two tasks in a separate fashion, but I've been having issues trying to do them both on the same MDB.
This is the code for my MDB
#MessageDriven(mappedName = "jms/propuestasQ")
public class ObtenerNumPolizaBean implements MessageListener {
#Resource(name="jms/polizasQCF")
private QueueConnectionFactory connectionFactory;
private Connection connection;
#Resource(name = "jms/polizasQ")
private Destination targetQueue;
#PostConstruct
private void initJMS() {
try {
connection = connectionFactory.createConnection();
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
#PreDestroy
private void closeJMS() {
try {
connection.close();
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
/**
* #see MessageListener#onMessage(Message)
*/
#Override
public void onMessage(Message message) {
//validate the received message type
if (message instanceof FolioEntity) {
try {
//generate Web Service proxy
GenerarFoliosImplService serviceGenerarFolios = new GenerarFoliosImplService();
GenerarFoliosImplDelegate delGenerarFolios = serviceGenerarFolios.getGenerarFoliosImplPort();
//call the method with the object
FolioEntity responseFolio = delGenerarFolios.generarFolios((FolioEntity)message);
System.out.println("Bean generated the following FolioNumber: " + responseFolio.getNumeroFolio());
//put the message on the next queue
putMessage(responseFolio);
}
catch (JMSException e) {
throw new RuntimeException(e);
}
}
else {
throw new IllegalArgumentException("Message must be of type FolioEntity");
}
}
private void putMessage(final FolioEntity folio) throws JMSException {
final Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
final MessageProducer producer = session.createProducer(targetQueue);
final ObjectMessage objectMessage = session.createObjectMessage();
producer.send(objectMessage);
session.close();
}
Here is the content of my ejb-jar.xml file
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<display-name>MDBRenovarPolizaEJB </display-name>
<enterprise-beans >
<message-driven>
<ejb-name>ObtenerNumPolizaBean</ejb-name>
<message-destination-ref>
<description />
<message-destination-ref-name>
jms/polizasQ
</message-destination-ref-name>
<message-destination-type>
javax.jms.Queue
</message-destination-type>
<message-destination-usage>
ConsumesProduces
</message-destination-usage>
<message-destination-link>
jms/polizasQ
</message-destination-link>
</message-destination-ref>
<message-destination-ref>
<description />
<message-destination-ref-name>
jms/polizasQCF
</message-destination-ref-name>
<message-destination-type>
javax.jms.QueueConnectionFactory
</message-destination-type>
<message-destination-usage>
ConsumesProduces
</message-destination-usage>
<message-destination-link>
jms/polizasQCF
</message-destination-link>
</message-destination-ref>
The issue I'm having is that I can't set the "Message Driven Bean listener bindings" on WAS Console 8.5.5, when I try to set the activation specification I'm getting the error:
MDBRenovarPolizaModelEJB.jar\META-INF\ejb-jar_merged.xml (The system cannot find the file specified.)
I don't know what this exception means. I've always set the "Activation specification" this way to listen to a particular queue, so I have no idea what is this file: "ejb-jar_merged.xml".
Any clue? Thanks in advance.
Or if anyone has a working example to achieve this with step by step to make it work under WebSphere that would be useful.
I just solved similar problem (WAS 8.5.5, but MDB, EJB, servlet - all stuffed into one war module)
It is clearly a bug in WAS. This is workaround:
Ensure Run server with resources on Server
Publish to repeat an error (but this time with resources on server)
Find directory where WAS expects "ejb-jar_merged.xml":
Locate WAS SystemErr.log
There are messages about missing "ejb-jar_merged.xml".
You are looking for directory name of missing file.
Goto to the found directory.
(something like .IBM/WebSphere/AppServer/profiles/AppSrv01/wstemp/0/workspace/... ....deployments /.....-INF/
copy ejb-jar.xml ejb-jar_merged.xml
In case of missing web_merged.xml just copy web.xml into web_merged.xml.
The problem will not appear again at application updates, it has to be reapplied sometimes after app remove/install.

HttpInvokerServiceExporter + HttpInvokerProxyFactoryBean - Could not access HTTP invoker remote service

I'm trying to use HttpInvokerServiceExporter + HttpInvokerProxyFactoryBean, but whatever I do I get an exception:
org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [http://localhost:9999/testcaseapp/testcaseservice]; nested exception is java.io.IOException: Did not receive successful HTTP response: status code = 404, status message = [Not Found]
For the simplicity, I've created a test case.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class RemoteTest {
private static final Logger logger = LoggerFactory.getLogger("TestsLogger");
static interface TestCaseService {
public Integer add(Integer arg1, Integer arg2);
}
static class TestCaseServiceImpl implements TestCaseService {
public Integer add(Integer arg1, Integer arg2) {
return (arg1 != null ? arg1.intValue() : 0) + (arg2 != null ? arg2.intValue() : 0);
}
}
#Configuration
static class Config {
#Bean
public HttpInvokerServiceExporter httpInvokerServiceExporter() {
HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
httpInvokerServiceExporter.setService(new TestCaseServiceImpl());
httpInvokerServiceExporter.setServiceInterface(TestCaseService.class);
return httpInvokerServiceExporter;
}
#Bean
public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean = new HttpInvokerProxyFactoryBean();
httpInvokerProxyFactoryBean.setServiceInterface(TestCaseService.class);
httpInvokerProxyFactoryBean.setServiceUrl("http://localhost:9999/testcaseapp/testcaseservice");
httpInvokerProxyFactoryBean.afterPropertiesSet();
return httpInvokerProxyFactoryBean;
}
}
#Autowired
private TestCaseService[] testCaseServices;
private static Server server;
#BeforeClass
public static void setUp() {
try {
server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(9999);
server.addConnector(connector);
//
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/testcaseapp");
webAppContext.setWar("src/test/java/" + RemotingTest.class.getPackage().getName().replace('.', '/'));
server.setHandler(webAppContext);
//
server.start();
} catch (Exception ex) {
logger.info("Could not permorm the set up: {}", ex.toString());
}
}
#AfterClass
public static void destroy() {
try {
server.stop();
} catch (Exception e) {
}
}
#Test
public void addTest() {
for (TestCaseService testCaseService : testCaseServices) {
Integer sum = testCaseService.add(10, 5);
Assert.assertNotNull(sum);
Assert.assertEquals(15, sum.intValue());
}
}
}
I've also tried to create a TestCaseService bean
#Bean public TestCaseService testCaseService() ...
and provide it as a httpInvokerServiceExporter argument
#Bean public HttpInvokerServiceExporter httpInvokerServiceExporter(TestCaseService testCaseService)
...
httpInvokerServiceExporter.setService(testCaseService);
but the result is still the same.
What am I doing wrong? Thanks!
I think the problem is that the Servlet is not accesible.
SERVER SIDE
Make sure you have in your WEB-INF/web.xml (on the app that is exposing the methods -SERVER-) this code:
<web-app>
...
<servlet>
<servlet-name>remoting</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>remoting</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
...
</web-app>
Here, the remote methods are served under "services", that is, for calling the method, the URL should be:
http://localhost:8080/sample/services/list
And you have to define this Servlet as accesible, by creating a bean (in my case under WEB-INF/remoting-servlet.xml):
<bean name="/list" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="myObjectQueryService" />
<property name="serviceInterface" value="com.kategor.myapp.sample.service.ObjectQueryService" />
</bean>
CLIENT SIDE
If your using Spring under the client (not as in your example), you must define a bean for accessing the remote resources, defining some beans (one for each public resource):
In this case, it would be:
<bean id="listService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/sample/services/list" />
<property name="serviceInterface" value="com.kategor.myapp.sample.service.ObjectQueryService" />
</bean>
In your example is right.
This way, calling the Service "listService", you would have all the methods available in the class com.kategor.myapp.sample.service.ObjectQueryService
#Controller
public class HomeController {
// This is the remote service definition
#Autowired
private ObjectQueryService<MyObject, Long> objectQueryService;
/* .... */
/**
* List all Objects retrieved through Web Service from a remote Server
*/
#RequestMapping(value = "listRemoteWS", method = RequestMethod.GET)
public String listRemoteWS(Locale locale, Model model) {
StringBuilder result = new StringBuilder();
try {
// The Remote Service is called
List objs = objectQueryService.findAll(0, 10);
result.append(objs.size() + " objs found");
for (MyObject o : objs) {
result.append("<br>* ").append(o.getId()).append(" = ").append(o.getName());
}
} catch (Exception e) {
result.append("No objs have been found");
e.printStackTrace();
}
model.addAttribute("result", result);
return "index";
}
}
So I think the problem comes from the URL: maybe the service is not visible or this is not the correct path to it.
For more information, check this links (the first is really useful):
https://github.com/JamesEarlDouglas/barebones-spring-mvc/tree/master/reference/spring-remoting
http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html
For me the problem was tomcat picked up two versions of the same applications. This raised the above error on running the client from STS in debug mode.
So solution is to clean up all the expanded webapp folders in tomcat for the application. Then redeploy the application.

Resources