I am having an issue with visiting a rest url via load balanced web server (2 web servers forwarding request to two app servers). This issue does not occur when the set up is single web server to single jboss app server.
Following is the error message I see from the jBoss application server logs:
16:02:46,711 DEBUG [org.jboss.resteasy.core.SynchronousDispatcher] (http-/30.31.32.33:8080-14) PathInfo: //AppName/rest/game/userStatus
16:02:46,711 DEBUG [org.jboss.resteasy.core.SynchronousDispatcher] (http-/30.31.32.33:8080-14) Failed executing GET //AppName/rest/game/userStatus: org.jboss.resteasy.spi.NotFoundException: Could not find resource for relative : //AppName/rest/game/userStatus of full path: http://stg.testing.com//AppName/rest/game/userStatus?userId=99984029883634
at
org.jboss.resteasy.core.registry.RootSegment.matchChildren(RootSegment.java:360) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.registry.RootSegment.matchRoot(RootSegment.java:374) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.registry.RootSegment.matchRoot(RootSegment.java:367) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:315) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:173) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:118) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.1.Final-redhat-1.jar:1.0.1.Final-redhat-1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:679) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:931) [jbossweb-7.0.16.Final-redhat-1.jar:]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_37]
Following is my rest service:
package com.testing.game;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonInclude;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.log4j.Logger;
@Path("/game")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GameRest implements Serializable{
/**
*
*/
private static final long serialVersionUID = 9029403154444232148L;
private final static Logger logger = Logger.getLogger(GameRest.class);
@GET
@Path("/userStatus")
@Produces(MediaType.APPLICATION_JSON)
public UserReportStatus getUserStatus(
@QueryParam("userId") @DefaultValue("") String userId){
logger.info("received request getReportStatus " + userId);
GameService gs = new GameService();
return gs.getUserReportStatus(userId);
}
}
Following is the main content from web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:.. id="WebApp_ID" version="2.5">
<display-name>AppName_Axis1</display-name>
<!-- Auto scan REST service -->
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<!-- this need same with resteasy servlet url-pattern -->
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<display-name>Apache-Axis Servlet</display-name>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet>
<display-name>Axis Admin Servlet</display-name>
<servlet-name>AdminServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servlet/AdminServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
The result I expect is:
{"status":"Yes","dob":"01/01/1934","userName":"John Doe","reportStatus":"No"}
I receive the above correct result when making the request to the ip address of the app server like so http://30.31.32.33:8080/AppName/rest/game/userStatus?userId=99984029883634
The actual result I get when going through the load balanced web server is:
HTTP Status 404 - Could not find resource for relative : //AppName/rest/game/userStatus of full path: http://stg.testing.com//AppName/rest/game/userStatus?userId=99984029883634
I receive the above result when making the request to the web server url. http://stg.testing.com/AppName/rest/game/userStatus?userId=99984029883634
Note: I tested by assigning stg.testing.com to the web server ip address in hosts file.
Following is the setting in the httpd.conf file w.r.t the locations where the app server's name / ip address comes up.
<Proxy balancer://stgsilo stickysession=JSESSIONID>
BalancerMember http://30.31.32.33:8080/ min=10 max=100 route=node1 loadfactor=1
BalancerMember http://30.31.32.34:8080/ min=10 max=100 route=node2 loadfactor=1
</proxy>
<Proxy balancer://stgsiloadmin stickysession=JSESSIONID>
BalancerMember http://30.31.32.33:9990/ min=10 max=100 route=node1 loadfactor=1
BalancerMember http://30.31.32.34:9990/ min=10 max=100 route=node2 loadfactor=1
</Proxy>
ProxyPass / balancer://stgsilo/
ProxyPass /console balancer://stgsiloadmin/console
ProxyPass /management balancer://stgsiloadmin/management
ProxyPassReverse / http://30.31.32.33:8080
ProxyPassReverse / http://30.31.32.34:8080
ProxyPassReverse /console http://30.31.32.33:9990/console
ProxyPassReverse /console http://30.31.32.34:9990/console
ProxyPassReverse /management http://30.31.32.33:9990/management
ProxyPassReverse /management http://30.31.32.34:9990/management
<Proxy *BATCHJOB*>
Order Deny,Allow
Allow from 30.
Deny from all
</Proxy>
<Proxy *-WS*>
Order Deny,Allow
Allow from all
</Proxy>
I am using jboss 7.1.2 as my app server and apache as the web server. This Rest app uses a axis soap webservice client in the backend. Therefore I have axis related statements in the web.xml. I have verified that the soap client works in both cases. I am not sure if this is due to the web server issue (automatically adding 2 forward slashes before the AppName) or a jboss issue like the ones listed here , here and here I have tried the above three recommendations for jboss fixes and still have the same error. Any help identifying the cause of my error would be great.
An Update: I tried by inserting a servlet in a separate directory under the context root and the servlet is reachable from load balancer. So for now I am assuming this is a software issue and not a hardware issue. Also as org.jboss.resteasy.core.SynchronousDispatcher is invoked during the request per the logs, I am assuming that it is not a 404 but an internal redirect that is causing a double forward slash. Any help would be useful. Thanks in advance.