springspring-remoting

Using HttpInvokerServiceExporter giving 500 error code


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.


Solution

  • 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.