I am struggling for last two days to expose a service using HttpInvokerServiceExporter. The error says Did not receive successful HTTP response
The complete stack trace is below for details. The code is checked in Git repo. Link is - Github link
org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [http://localhost:8080/spring-remoting/AccountService]; nested exception is java.io.IOException: Did not receive successful HTTP response: status code = 500, status message = [Internal Server Error]
org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.convertHttpInvokerAccessException(HttpInvokerClientInterceptor.java:216)
org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:147)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy8.add(Unknown Source)
com.remoting.ClientInvoker.getCube(ClientInvoker.java:9)
org.apache.jsp.process_jsp._jspService(process_jsp.java:118)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
java.io.IOException: Did not receive successful HTTP response: status code = 500, status message = [Internal Server Error]
org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor.validateResponse(SimpleHttpInvokerRequestExecutor.java:185)
org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor.doExecuteRequest(SimpleHttpInvokerRequestExecutor.java:92)
org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor.executeRequest(AbstractHttpInvokerRequestExecutor.java:138)
org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:194)
org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.executeRequest(HttpInvokerClientInterceptor.java:176)
org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:144)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy8.add(Unknown Source)
com.remoting.ClientInvoker.getCube(ClientInvoker.java:9)
org.apache.jsp.process_jsp._jspService(process_jsp.java:118)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
I have followed the documentation properly and have implemented all the steps. Below is the service interface:
package com.remoting;
public interface AccountService {
public int add(int a, int b);
}
Then the service implementation
package com.remoting;
public class AccountServiceImpl implements AccountService {
@Override
public int add(int a, int b) {
return a + b;
}
}
Then the web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>spring-remoting</display-name>
<!-- The front controller of this Spring Web application, responsible for
handling all application requests -->
<servlet>
<servlet-name>accountExporter</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>accountExporter</servlet-name>
<url-pattern>/AccountService</url-pattern>
</servlet-mapping>
</web-app>
Then the application beans. The application beans are placed in applicationContext.xml
and is inside the /WEB-INF/classes
directory:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<bean id="accountService" class="com.remoting.AccountServiceImpl"></bean>
<bean name="accountExporter"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="accountService" />
<property name="serviceInterface" value="com.remoting.AccountService" />
</bean>
<bean id="httpServer"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:8080/spring-remoting/AccountService"></property>
<property name="serviceInterface" value="com.remoting.AccountService"></property>
</bean>
</beans>
Now to invoke the service I have two jsp files and a helper class to load the beans and invoke the function:
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="process.jsp">
Enter Number:<input type="text" name="number" /> <input type="submit"
value="cube" />
</form>
</body>
</html>
process.jsp
<jsp:include page="index.jsp"></jsp:include>
<hr/>
<%@page import="com.remoting.ClientInvoker"%>
<%
int number=Integer.parseInt(request.getParameter("number"));
out.print("sum of "+number+" is: "+ClientInvoker.sum(number));
%>
Finally the ClientInvoker
class
package com.remoting;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClientInvoker {
public static int sum(int number){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
AccountService service = (AccountService)context.getBean("httpServer");
return service.add(4, 4);
}
}
The applicationContext.xml is placed inside the /WEB-INF/classes
directory.
Please let me know where I am going wrong.
I know it's an old question, but today I stumbled upon the same error occurring in HttpInvokerClientInterceptor
. In my case, the cause was two different Java object versions used by the server and the client. As Spring's HTTP invoker uses Java object (de)serialisation, make sure that server and client are using the same version of objects/classes.
Referring to this question, it can also mean to just use the same serialVersionUID
and different classes.