Friday, December 28, 2007

OT: How dreary

This is why it's so hard on some people this time of year. How can you
stay upbeat when that's the view @ 4:30pm? Maybe we should just stay
drunk until March.

Wednesday, December 19, 2007

Google r0xor5 the iPhone

If you have an iPhone and haven't visited google apps for a while, you
might want to take a look again. Goggle has mobile enabled many of
their applications. I'm actually making this blog entry while sitting
in a restaurant waiting for the bill.

They have even made google docs work in the mobile space. Cool.

And for those people that constantly bemoan the iPhone not having g3
service, I'm doing this completely through edge without an issue.

Tuesday, December 18, 2007

Fair Tax Calculator written in FLEX!

Check out the new calculator that shows how your personal wealth situation would change under the Fair Tax. While there are probably a few over zealous assumptions in there, for me it becomes obvious why I will only support Fair Tax candidates for president or congress. If you think some of their assumptions are incorrect, you can tweak them with your own figures in the last view stack/tab.

Have fun: http://www.fairtax.org/site/PageServer?pagename=calculator

Thursday, December 13, 2007

Flex Builder 3 Beta 3 - Be afraid, be very afraid

I'm hoping that another build is in the works real quick for FlexBuilder 3. The current beta is really flaky. Just switching between views in eclipse occasionally makes all controls on the screen go blank until they are reactivated. They will all come back if you move the panels or exercise the buttons, but it means that you have to move something around on your eclipse toolbar to make them show up again.

Also, all of the interesting work in the design view regarding constraint based layouts appears to have reverted back to Beta 1 or FB2 (I'm not sure which). If you wrote anything in beta 2 that used the new column and row constraints, it stills works in code, but you can't see it in action in design view. Unfortunately, working with these new types of constraints in code view is a painful exercise.

Unfortunately, I've become so confident in these last few betas that I didn't bother to save my installer for the beta 2 (mac plugin version if anybody is feeling generous). Doh!

Unsettling Flex Builder 3 Beta 3 Install

I just installed the OS X plugin version Flex Builder 3 Beta 3 that was put up on labs last night. Before I started, I ran the uninstall script from Beta 2. Everything went smoothly until the very end when I get the message that says Installation complete, but with errors, please check the log.

So I went and checked the log and for the life of me, I can't find any errors. Oh well, it seems to be running.

The second thing that was a little disturbing was that when it asked for the serial numbers for registration, it no longer likes you FB2 license and there is no place to put in your serial number for charting. I'm betting that this is what is actually supposed to happen this time. I think I read somewhere that charting is being included now in the base product. That's awesome. I think charting is one of flex's biggest selling points to non-techies. Also, I'm guessing that the serial number doesn't work this time because we're going to get the real release withing 90 days (fingers crossed).

Monday, November 26, 2007

Is the DB the chicken or the egg?

There have been a few discussions recently about whether it is better to design your new application by starting with the model or the database. Arguments about starting with requirements aside, it seems like the prevailing thought is that you should start with the model. I'm sure that this position seems like the logical approach to many programmers because of all the attention object oriented (like) programming is getting in the ColdFusion community.

I believe this to be a bit of a spurious argument. If you think about it, the model and the logical design of the db are two sides of the same coin. They both share the same primary responsibility of providing a programmatic representation of real world objects/entities. While the two are not perfectly aligned in implementation, they are extremely similar when looked at logically. Even our tools for representing them are so close as to be nearly indistinguishable to the lay person. Try putting a UML Class diagram and ER Diagram in front of a non programmer and see if they get any additional information out of one type of diagram or the other. The UML even uses a stereotyped class diagram as a tool to do database modeling (although it's not an official diagram type). We even have object-relational mapping tools to bridge the two.

I've heard the argument that the best one to start with depends on the project being undertaken. I would take this a bit farther and say that it's not so much the project being undertaken as the developer doing the design that should influence which one you start with. It all depends on your view of what these two things represent. If you think of your object model as the true arbiter of your business rules and the db is merely a persistence mechanism, then you probably should base your design on the model first. It's where you feel most comfortable translating your requirements into code. Building the db is something that you just have to do in order to persist your objects. It's grunt work.

If on the other hand, you think of the database as the primary store and final authority on your business rules and that the model is simply a communication mechanism (albeit a very robust one) necessary to support your view and controller layers, then starting from the db is probably a better approach for you.

Personally, I like to start with the db, only because to me, it feels like the "deepest" part of the application. I tend to think of the db as the foundation of an application. It seems more difficult to fix design flaws in the db than it does in the object model. It also feels like the db is slightly better at modeling real world entities simply by virtue of its persistence. Real world objects don't wink out of existence by falling out of scope, but that could be a discussion better had by philosophers.

That's my $0.02.

p.s.: Regarding the chicken and the egg question. I think that the chicken would have to have come first. My reasoning for that is that we define the type of egg by the animal that produced it. For example, if we have a hen's egg and a chuck-stritch comes out, it was and always will be a hen's egg. We couldn't have referred to it as a chuck-stritch egg since we didn't know what a chuck-stritch was until it hatched. If the chuck-stritch grows up and lays an egg, we'll always know that it is a chuck-stritch egg.

Wednesday, November 21, 2007

flex 3 Beta and FF3 Beta flakieness

After installing the Firefox beta, it seems like it picks up your existing flash player install if you had it set up with Firefox 2. All is not well, though. There must be a few files or settings that don't migrate perfectly.

I didn't notice it at first because the debug output for me was still working. It wasn't until I started working with some rollOver effects that things seemed strange. The rollover event wouldn't fire on a component unless I first clicked it.

Not to worry. If you've installed the flex 3 beta, you should have a player distribution included in your Adobe Flex Builder 3 Plug-in directory (I'm not sure where it is in the standalone install, but it's probably similar). In there, on my mac, there is a player directory, a mac directory and a few flash Player install files. I simply launched the "Install Flash Player 9 UB.dmg" file, ran through the process and tried again. Everything seems back to normal now.

Great idea for the security bound.

I know of an organization that has strict security requirements for its network and employees that has implemented a nice tool.

As we all know, if we work for a company and use their equipment, we are generally not allowed to have any expectation of privacy. IM is blocked, websites are blocked, email is blocked, cell phones disrupted, etc.

For many of us that are technically and socially accustomed to being able to contact who we want, when we want, this arrangement can really chafe. So much so that I've know good talent to look for jobs where an open information policy is a major consideration when deciding where to work.

One forward thinking organization that I know of has realized this and tried to provide at least a partial solution. While they can't open up their network because of the sensitive nature of the work they do, they put together a small network that is off their grid in a common area. They have a number of cycled out computers in their cafeteria that are not connected to the organization's network that anybody can use. They also have a wireless hotspot there (which is great for my iPhone) that the company does not monitor.

Employees can check their external email, surf the web and generally use their lunch period as their own without management snooping through the logs afterwords. Generic logins are used by everybody and are publicly posted which helps to make the idea of monitoring those machines less attractive.

What a good idea. Kudos.

Tuesday, November 20, 2007

Firefox 3 plugs over 300 memory leaks

I've been using the new Firefox beta for a whole day now and not one crash or lockup. Of course I don't have my extensions installed now either, which I suspect is usually the culprit for most problems, although the occasional mishandled piece of html seemed to be a problem every once in a while.

I like the more mac-like skin (especially in forms) in the mac version. It seesm pretty zippy, too.

The Mozilla Blog

OT: Best Political Ad Ever

Sorry for having two political posts in a row, but this just cracks me up. That has to be about the best endorsement a candidate could hope to get.

Wednesday, November 14, 2007

OT:21% In Iowa!

Fred Who? Mike Huckabee IS electable

For the hordes of Republican ColdFusion and Flex developers out there, it's nice to see someone like Mike Huckabee doing well. We know what it's like to have the best solutions to our problems and yet often remain the underdog technology/candidate. Fred Thompson seemed promising before he got in the race, but he always reminds me of Dan Akroyd as the judge in "Nothing but Trouble".

read more | digg story

Thursday, November 08, 2007

onMissingMethod clarification

I few days ago, I posted a question regarding the use of the new "onMissingMethod" capability in cf8. I was trying to put together a simple bean and utilize the onMissingMethod to create all purpose getters and setters (in my case the setters are really three methods, 2 of which I wanted to use the onMissingMethod to handle). I had a problem in that onMissingMethod would not fire if I called another method in the same component. A basic example would be calling the setter from inside the init() method in order to exercise my business rules when the object is created. Since the method didn't exist, cf would throw an error.

Thanks to Sean Corfields comment about using the "this" scope for the internal method calls, I was able to get it to work the way I wanted. While I think my particular implementation adds a bit of overhead (not due to the onMissingMethod use), I don't think it will have a huge impact, so I willing to give it a shot until it proves to be a problem.

My code is a little rough at the moment, but when I get it cleaned up a bit, I'll post a sample and probably add a template or two to cfcBlaster.

Monday, November 05, 2007

onMIssingMethod question

I've just started experimenting with the onMissingMethod capability in cf8. It looks like the function only fires when missing methods are fired from outside the component. If you attempt to call a missing method from inside, you get a message stating that your method is undefined as a variable.

This is unfortunate because it precludes me from using it as a way to replace my getter/setter functions since I use them to enforce my business rules in a roundabout way. My setters get called in my init() method to set up the object's properties. Doing this instead of just setting the property value lets me enforce any constraints on my data on the way in to the object. It looks like I can't actually use the onMissingMethod capability for a missing setter. Is this true? Is there a workaround?

Thursday, October 25, 2007

Flex2 connection debugging

Ok, so it took me way too long to find out about this. Flex2 lets you track what' s happening with your remote connections using a tool similar to the Flash Connection Debugger. All you have to do is add <TraceTarget/> after your application tag. After that, when you launch the debug version of your app, you'll see all the traffic going back and forth between flash and your remote amf technology (in my case, ColdFusion). It's a huge help when your app just seems to hang when attempting to connect to a remote service. Too bad it spits its output into the console window instead of the neat little app that ships with Flash. A collapsed panel in the debug view would do just as well. Let me know if there is one and I just haven't found it.

One thing I've noticed that I haven't found a solution for is that the information provided by the TraceTarget tag/object doesn't include information received from your remote service provider. That's going to be a problem with CF since it has a habit of doing things like changing the case of your objects properties or your code is returning a generic object when you had intended for it to be typed.

You can still see the results of the information coming back in the variables panel in eclipse using the debugging perspective, but I got used to the Flash NetConnection debugger where everything was in one place. No big deal, I'm sure we all can get used to a slightly different workflow.

Friday, October 19, 2007

flex2:TFS on my mac

I'm going to use this entry mainly as a place to mark down some of the issues I encountered going through the last third of the flex2:Training from the Source book. First, I guess it's important to describe the environment I'm working in because it's not exactly what the book was looking for.

My Environment
  • Mac book pro on OS X
  • flex 3 beta 2 (not the same as the book, but issues have been minimal. The only thing I remember being different has been a few screen shots at the beginning of the book. No big deal.
  • MySQL 5.0 beta (very stable at this point, although the gui tools occasionally abend on the mac)
  • ColdFusion 8 developer edition installed to use the embedded Apache web server on OS X
In order to finish the book, you need to set up a ColdFusion site on your local computer. The site is included on the CD that is distributed with the book, but it's inside the ColdFusion for windows zip file. I've extracted the flexGrocer CF site and updated a few of the xml files that were only found on flexGrocer.com and put a copy up on my share account. You won't have to bother with unpacking the entire ColdFusion install to get the site. Both of the folders should be unpacked to your web root. You might also want to create a cf project (using cfeclipse, of course) to point to the sites in case you need to make an edit or two.

  • page 397 - This is the first place I had to deviate from the text a bit. My local webserver uses the default port, so I was able to remove the :8300 from the httpservice entries. Also, a few of the xml files were not in my copy of the site from the cd. I was able to fetch them from the www.flexGrocer.com site and I've included them with the site download mentioned above.
  • oops. A bug in the script I posted with the db. I named a field in the unit table "uintID". I've corrected the typos (it wound up in several places) and posted the corrected file back on my share.
  • MySql uses tinyint(1) as a boolean and mssql server records boolean values as 1 or 0 (or null, but we won't take that on here). You'll need to modify the addProduct method of the productManager.cfc file on the cf website to handle booleans coming into the object with 'yes' and 'no' values. I just did a little inline iff like this: iif(arguments.aProduct.isOrganic,1,0), and the same for isLowFat.
  • Do the same thing for the updateProduct method in the productManager.cfc file as well.
  • Edit the cffile file attribute of the productManager.cfc in the ColdFusion part of flexGrocer to point to your local install of cf.
  • Edit flexGrocer(CF)/cfcs/fileUpload.cfm to point to your flexGrocer/assets directory.
  • Edit the FlexGrocer_CF_Services.xml file that is used in your flex2 compiler settings to point to your install of ColdFusion's flash services. For me, this is: http://localhost/flex2gateway/
  • Page 428: I'm not sure if this is something strange with my setup, an error I have in the code, a difference between running on a Mac vs WinTel or an issue with the book. In order for the remoting lesson to actually work for me, I had to change the Alert command in step 12 to refer to the event result as event.result.ORDERNUM. I know there have been issues with case involving coldfusion remoting in the past, and I guess this is just another instance of that. Note that the text explains that we are expecting a generic Object and not an OrderInfo instance. I think if we had an alias for the coldFusion component in our OrderInfo vo, we might be able to return a typed object and preserve the property case with the use of the cfproperty tags. If I get some time later, I'll have to look into this.

Thursday, October 18, 2007

Flex2:TFS with MySQL for OSX

Here I am, having a lot of fun working through the "Adobe Flex 2:Training from the Source" book. Some of it is a bit of a rehash for me since I've been dabbling with flex for some time, but I like the way the book takes you through pretty much one application all the way through. It helps build continuity as you work and you get to see the thing take shape. Much better than the little code snippets you get in a lot of books when you're trying to learn a new technology. Those work better when the book turns into a reference.

So here I am, about two thirds of the way through the book, getting ready for the really good bits, when the book goes all Microsfty on me. I have to install cf on windows and hook it up to an access database. Well, I'll have none of that. So I took a few hours today to build a script that would do the same job in MySQL. You can get it from my share, as well as a script to drop everything and start over. The only thing you have to know from here is that I named the schema

flex2tfs


I haven't had a chance to work with it yet, so it may be full of bugs.

You need to name your ColdFusion data source flex2.

Wednesday, October 17, 2007

Mylyn works with Google Code

I just updated my copy of mylyn to the current version and I was happy to find that it now works easily with Google Code. In order to set it up, all you have to do is add a repository for the Google Code issue page. The easiest way to do this is to select the sample server entry for Google Code when adding the repository. All the necessary fields are filled in for you to make it work. Generally all you have to do is change the url is puts in the server field to point to your specific application. You don't get the fancy edit page that you would with something like Jira, but it will pull up the appropriate web page in eclipse's web browser. Pretty cool.

Also, if you hate that mylyn removes a file from context when you close it, there is a new check box in the settings that allow you to change that behavior.

Mylyn tends to be a little buggy out of the gate, but it eventually starts working as it should for me. Sometimes I have to move around the interface a few times to get things rolling after an update.

Wednesday, October 10, 2007

DIAPER 101

I've had a number of requests to explain DIAPER a little bit more since my last post, so I thought I would put a few thoughts here.

DIAPER is just an acronym for the sections I'm using in bean/vo style ColdFusion objects. These sections are:

Define: this is just a group of cfproperty tags that provide basic documentation for the object's properties. cfproperty doesn't really do anything in a programming sense for plain cf components, so I wouldn't normally do these if I wasn't using some sort of code generator or I was planning on handing off the actual coding to someone else instead of doing it myself. They provide a nice place to do a little documentation that gets picked up by numerous cfc introspection tools.

Initialize: This is your typical init() function that you use to get your component instance started. Mine almost always just start off with a list of cfarguments that match the "D" section above with all of the properties set to be not required and with a default. Following this, all of the arguments are assigned to a structure called "instance" that is stored in the variables scope. Using a structure of property values instead of just putting them into the variables scope individually is just a way to make them a little easier to use with some inspection utilities that I tend to use.

Access: These are your typical getter/setter functions that you see in lots of cfcs to provide access to private variables/properties. With DIAPER, though, the setters are changed into a "set", a "test" and a "do". This is done primarily to support unit testing and provide a way to circumvent your business rules. The way this works is that in normal operation, we call the set function as we normally would. It then does two things: 1) tests the value that you are trying to set against any business rules you may have for this property. Normally, I use lots of regular expressions here and use cfthrow to bail out of the function if the value doesn't pass. This can also get pretty complex when you do things like compare values with other components and queries. Lastly, the "do" function actually sets the value. Also having the "do" function allows you to bypass your business rules which can really come in handy with unit testing.

Pretty simple, really, but I wouldn't want to code all of this stuff by hand if I can avoid it.

Sean Corfield made a comment about how he is using the new onMissingMethod feature of cf8 in his work now. I really like the idea of eliminating some of the clutter that all these methods tend to put in my cfcs, so look for a new template eventually that will take advantage of that approach in cfcBlaster.

Print is pretty much a developer tool that lets you spit out the content of the component quickly. It is akin to the "toString" methods you see in so many other languages.

Equals lets you test two instances of a component to see if they are equal to each other. I don't find myself using this too often, so I still am not sure exactly what the best approach here is. If you want to use it to see if you have two handles on the same instance, then I would suggest adding a guid property to your component that is populated when you creat your instance. Then you can just compare those values. If on the other hand, you have a need to check if two instances are functionally equivalent, then the approach of serializing your properties and comparing the values seems to work. This area could use a little more testing, especially when dealing with aggregates.

Run is used to return an instance of the component with reasonable values in all of its properties. This is a big help with unit testing or testing your aggregate functions where you don't want to fire things into your db. It's roughly equivalent to a method that provides you with a mock object which can be tricky to get right using some of the unit testing frameworks.

A few things to keep in mind. cfcBlaster does not do anything with aggregates. You still need to code those yourself. In the accessor section of my components you will see "add" and "remove" methods that handle those. They get used extensively in my DAOs to populate components retrieved from the db that have parent/child relationships. Note that one of the interesting disconnects between objects and rdbms systems is that I never represent a many-to-many relationship in objects. I'm always dealing with one side of that or the other, unlike how that would be represented in the db.

Another thing to keep in mind is that DIAPER is all about your business logic (ie, it lives in your model). It doesn't deal with presentation at all, so if your set up with an MVC framework, these objects don't deal with controller or view issues at all.

Wednesday, July 25, 2007

Remove auto-registered web services while you are working

One of the little annoyances I've run into while working with publishing web services in ColdFusion is that it can be tiresome to remove the auto-registered wsdl files as you test. Here is a little bit of code you can stick at the top of your test files to clear out that cache.


<cfinvoke
component="CFIDE.adminapi.administrator"
method="login"
returnVariable="administrator" >
<cfinvokeargument name="adminPassword" value="yourAdminPassword" />
<cfinvokeargument name="adminUserId" value="admin" />
</cfinvoke>
<cfinvoke
component="CFIDE.adminapi.extensions"
method="getWebServices"
returnVariable="extensions" >
<cfinvokeargument name="includeAutoRegistered" value="true" />
</cfinvoke>
<cfloop collection="#extensions#" item="webservice">
<cfinvoke
component="CFIDE.adminapi.extensions"
method="deleteWebService" >
<cfinvokeargument name="name" value="#webservice#" />
</cfinvoke>
</cfloop>

Monday, July 23, 2007

Typed arrays in cfcs

This is interesting. I was trying out the new shorthand methods of creating arrays (and structures) and I came across this strange effect.

I haven't found any docs on this yet, but it seemed like a natural extension of the array shorthand. You can now do something like this:

<cfargument name="aggregate" type="dm3.com.color[]" required="false" default="#arrayNew(1)#">

The idea is to have cf throw an error if you submit anything other than an array of dm3.com.color objects. At first, this seems to work. Great! I thought. What I later found out was that the type checking appears to only occur on the first item in the array. You can put anything you want in any position other than one and the type checking will let it go through without error.

For me, the way to prevent issues (however unlikely they actually may be) is to restrict adding and removing collaborating objects with add() and remove() methods that can enforce the object type on each element. These work pretty much the same as your simple getters and setters, but instead of dealing with a simple value, they deal with one or more objects.

--- UPDATE: Sample code to illustrate the issue
The two objects are just for illustration. You should be able to use any objects you've created that use arrays to store aggregate collections. The scribble.cfm page at the bottom is used to exercise them.


Color.cfc

*============================================================================
* Template Name: Color
* ---------------------------------------------------------------------------
* Created by: CFC Blaster
* Creation date: 07/23/2007
* Description: Color Bean
*============================================================================

<cfcomponent name="Color.cfc" output="false">
<!--- Define --->
<cfproperty name="Background" required="false" default="" type="string">

<!--- Initialize --->
<cffunction name="init" access="public" output="false" returntype="dm3.com.Color">
<cfargument name="Background" required="false" default="" type="string" />

<cfscript>
// setup
variables.instance = structNew();

// assign arguments passed in to properties
setBackground( arguments.Background );

return this;
</cfscript>
</cffunction>

<!--- Accessors --->


<cffunction name="getBackground" access="public" output="false" returntype="string">
<cfreturn variables.instance.Background />

</cffunction>
<cffunction name="setBackground" access="public" output="false" returntype="void">
<cfargument name="Background" required="true" type="string" />
<cfscript>
testBackground(arguments.Background);
doBackground(arguments.Background);
</cfscript>
</cffunction>
<cffunction name="testBackground" access="public" output="false" returntype="void">
<cfargument name="Background" required="true" type="string" />
<!--- TODO: Write business rules --->
</cffunction>
<cffunction name="doBackground" access="public" output="false" returntype="void">
<cfargument name="Background" required="true" type="string" />
<cfset variables.instance.Background = arguments.Background />
</cffunction>

<!--- Print --->
<cffunction name="print" access="public" output="true" returntype="void">
<cfdump var="#variables.instance#" />

</cffunction>

<!--- Equals --->
<cffunction name="isEqual" access="public" output="false" returntype="boolean">
<cfargument name="obj" required="true" type="dm3.com.Color" />
<cfset var private = structNew() />
<cfwddx action="cfml2wddx" input="#print()#" output="private.obj" />
<cfwddx action="cfml2wddx" input="#arguments.obj.print()#" output="private.obj2" />
<cfif private.obj eq private.obj2>
<cfreturn true />
<cfelse>
<cfreturn false />
</cfif>
</cffunction>

<!--- Run --->
<cffunction name="run" access="public" output="false" returntype="dm3.com.Color" >
<cfset var obj = createObject("component","dm3.com.Color") />
<!--- TODO: fill in reasonable values --->
<cfset obj.init(
Background = ""
) />
<cfreturn obj />
</cffunction>

</cfcomponent>


temp.cfc

<cfcomponent output="false">

<cfproperty name="TestString" type="string" default="Hi There" required="false" hint="Here is where you would write your documentation.">
<cfproperty name="TestId" type="numeric" default="99" hint="z" />
<cfproperty name="AnArray" type="array" default="0">
<cfproperty name="YsNo" type="boolean" default="false">
<cfproperty name="colorArray" type="dm3.com.color[]">

<cffunction name="init" access="public" output="false" returntype="dm3.com.temp">
<cfargument name="aggregate" type="dm3.com.color[]" required="false" default="#arrayNew(1)#">
<cfset variables.instance = structNew() />
<cfreturn this />
</cffunction>

<cffunction name="setColorArray" access="public" output="false" returntype="void">
<cfargument name="val" required="true" type="dm3.com.color[]" />
<cfset variables.instance.colorArray = arguments.val />
</cffunction>
</cfcomponent>


scribble.cfm

<cfset colorArray = arrayNew(1)>

<cfloop index="i" from="1" to="3">
<cfset arrayAppend(colorArray,createObject("component","dm3.com.color").init())>
</cfloop>
<cfset arrayAppend(colorArray,"Hi There")>

<cfset temp = createObject("component", "dm3.com.temp").init(colorArray)>
<cfdump var="#colorArray#">
<cfdump var="#temp#">


Move the "Hi There" line above the loop to see the type checking fail. Move it below the loop to see it succeed.

Thursday, July 19, 2007

cfcBlaster gets a DIAPER

I made a small update to the cfcBlaster code that has made some of the work I've been doing with unit testing a little easier.

There is a new template called bean.xslt that I put together based on the Streamlined Object Modeling DIAPER ideas. It can only handle the simple properties that you can pull out of your db. You would have to add on any/all object collaboration methods and properties by hand.

There are a few things I like about these objects. The first is that they are really well encapsulated to start with (you can certainly make them less so as you work with them). They are completely ignorant of storage. I've been pushing that functionality into the DAO/Gateway object(s). You can easily instantiate one using the scribble pad in cfeclipse and it will generally work. You don't need any supporting code to get the thing off the ground. The run method is handy because not only does it make getting a sample of the object with reasonable values really easy, it can also be used to help with the mock object issues with some of the unit testing frameworks.

Speaking of cfeclipse, while the resulting cfcs are a little large (bloated?), they do collapse up pretty nicely.

Thursday, July 12, 2007

VSS Plugin update for Eclipse 3.3

If you've been using the VSS Plugin for cfeclipse and you're looking to upgrade to eclipse 3.3, you'll find that some of the functions don't work correctly. In particular, for me, I lost the ability to inspect the file histories in vss.
VSS Plugin Patch

Kudos to Jeff Barcalow for patching the jar file and Peter Szanto for packaging up the distribution and publishing it.

Use at your own risk, though.

Monday, June 25, 2007

Security design brain teaser.

Since there is a lot of concern now about how to protect personally identifiable information in our networks, I thought I would pose a question to the community. What is the best way to protect this information in our coldFusion apps. The information I think we should be concerned about the most would be anything that could be used to compromise somebody's identity. That would include names, addresses, phone numbers, social security numbers, bank account numbers, credit card info, etc. I wouldn't include passwords in the group because they can always just be hashed.

For the rest of the list, most companies don't have a need to store the bulk of that information, but certainly names/address combinations are very common. Should that be stored in your database in an encrypted state? For eCommerce companies, the obvious encryption candidate would be the credit card information. Whatever you need to encrypt, the general strategy can pretty much be the same.

Here are three thoughts I've had about protecting this type of data:

1. Utilize the CF encryption functions that now support AES whenever storing or retrieving sensitive data. This is probably the easiest method for me, but I think it suffers from a few drawbacks. The first being that your key would be stored in your cf code. If the webserver is compromised, your password can be easily discovered. Second is that if a brute-force attack is made against your application successfully, the key is retrieved for the entire db. That seems risky to me.

2. Utilize the stored procedure and encryption capabilities of your database. MSSQL2005 and MySQL 5.x+ both include AES encryption functions. For MSSQL2000, you'd have to buy an add-on product. In this case, you would write stored procedures to handle reading and writing sensitive data that encrypted/decrypted data as necessary between the db and your user interface. I think this is quite a bit better than option 1 because we tend to protect our db servers better. Most likely, the db server will not be exposed to the web directly. The one area where this is the same as option 1 is that a single key is being used to encrypt/decrypt your data. Key rotation processes could be introduced at the db level, but they will probably cause some downtime while data is decrypted and re-encrypted with the new key. While that will narrow the window of opportunity, it still puts the db at risk of being compromised with a single key crack.

3. The last idea I had was to use a separate key, like a uuid, for each record and create a new db to act as a keystore. The benefit to doing something like this is that you can put very tight security on the keystore. There also would be no hint of how you are encrypting your data unless you were to have your stored proc code discovered (of course it would be vulnerable to certain insiders). You could also introduce key rotation procedures with this method. What I'm really worried about here is if at this point you're beginning to get diminishing returns. Are we starting to degrade our performance too much to justify the increase in difficulty to crack?

Any thoughts? Is there a developing industry standard for handling this type of information because of Sarbanes/Oxley concerns? What approach are you using?

Wednesday, June 13, 2007

Obscure cf8 error message

While doing some work on a project that is currently running on cfmx, but which I'm testing on cf8, this strange error message appeared:

coldfusion.compiler.ASTsimpleVariableReference cannot be cast to java.lang.String

If you get this message, it's basically telling you that somewhere you've passed a variable or object where a string was expected. In my case, it was with a code bug that the previous versions of cf worked with but probably should have thrown an error. What I found was an indexed loop tag with a variable being used for the index. If you think about it, that really doesn't make sense. I don't think the author meant that the actual variable name would change as the loop executed or that it needed to change based on some value passed in.

BAD
<cfloop from="1" to="#upperLimit#" index="#myIndex#">

Good
<cfloop from="1" to="#upperLimit#" index="myIndex">

What lead me to look at the loop was the stack trace that came along with the error. I don't know if anything else will cause this error, but the variable for an index string will cause it every time.

Thursday, May 24, 2007

OT: Boom!

Humbling, mesmerizing. Watching this can make a person view their life in a different light.



Anybody know what the song is?

Tuesday, May 22, 2007

Better alternating row colors

Occasionally you work something out to the point where it's good enough and you don't bother to go back and look at it again.

I thought I had done about all I could with alternating row colors by just doing a simple cfif before the rows started that picked a class for the row. It worked something like this:

--- in css file ---
.odd {background-color: #F7F7F7}
.even {background-color: #FFFFFF}

--- in code ---
<cfif myQuery.currentrow mod 2>
<cfset rowclass = "odd">
<cfelse>
<cfset rowclass = "even">
</cfif>
<tr class="#rowclass#">
STUFF
</tr>

That seems to work ok, but here is a shorter way that seems to be just a little more elegant.

--- in css file ---
.row1 {background-color:#F7F7F7;}
.row0 {background-color:#FFFFFF;}

--- in code ---
<tr class="row#CurrentRow mod 2#">
STUFF
</tr>

That seems much better to me.

Thursday, April 19, 2007

cfcBlaster update

I don't know if anybody is using this or not, but I just updated the little cfcBlaster tool our on Google Code (http://code.google.com/p/cfcblaster/).

A couple of changes:
  1. There is a new branch in the svn repository to support mySql. Since my switch to the Mac, I've also become a big MySql fan. I expect to be doing a lot more with it in the near future. (OT: You know, a few years ago, if a startup web company was trying to raise capital and they were not using one of the big enterprise databases, nobody really took them seriously. I think if I where a vc now and a start-up was NOT looking at something like mySql, I'd have trouble taking them seriously. To me, that would be money just wasted that could have been spent on developing the product)
  2. I added a few new templates that jam out some simple html from your db that support basic list and CRUD functions. Handy for just getting something put together really quickly with all the warts.
  3. I added a new template to build a test file for your generated cfcs to work with cfUnit. It doesn't do much more than just get you started.

Monday, February 19, 2007

Save up to $100 on Flex Builder 2 with Charting

If you've been here recently, you may know that I've made the switch to the Mac as my primary development computer. It has been great fun getting to learn some of the ins and outs of the new platform. One of the things I find surprising is the ease with which you can type on the keyboard. I didn't really expect to actually type faster. I'm still missing a few of the windows editing keys, but I'm sure I'll get used to their equivalents eventually.

One that that hasn't been so great is that none of my Adobe software can be transferred to the other platform even though the computer I used them on no longer exists. Bummer.

Here is my shameless plug to help unload my copy of Flex Builder:

So, if you're using windows/vista and intend to keep using it and you haven't purchased your copy of Flex Builder 2 yet, maybe we can help each other out.

I'm selling my copy of Flex Builder 2 with Charting for windows on eBay in order to raise some cash to help pay for my Mac copy. In order to entice you to pick up my used copy, I'll save you as much as $100.00; maybe more if you include sales tax and Adobe's expensive shipping.

UPDATE: I'm no longer selling my copy on eBay. Check out the comments below for some good advice.

Wednesday, February 14, 2007

Are we being taken to the Sarbanes/Oxley cleaners?

In the past week, I've read 3 distinct stories about sarbox compliance and the use of instant messaging in the enterprise. From what I can tell, all of the IT hubbub is around section 404. I can't for the life of me imagine a situation where IM would fall under this rule.

In general, issuers are required to publish information in their annual reports concerning the scope and adequacy of the internal control structure and procedures for financial reporting.

The registered accounting firm shall, in the same report, attest to and report on the assessment on the effectiveness of the internal control structure and procedures for financial reporting.

On its face, maybe you could construe the meaning of "system of internal control" to include everything that the company does to conduct business. It is my opinion that this interpretation goes far beyond what the intent of the crafters of this legislation was.

In the late 80s or early 90s, the accounting profession changed it's rules regarding the audit engagement. Prior to that point, each audit required an opinion on the adequacy of the company's internal control systems. I feel that the intent of this law was to put that part of the audit back in place.

In that system, the system of internal control was concerned with the nature of recording accounting transactions. It was based on the concept that a strong internal control system required that the custody of assets, the authorization of transactions and the recordation of transactions be vested in separate individuals in the company. This is a strong method for combatting internal fraud since it forces 2 or 3 people to collude to defraud either the company or its stockholders. This is obviously a laudable goal of any responsible company.

So, how does instant messaging, or even email, fall under this rule? It seems like it would be crazy to require the use of either of these pieces of technology as part of your system for recording financial transactions. I would certainly be uncomfortable accepting transactional authorization through instant messaging. I would either want a real signature on a source document, or an archived electronic document with an electronic signature.

It seems to me that there is actually a pretty good argument for outsourcing both types of technology as employee empowerment tools. By bringing those systems in house and logging all activity, you're now subjecting those records to being subpoenaed. While that certainly has some legal ramifications, it still appears to be outside the scope of SarbOx. So, in effect, the enterprise has actually increased it's liability by bringing these systems in house.

I think that the SarbOx compliance industry is banking on people not actually reading and understanding the context of the law in order to sell more services into the enterprise.

If you look at the technology as just alternate methods of facilitating employee communication and collaboration, it seems like the compliance thoughts are misplaced. How many companies record all phone conversations, or even water cooler conversations. I doubt anybody would claim that your conversations with your coworkers in the rest room are the property of the corporation. It just seems rediculous that other methods of communication are not treated the same way.

I've also read about the disproportionately high compliance expenses incurred by smaller corporations (although even small corporations covered by SarbOx would be considered large corporations by almost any standard). This is due primarily by the heavy hand of government imposing the internal control standards equally across the board. In the pre-dregulation days of the public accounting method of studying internal control systems, the study was always able to make judicious use of the materiality principle. In essence, if a failure of the specific internal control system would not lead to a materail misstatement on the company's financial statements, some allowance could be made for simply not having enough people to separate all three parts of the control structure in certain places. Unfortunately, the law doesn't take company size into account or the materiality principle.

It is my understanding that there is some movement in Congress to address some of the size issues. I don't know the nature of the proposed amendments or the chances of them passing. I hope they offer some clarification on some of these issues.

So, when your company tells you that they need to bring IM in house because of SarbOx, ask them what is it exactly they are complying with. Make sure you tell me, because I'd really like to know.

Personally, I think it's just another questionable sales practice being perpetrated in order to dig into your privacy even more. Unfortunately, there is almost no law in the US regarding workplace privacy. Some states have taken on some of this, but it's a sparse patchwork at best. Maybe it's time the Country got serious about protecting our privacy a bit more.

More Intel Mac Tips

Thanks for the nice tips, Matt. I'm looking forward to getting most of these things added to my PowerBook soon.

Matt Woodward's Blog

Monday, February 12, 2007

Running CF on Intel Macs

Running ColdFusion on the intel based Macs is currently not supported by Adobe. There are, however many people reporting success in getting this to work. The definitive guide to help you step through the process can be found at webmages.com. I haven't had a chance to try this yet, and I'm not sure I will. There are a few REALLY large downloads you have to get. I think the Apple developer tools is in the neighborhood of a 1Gig download.

As far as I can tell, you pretty much have no chance of an OS X version of Microsoft SQL appearing anytime soon/ever. That means that if you want to try to run it, you're going to have to use something like Parallels to run Windows on your mac. If you're going to the trouble of setting up Parallels to run windows/SQL, why not run CF, too. Is there a problem with that approach that's not obvious?

Wednesday, January 31, 2007

Goodbye IE. I wish I'd never met you.

An interesting article that puts some of the browser vulnerability in perspective. Granted, the story is only dealing with IE6, so I imagine that IE7 on Vista will be marginally better in terms of security. Funny, that's pretty much the same story we heard about WinXP SP2, wasn't it?

Boiling the article down into one, easy to understand statistic:

Number of days in 2006 your computer could be completely p0wn3d through no fault of your own on a completely patched computer because of the browser you are running:

IE: 284 days
Firefox: 9 days

Why are we unable to convince US management that this piece of software is just too dangerous to use? And yet, it is not unheard of to have an organization bolt down the use of gTalk for security reasons, although I've yet to hear of a single exploit going through the system. I imagine that what they are really irritated about is that the jabber back end uses TLS to provide encrypted connections that they can't look into.

Have you found evidence of a gTalk exploit? An article somewhere? Please post a link if you have.

Internet Explorer Unsafe for 284 Days in 2006 - Security Fix

Tuesday, January 30, 2007

Joining the Light side

Well, I finally did it. After dealing with repairing a head crash and a 5 hour reinstall of windows xp (plus patches), I broke down and decided to join the light side.

My new 17" PowerBook Pro is arriving tomorrow. I can hardly breathe. I have a feeling an iPhone may be in my future, too, when my Verizon contract is up.

Friday, January 26, 2007

CFEclipse 1.3 released!

CFEclipse.org

The new version of CFEclipse has just been released. I use this program every day now. The only time I revert back to dreamweaver for ColdFusion coding now is for doing visual interface work.

I think the real strength of the CFEclipse IDE has to be that it's built on Eclipse. The number and variety of plugins for the environment allow you to build your own best of breed development environment.

For me, of course, plugin #1 is CFEclipse. But there are several others I regularly use that allow me to work in this editor and rarely need to leave.

Some of the features I like are native to Eclipse, like support for xml and javascript code hinting. Others are built by professional outfits like Adobe (FlexBuilder being plugin #2 for me). And still others are built by the open source community, like the columns plugin that lets you do things like cut and paste a column in your text editor or line things up on a specific character.

The plugin for vss is top notch and works better and more reliably than anything I've ever seen in an IDE including Visual Studio. Sorry Adobe, but it's even better than the vss integration in either CFStudio or DW.

Back to the new version of CFEclipse. One of the more interesting features that made it into this version has to be integrated support for unit testing with both CFUnit and CFCUnit. I've only used the CFUnit side of things because of the ANT integration thats available, but it totally rocks! If you haven't looked into unit testing your OOCF, this should help encourage you to do so, especially if you work on projects that have lots of far reaching cfcs developed by different people.

If you've been putting off looking at CFEclipse, now is a good time to reconsider getting over that initial learning hump. Once I got comfortable with some of the differences in terminology (workbench, perspectives, etc.) I've never really looked back.

Friday, January 19, 2007

Where's my aPhone?

Ok, we've seen the razr, the krazr, the proposed iPhone, etc. It's time to announce the "aPhone". A breakthrough in cellular technology brought to you by Adobe. Here are some of the interesting features we are likely to see when the product is released:\
  • Usable with all major cellular networks
  • dual 5.5in touch screens allowing multiple applications to be viewed at the same time.
  • More stylish than an iPhone.
  • Allows you to make phone calls in Dolby 5.1 surround sound.
  • Sound enhanced by THX
  • Dropped calls credit your account for the cost.
  • Uses Flash Lite as the programming environment.
  • open architecture that lets you build whatever applications you want and service them with whatever you want.
  • Touch screens are protected when folded in half.
  • 5TB of mp3 data available.
  • TASP interface lets you plug the phone directly into your head (neurosurgery available for an extra fee).
  • Utilizes high speed networks for internet and media connections.
  • Only costs $1 with a 3 year contract.
  • Above all else, it is A phone.
Ok, so this is a bit facetious, but the more I hear about the iPhone vaporware, the more I think there is an opportunity for somebody to one up them. Why only the one network? Why the low speed data network? Why the completely closed software stack? Why compete directly with the iPod? So many things about the iPhone make me thing that it may not be the next great thing.

Are there any features you'd like to see on the iPhone that are not being delivered?

Monday, January 15, 2007

CFUnit in CFEclipse

I've been playing with the new unit testing features built into CFEclipse for about two weeks now, and I have to say that they work GREAT! This is definitely a step forward for all of us cf developers.

The new tools built into CFEclipse will make it easier for you to develop you tests quickly, but you'll also want to look into the ant integration that's mentioned on the cfunit site. The ant approach will fire off your test suites whenever you save a file, helping to make sure that your new code doesn't break something elsewhere in your app. This is really helpful when you have several developers working on a large project where you might be unaware of how your code is actually being used.

Another situation where unit testing becomes even more important is where you are tasked with wring the cf side of a flex app. It's very possible that you will outstrip you flex compatriots since they are fighting a learning curve right now. Unit testing allows you to validate that your code works as expected before there is an interface that uses it.

Great Stuff!

Hats off to:
Mark Drew for the CFEclipse work
Robert Blackburn for the CFUnit work
Andy Jarrett for the nice quickstart