Monthly Archive for March, 2006

Another Neuromancer Bug Fixed

Chris Philips found another Bug in Neuromancer today.  Computed numbers, returned as members of a struct, were always deserialized as null.  Literal numbers, however, were handled correctly.  While debugging the problem, I realized the methods with returntype="numeric" simply refused to run as well, for much the same reason.  Both glitches are now fixed.

As before, the zip on SourceForge has not been updated, though the changes are available in the Subversion repository.  I've included a patch below for js/io/RemoteObject.js that you can use to get the fix as well.  The patch should work with or without last night's update, but I'd recommend applying them both in order.  If you want the updated test cases, you'll have to hit the SVN repository.

Index: RemoteObject.js
===================================================================
— RemoteObject.js (revision 6)
+++ RemoteObject.js (revision 7)
@@ -24,6 +24,8 @@
var DATATYPE_STRING2 = "xsd:string";
var DATATYPE_ARRAY = "soapenc:Array";
var DATATYPE_BOOLEAN = "soapenc:boolean";
+var DATATYPE_NUMBER = "soapenc:double";
+var DATATYPE_NUMBER2 = "xsd:double";

/**
* Variable: REMOTE_OBJECT_VERSION
@@ -74,11 +76,16 @@
//if(dItem.item(z).getAttribute("href")== null
// || typeof dItem.item(z).getAttribute("href") == "undefined"
// || dItem.item(z).getAttribute("href") == "")
- if(dItem.item(z).getAttribute("xsi:type") == DATATYPE_STRING)
+ var xsiType = dItem.item(z).getAttribute("xsi:type")
+ if(xsiType == DATATYPE_STRING || xsiType == DATATYPE_STRING2)
{
value = dItem.item(z).firstChild.nodeValue;
}
- else if(dItem.item(z).getAttribute("xsi:type") == DATATYPE_MAP)
+ else if (xsiType == DATATYPE_NUMBER || xsiType == DATATYPE_NUMBER2)
+ {
+ value = parseFloat(dItem.item(z).firstChild.nodeValue);
+ }
+ else if(xsiType == DATATYPE_MAP)
{
value = new Map();
//value = "!ref! " + dItem.item(z).getAttribute("href");
@@ -705,6 +712,10 @@
eval(__dfh__variable + " = resvalnodes.item(0).firstChild.nodeValue");
}
}
+ else if (returntype == DATATYPE_NUMBER || returntype == DATATYPE_NUMBER2)
+ {
+ eval(__dfh__variable + " = parseFloat(resvalnodes.item(0).firstChild.nodeValue)");
+ }
//}
//this is a structure (a coldfusion struct)
//else if(complextypeid != null && complextypeid.length > 1)

Neuromancer Bug Fixed

 Chris Phillips found a bug in the Neuromancer 0.6.0beta today.  If you used the RemoteObjectLoader class (recommended), instead of the raw RemoteObjectFactory (way nasty), it was impossible to create multiple remote objects on a single page, because the RemoteObjectLoader class was not thread safe.  The first remote object created was always returned by every RemoteObjectLoader, ragerdless of what remote object it was supposed to load.

Unfortunately, Rob and I are still getting the project all set up on the SourceForge system, so a new build with the fix included hasn't been released.  As such, the bug fix is only available via Subversion or via the patch file below.  Subversion instructions can be found on this page, and as they suggest, you will want to append "/trunk" to the URL listed in the command.

Since that's not very user friendly, I've included a patch for js/io/RemoteObject.js that will update an existing 0.6.0beta version with the bug fix.  Note that you want to patch just that one file, not the whole directory tree.

Index: RemoteObject.js
===================================================================
— RemoteObject.js (revision 3)
+++ RemoteObject.js (revision 4)
@@ -136,8 +136,10 @@
if(typeof async == "undefined")
async = false;
- RemoteObjectLoader.RemoteObjectFactory.setAsync(async);
- RemoteObjectLoader.RemoteObjectFactory.createObject(RemoteObjectLoader.HTTPConnectFactory.getInstance(), url);
+ this.remoteObjectFactory = new RemoteObjectFactory();
+
+ this.remoteObjectFactory.setAsync(async);
+ this.remoteObjectFactory.createObject(RemoteObjectLoader.HTTPConnectFactory.getInstance(), url);
var self = this;
@@ -143,7 +145,7 @@
checkLoaded = function()
{
- var remObj = RemoteObjectLoader.RemoteObjectFactory.getObject();
+ var remObj = self.remoteObjectFactory.getObject();
var fieldCount = 0;
for(var i in remObj)
{
@@ -160,7 +162,6 @@
this.loadInterval = setInterval(checkLoaded, 100);
}
RemoteObjectLoader.HTTPConnectFactory = new HTTPConnectFactory();
-RemoteObjectLoader.RemoteObjectFactory = new RemoteObjectFactory();
/////////////////////////////////////////////////////////////////////////////////////

Any decent IDE (cough, Eclipse, cough) will have a patch function, or you can use the command line patch utility.

Where have I been?

It's been a LONG time since I've posted, and I feel bad.  But hopefully I'll get back on track.

In the past two months, I've primarily been focused on designing new version of our main application.  For various reasons, we're moving away from CF and to a "pure" Java application.  While I'm not particularly happy to be losing such a fantastic tool, the benefits of the platform we've selected more than outweigh what CF can offer.  I'll still be CF user for a while, at least another couple years, but it'll stop being my primary tool here within a month or two.

In my personal life, the kids are growing, and they're quite happy the weather's making a turn for the better.  Lindsay's quite happy to run around in the back yard, and ride her bike out front.  Emery definitely likes the outdoors as well, and he shows it, even without any sort of verbal communication.

Hopefully I'll get back to blogging regularly, but no promises.  ; )