I'm using DWR at work and it's an excellent tool for AJAX (easily doing RPC from the client browser in JavaScript back to the Java Server). It also has good enough integration with Spring, which is a plus.
But for quite some time, we've had errors popping up in our logs every time we sent a JavaScript object to over DWR. The errors would look something like this:
2007-03-07 03:56:14,783 [ERROR] InboundVariable - Found reference to variable named 'c0-e6', but no variable of that name could be found.
To keep a long story short, if you happen to use the prototype.js library, it adds a function called 'extend' to the prototype of Object, so all objects have it. For some reason, DWR tries to marshal that 'extend' function as a property, but fails (it's a function), the the POST request that DWR sends, the 'extend' property is specified, but doesn't have a corresponding value.In our case, we didn't acutally use prototype at that point, so we removed the
<script src="prototype-x.y.x.js"> from our JSP pages and the error was gone. If you need to fix this problem, but want to keep using prototype.js, you'll probably have to remove the 'extend' property from objects you send using DWR (or set the property to null).
BTW, if you ask me - it's a bug in DWR, since functions should not be marshaled. I'm using DWR 1.1.3, so this might have been fixed in 1.1.4, but I didn't see too much information about this using the almighty search engine.
How the problem was found
I used the LiveHttpHeaders extension for FireFox, and captured a DWR call. It seems very straightforward:
POST /Console/dwr/exec/XXXSearch.handleAddOrUpdate.dwr HTTP/1.1The request reminded me that DWR calls can be batched (hence the callCount field), and all the c0-{name} arguments describe call number 0, I assume I would have seen c1-{name} if I had more calls in this request.
Host: localhost:8085
User-Agent: Mozilla/5.0 (...) Gecko/20070216 Firefox/1.5.0.10
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9...
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Content-Type: text/plain
Content-Length: 393
Cookie: JSESSIONID={don't tell}; Country=US; Language=en
Pragma: no-cache
Cache-Control: no-cache
callCount=1
c0-scriptName=XXXSearch
c0-methodName=handleAddOrUpdate
c0-id=8297_1173264435303
c0-param0=boolean:false
c0-e1=number:1
c0-e2=string:session.5
c0-e3=boolean:false
c0-e4=string:1
c0-e5=string:orcl
c0-param1=Object:{currRow:reference:c0-e1, factory:reference:c0-e2,
orCondition:reference:c0-e3, cond:reference:c0-e4,
values_0:reference:c0-e5, extend:reference:c0-e6}
xml=true
I've also sent two parameters. The first (co-param0) is a boolean. The second (c0-param1) is complex, so it references other entries in the request, called c0-e{num}.
It's easy to see that 'extend' references 'c0-e6', that doesn't exist in the request.
I didn't know why 'extend' was there - I didn't send it, so I tried a short HTML with a DWR request, and indeed, it didn't send an 'extend' as part of the object I sent. Now, it was obvious this is done by one of the many JS files included in our real application page, and a quick search revealed the offender.