1 2 Previous Next 17 Replies Latest reply on Jan 30, 2009 7:47 AM by jaikiran

    Remoting 2: Servlet Invoker

    alrubinger

      I've got failing integration tests for the following construct:

      @Stateless
      @RemoteBindings({
       @RemoteBinding(clientBindUrl="http://localhost:8080/servlet-invoker/ServerInvokerServlet", jndiBinding="StatelessHttp")
      })
      @Remote(StatelessRemote.class)
      public class StatelessBean implements StatelessRemote


      Server error is:

      01:42:45,616 ERROR [STDERR] java.lang.reflect.UndeclaredThrowableException
      01:42:45,616 ERROR [STDERR] at $Proxy108.processRequest(Unknown Source)
      01:42:45,616 ERROR [STDERR] at org.jboss.remoting.transport.servlet.web.ServerInvokerServlet.processRequest(ServerInvokerServlet.java:144)
      01:42:45,616 ERROR [STDERR] at org.jboss.remoting.transport.servlet.web.ServerInvokerServlet.doPost(ServerInvokerServlet.java:177)
      01:42:45,616 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
      01:42:45,617 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      01:42:45,617 ERROR [STDERR] at
      Trimmed for brevity
      01:42:45,618 ERROR [STDERR] Caused by: java.lang.IllegalArgumentException: Unable to find operation processRequest(javax.servlet.http.HttpServletRequest,[B,javax.servlet.http.HttpServletResponse)


      My config is:

      <!-- Unified invoker (based on remoting) -->
       <mbean code="org.jboss.invocation.unified.server.UnifiedInvoker"
       name="jboss:service=invoker,type=unified,transport=servlet">
       <depends>jboss:service=TransactionManager</depends>
       <depends>jboss.remoting:service=invoker,transport=servlet</depends>
       </mbean>
      
       <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=invoker,transport=servlet"
       display-name="Servlet transport Connector">
       <attribute name="Configuration">
       <config>
       <invoker transport="servlet">
       <attribute name="dataType" isParam="true">invocation</attribute>
       <attribute name="marshaller" isParam="true">org.jboss.invocation.unified.marshall.InvocationMarshaller</attribute>
       <attribute name="unmarshaller" isParam="true">org.jboss.invocation.unified.marshall.InvocationUnMarshaller</attribute>
       <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
       <attribute name="serverBindPort">8080</attribute>
       <attribute name="path">servlet-invoker/ServerInvokerServlet</attribute>
       </invoker>
       <handlers>
       <handler subsystem="invoker">jboss:service=invoker,type=unified,transport=servlet</handler>
       </handlers>
       </config>
       </attribute>
       </mbean>


      JBossAS 5.0.0.GA has jboss-remoting 2.5.0.SP2. I've checked this out from https://svn.jboss.org/repos/jbossremoting/remoting2/tags/2.5.0.SP2/, but when running the build (just "ant" w/ no args), I get:

      -rw-rw-r-- 1 alrubinger alrubinger 1045131 2009-01-10 23:36 output/lib/jboss-remoting.jar


      AS has:

      -rw-rw-r-- 1 alrubinger alrubinger 1074220 2009-01-10 21:31 client/jboss-remoting.jar


      Additionally, I'm seeing different file sizes for ServerInvokerServlet:

      My build from tags:
      7519 01-10-09 23:36 org/jboss/remoting/transport/servlet/web/ServerInvokerServlet.class]


      AS Version (reports 2.5.0.SP2):
      8304 11-21-08 02:28 org/jboss/remoting/transport/servlet/web/ServerInvokerServlet.class


      So two questions:

      1) Do we know why ServerInvokerServlet is causing errors?
      2) Why the mismatch between the 2.5.0.SP2 artifacts in the repo and what I'm building from tags?

      This is reproducible by building AS from trunk, then:

      1) Set $JBOSS_HOME to your build of AS
      2) svn co http://anonsvn.jboss.org/repos/jbossas/projects/ejb3/trunk/testsuite/ .
      3) mvn install
      4) ant -f build-test.xml invoker-test

      S,
      ALR

        • 1. Re: Remoting 2: Servlet Invoker
          alrubinger

          Also I've used a non-unified invoker config:

          <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=invoker,transport=servlet"
           display-name="Servlet transport Connector">
           <attribute name="InvokerLocator">servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</attribute>
           <attribute name="Configuration">
           <handlers>
           <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
           </handlers>
           </attribute>
           </mbean>


          Same issues present.

          S,
          ALR

          • 2. Re: Remoting 2: Servlet Invoker
            ron_sigal

            Hi A,

            This is an amazing coincidence. I've just been working on JBPAPP-1274 "Fix JBoss Messaging and JBoss Remoting so that servlet transport can be used", for which I've been trying to get a single client to make EJB2, EJB3, and JBM invocations over the servlet transport. I've got EJB3 and JBM working, and just a couple of hours ago I was working on an EJB2 invocation. Unfortunately, the proxy is, for some reason, using the socket transport.

            Anyway, as for the jar sizes, I just built a jboss-remoting.jar with jdk1.5.0_06 and jdk1.5.0_15 and got 1047846 and 1046394 bytes, respectively, so that's a possible explanation. But there's something strange about your line numbers - they don't match what I see under https://svn.jboss.org/repos/jbossremoting/remoting2/tags/2.5.0.SP2. Don't know what's going on there.

            Here's how the servlet transport works. org.jboss.remoting.transport.servlet.web.ServerInvokerServlet gets the invocation and ServerInvokerServlet.processRequest() calls org.jboss.remoting.transport.servlet.ServletServerInvoker.processRequest(), where it's the latter method that isn't being found. When ServerInvokerServlet is initialized, it gets either the ObjectName or the InvokerLocator of the ServletServerInvoker it's supposed to use. In the latter case it gets a reference to the actual ServletServerInvoker, so I doubt you'd see an "Unable to find operation" exception in that case. If ServerInvokerServlet gets an ObjectName, then it makes invocations on an MBean proxy, which is what I guess is happening. So, the question is, what ObjectName are you initializing ServerInvokerServlet with in your web.xml file?

            Note that in Remoting 2.2.x, every ServletServerInvoker has the same ObjectName: "jboss.remoting:service=invoker,transport=servlet". But in Remoting 2.4+, the ObjectNames for ServletServerInvokers are created by

             public String getMBeanObjectName()
             {
             InvokerLocator locator = getLocator();
             StringBuffer buffer =
             new StringBuffer("jboss.remoting:service=invoker,transport=" + locator.getProtocol());
             String host = locator.getHost();
             boolean isIPv6 = host.indexOf("[") >= 0 | host.indexOf(":") >= 0;
            
             buffer.append(",host=");
             if (isIPv6)
             buffer.append("\"");
             buffer.append(locator.getHost());
             if (isIPv6)
             buffer.append("\"");
            
             buffer.append(",port=").append(locator.getPort());
             Map param = locator.getParameters();
             if(param != null)
             {
             Iterator itr = param.keySet().iterator();
             while(itr.hasNext())
             {
             buffer.append(",");
             String key = (String) itr.next();
             String value = (String) param.get(key);
             buffer.append(key);
             buffer.append("=");
             buffer.append(value);
             }
             }
            
             return buffer.toString();
             }
            


            So, for example, the ObjectName for the EJB2 servlet invoker I'm playing with right now is "jboss.remoting:dataType=invocation,host=127.0.0.1,marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller,port=8080,return-exception=true,service=invoker,transport=servlet,unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller".

            Does that help? By the way, I didn't even know there was a servlet test in the EJB3 test suite. I'll take a look at that. But not tonight. :)

            -Ron

            • 3. Re: Remoting 2: Servlet Invoker
              alrubinger

              Sorry Ron, I hadn't put a watch on this Thread until now.

              "ron.sigal@jboss.com" wrote:
              But there's something strange about your line numbers - they don't match what I see under https://svn.jboss.org/repos/jbossremoting/remoting2/tags/2.5.0.SP2 . Don't know what's going on there.


              The wrong line numbers may be due to that we had a version of ServletSocketInvoker in WEB-INF/classes of the test, and I'd copied from an older log. But after that issue was resolved, the problem I explained in the previous post persisted. Something's not lining up between the release JARs and what I can build from tags...

              "ron.sigal@jboss.com" wrote:
              So, for example, the ObjectName for the EJB2 servlet invoker I'm playing with right now is "jboss.remoting:dataType=invocation,host=127.0.0.1,marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller,port=8080,return-exception=true,service=invoker,transport=servlet,unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller".


              Just tried the ObjectName of that form from my JMX console; same IllegalArgumentException.

              "ron.sigal@jboss.com" wrote:
              By the way, I didn't even know there was a servlet test in the EJB3 test suite. I'll take a look at that. But not tonight. :)


              Great.

              We'll plan to move this out of EJB3 and into AS (as the EJB3 component responsibility ends with invoking upon the correct endpoint) once it's passing. For the time being I have this marked as a "known issue" to help us track true regressions.

              BTW we've got a Thread on this regression over here: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4201180

              S,
              ALR



              • 4. Re: Remoting 2: Servlet Invoker
                ron_sigal

                For what it's worth, I just had a successful EJB2 invocation over the servlet transport. In jboss-service.xml I have

                <mbean code="org.jboss.remoting.transport.Connector"
                 name="jboss.remoting:service=connector,transport=servlet"
                 display-name="Servlet transport Connector">
                 <attribute name="Configuration">
                 <config>
                 <invoker transport="servlet">
                 <attribute name="dataType" isParam="true">invocation</attribute>
                 <attribute name="marshaller" isParam="true">org.jboss.invocation.unified.marshall.InvocationMarshaller</attribute>
                 <attribute name="unmarshaller" isParam="true">org.jboss.invocation.unified.marshall.InvocationUnMarshaller</attribute>
                 <attribute name="return-exception" isParam="true">true</attribute>
                 <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
                 <attribute name="serverBindPort">8080</attribute>
                 <attribute name="path">unified-invoker/ServerInvokerServlet</attribute>
                 </invoker>
                 <handlers>
                 <handler subsystem="invoker">jboss:service=invoker,type=unified,transport=servlet</handler>
                 </handlers>
                 </config>
                 </attribute>
                 </mbean>
                


                and in web.xml I have

                 <servlet>
                 <servlet-name>ServerInvokerServlet</servlet-name>
                 <description>The ServerInvokerServlet receives requests via HTTP protocol
                 from within a web container and passes it onto the ServletServerInvoker
                 for processing.
                 </description>
                 <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class>
                 <!--init-param>
                 <param-name>invokerName</param-name>
                 <param-value>jboss.remoting:service=invoker,transport=servlet</param-value>
                 <description>The servlet server invoker</description>
                 </init-param-->
                 <init-param>
                 <param-name>locatorUrl</param-name>
                 <param-value>
                 <![CDATA[servlet://${jboss.bind.address}:8080/unified-invoker/ServerInvokerServlet/?dataType=invocation&marshaller=org.jboss.invocation.unified.marshall.InvocationMarshaller&return-exception=true&unmarshaller=org.jboss.invocation.unified.marshall.InvocationUnMarshaller]]>
                 </param-value>
                 <description>The servlet server invoker</description>
                 </init-param>
                 <load-on-startup>1</load-on-startup>
                 </servlet>
                




                • 5. Re: Remoting 2: Servlet Invoker
                  alrubinger

                  Thanks, will give a spin tomorrow. :)

                  S,
                  ALR

                  • 6. Re: Remoting 2: Servlet Invoker
                    ron_sigal

                    While you were off finding G-d, I got invoker-test to pass. :)

                    There's one change in servlet-invoker-service.xml:

                    <?xml version="1.0" encoding="UTF-8"?>
                    
                    <server>
                    
                     <mbean code="org.jboss.remoting.transport.Connector" name="jboss.remoting:service=connector,transport=servlet"
                     display-name="Servlet transport Connector">
                     <attribute name="InvokerLocator">servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</attribute>
                     <attribute name="Configuration">
                     <handlers>
                     <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
                     </handlers>
                     </attribute>
                     </mbean>
                    
                    </server>
                    


                    In particular, I changed the MBean name from "jboss.remoting:service=invoker,transport=servlet" to "jboss.remoting:service=connector,transport=servlet". That's the source of the "Unable to find operation processRequest(javax.servlet.http.HttpServletRequest,[B,javax.servlet.http.HttpServletResponse)" problem. ServerInvokerServlet found the "jboss.remoting:service=invoker,transport=servlet" it was looking for, but what it was finding was an org.jboss.remoting.transport.Connector instead of the ServletServerInvoker created by the Connector.

                    Also, I changed web.xml:

                    <web-app>
                     <servlet>
                     <servlet-name>ServerInvokerServlet</servlet-name>
                     <description>The ServerInvokerServlet receives requests via HTTP
                     protocol from within a web container and passes it onto the
                     ServletServerInvoker for processing.
                     </description>
                     <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class>
                     <!--init-param>
                     <param-name>invokerName</param-name>
                     <param-value>jboss.remoting:service=invoker,transport=servlet</param-value>
                     <description>The servlet server invoker</description>
                     </init-param-->
                     <init-param>
                     <param-name>locatorUrl</param-name>
                     <param-value>servlet://${jboss.bind.address}:8080/servlet-invoker/ServerInvokerServlet</param-value>
                     <description>The servlet server invoker</description>
                     </init-param>
                     <load-on-startup>1</load-on-startup>
                     </servlet>
                     <servlet-mapping>
                     <servlet-name>ServerInvokerServlet</servlet-name>
                     <url-pattern>/ServerInvokerServlet/*</url-pattern>
                     </servlet-mapping>
                    </web-app>
                    


                    so that it searches for the ServletServerInvoker by InvokerLocator instead of MBean name. Strictly speaking, that shouldn't be necessary, as long as the correct MBean name is supplied.

                    • 7. Re: Remoting 2: Servlet Invoker
                      alrubinger

                      :D

                      Just finished w/ my other tasks for the day, booting this up now.

                      S,
                      ALR

                      • 8. Re: Remoting 2: Servlet Invoker
                        alrubinger

                        That last one was the magic sauce, Ron, thanks.

                        Resolving EJBTHREE-1675, and now that it's passing this test becomes eligible for moving into AS TestSuite and out of EJB3.

                        S,
                        ALR

                        • 9. Re: Remoting 2: Servlet Invoker
                          ron_sigal

                          Who can complete:


                          He will drink his super sauce
                          And throw the bad guys for a loss
                          He will bring them in alive and kickin'


                          • 10. Re: Remoting 2: Servlet Invoker
                            formica

                            I have a question about the previous posts you have been sending.
                            You mention several time a web.xml file : where is this file located ?
                            I'm using the last JBoss 5 GA binary distribution, and I needed to add the servlet-invoker.war repository inside
                            my config/deploy directory in order to be able to declare the ServerInvokerServlet.
                            Is there a way to avoid this inside the official JBoss 5 distribution ?
                            Sorry if it is a silly question, and thanks in advance for your answers.

                            Andrea


                            • 11. Re: Remoting 2: Servlet Invoker
                              jaikiran

                              Andrea,

                              I documentation for this on JBoss-5 isn't yet available. As i mentioned in our discussion in the user forum http://www.jboss.com/index.html?module=bb&op=viewtopic&t=148787, i'll come up with a wiki for this.

                              • 12. Re: Remoting 2: Servlet Invoker
                                ron_sigal

                                For the record, there is also the wiki page "EJB, JMS and JNDI over HTTP with Unified Invoker" (http://www.jboss.org/community/docs/DOC-9632). It refers to AS 4.2, but, as far as I know (Jaikiran, correct me if I'm wrong), it's also applicable to AS 5.0.

                                • 13. Re: Remoting 2: Servlet Invoker
                                  formica

                                  Thanks Ron,I was wondering in fact at which level I could apply the instructions in the wiki.
                                  That is why I did copy the servlet-invoker.war from the jboss remoting distribution, in order to apply the instructions from the wiki and previous posts.
                                  Later on I will test also the unified-invokers, once I understood what they are ;-)

                                  Andrea


                                  • 14. Re: Remoting 2: Servlet Invoker
                                    jaikiran

                                     

                                    "ron.sigal@jboss.com" wrote:
                                    For the record, there is also the wiki page "EJB, JMS and JNDI over HTTP with Unified Invoker" (http://www.jboss.org/community/docs/DOC-9632). It refers to AS 4.2, but, as far as I know (Jaikiran, correct me if I'm wrong), it's also applicable to AS 5.0.


                                    I hadn't seen that wiki earlier. Now that i read it, i don't see much differences for JBossAS5. There are however some differences in the configurations of the servlets in the invoker.war for example the JNDIFactory configurations. In the 4.x version of this servlet, the init-param was:
                                    <init-param>
                                     <param-name>namingProxyMBean</param-name>
                                     <param-value>jboss:service=proxyfactory,type=unified,transport=servlet,target=naming</param-value>
                                     </init-param>

                                    and for JBossAS5, this has changed to
                                     <init-param>
                                     <param-name>namingProxyMBean</param-name>
                                     <param-value>jboss:service=invoker,type=http,target=Naming</param-value>
                                     </init-param>


                                    Not sure how its going to affect AS5. So if the changes to the default servlets (that come shipped with each version of AS) are left out, then yes the wiki should be applicable for AS5 too. Infact, the one i created yesterday can be termed as a trimmed down version of this one and talks only about EJB3 over HTTP and HTTPS :)

                                    1 2 Previous Next