1 2 Previous Next 24 Replies Latest reply on Oct 24, 2008 1:37 AM by ron_sigal

    Exception propagation using HTTP servlet transport on 1.4.4

    cyberax

      There's a bug in ServletServerInvoker in 1.4.4 version of remoting.

      'processRequest' methods do not support propagation of exceptions to remote clients.

      This code:

       try
       {
       // call transport on the subclass, get the result to handback
       invocationResponse = invoke(invocationRequest);
       }
       catch(Throwable ex)
       {
       log.debug("Error thrown calling invoke on server invoker.", ex);
       invocationResponse = ex;
       isError = true;
       }
      
       //Start with response code of 204 (no content), then if is a return from handler, change to 200 (ok)
       int status = 204;
       if(invocationResponse != null)
       {
       if(isError)
       {
       response.sendError(500, "Error occurred processing invocation request. ");
       }
       else
       {
       status = 200;
       }
       }
      

      sends "500 Server Error" message in response body to client. Client then tries to unmarshal this message using ObjectInputStream and fails.

      The simple fix is:
       try
       {
       // call transport on the subclass, get the result to handback
       invocationResponse = invoke(invocationRequest);
       }
       catch(Throwable ex)
       {
       log.debug("Error thrown calling invoke on server invoker.", ex);
       invocationResponse = ex;
      
       String sessionId=null;
       if (invocationRequest instanceof InvocationRequest)
       sessionId=((InvocationRequest)invocationRequest).getSessionId();
       invocationResponse=new InvocationResponse(sessionId,ex,true,null);
       //isError = true;
       }
      


      It seems to be working for me.

      Should I create JIRA bug for this issue?

        • 1. Re: Exception propagation using HTTP servlet transport on 1.

          This should be fixed with the 2.x remoting code base. Can find more info on how exceptions from server are handled by remoting client at http://labs.jboss.com/portal/jbossremoting/docs/guide/ch05.html#d0e1367.

          Have you been able to test you scenario with remoting 2.x?

          • 2. Re: Exception propagation using HTTP servlet transport on 1.
            cyberax

            I was not able to test it, because JBoss 4.0.5 doesn't support Remoting2 yet.

            BTW, it's not clear from documentation: does Remoting2 preserve exception type thrown from server?

            • 3. Re: Exception propagation using HTTP servlet transport on 1.

              Just ran the org.jboss.test.remoting.transport.servlet.ServletInvokerTestClient test (which extends org.jboss.test.remoting.transport.web.WebInvokerTestClient) with latest JBossAS 4.2.0 code base and remoting code base (see src/test/org/jboss/test/remoting/transport/servlet/readme.txt for instructions how to setup test).

              The code within WebInvokerTestClient that tests exception handling looks like:

               Object response = null;
               try
               {
               response = remotingClient.invoke(WebInvocationHandler.THROW_EXCEPTION_PARAM, metadata);
               assertTrue("Should have thrown WebServerError and not made it to here.", false);
               }
               catch (IOException error)
               {
               // having to check class name instead of just catching type WebServerError so
               // can use for backwards compatibility tests since WebServerError is new since 2.0.0.CR1.
               if (error.getClass().getName().endsWith("WebServerError"))
               {
               assertTrue(true);
               }
               else
               {
               assertTrue("Did not get WebServerError thrown as expected", false);
               }
               }
               metadata.put(HTTPMetadataConstants.NO_THROW_ON_ERROR, "true");
               response = remotingClient.invoke(WebInvocationHandler.THROW_EXCEPTION_PARAM, metadata);
               if (response instanceof Exception)
               {
               System.out.println("Return from invocation is of type Exception as expected.");
               assertTrue("Received exception return as expected.", true);
               }
               else
               {
               System.out.println("Did not get Exception type returned as expected.");
               assertTrue("Should have received Exception as return.", false);
               }
              


              This test passes when running with the servlet invoker.

              In the case of servlet invoker, org.jboss.remoting.transport.http.WebServerError is thrown (or returned for the second invocation), so the original exception thrown on the server side is not the one thrown on the client side.

              • 4. Re: Exception propagation using HTTP servlet transport on 1.
                cyberax

                 

                In the case of servlet invoker, org.jboss.remoting.transport.http.WebServerError is thrown (or returned for the second invocation), so the original exception thrown on the server side is not the one thrown on the client side.

                Yes, that was my problem - my code relies on exceptions for creating user-friendly error messages.

                For now, I just modified servlet transport to preserve exception type.

                • 5. Re: Exception propagation using HTTP servlet transport on 1.

                  Mind posting (or sending me) that modification?

                  • 6. Re: Exception propagation using HTTP servlet transport on 1.
                    cyberax

                    It's in the code of the ServletServerInvoker which I uploaded:

                     try
                     {
                     // call transport on the subclass, get the result to handback
                     invocationResponse = invoke(invocationRequest);
                     }
                     catch(Throwable ex)
                     {
                     log.debug("Error thrown calling invoke on server invoker.", ex);
                     invocationResponse = ex;
                    
                     String sessionId=null;
                     if (invocationRequest instanceof InvocationRequest)
                     sessionId=((InvocationRequest)invocationRequest).getSessionId();
                     invocationResponse=new InvocationResponse(sessionId,ex,true,null);
                     //isError = true;
                     }
                    


                    • 7. Re: Exception propagation using HTTP servlet transport on 1.
                      dlarsson

                      When will this code become available? It would also be great if the ServerInvokerServlet could set the http header NoThrowOnError to true.

                      I'm running JBoss 4.2.1 with the same problem...

                      Regards David

                      • 8. Re: Exception propagation using HTTP servlet transport on 1.
                        ron_sigal

                        Hi David,

                        A fix for JBREM-813 "ServletServerInvoker should return an exception instead of just an error message" (http://jira.jboss.com/jira/browse/JBREM-813)
                        is now available in Remoting release 2.2.2.SP2, which may be downloaded from the repository: http://repository.jboss.com/jboss/remoting/.

                        Note that to obtain the desired behavior, it is necessary to configure the Connector with the parameter "return-exception" set to "true".

                        • 9. Re: Exception propagation using HTTP servlet transport on 1.
                          martinganserer

                          Hi,

                          a stupid question! Where do I have to put the parameter "return-exception"?

                          Thank you

                          • 10. Re: Exception propagation using HTTP servlet transport on 1.
                            martinganserer

                            Well,

                            I think I have to note that I don't use something like

                            invocationResponse = invoke(invocationRequest);


                            I do have a remote EJB3 client that that works with an InitalContext. So from the developer's point of view the invocation of a remote service is completely wrapped!

                            • 11. Re: Exception propagation using HTTP servlet transport on 1.
                              ron_sigal

                              Hi Martin,

                              In $SERVER_HOME/server/default/$DEPLOY_DIR/ejb3.deployer/META-INF/jboss-service.xml, change the line

                              <attribute name="InvokerLocator">socket://${jboss.bind.address}:3873</attribute>
                              


                              to

                              <attribute name="InvokerLocator">socket://${jboss.bind.address}:3873/?return-exception=true</attribute>
                              


                              As you say, you can't access this stuff programmatically.

                              • 12. Re: Exception propagation using HTTP servlet transport on 1.
                                ron_sigal

                                Actually, that should have been, change

                                 servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet
                                


                                to

                                 servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet/?return-exception=true
                                


                                • 13. Re: Exception propagation using HTTP servlet transport on 1.

                                  Hey there,

                                  another tip after some frustrating hours of trying to get the f**ck running:

                                  Update the jboss remoting lib in the JBossAS with the current version.

                                  Sounds stupid, but it worked for me until the Eception and WebServerError thing...

                                  So at least i replaced the jboss-remoting.jar in server/default/lib in my 4.2.2GA with the release 2.4 CR1 of the jboss remoting project.

                                  After this, the
                                  ServerInvokerServlet/?return-exception=true
                                  works.

                                  Bye,
                                  Timo

                                  • 14. Re: Exception propagation using HTTP servlet transport on 1.
                                    martinschweigert

                                     

                                     <mbean code="org.jboss.remoting.transport.Connector"
                                     name="jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3">
                                     <depends>jboss.aop:service=AspectDeployer</depends>
                                     <!--attribute name="InvokerLocator">
                                     servlet://${http.rmi.host}:${http.rmi.port}/servlet-invoker/ServerInvokerServlet
                                     </attribute-->
                                    
                                    
                                     <attribute name="Configuration">
                                     <config>
                                    
                                     <invoker transport="servlet">
                                     <attribute name="serverBindAddress">${http.rmi.host}</attribute>
                                     <attribute name="serverBindPort">${http.rmi.port}</attribute>
                                     <attribute name="path">servlet-invoker/ServerInvokerServlet</attribute>
                                     <attribute name="return-exception" isParam="true">true</attribute>
                                     </invoker>
                                     <handlers>
                                     <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
                                     </handlers>
                                     </config>
                                     </attribute>
                                     </mbean>
                                    


                                    1 2 Previous Next