Announcement Announcement Module
Collapse
No announcement yet.
Concurrency Problem consuming Axis WS with JaxRpcPortProxyFactoryBean in Spring 1.2.8 Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Concurrency Problem consuming Axis WS with JaxRpcPortProxyFactoryBean in Spring 1.2.8

    Hi, I don't know if I am missing something but when I concurrently invoke a web service via JaxRpcPortProxyFactoryBean I get a strange exception telling me that

    "Number of parameters passed in doesn't match the number of IN/INOUT parameters from the addParameter() calls"

    This is definetely a concurrency problem since I don't have this problem when not accessing simultaneously this web service. Besides, I have implemented my own JaxRpcProxyFactoryBean with axis client which works fine.

    Surprisingly for me, I have searched google, these forums and haven't found any commentaries on this issue. If this is not correct, I apologize and ask for reference material on this issue.

    If this is an unkown issue, I can provide a proof of concept and the implemented workaround.

    Thanks to you all!

    Nacho G. Mac Dowell

  • #2
    Same problem without response

    I have exact same problem that you are speaking of. If I use the same code directly with the Axis stubs outside of spring it works, with spring it doesn't. You said you found a work around, could you please share? I have not. I posted this same problem about 4 weeks ago and a lot of people viewed it but no one posted any support. Thank you

    Comment


    • #3
      Same problem

      Indeed - if there is a workaround, I would truly appreciate any details that can be provided. Thanks!

      Comment


      • #4
        Proof of concept

        Take as an example any wsdl you have available and generate the Interface.

        The following applicationContext would do:

        Code:
        <bean id="TestProxy" class="org.springframework.remoting.jaxrpc.CustomJaxRpcPortProxyFactoryBean">
            <property name="serviceInterface">
        		<value>gov.weather.www.forecasts.xml.DWMLgen.wsdl.ndfdXML_wsdl.NdfdXMLPortType</value>
        	</property>
        	<property name="wsdlDocumentUrl">
        		<value>http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php?wsdl</value>
        	</property>
        	<property name="namespaceUri">
        		<value>http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl</value>
        	</property>
        	<property name="serviceName">
        		<value>ndfdXML</value>
        	</property>
        	<property name="portName">
        		<value>ndfdXMLPort</value>
        	</property>
        </bean>
        and the following TestCase:

        Code:
        public void test1() throws Exception {
        	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
        		new String[] { "./spring/test/applicationContext.xml" });
        	final NdfdXMLPortType proxy = (NdfdXMLPortType) context
        		.getBean("TestProxy");
        	new Thread() {
        		public void run() {
        			try {
        				proxy.NDFDgenByDay(new BigDecimal(0),
        					new BigDecimal(0), new Date(), BigInteger.valueOf(1), FormatType.value1);
        			} catch (RemoteException e) {
        				e.printStackTrace();
        			}
        		}
        	}.start();
        	Calendar end = Calendar.getInstance();
        	end.add(Calendar.DAY_OF_YEAR, 1);
        	try {
        		proxy.NDFDgen(new BigDecimal(0), new BigDecimal(
        			0), ProductType.value2, Calendar.getInstance(), end,
        			new WeatherParametersType());
        	} catch (Exception e) {
        		throw e;
        	}
        }
        This test fails with a "strange":

        javax.xml.rpc.JAXRPCException: Number of parameters passed in (5) doesn't match the number of IN/INOUT parameters (11) from the addParameter() calls

        Comment


        • #5
          Workaround

          Actually, the workaround is quite simple. Make JaxRpcPortProxyFactoryBean alwaysUseJaxRpcCall. This problem only happens with traditional RMI stub invocation. When using JAX-RPC dynamic calls, you don't have this problem.

          I have to further investigate this issue to find out where the bug actually is. When I have deeper conclusions, I will post them here.

          In the mean time, you can just roll your own CustomJaxRpcPortProxyFactoryBean which extends JaxRpcPortProxyFactoryBean and make it alwaysUseJaxRpcCall.

          So you could use:
          Code:
          package org.springframework.remoting.jaxrpc;
          
          import org.springframework.beans.factory.FactoryBean;
          
          public class CustomJaxRpcPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean
          		implements FactoryBean {
          
          	protected boolean alwaysUseJaxRpcCall() {
          		return true;
          	}
          }
          and your applicationContext would look like:

          Code:
          <bean id="TestProxy" class="org.springframework.remoting.jaxrpc.CustomJaxRpcPortProxyFactoryBean">
              <property name="serviceInterface">
          		<value>gov.weather.www.forecasts.xml.DWMLgen.wsdl.ndfdXML_wsdl.NdfdXMLPortType</value>
          	</property>
          	<property name="wsdlDocumentUrl">
          		<value>http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php?wsdl</value>
          	</property>
          	<property name="namespaceUri">
          		<value>http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl</value>
          	</property>
          	<property name="serviceName">
          		<value>ndfdXML</value>
          	</property>
          	<property name="portName">
          		<value>ndfdXMLPort</value>
          	</property>
          </bean>
          The test previously provided, now works!

          Feedback would be greatly appreciated...

          Best Regards

          Nacho G. Mac Dowell

          Comment


          • #6
            Hi,

            thought I add the little extra info we have found out about this issue as we also encountered the same problem.

            We are using Spring 1.2.5 and Axis 1.1 and dynamic proxies by extending Spring's JaxRpcPortProxyFactoryBean. To frequently repeat the problem we have a tight loop that starts 100 threads that call a trivial web service that sits on the same PC. We can see error messages such as

            javax.xml.rpc.JAXRPCException: Number of parameters passed in (1) doesn't match the number of IN/INOUT parameters (96) from the addParameter() calls

            As per earlier in the thread, if we add

            Code:
                protected boolean alwaysUseJaxRpcCall() {
                    return true;
                }
            to our JaxRpcPortProxyFactoryBean subclass the problem stops and all the highly concurrent web service calls work.

            The reason why setting alwaysUseJaxRpcCall() to true avoids the problem is that this causes that it causes a different path to be followed through the code in the Spring JaxRpcPortClientInterceptor class. With this set to false the prepare method runs the
            Code:
            code Remote remoteObj = 
            this.jaxRpcService.getPort(this.portQName, actualInterface);
            which returns an Axis Call object which is then assigned to an instance variable of the Spring class with
            Code:
            this.portStub = remoteObj;
            With alwaysUseJaxRpcCall() set to true none of the above code runs. Instead the invoke method calls
            Code:
            performJaxRpcCall(invocation);
            (rather than using the portStub instance variable) and the performJaxRpcCall method creates a Call local to the method (i.e. thread safe).

            When looking at this problem there was a message - http://mail-archives.apache.org/mod_...l.jira@ajax%3E - on the Axis mailing lists that suggested the problem was mainly in the Axis 1.1 Call class. This class does look to be non threadsafe as the overloaded createCall methods does indeed assign the created call to an instance variable but I don't believe this to be the root cause of the problem as there is only one (deprecated) method that returns the instance variable rather than returning a newly created instance and I don't think Spring calls that method.

            We haven't traced the multi threading issue all the way through the Call code. We can see addParameter methods on the Call adding (ahem) parameters and this can clearly be called from multiple threads (without alwaysUseJaxRpcCall being set to true) and hence the problem listed above. We haven't traced through to see where these are supposed to be cleared down on the Call instance as setting alwaysUseJaxRpcCall to true has solved the problems we were seeing.

            Aidan

            Comment

            Working...
            X