<< Will the BEA Acquisition Push Spring Framework? | Home | The Advantage of Being Non-Agile >>

The specified call count is not a number: null

Acegi + DWR + IE6 - ActiveX = Boom!

Today we had an interesting bug in a small web application developed for a customer in the financial industry. The application is based on the Spring Framework, secured by Acegi Security and makes heavy use of AJAX (powered by DWR).

Everything went fine while testing with different browsers from Firefox to Safari and Internet Explorer in different versions. Finally we have started testing in the target environment - well locked down and without support for ActiveX controls from untrusted sites. IE6 needs ActiveX for its implementation of XMLHttpRequest (XHR) - the heart of AJAX. If XHR is not available DWR automatically switches to using IFrames to emulate XHR. This usually works well and has already been used in the previous version. Nevertheless the application just didn't work: Every remote call failed with a not so user friendly error message: "The specified call count is not a number: null".

Remote debugging of Tomcat showed that DWR is trying the read the request data using req.getInputStream() to parse it. When using IFrames reading from the request's input stream fails immediately and returns null, when using XHR it works fine. The main difference is the content type of the requests "application/x-www-form-urlencoded" for IFrames and "text/plain" for XHR. As IFrames do work without Acegi but fail with the Acegi filters in place I guess Acegi does mess with the requests when it wraps them in its SavedRequestAwareWrapper.

I didn't have the time to further track it down, but I created a small workaround that falls back to using req.getParameter() if reading the stream fails.

The following snippet shows the modification made to DWR's ParseUtil.java:


in = new BufferedReader(new InputStreamReader(req.getInputStream()));

while (true)
{
    String line = in.readLine();

    if (line == null)
    {
        if (paramMap.isEmpty())
        {
            Enumeration nameEnum = req.getParameterNames();
            while(nameEnum.hasMoreElements())
            {           
                String name = (String) nameEnum.nextElement();
                paramMap.put(name, req.getParameter(name));
            }           
        }
        break;      
    }
...

And who is to blame? Well, as with many interesting problems that's hard to decide. It's just a combination of multiple pieces of software mixed with environment constraints. I guess it's something that just happens and reminds us that testing is not useless.

Update 2008-02-22

Joe has just released DWR 2.0.3 that includes a fix for this issue.



Re: The specified call count is not a number: null

Thanks for the working digging into this. I agree that it's not easy to work out who got it wrong. Deep down we're all working around issues with how poorly the web itself is defined, so I think that's where the problem lies.

Anyway I've added some similar code that should go into DWR 2.0.3 and DWR 3.

Joe.

Re: The specified call count is not a number: null

I'm forcing the same problem using DWR 2.0.3 with a similar message "The specified call count is not a number".

I found a bug reported about this issue for release 2.0.3 on DWR JIRA and it still open

Re: The specified call count is not a number: null

Hi,
Very good post. Helped me to solve my problem with testing Web Application. While sending the request-XHR(using httpunit) server response was always 'The specified call count is not a number'. However change of header field 'Content-Type' from 'application/x-www-form-urlencoded' to 'plain-text' solved the problem.  Hope this helps someone who is testing web applications powered by Ajax.

Re: The specified call count is not a number: null

Hi,
I am facing the same problem in my application and
the problem is not consistent. I am using DWR version 2.0.5.

The snippet shown above is there in the source code (DWR version 2.0.5).

Re: The specified call count is not a number: null

We too had this problem... setting the content type to text/plain also did not help.

Here is what we found :

# "callCount" basically represents the no. of DWR function calls the client is requesting.

# this info is required by DWR so, it can construct a list of calls and execute them one after the other.

# dwr gets the inputstream on the request and reads each lines.. it expects to get parameters and their values like "callCount=1", "scriptName=DiscountCalculator", "methodName=calculateDiscount", "httpSessioId=FH65865GHFG" etc.  each time it reads a line (a parameter=value pair).

# in our case the whole string went in as one line "callCount=1scriptName=DiscountCalculatormethodName=calculateDiscounthttpSessioId=FH65865GHFG"....

# so, dwr thought that the value for parameter "callCount" was "1scriptName=DiscountCalculatormethodName=calculateDiscounthttpSessioId=FH65865GHFG"... which obviously, is not a number. so this exception.

#  The other thing that one can do is, add a "&" between "parameter=value" pairs. dwr understands that as well and will work fine. like "callCount=1&scriptName=DiscountCalculator&methodName=calculateDiscount&httpSessioId=FH65865GHFG"

Hope understanding this will help you resolve the problem you are facing.

Re: The specified call count is not a number: null

<span class="unauthenticated" id="comment1237340013378.author">Hi Shrikanth,

Can you please let me know how to get the handle of the request in DWR in order to add '&' as suggested by you in above thread

Thanks,
Mandar
</span>

Re: The specified call count is not a number: null

We experience the same error, however intermittent and have no test case so far to force it.

We use Jive Clearspace which uses inside DWR, running on Suse Linux (VMware) and Tomcat in a cluster of two servers. Stopping one as mentioned in DWR discussions didn't help.

Any suggestions how to isolate to area causing the problem?

~Wolfgang

Add a comment Send a TrackBack