PDA

View Full Version : DirectCFM: A ColdFusion Server-side Stack



aconran
8 May 2009, 10:40 AM
Here is the first rendition of a simple server-side stack for the Ext.Direct protocol for ColdFusion 8. It requires the SerializeJSON function. If you are looking to use this with CFMX 6 or 7, you should look into integrating the CFJSON project (http://www.epiphantastic.com/cfjson/).

It consists of 3 files:

Direct.cfc - Ext.Direct specific logic
Api.cfm - This is the file you will include via a script src tag to auto generate the API.
Router.cfm - This is the file which will route your request.


To use:
Create a folder in your CF project, for now i will call it "servicebus". Extract these 3 files into that folder.

After all of your standard page includes for javascript and CSS, link the Api.cfm page.


<script src="servicebus/Api.cfm"></script>


Configure where your router is located in Direct.cfc:


<cfset variables.routerUrl = 'servicebus/Router.cfm' />


When your page now loads it will be creating an api descriptor in a javascript variable called Ext.ss.APIDesc.

You can configure this in the Api.cfm page:


<cfset args['ns'] = "Ext.ss" />
<cfset args['desc'] = "APIDesc" />


In order to start using Ext.Direct on the client side you will now have to add the API Descriptor as a provider within Ext.Direct.


var provider = Ext.Direct.addProvider(Ext.ss.APIDesc);


This is the generic setup, however we have not exposed any of our service CFCs yet. In order to expose a CFC, place it in the servicebus directory and add the ExtDirect meta attribute to the CFC and to each method you want to expose. For example:


<cfcomponent name="Echo" ExtDirect="true" >
<cffunction name="send" ExtDirect="true">
<cfargument name="data" required="true" />

<cfreturn data />
</cffunction>
</cfcomponent>


You will now be able to execute the Echo method after importing it (with addProvider).



Ext.ss.Echo.send('sample', function() {
// callback here...
});




CFC methods can also be marked to be handled as a form post via an ExtFormHandler attribute. This is most commonly used for things like file uploads. For example:


<cfcomponent name="File" ExtDirect="true">
<cffunction name="add" ExtDirect="true" ExtFormHandler="true">
<cfargument name="formfield" required="true" />
<cfset var file = '' />
<cffile action="upload" filefield="#arguments.formfield#" result="file" destination="#expandPath('data/')#" nameConflict="MakeUnique"/>
<cfreturn file />
</cffunction>
</cfcomponent>


Note here that we needed to specify what the name of the formfield is when we upload. This is a CF specific issue which was detailed a ways back by Ben Nadel I think... I'll try to find the blog entry.

aconran
8 May 2009, 2:24 PM
The blog entry which I referenced above was actually an entry by Sean Corfield that can be found here: http://corfield.org/blog/index.cfm/do/blog.entry/entry/File_Upload_and_CFCs

brookd
12 May 2009, 12:42 PM
I am using AJAXCFC to be able to call CFC's directly from within EXT. The syntax is more verbose, are there any other major differences that you know of?

A simple AjaxCFC call looks like something like this:



jQuery.AjaxCFC({
url: "/adapter/coreAdapter.cfc",
method: "keepAlive",
data: {loadClientData:true},
serialization: "json",
debug:false,
useDefaultErrorHandler: false,
success: function(result){

}
});

kanntronics
12 May 2009, 5:23 PM
I think DirectCFM is purposely for Ext.Direct stuff..

To make a simple ajax request to cfc, you can do like this:



Ext.Ajax.request({
url: 'data.cfc',
method: 'post',
params: {
method: 'cfcFunc',
param1: 'val1'
},
success: function(r){

},
failure: function(r){

}
});

dawesi
12 May 2009, 5:43 PM
I have two questions regarding this:

1) In ColdFusion terms, why wouldn't you use an ajaxProxy (I use a homegrown version) instead of your router?

2) Secondly, if you have an intranet app, you may have hundreds of exposed methods for a business object. Does this mean all of them are written to the javascript file?

dawesi
12 May 2009, 5:45 PM
3) Why wouldn't you just wrap the whole lot into extdirect.cfc?

4) At what level would you apply your security context, as some people may not have permission to various pages, so you would have to then remove objects referencing items you don't want people to see. Also sometimes you don't want people to know every method that is available, you then need to create a security proxy for the server-side code? How would you suggest going about this.

kanntronics
12 May 2009, 11:39 PM
4) At what level would you apply your security context, as some people may not have permission to various pages, so you would have to then remove objects referencing items you don't want people to see. Also sometimes you don't want people to know every method that is available, you then need to create a security proxy for the server-side code? How would you suggest going about this.

Just share some thought..

security context should be managed at server side code.. in my application, I manage the security in Application.cfm; any access to cfm or cfc must passed the Application.cfm authentication via <cflogin>.

in my case, i don't care if all my method exposed @ client side as long they cannot access it. By looking @ DirectCFM code, only component / function with 'ExtDirect' attribute will be exposed to the client

Cheers.. ~o)

dawesi
13 May 2009, 2:24 AM
@kanntronics... you should care... exposed methods are an attack surface.

ah... ExDirect attribute... if only I used tags instead of script...bummer... unusual way to generate code reading the file structure tho.. would be fairly slow, but I guess it is cached by the browser

aconran
13 May 2009, 6:47 AM
I am using AJAXCFC to be able to call CFC's directly from within EXT. The syntax is more verbose, are there any other major differences that you know of?


brookd -

DirectCFM was created to integrate with Ext.Direct and therefore works very well with all of the Ext components and the Ext.data package. Check out the Ext.Direct blog entry (http://extjs.com/blog/2009/05/13/introducing-ext-direct/) which we posted this morning which may explain more about direct.

I'm not that familiar with AjaxCFC, but had used cfajax several years ago which was Rob Gonda's original project circa 2005. A few added benefits of DirectCFM:

Ability to execute methods like 'normal' Users.getUsersByGroupId(462)
Intrinsic Batching, calls will be batched together in a single request
Support for file uploading - does ajaxCFC support this?
Integration with Ext

aconran
13 May 2009, 6:52 AM
I have two questions regarding this:
1) In ColdFusion terms, why wouldn't you use an ajaxProxy (I use a homegrown version) instead of your router?

The router is essentially a custom ajaxProxy which supports things like batching, file uploading, etc



2) Secondly, if you have an intranet app, you may have hundreds of exposed methods for a business object. Does this mean all of them are written to the javascript file?

No! Components/Methods which are marked with a custom attribute of ExtDirect will be exposed via the API. This is how you can configure methods to be exposed.

In terms of security there should be an additional check on the server-side in the Direct.cfc's invokeCall method to ensure that the component you are invoking has the ExtDirect attribute and so does the method.

aconran
13 May 2009, 6:58 AM
3) Why wouldn't you just wrap the whole lot into extdirect.cfc?
Most of the functionality is wrapped inside of Direct.cfm. Initially i had this implemented as a single Application.cfc file which you could drop inside a "service" directory and then it handled all sorts of things such as security etc. However, I thought that this would be too limiting to many users and refactored it into the 3 file structure it is now.



4) At what level would you apply your security context, as some people may not have permission to various pages, so you would have to then remove objects referencing items you don't want people to see. Also sometimes you don't want people to know every method that is available, you then need to create a security proxy for the server-side code? How would you suggest going about this.

You can customize what is sent down to the client via any application specific logic that you want. This could be a new custom attribute such as a Role like "Administrator", "Moderator", "User" or it could be something more fine grained such as the users userId and a complex set of permissions that are stored in a db/file system/web service call somewhere.

Perhaps this would be best done by allowing users to provide a filter in Direct.cfc getAPIScript immediately before outputting the API spec. What do you think?

EDIT: As I posted above the invokeCall method in the CFC should be checking to make sure that ExtDirect attribute is set on both the CFC and Method.

As another poster mentioned all of your other security constraints should be handled at the server-side just like we've done in the past in a typical Ajax app.

jvrozier
13 May 2009, 1:02 PM
How about a small grid example. Please. Is CFQueryReader.js no longer needed to return json from a cfquery cfc ?

CutterBl
14 May 2009, 1:45 PM
@Jvrozier - I'll be looking at that this weekend, since I just put out a new version of the CFQueryReader. Haven't had a chance to look at all of this in depth yet, but I did see a mention of SerializeJSON(), which would mean your CF methods weren't portable, allowing you to use them throughout your application (direct method call within a cfm or other cfc, for instance).

CutterBl
15 May 2009, 7:24 AM
I've completely read through Aaron's code, and stepped through the processes laid out by each of the individual templates.

I'm not sure how I feel about the way the API is constructed, and feel it may be better to use a different method of constructing the descriptor. Something akin to how you might do it with ColdSpring I think would work better. Since this would be run on a page request, it would be nice to have the data in some type of persistent scope, so that you're only looping your file structure once on application or session startup. I'm also not sure about a .cfm being used as the router. I guess that could be changed, as it is a config option within your Direct.cfc. All of this is another discussion.

Direct is used for pushing data to, and getting data from, the server. Aaron's script is automatically serializing the ColdFusion struct into a JSON object, so you wouldn't need to utilize the returnFormat: 'JSON' attribute any longer within your baseParams. For reading queries into a Store, you would need to use the latest version of CFQueryReader v1.1 (http://blog.cutterscrossing.com/index.cfm/2009/5/13/CFQueryReader-v11), as you would need the ability to set your 'root' attribute for the location of any CF Query return object, which isn't part of the original CFQueryReader.

aconran
18 May 2009, 6:28 AM
I've completely read through Aaron's code, and stepped through the processes laid out by each of the individual templates.
Glad to see some people looking through the code! :D


I'm not sure how I feel about the way the API is constructed, and feel it may be better to use a different method of constructing the descriptor.

This is simply meant to be a reference implementation demonstrating to ColdFusion developers how they can integrate it into their own environments. It is simple on purpose. :D



Since this would be run on a page request, it would be nice to have the data in some type of persistent scope, so that you're only looping your file structure once on application or session startup.
This is how I initially implemented it and cached it in the application scope. (This code actually goes a couple years back and was originally used in CFMX 6.1 w/ the CFJSON project.) One thing you need to be aware of when caching your API is that an application cache provider will not work for all environments. For example say you have user/role based security then a session provider cache would probably be a better implementation.

Tommy has a good approach for this in his Altenative PHP Direct Stack (http://extjs.com/forum/showthread.php?t=68186) that allows you to implement CacheProviders. I'd love to see someone take the DirectCFM and run with it!

CutterBl
18 May 2009, 6:35 AM
Yeah, that's kind of where I thought you (Ext) was going with these server-side stacks. That's the same comment I made a few minutes ago here:

http://www.sporcic.org/2009/05/extdirect-miss/ (http://www.sporcic.org/2009/05/extdirect-miss/)

I hope to get some time to look a bit closer in the future, but I do have a new project I'm working on;)

CutterBl
27 May 2009, 7:44 PM
Hopefully Aaron is watching this thread, and maybe could speak to what I'm seeing.

I successfully setup the API and Router config, and was able to make a request. I then tried to setup a DirectStore using the CFQueryReader.



var provider = Ext.Direct.addProvider(com.cc.APIDesc);

// This is the Field Definition to be used by the CFQueryReader of each Store
var fieldDef = [
{name:'city', type:'string'},
{name:'state', type:'string'},
{name:'zip', mapping:'postalcode', type:'string'},
{name:'email', type:'string'},
{name:'phone', type:'string'},
{name:'fax',type:'string'},
{name:'thepassword',type:'string'},
{name:'artistId', type:'int'},
{name:'firstName', type:'string'},
{name:'lastName', type:'string'},
{name:'address', type:'string'}
];

var sds = new Ext.data.DirectStore({
storeId: 'Standard',
directFn:com.cc.testProxy.getAllStandard,
reader: new Ext.data.CFQueryReader({
id:'artistId',
root:'result'
},fieldDef)
});
sds.load();


When running the code, I see that the request is made of the Router, and gets a valid response array.



[{"method":"getAllStandard","tid":2.0,"action":"testProxy","type":"rpc","result":{"COLUMNS":["ARTISTID"
,"FIRSTNAME","LASTNAME","ADDRESS","CITY","STATE","POSTALCODE","EMAIL","PHONE","FAX","THEPASSWORD"],"DATA"
:[[1,"Aiden","Donolan","352 Corporate Ave.","Denver","CO","80206-4526","aiden.donolan@donolan.com","555-751-8464"
,"555-751-8463","peapod"],[2,"Austin","Weber","25463 Main Street, Suite C","Berkeley","CA","94707-4513"
,"austin@life.com","555-513-4318","510-513-4888","nopolyes"],[3,"Elicia","Kim","2523 National Blvd","Los
Angeles","CA","90064-5134","eleciakim@newmedia.com","555-846-4613","","longtail"],[4,"Jeff","Baclawski"
,"903 Boardwalk Ave","Hollywood","FL","33021-8894","user@demodata.com","239-213-4561","239-213-7465"
,"demo"],[5,"Lori","Johnson","6462 Cowtown Rd","Pierre","SD","57501-7782","lb@bovinas.com","605-776-8461"
,"605-776-8462","nowhere"],[6,"Maxwell","Wilson","72500 MLK Blvd","Tulsa","OK","74116-4613","max@mypaintings
.com","918-347-4513","918-456-1315","eyeball"],[7,"Paul","Trani","3320 Fashion Dr","New York","NY","10017-1231"
,"paul.trani@trani.com","212-630-5345",null,"ouchy"],[8,"Raquel","Young","1120 Presidential Ave","Atlanta"
,"GA","39901-4813","raquel@soulpaints.com","770-397-9486","770-391-8435","cmyk"],[9,"Viata","Trenton"
,"4563 42nd St","New York","NY","10012-4562","trenton.v@trenton.com","212-456-8468","212-468-8765","pillow"
],[10,"Diane","Demo","123 Demo Lane","Denver","CO",55555.0,"diane@demo.com","555-555-5555","","demo"
],[11,"Anthony","Kunovic","111 94th Ave","Aspen","CO",90809.0,"aj@ajgalleries.com","970-555-1373",null
,"overlord"],[12,"Ellery","Buntel","23 Elm St","Washington","DC",77893.0,"ellery.buntel@myart.com","637-902-7200"
,"637-300-2888","crayon"],[13,"Emma","Buntel","789 Main St","Washington","DC",77834.0,"emma.buntel@myart
.com","637-930-2999",null,"bluebird"],[14,"Taylor Webb","Frazier","58 Plaza Ct","Santa Fe","NM",34453
.0,"taylor.webb@myart.com","444-333-9876",null,"icecream"],[15,"Mike","Nimer","qwed qdsa","asd da","ca"
,1321.0,"me@m.com",null,null,"admin"]]}}]


What I don't see is the response ever being passed to the custom DataReader. I thought that it was because the response object was an array, but when I tried to place a console.log statement on the read() method of the custom reader, the object never appeared to be passed in to the custom reader at all.

Any ideas? I am using the latest (v1.1) version of CFQueryReader, which works fine under a normal Ext.data.Store with Ext 3.0. I'm fighting Direct right now.

kanntronics
27 May 2009, 8:15 PM
Hi Steve, just fyi, I successfully setup DirectCFM with your CFQueryReader 1.1 without any issues.. here my config:



store: new Ext.data.DirectStore({
autoLoad: true,
storeId: 'Standard',
directFn: Ext.ss.Data.load,
paramsAsHash: false,
reader: new Ext.data.CFQueryReader({
id:'uid',
root:'records'
},
[
{name: 'uid', type: 'int'},
{name: 'display_name', type: 'string'}
]
)
})


I think you missed the paramsAsHash config..

CutterBl
28 May 2009, 2:27 AM
@kanntronics

Sweet! I didn't think that the paramsAsHash attribute was required. Dropped it in and away we go:)

And please, call me Cutter. Only my mom calls me Steve;)

CutterBl
28 May 2009, 2:32 AM
Small error I found yesterday within Direct.cfc. If you define a custom namespace within Api.cfc, you expect to get that namespace for use. Within Direct.cfc, in the getAPIScript() method, you'll need to adjust line 65 from:



<cfset jsonPacket['namespace'] = "Ext.ss" />


to read:



<cfset jsonPacket['namespace'] = ARGUMENTS.ns />

aconran
28 May 2009, 5:19 AM
Glad to hear that people are up and running with this!

Cutter, I'll fix the bug you reported within Api.cfc. Is anyone interested in contributing to DirectCFM? I could put it up on RIAForge.

CutterBl
28 May 2009, 5:34 AM
@aconran

Yeah, I'm updating my CFQueryReader examples using Direct. Want to put together a quick paging grid example for people. I think putting DirectCFM up on RIAForge is a great idea, though I think you might add your Echo.cfc and example code first, to give some direction.

jimmifett
3 Jun 2009, 12:24 PM
I've heavily modified your very useful and educational stack.

The version I have acts as a stateful bean, holding a list of registered components and their exposed methods. It gets loaded into application scope. This allows the api script generation to not have to do as much work since all the component reflection is done once, yet additional components can be registered with the bean (think management console for ExtDirect cfcs).

I added an attribute to the cfcomponent tag, AllowExtDirectReflection (boolean) that is required for any component to be registered with the bean. This is to give the ability to scan directories (still under construction) and only pick up cfcs specifically designed to implement ExtDirect.

Each cffunction in a cfc will also require an ExtDirect attribute (boolean) in order for the method within the cfc to be register with the bean, as you already have. The method to register components also has 4 optional flags, allowExtDirectRemote, allowExtDirectPublic, allowExtDirectPackage, allowExtDirectPrivate. These allow the registration method to register only specific access levels and ignore methods even if they have the ExtDirect attribute. In case you want to prevent private methods and such from ppl copy pasting code around willy nilly being exposed that you didn't know about, or want to keep remote level as some sort of wrapper for a public level function. Even more useful for registering whole directories. Of course, I don't know why any sane person that would want to expose their non public or remote methods, but the option is there.

Also added was the restriction of invoking methods if that function has a Role attribute and the user does not have a valid role in that list, thus preserving application security even when exposed via Ext.Direct.

My version also checks to make sure there are sufficient arguments to atleast match if not exceed any cfargument tags with the Required attribute set. Also makes sure the are not more params than arguments.

Finally, it introduces an error handling system that i use for just about everything else. If properly implemented in cfc design, it allows very useful debug info similar along the lines of a java Exception.

Almost forgot, I also rewrote as much as inhumanly possible in cfscript and fully scoped out loose variables, type checking, and added access levels to all the code.

I have no idea where to put these up for ppl to use, any suggestions?

Application.cfc //example simple framework (a lite version of a more robust framework I use) created showing how to instantiate the bean and register cfcs

ExtDirect.cfc //replaces Direct.cfc. Still needs work for the mass recursive directory registration.

API.cfm //slight tweaks to api.cfm

Router.cfm //medium rework of Router.cfm

Example.cfc //a sample cfc showing off features

Example.cfm //test page using the above

-Jim

aconran
3 Jun 2009, 12:37 PM
Jim -

Sounds great, I'd love to see it; You should be able to attach it here on the forums for people to download or create your own thread and name it something different since it has been changed so much.

jimmifett
3 Jun 2009, 1:20 PM
I went ahead and forked it since there is considerable difference code and feature wise. It'd be confusing to others trying to follow both pieces of code.

http://extjs.com/forum/showthread.php?t=70264

Thanks again. This was a great introduction to the underpinnings of Ext.Direct.

srconklin
31 Jul 2009, 6:03 PM
Do you have any samples of this working in conjuction with a ColdBox Application?
thanks

TomChiverton
29 Oct 2009, 3:31 AM
I had to make a few minor mods to get this to run under the Railo CFML engine.
Router.cfm needs to check for the absence of the form variables in it's first CFIF, and Direct.cfc's invokeCall() needs to scope all references to the 'request' argument.

Patch attached.

Gjslick
11 Dec 2009, 3:06 PM
Hey Aaron, first off, thanks for your example CF stack code. I'm currently putting together a simple application instantiated rendition of it, to save on the introspection step, and to cover CFC's in sub directories. Didn't want to go quite as far as jimmifett's version (although nice job Jim), but still wanted good performance on the requests for the API, and the ability to keep my components in the packages that they're currently in.

Was wondering about something though. What made you decide to get the request's post body the way you did?


<cffunction name="getPostBody" returnType="string" output="false">
<cfscript>
var size=GetPageContext().getRequest().getContentLength();
var emptyByteArray = createObject("java", "java.io.ByteArrayOutputStream").init().toByteArray();
var byteClass = createObject("java", "java.lang.Byte").TYPE;
var byteArray = createObject("java","java.lang.reflect.Array").newInstance(byteClass, size);
GetPageContext().getRequest().getInputStream().readLine(byteArray, 0, size);
createObject('java', 'java.lang.System').out.println("{GetJSONRequest} ByteArray.ToString=" &ToString( byteArray ) );
return ToString( byteArray );
</cfscript>
</cffunction>
Instead of doing something simple like this:


<cfset postBody = toString( getHttpRequestData().content )>
Any reason? Performance? Yours works in more situations? (Possibly didn't know about getHttpRequestData?) Was basically wondering if I needed to include that code in my final version or not.

Thanks man, and appreciate it.

-Greg

aconran
11 Dec 2009, 3:37 PM
That looks much simpler! That bit of code to pull the body of a post was written several years ago.

I used it on a CFMX 6.1 project and I knew that it worked :)

Looking forward to seeing your implementation!

Gjslick
11 Dec 2009, 4:44 PM
Well that answers that question! lol

Alritey, I'll post my code when I'm done. I'm actually almost finished, just gotta work around an issue with ColdSpring's AOP templates not parsing correctly (for all you ColdSpring users, myself included B)), and then test it out a bit. I'll try to put it up in the next day or so.

Thanks again,

-Greg

Gjslick
13 Dec 2009, 3:38 PM
Hey Aaron, just posted my application instantiated version of the stack. It's located here: http://www.extjs.com/forum/showthread.php?p=418346. It was really originally just for the implementation of my site, but I tried to make customizable enough for others as well. Anyway, take a look and let me know what you think :)

Thanks again for your great example stack btw, really got me going on this.

-Greg

TomChiverton
18 Dec 2009, 6:11 AM
I ran over my project recently with the VarScoper tool, and it found a few missed vars.

Patch attached.

vs0uz4
9 Jul 2012, 4:06 PM
Dear Aaron Conran,


In version v0.1 DirectCFM, when I run the code on a server Coldfusion 9 it is returning the following exception:


18:08:23.023 - java.lang.NegativeArraySizeException - in C: \ wamp \ www \ cfdirect \ ServiceBus \ Direct.cfc: line 13


The line in question is the following:
var byteArray = CreateObject ("java", "java.lang.reflect.Array"). newInstance (byteClass, size);


The DirectCFM be incompatible to the ColdFusion 9?


Sincerely,
Vitor Rodrigues S

CutterBl
11 Jul 2012, 2:51 AM
Vitor,

I'm not sure what is causing your issue, but it isn't CF 9 itself. I wrote the Ext Direct chapter of Learning Ext JS 3.2 using ColdFusion 9 for the sample code, and all worked well. You may want to look deeper, like did you add the custom attributes to your component and methods?

vs0uz4
11 Jul 2012, 3:33 PM
CutterBi,


Excuse me, the problem was lack of attention. The path was wrong.


It worked perfectly now, and I noticed that not all the original files on Aaron Conran run directly in browser.


When you run the link http://localhost/cfdirect/servicebus/Api.cfm the return of the browser:


Ext.ns('Ext.ss');Ext.ss.APIDesc = {"url":"servicebus\/Router.cfm","namespace":"Ext.ss","type":"remoting","actions":{"echo":[{"len":1,"name":"send"}],"gridExample":[{"len":1,"name":"addGame"},{"len":2,"name":"updateGame"},{"len":1,"name":"deleteGame"},{"len":4,"name":"getGames"}]}};

When you run the link http://localhost/cfdirect/servicebus/Direct.cfc, I'm redirected to the CFCExplorer Coldfusion Application Server.


And when running http://localhost/cfdirect/servicebus/Router.cfm link, I get the following message:



Error Occurred While Processing Request













The error occurred in C:\wamp\www\cfdirect\servicebus\Direct.cfc: line 10




8 : var emptyByteArray = createObject("java", "java.io.ByteArrayOutputStream").init().toByteArray();9 : var byteClass = createObject("java","java.lang.Byte").TYPE;10 : var byteArray = createObject("java","java.lang.reflect.Array").newInstance(byteClass, size);11 : GetPageContext().getRequest().getInputStream().readLine(byteArray, 0, size);12 : createObject('java', 'java.lang.System').out.println("{GetJSONRequest} ByteArray.ToString=" &ToString( byteArray ) );





Resources:

Check the ColdFusion documentation (http://www.adobe.com/go/prod_doc) to verify that you are using the correct syntax.
Search the Knowledge Base (http://www.adobe.com/go/prod_support/) to find a solution to your problem.





Browser
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11


Remote Address
127.0.0.1


Referrer
http://localhost/cfdirect/servicebus/


Date/Time
02-Jul-12 08:30 PM







Stack Trace


at cfDirect2ecfc1912446458$funcGETPOSTBODY.runFunction(C:\wamp\www\cfdirect\servicebus\Direct.cfc:10) at cfRouter2ecfm1678883259.runPage(C:\wamp\www\cfdirect\servicebus\Router.cfm:33)


java.lang.NegativeArraySizeException at java.lang.reflect.Array.newArray(Native Method)






My development environment is as follows:
- 2.40GHz Core I3
- 4GB DDR3
- 1 TB SATA HD
- Windows 7 64 Bit
- Coldfusion 9 64 Bits
- Apache 2.2.21


Does it have any problem in this environment or Router.cfm can not really be directly accessed?

Tuminh112
28 Feb 2014, 1:05 PM
I am fairly new to ExtJs but want to get a better understanding of Ext.direct for CFM use. I downloaded the zip file and followed the instruction but i'm getting a error.
Uncaught TypeError: Cannot read property 'APIDesc' of undefined

Can anyone help elaborate on this ?


Thanks!

blomasky
1 Mar 2014, 9:46 AM
I tweaked some work that was done with others. Give me your email and I will be happy to zip up a folder with all that you need (including example CFCs). It's Easy-Peasy. Just have to add one file in a resource (assume you are using Architect.)

Bruce