Installing Microsoft IntelliType Keyboard and IntelliPoint Mouse -- Error 1603

Friday, December 31, 2010

The Problem: Error 1603 During Installation

While attempting to install the software for both the Microsoft MultiMedia Keyboard (1.0A) and the Mobile Mouse 3500, I received the “Error 1603 Fatal Error During Installation” message and the software failed to install.

In English, the 1603 error means:

“We don’t know WTF is wrong. Later”.

The Solution

You will find lots of advice on getting to the root of this error, from futzing with registry keys to changing permissions on folders. It’s possible you’ll need to do that. But before you go down that route, try this:

  • If you have any pending Windows updates, install them and reboot
  • Clean your Temp directories

You most likely have two of these directories:

  1. c:\Windows\Temp
  2. c:\Users\<your username>\AppData\Local\Temp

How to do it

 

Install pending updates

You’ll know if you have pending updates if you have a little yellow shield in your “Shut Down” button:

winupdate

Simply click “Shut Down” and let it do its thing. If you don’t have that icon, then you’re ready to move on to the next step.

Clean your Temp directories

To find your local user directory:

  1. open a command prompt (win key, then type “cmd”)
  2. type echo %temp% at the prompt

It’ll show you the full path to your user temp directory:

tempdir

Now, open each of those locations in Windows Explorer, select all the files in the directory (ctrl-A), and hit the Delete key. If you’re prompted with dialogs indicating that certain files can’t be deleted because they’re in use, hit “Skip” as those files are not your problem.

Do this for both directories, then try the installation again.

Again, this might not be your problem, but it’s an easy first step before attempting more involved solutions.

Wireless Mobile Mouse Transceiver -- Can’t find drivers


I received a Microsoft Wireless Mobile Mouse 3500, which comprises 2 pieces of hardware:

  • USB Transceiver
  • The Mouse

In the typical case, you plug the transceiver into a USB port, Windows attempts to load the drivers, it works, and all is well.

The Problem

In my case, Windows could not locate the drivers and consequently the mouse would not work.

It did not work correctly for me because Windows was looking in the wrong place for the drivers. Why is this? Perhaps a month ago, I had set up my machine for Android development, and to do so I needed to install some drivers for the Droid 2 that were bundled with Flash Builder Burrito. I followed the usual Windows procedure for pointing to that driver location.  To wit:

driver_location

You get to this screen by manually choosing the driver location. Remember that.

The Solution

Lo these weeks later, when plugging in the transceiver, Windows was still looking in that previous driver location, even though I told Windows to “search automatically” for the driver software for the transceiver. I had mistakenly thought that “search automatically” meant “Dear Windows, you know where your drivers are, so please look there”. Nope. In this case, it meant “Search in the folder that is currently set as the Driver location in the ‘Browse driver software on your computer’ Dialog. WTF?

This feels like a bug to me.

At any rate, the solution for getting Windows to correctly find the transceiver drivers was to select “Browse my computer for software” and then use “C:\windows\winsxs” as the driver location.

In Pictures

Locate your transceiver in Device Manager (Right click “Computer”, select “properties”, then “Device Manager”. Or type “Device Manager” in the “Search Programs and Files” box)

driver_1

Select “Properties”

driver_2

Click “Update Driver”

driver_3

Click “Browse my computer for driver software”

driver_4

Type “C:\Windows\winsxs”. Click through the rest of the screens till it completes

Creating arrays of Objects in Java

Monday, December 6, 2010

You may have seen Groovy's now infamous "ArrayUtil.java" class, which contains 200+ variations on this theme:

    public static Object[] createArray(Object arg0, Object arg1, Object arg2) {
        return new Object[]{
                arg0, arg1, arg2};
    }

The authors are clear that this is a generated class whose ugliness is performance driven, and that you would never want to do such a thing in your own source code.

How would you do this in your Java? One simple approach is to use varargs:

public class VarArgsPlay {

	public static void main(String[] args) {
		VarArgsPlay v = new VarArgsPlay();
		System.out.println( v.returnArray("one","two").length );
	}
	
	public Object[] returnArray(Object... obj){
		return obj;
	}
	
}

Javabeat has a thorough treatment of this easy-to-use language feature.

cf.Objective() Call for Speakers is now Open!


You know you wanna speak at the best damn ColdFusion conference, period. Now’s your chance.

Very important: This is different from the topic survey we posted over the past few weeks. That survey helped us keep our finger on the pulse of the CF Community, as it were. If you previously suggested a topic, we thank you. But if you want to speak, you must submit a detailed proposal for that session.

The deadline is January 9, 2011. We look forward to reading your submissions… you are the reason cf.Objective() is such a fantastic event!

Simple Geospatial Queries with MongoDB

Tuesday, November 23, 2010

MongoDB has supported geospatial queries for a while, and in the upcoming 1.7 release it’ll get even better. Let’s take a look at how easy it is to query MongoDB in an idiomatic geospatial manner.

First, as described in the docs, you’ll need your data structured a certain way, and then you’ll need to add a 2d index. In my example, I’ll have documents that contain non-geospatial data (names, dates, other stuff) and then an embedded “LOC” document which contains “LAT” and “LONG” fields. These are arbitrary names… what’s important is that you get the order right. First, your “location” field will contain 2 values. You can do this in two ways:

  1. array
  2. nested document with keys

For example:

{  LOC: [38, –102] } is a valid “location” field because it contains an array with 2 values

{ LOC: { LAT: 38, LONG: -102 } } is a valid location field because it contains a nested document with two keys, and those keys contain numeric values. 

Note that the order is important! You’ll insert the data in the order in which you’d query the data. In general, stick with lat/long or x/y order.

Sample data

geodata

As you can see, this “treatment unit” is positioned at roughly [38,-102]

Adding the 2d Index

Let’s add an index:

> db.treatmentunits.ensureIndex( { LOC: “2d” } )

Cool, that was easy.

Querying with geospatial operators

Exact matches are rarely useful unless, and become even more so the more granular your lat/long storage becomes. You’ll notice in this example that I have ridiculously precise location data (it’s precise b/c it’s fake). Still, if you want to query for exact matches, you’d do this:

> db.treatmentunits.find( { LOC: [38,-102] } )

Due to the precision of my data, this will yield no results. So let’s widen the net by using the “$near” operator:

> db.treatmentunits.find( { LOC: { $near: [38,-102] } } )

That’s better… lots of results. By default, Mongo will give you the closest 100 results. You probably don’t want that. So, let’s tighten it up by setting some “bounds”, using the $maxDistance operator:

> db.treatmentunits.find( { LOC: { $near: [38,-102], $maxDistance: 5 } } )

You might be thinking: how’s that different from using limit(x)? Simple: limit() is merely a limit on the number of rows returned. If you want only 5, you get only 5. But by using $maxDistance, you’re not specifying how many results you want but rather how close the locations must be to your target location in order to be included in the results. If you want the closest 10 locations that meet a $maxDistance of 5, that’s where you’d use limit:

> db.treatmentunits.find( { LOC: { $near: [38,-102], $maxDistance: 5 } } ).limit(10)

Now, picture a map in your head, and draw a box somewhere on that map. Let’s say you want to find results whose location is within that bounding box. You’ll use the $within and $box operators, like so:

> db.treatmentunits.find( { LOC: { $within : { $box : [[40,-120], [48,-108]] } } }  )

Now that’s a big box, comprising nearly the entire southwestern US, so it’s going to return a lot of records. Tighten up the box to limit your results.

Finally, to find records whose location starts at a center point and radiates out, you’ll use the $within and $center operators:

> center = [38, -102]
> radius = 10
> db.treatmentunits.find({ LOC: { $within: { $center: [center, radius] } } } )

You may be wondering at this point, “Why don’t you have any sort() applied?”. The answer is: MongoDB will provide the correct sort for you when using geospatial queries

Debugging Flex/AIR Applications on an Android Device


At RIAUnleashed 2010, I attended a lab titled "Building your first Android application using Flex and AIR". One of the first things you'll want to do is see your "Hello World" app running on a device, and not just the emulator. On Mac and Linux, you shouldn't need to do anything special. On Windows, however, you'll need to do some work.

Note: This assumes you have Flash Builder Burrito installed. If not, you can get it at labs.adobe.com. In addition, I’m using a Droid 2, which is a supported device.

Note 2: You need wifi. Though you’ll be using USB to deploy the app to the device, the actual “debugging” happens over wireless. If you don’t have wifi, you can still run the app on the device, but you won’t be able to set breakpoints in your code, etc.

First, if you're new to Android, and you haven't yet attempted to connect your device to your PC yet, there's one small but important thing you'll need to do, and it appears that it does not do this by default, leading to potentially a lot of time and frustration.

I had two different installation experiences on two different machines. On a Windows 7 AMD64bit laptop, installing the Android drivers for the Droid 2 worked exactly as described in the Adobe docs. However, on a Windows 7 IBM 64bit PC, I had no luck installing the drivers manually. To finally get the Droid 2 installed properly, I did the following:

  1. Connect via usb (duh)
  2. slide the notification panel down and select "USB Connection".
  3. It will give you several options, and probably defaults to "Charge Only". Change this to "PC Mode", and then it'll install the appropriate drivers from the web. If you connect the device with “Charge Only”, you’ll bang your head against the wall trying to figure out why Flash Builder can’t connect.

This should be all you need to get FB to recognize your device. Now, you’ll need to change some settings on the device to “open it up”, namely enabling USB debugging.

  1. On your droid, go to Settings
  2. Choose Applications –> Development
  3. Enable USB Debugging

Now, back in FlashBuilder, do the following. This assumes you have a Mobile project:

  1. Right click either in the editor of your “main” file or in the package explorer
  2. Select “Debug As”, and then “Debug Configurations”. You can also choose “Run As” to run it, though it won’t be in debug mode.
  3. Select “Mobile Application”, and then  click the “New” icon.
  4. Give it a name, like “My App on Droid 2”
  5. In “launch method”, choose “on device”, and then hit “run”
  6. This should pop up a grid with connected devices, and your device should be in there.

Note: on the PC, it took about a minute after installing the drivers before FlashBuilder would recognize it as a connected device. In fact, I changed it from Charging to PC mode several times, and then finally it showed up in the grid.

Finally, after getting the drivers installed (if you’re on Windows), correctly setting the Droid to enable USB debugging, and configuring a FlashBuilder run configuration, you should be all set for debugging on your device. If you still can’t debug, it might be due to being on a VPN, or also due to firewall settings. You’ll need to correctly configure your firewall and perhaps your wireless router to enable the communication between your dev machine and your Android device.

Imagine If you could design your own conference…

Sunday, November 21, 2010

OK, so designing your own conference is probably not realistic. But with cf.Objective() 2011, you can at least let your voice be heard. Go to http://engage.cfobjective.com and submit topics you’d like to see. Vote on previously submitted topics if you see topics that speak to you. Comment on those topics if you have additional input.

You’ll note that we’ve provided for ‘suggested speakers’, but we’re not showing those names. Why? Simple: this isn’t a speaker popularity contest. We have a lot of great ideas for the kinds of sessions we want to include, and we need your input to both confirm what we have in mind and also to add content we haven’t thought of. Please… submit and vote!

It may also be helpful to think in terms of “What’s the single topic I absolutely, positively want to see?”. Add that as a comment, please. We’ll be looking not just at raw number of votes but also at other trends that emerge in the comments.

If you want to know more about why we’re doing this, Jared explains it all.

http://engage.cfobjective.com

MXUnit 2.0.2 Released

Thursday, November 18, 2010

MXUnit 2.0.2 is now released! This small update provides:

  • a bug fix to JUnitXMLTestResult
  • some HTMLResult tweaks
  • a new restoreMethod() to complement injectMethod()

Release notes are here, along with the download link.

Thanks to everyone who contributed code for this release!

--marc

MXUnit Eclipse Plugin 1.4 Released

Wednesday, November 17, 2010

It’s been way too long since I’ve written about an update to the Eclipse plugin. Quietly, some time back, I added a few niceties but never announced it. Recently, Denny Valliant of CFEclipse renown sent me a patch with several feature additions, and this prompted me to finish work on something long overdue in the plugin.

The new hotness:

  1. RemoteFacade URL at any resource level… not just project. This is particularly useful if you separate your tests into “unit”, “integration”, and perhaps even “ui”. Now, you can stuff relevant functionality – ORM Reloading, Selenium server startup, etc – into a custom remote facade for a given folder of tests. Prior to this addition, custom RemoteFacades usually had gnarly logic to determine what type of test was being run and what action should be taken as a result. No more
  2. In addition, when you set a custom remote facade, you can ping it from the Property page and get an HTML response back to confirm all is well
  3. When you run a test in the plugin and something catastrophic happens – something the plugin can’t handle – you’ll now get a popup browser window showing you an HTML version of the error. This should help considerably in debugging communication problems between Eclipse and ColdFusion
  4. The plugin no longer “hangs” Eclipse when it starts its initial communication with ColdFusion. Previously, if CF was shut down, or if it had just start up, attempting to run a test from the plugin would often hang the entire IDE while it waited for ColdFusion. No more.

For first-time installers: The update site url is http://mxunit.org/update

As always, if you hit any problems, let me know.

And, as always, if you have any problems figuring out how to configure the plugin, PLEASE click the green help icon in the plugin! In addition, see this page and its children on the MXUnit wiki for troubleshooting and other tips and tricks.

Finally, a huge “Thanks!” to Denny. You’re a code machine, bro.

ColdFusion Skunkworks Slides and Materials from MAX 2010

Tuesday, November 16, 2010

At Adobe MAX 2010, Joe Rinehart and I presented a session titled “ColdFusion Skunkworks”. What an experience!

I’ve posted the slides and materials on the MXUnit Wiki, and a recording of the presentation is available on Adobe TV. Please check it out. As I wrote on the MXUnit wiki, this presentation is our ode to playful programming, to putting aside, if only temporarily, familiar approaches, to taking risks, and to exploration.

I’d like to say “I hope you take as much from it as I did,” but I do not believe that is possible. This experience was transformative for me, to be sure. I’ve given a number of presentations at conferences, but none of them led me to learn so many new things as this one. Joe and I decided that if were were going to present on a topic as bold as skunkworks, then we needed to live it ourselves. It was fun, exhausting, exhilarating. So how about this: I hope you get a glimpse of what can happen when you devote some time to you instead of giving it all to the man. Go play!

--marc

MongoDB Slides and Materials from RIAUnleashed 2010


Picture, if you will, a ColdFusion Structure. Perhaps it looks like this:

doc =
	{
		NAME = "Marc",
		SPOUSE = "Heather",
		KIDS = [
			{NAME="Alexis", AGE=7, HAIR="blonde", DESCRIPTION="crazy" },
			{NAME="Sidney", AGE=2, HAIR="dirty blonde", DESCRIPTION="ornery" }
		],
		BIKE = "Felt",
		LOVESSQL = true,
		LOVESMONGO = true,
		TS = now(),
		COUNTER = 1
	};

Now, imagine if you could save that struct, query for that struct, update that struct. Imagine if you had a whole database full of structs, and querying them was finger-snap fast. Imagine if the database they lived in could grow to sizes unmanageable in a relational database. Imagine if scalability were sane, and replication were a few commands.

This database exists today, and it’s called MongoDB. MongoDB is a Document-oriented database, like CouchDB. A major player in the so-called “NoSQL” database market, MongoDB is a pleasure to use, partly because it aims to bridge the gap between NoSQL and relational databases by providing ad-hoc query support similar to SQL while still giving you MapReduce which most Document-oriented datastores use as their main query mechanism.

I began working with MongoDB when I began at BAH in May, 2010. I was tasked with creating a system whose data model was rather heterogeneous. We modeled the system first in a relational database, and while the result was familiar, it was also the embodiment of the “Object-relational impedance mismatch” which developers have bemoaned since the onset of Object-relational mapping systems. Ideally, the heterogeneous data could be persisted directly, without splitting apart before storing and reassembling upon fetching.

With MongoDB, we were able to achieve such data persistence. Thanks to that experience, I continued to work with MongoDB, and this November I presented on the topic at RIAUnleashed in Boston. This was also the first public presentation demonstrating CFMongoDB, of which I and the rest of the team are becoming quite proud.

The slides and sample code are available here: http://bit.ly/mongodbriau. Enjoy!

How RIAUnleashed is doin’ it right

Wednesday, September 29, 2010

This year, Brian Rinaldi invited me to speak at RIAUnleashed. By way of background: RIAUnleashed is a 2-day conference, held in Boston, founded by Brian Rinaldi, with a speaker and topic list as diverse as the fair city in which it’s held. As its name implies, its focus is “RIA” – Rich Internet Applications, though that concept is now so broad that it perhaps defies definition. This year, you’ll see Flex, AIR, Android, LiveCycle, ColdFusion, and even something called “Blitting” which, as a server-side dude, I’m both proud and ashamed to say is something that gets a WTF? from yours truly.

Check out the Agenda. It is, in a word, Fun! But that’s not what I want to talk about. This isn’t a post about “Why you should attend RIAUnleashed”. If the topics don’t interest you, fair enough. I want to get more personal.

This is my story

 

I know a little bit about education

I began my professional life as an English teacher. I graduated from IUP in 1996 with a degree in English Education. I taught high school English from January 1997 to June 2000. My heart was, and to some degree a part still is, in education. I left this hallowed profession for the most pedestrian of reasons (money. duh.). But I was good. I think. Anyways, as a student of teaching, and as a teacher, I learned much, the most germane here being this: when you give people ownership, they tend to respond in ways you could not predict. This is most certainly true of young people, in my experience as both a teacher and a parent. The difference between “ye shall do this”, and “what are you interested in? Now do it. Make us proud” is nebulous and enormous. It’s hard to measure. I shan’t attempt to do so here. Thus, this is yet another in the annals of subjective wish-wash. I’m cool with that.

Upon the approaching of the first RIAUnleashed, Brian asked me if I’d speak at his conference. I was honored, to be sure, but occupational obligations prevailed (never again, btw… the “deadline” I needed to meet never came to pass). Lesson learned.

This year, Brian asked again. I graciously accepted and asked what he’d like me to speak on. His response:

What do you want to talk about?

My gut tells me that this is probably one of the riskiest responses a conference organizer could propose. Think about it: you’re bootstrapped. You have no mega backing. You are funding this conference on attendance and the goodwill of some some supporting sponsors, but above all, asses in seats pay the bills. By all rights, Brian should be “reading the tea leaves”, asking of the world: “what do you, dear World, want to know about?” and then he’d enlist speakers to present on those topics.

Instead, he asks people, “what do you want to talk about?”. He chose speakers first, and the topics came later. This I admire.

Why this matters to me

While I have a J-Lo sized booty, I’m no prima donna. I’m generally known for being part of the unit testing / TDD fringe of the CFML community. I typically propose conference topics in those areas because they’re “safe” for me, and frankly because there’s not much competition.

But I’ve given those presentations, and I don’t like to talk about them more than once. Part of my fake motivation as a speaker is that I know if I’m talking about something in front of an audience, I’m probably only going to get one shot at it. I don’t recycle topics. So lately, while I’m known for one thing, my interests have gone in other directions. I’ve been spending more of my free time on datastores, parallel computing, and other investigations into “high scalability” applications.

In May, when I joined Booz Allen Hamilton, I was given the opportunity to investigate NoSQL datastores for an application, and I settled on MongoDB for a POC application. A love affair was born, and I haven’t let go.

So recently, when Brian asked me if I’d speak, I asked him if he’d accept “MongoDB for CFML developers” as a topic. He didn’t flinch, and I’ll be there in November, talking about my current passion.

How is this any different from what I’ve done in the past?

As I said, this is my own story. I’m not writing from the perspective of a business owner or conference organizer or, even, as a “smart guy”. This is a dude who will stand at the front of a room for an hour.

Several times recently, I decided to stop submitting topics that would increase my chances of acceptance, and instead submitted on only the things I cared most deeply about. By my count, I’m at about a 33% accept rate with that approach, not including RIAUnleashed. That’s completely cool! Because for the topics I’m presenting on, I feel as energized as I’ve ever been. I’m grateful for the opportunity to speak on things that matter to me, and I hope that translates into meaningful presentations for the folks gracious enough to attend.

So, to Brian: thank you for this honor. I’m excited to be in Boston for RIAUnleashed, both as a speaker and attendee of other fantastic sessions!

MXUnit 2.0.1 Released

Tuesday, September 28, 2010

MXUnit 2.0.1 is now out in the wild. It fixes some bugs and adds some enhancements. Read all about it in the Release Notes.

Enjoy!

--marc

Calling Java methods expecting Generic types in your CFML

Sunday, September 12, 2010

On Twitter, Jason Dean asked: “Is there a way for me to create an ArrayList<String> in ColdFusion for passing into a Java constructor?”

I responded saying I thought he should only need to create a regular old ArrayList and that the jvm should accept it, even though there’s technically no way to do “Generics” in java.

Summary

Your CFML code needn’t care if a java method expects a Collection of  Generic types. You can create objects of the “raw” type and pass those. However, If your collection object contains objects of a type that the original programmer didn’t expect, your code will most likely fail. Thus, consider the Generic type declaration as an instruction to you, the programmer, instead of an instruction to the compiler.

If you want to know why, read further.

If you’d like to play along, you can get all the code here: http://github.com/marcesher/HybridCFJava

What are Generics?

What he’s talking about are Java Generics. That’s the little angle bracket thing in there.

Given this code:

public String echoGenericStringList(List<String> list){
	return list.toString();
}

And then some driver code:

ArrayList list1 = new ArrayList();
list1.add("Hi");
list1.add("Hi2");

ArrayList<String> list2 = new ArrayList<String>();
list2.add("G: Hi");
list2.add("G: Hi2");

System.out.println(gm.echoGenericStringList(  list1   ));
System.out.println(gm.echoGenericStringList(  list2   ));

1) The echoGenericStringList method declares an input of type List. Additionally, it expects that list to contain only Strings.

2) The first ArrayList – list1 – is a “raw” ArrayList. I’ve declared no additional type requirements on it. It can contain any types: Strings, Integers, Foos, Bars, Unicorns. Whatever.

3) The second ArrayList – list2 – is a a “typed” ArrayList. It instructs the compiler to fail if any attempt is made to add something to the list that isn’t a String. Thus, list2.add(“one”) is fine, but list2.add(1) is not.

Raw vs Generic; Compile-time vs. Runtime

Neither of these last two lines will fail compilation. The second one is obvious: the method declares an input of type List<String> and gets it. But the first one… why doesn’t it fail? It’s getting a “raw” list, not a generic list.

The answer is: Because that’s how generics work.  The compiler will issue a warning, but it will not fail. A method declaring inputs with Generic types must accept inputs of raw types. The downside is that when using raw types, you lose the type safety which Generic types confer.

The key to understanding this behavior is this: Currently, generics are a compile-time type check. The typing of that list: ArrayList<String>, is erased upon compilation, and during run-time no check is made. That’s why, for example, the compiler would not complain if you added an Integer to list1 above and passed it to echoGenericStringList(List<String> list), but it would complain if you attempted to add an Integer to list 2 – since that list has been declared to only accept Strings.

Importantly, if you were to try this, the compiler does not complain at the line of the actual method, the public String echoGenericStringList(List<String> list), but at the point where you attempt to create a List that does not honor the contract of that list’s declaration. See this screenshot:

sshot-1

Notice that the compilation failure – the line of code with the red x beside it – happens at list2.add(1), not on the method itself.

If none of this makes sense, well, that’s expected if you don’t know Java. The bottom line here is that Generics are inspected at compile time and erased prior to runtime. The contents of the Generic Collection only matter at compile time; at runtime, you’re on your own.

This compile-time check doesn’t eliminate the possibility of type errors at runtime… but it greatly mitigates it. If you’re a CF developer, you probably don’t care at all about compile time type checks, which brings us to…

What does this mean for CFML developers?

Quite simply, it means that we can basically ignore generics in our CFML and treat methods that expect generic collections as if it expected a “raw” type collection. So, for us, a method declared thusly:

public String foo(List<String> list)

is the same as

public String foo(List list)

The reason is that by the time our CFML calls that foo() method from some Java class, that java code has already been compiled. The byte code does not have any notion of Genrics at this point. So when we create a non-Generic list in our CFML, the JVM will gladly accept it since it’s the same as if we were passing in a raw list, as in the example above. Java developers may bemoan the fact that Generics are erased at runtime, but we CFML developers can take advantage of that fact.

Thus, this CFML works fine:

<h2>Using Java Generics</h2>
<cfset genericMethods = loader.create("generics.GenericMethods")>
<cfoutput>

	#genericMethods.echo("hello")#
	<br>
	
	<cfset list = createObject("java", "java.util.ArrayList")>
	<cfset list.add("hi")>
	<cfset list.add("boo")>
	
	<cfset ilist = createObject("java", "java.util.ArrayList")>
	<cfset ilist.add(1)>
	<cfset ilist.add(2)>
	
	
	
	Echo a list: #genericMethods.echoList(list)#
	<br>
	Same list, passed to method expecting ArrayList<String>: #genericMethods.echoGenericStringList(list)#
	<br>
	New List with only ints, passed to method expecting ArrayList<Integer>: #genericMethods.echoGenericIntegerList(ilist)#
	<br>
	<cfset iList.add("foo")>
	Method expecting int list gladly takes list with non-ints: #genericMethods.echoGenericIntegerList(iList)#

</cfoutput>

MongoDB at Ria Unleashed

Thursday, August 26, 2010

RIA Unleashed is back for a 2nd year, and it’s going to be a great one? Why? Because yours truly is speaking, naturally!

No no no, I’m not going to yap for yet another hour on unit test this, TDD that, automate blah blah blah. This time, MongoDB gets some lovin’.

See, a while back, Billy started poking about with Mongo. He wrote some blog posts and started CFMongoDB. As fate would have it, earlier this year I had a chance to work on a project using Mongo, and I took to it quite naturally. With Billy going back to school to join the neckbeards doing Ph.D. work, I’ve taken up the reigns of CFMongoDB for the timebeing. Meanwhile, Brian Rinaldi asked me if I’d like to speak at RIA Unleashed, and he graciously accepted a topic on Mongo. Here it is:

MongoDB is a popular open source Document-oriented database. Like other NoSQL datastores, it's fast and scalable. Unlike most others, it provides rich ad-hoc query capabilities which we ColdFusion developers know and love. During the presentation, I'll give a broad overview of the usual introductory topics: MongoDB's "solution space", installation, working with the shell, administration, and replication. Then I'll dive into using Mongo with ColdFusion, showing why I enjoy working with Mongo, the problems I've encountered, and how to solve them.
By session's end, attendees should understand what problems MongoDB was meant to address and how to use MongoDB as a datastore in their CFML projects.

RIA Unleashed is a kick-ass, reasonably priced, 2-day conference featuring both sessions and workshops by world-famous speakers such as Ray Camden, Jesse Warden, Bob “All Your Mocks Are Belong to Us” Silverberg, and the guy who created Peanuts!

During its inaugural year, teh twitterz were buzzing with compliments. This year will be even better!

CF9 ORM: Using the Secondary Cache to optimize for expensive columns

Saturday, July 17, 2010

This is an experiment. It most likely speaks to my poor SQL skills and willingness to jump for a quicker code solution than to figure out how to write faster queries. So if you can tell me a faster way to do this in SQL, I’ll listen.

Still, this is mostly about using a combination of simple property mappings and the secondary cache for an interesting, perhaps unusual solution to a problem.

This is my story

I have a table. Its name is “N_Organizations”. It’s prefixed with “N_” because this is a blog post and I am experimenting. Like many organizations, an Org can be a parent of another Org: “Paint Shop” is a child of “Operations” is a child of “The Penthouse Suite”. In an untold number of places, in both the web application and in reports that are not web-driven, the “tree” for any given child organization has a simple requirement: Show the names of the parents as a single string:

"The Penthouse Suite –> Operations –> Paint Shop”

Ideally, The creation of this string would happen in one place, and then any place that needed it would not have to do the requisite looping to construct the string itself. If different formatting were needed, it’d be better to have the reformatter be a simple string reformatter than a parent org climber: simply replace the arrows with colons, for example.

So, when thinking of a typical query, you’d get something like this:

id | Name                  | ParentID | ParentName
1    The Penthouse Suite     null       
2    Operations              1          The Penthouse Suite
3    Paint Shop              2          The Penthouse Suite --> Operations

And so on.

To fetch this stuff, I created a view that uses a Common Table Expression (CTE) to recursively loop over the parents in order to derive the ParentName. It does some other foolishness with “level”, but ignore that. CTEs are kind of like recursing but without functions:

CREATE view [dbo].[v_organizations]   as

WITH cte_tree AS
		(
			SELECT id, organizationname, OrgNode.GetLevel() as Level, CAST('' AS varchar(500)) AS ParentName
			FROM dbo.n_organizations
			WHERE organizationtypecode = 'D'

			UNION all

			SELECT parent.id, parent.organizationname, OrgNode.GetLevel() as Level,
			CAST(
				cte_tree.parentName +
				case when cte_tree.parentname = '' then '' else ': ' end
				+  cte_tree.organizationname as varchar(500)
			)
			FROM dbo.n_organizations parent
			JOIN cte_tree ON parent.parentorganizationid = cte_tree.id
		)
		SELECT
			o.id, o.OrganizationName, OrganizationTypeCode,
				ParentOrganizationID, CreatedOn, ModifiedOn, 
				Level,
				case when Level <=3 then o.id else o.ParentOrganizationID end as GroupLevel,
			cte_tree.ParentName
		FROM cte_tree
		JOIN dbo.n_organizations o ON cte_tree.id = o.id

GO

There’s a big problem with this: it’s slow. The tables are as indexed as they can be, but you can’t index views with CTEs. And what’s worse, the query is slow regardless of what kind of criteria you add to it. 

Select * from v_Organizations runs about 125 milliseconds. Select * from v_Organizations where id = 215 runs in about 90 ms. The reason is that it still has to do all that recursion. Thus, this is probably a terrible way to solve this problem.

And yet, we continue….

This is my Component

Organization.cfc

component persistent="true" accessors="true" table="N_Organizations" {
	property name="id" fieldtype="id" generator="native";
	property name="organizationName" type="string";
	property name="parentName" column="parentName" readonly="true" type="string"  table="v_organizations" joincolumn="id" cacheuse="read-only";
}

Notice how the parentName property points to “v_organizations” as the table? Pretty cool, huh?  So now when I load this component, when I access the parentName property, it’ll pull it from v_organizations and all will be well. Hibernate will generate a query that simply joins table N_Organizations on v_Organizations where id = id. Yeah.

Except, that’s slow, too. Remember, as I said, querying v_organizations adds about 100ms no matter how many records I’m pulling back. Notice that “cacheuse=’read-only” attribute? Yeah… that doesn’t work. No matter how many times I ask for the parentName, it’s going to run that same query.

What If?

What if I just cached the Organization.cfc in Secondary cache? Wouldn’t that rock? No… most of the data in this component will change too frequently, so I can’t cache the entire component (I’m leaving off a bunch of other properties, obviously).

But… what if I could cache just that parentName property? That’s the slow one, after all. And that never changes. Or, it changes like 2x a year, and in that case, we just clear the cache and off we go.

How could you possibly achieve such awesomeness?

You need two components: 1) Your original Organization.cfc and 2) a new ParentName.cfc

Organization.cfc:

component persistent="true" accessors="true" table="N_Organizations"{
	property name="id" fieldtype="id" generator="native";
	property name="organizationName" type="string";
	property name="parentName" readonly="true" type="string" fieldtype="one-to-one" cfc="ParentName" constrained="true" cacheuse="read-only" ;
	
	//make it easy to get the parentName property
	function getParentName(){
		try { return parentName.getParentName(); }
        	catch(Any e) { return ""; }
	}

}

ParentName.cfc

component accessors="true" persistent="true" readonly="true" table="v_Organizations" cacheuse="read-only" cachename="ParentName"{
	property name="id" fieldtype="id";
	property name="parentName" type="string" ;
}

So what does this do, exactly?

First, what we’ve done is simply rolled that parentName field from v_organizations into a 4-line component. Notice that the “table” attribute on the component is v_organizations. Notice it specifies cacheuse=”read-only”. Notice that read-only is true.

Second, in Organization.cfc, we replaced the original parentName property with a new one that is a simple one-to-one relationship with this new ParentName property

Third,we add a function, getParentName(),  so that we could simply call organization.getParentName() instead of organization.getParentName().getParentName(). It’s wrapped in try/catch because this will fail for the very top-level organization which has no parent organization.

The result: The first time getParentName() is called for any organization, the view will run (slowly, as usual). Subsequently, CF will fetch that property from the cache until that cache is cleared or the server restarts or whatever. So you do take an initial one-time hit of 90ms or so for each organization, but after that, you’re gold.

But wait, there’s more!

I mentioned this experiment to my boss, and his first reaction was, Could you just do a one-time load of all those ParentName organization instances, right on app start, so that you’d never see that 90-ms / per object penalty?

So I tried it, and this is where it gets even better. None of this is unsurprising, by the way. It all makes complete sense.

Simple math:

Doing it the ‘pay-as-you-go’ way: You have 2500 records. You hit the view one time for each record. 2500 * 90ms = 225000 ms = 225 seconds = almost 4 minutes total to load each of those records were you to do them one at a time over the lifespan of the application between server restarts.

However, if you load them all at once, remember, SQL-wise, it’s only taking about 125ms to load. So if you created all 2500 instances of ParentName.cfc, you’ve got the 125ms for the SQL and whatever time it takes to create those 2500 component instances. In my case, it’s about a second, total. To achieve such a performance improvement, you run this when your app starts:

 

EntityLoad(“ParentName”);

 

Since ParentName is a cached component, it’ll get stuck in whatever cache you have configured in Application.cfc, and then all subsequent calls to organization.parentName() will take however long it would take to fetch a simple string from the cache. In my experience this is anywhere from 1/3 to 1 ms doing unscientific averaging.

If you need to clear the cache, simply use:

ormEvictEntity("ParentName");

Conclusion

1) I was amazed at how easy it was to work with Hibernate’s second-level cache with ColdFusion ORM. It just worked.

2) Sometimes, when you’re not Joe Celko and you don’t want to spend time time figuring out how to write a better view, you say “you know what, I think I’ll see if there are fun and interesting bits in CF ORM that could solve this problem for me”. And then you go play, and you come up with some nifty things.

3) I have no idea whether I’ll ever use this, but perhaps you’ll find a use for such a solution and, when you do, thank the CF team for doing such a fine job of integrating Hibernate’s L2 cache into CF.

Good luck!

 

--Marc

How to set up a new Eclipse environment

Sunday, July 11, 2010

Have you ever wanted to start using a new version of Eclipse but couldn’t justify it because of all the time you’ve spent getting your preferences and project settings just so? And you don’t want to type in all those Update site URLs again to get all your plugins? While there is currently no one-click easy way to completely migrate an existing Eclipse install to a new one, I do have some timesavers for you.

Always start with a new Workspace

I’ve seen too many problems with trying to reuse an existing workspace in hopes of saving some time moving from an old version of Eclipse to a new one. Don’t do it. When you fire up the new Eclipse, and it asks you for the workspace, give it a new location. I keep a directory named “Eclipse Workspaces”, and in it lay the corpses of a dozen or more old workspaces. I name my workspaces with this general pattern:

[Product]_[MajorVersionName]_[RCNumber]_[Purpose]

For example, for my work projects, I use ColdFusion Builder on Galileo. My workspace is Bolt_Galileo_Work. When I was fiddling with some of the Helios (Eclipse 3.6) RCs, I was using Bolt_Helios_RC2_Work.

For Eclipse Plugin development I use CFEclipse_Helios_PluginDevelopment.

I always reserve the right to break that pattern.

Getting all your plugins

I’ve seen some people suggest copying them from the old install, and perhaps that works just fine. Here’s how I do it: I Export the update sites I want to install into my new Eclipse, and then Import them in the new one. Then, I install the plugins using the tried-and-true software installer. Here’s how:

In your old Eclipse

  1. Help – Install New Software
  2. Click the “Available Software Sites” link
  3. On the Available Software Sites screen, select the plugins that you want to install into your new Eclipse
  4. Click the “Export” button, and go through the dialog of saving the XML file someplace sensible, like your Desktop

That screen looks like this:

updatesites

In your new Eclipse

  1. Following the same steps as above, get to the Available Software Sites screen
  2. Click the “Import” button
  3. Navigate to that XML file you saved previously and follow all steps
  4. Now you have those update sites available to you. From there, get back to the Install software screen, select “All Software Sites” from the dropdown, and let Eclipse find and install all those plugins you know and love

 

Getting some of your Preferences

You can export some of your preferences from the old install to the new one, though you do have to beware that you’re going to import some preferences you don’t actually want. More on that in a bit.

In your old Eclipse

  1. File – Export
  2. Select “Preferences”
  3. Follow the rest of the screens to save your prefs as an .epf file

In your new Eclipse

  1. File – Import
  2. Select “Preferences”
  3. Follow the rest of the screens

As I said, it’s going to copy some preferences that you don’t want. In particular for me, I always get bitten by the “ANT Runtime” preferences. In that case, I let it do its thing, and then I go back into Window – Preferences and point the ANT runtime to the one that comes bundled with the new Eclipse. Even with that little annoyance, it’s worth it to export/import preferences because it brings over so much.

 

Getting all your projects

Perhaps the most time-consuming part of moving to a new Eclipse installation is getting all your projects back in there. Fortunately, this can also be the least time-consuming. Here’s what to do in your New Eclipse installation:

In CFEclipse

  1. File – Import
  2. Select “Existing Projects into Workspace”. Click Next
  3. In the “Select Root Directory” field, type in the directory where you keep most of your projects. Hit Enter
  4. Once it finds all the projects in that directory, choose the ones you want, and hit “Finish”

In ColdFusion Builder

Follow the same steps as above, but at Step #2, choose “ColdFusion – Import existing Projects”

NOTE: This will not copy All of the existing properties for the projects, such as the MXUnit cfcpath and remote facade URL. For ColdFusion Builder, it will carry over the server settings since they are stored in a file that lives inside that project and not outside of it like most project properties in Eclipse

 

Some Preferences I’m always sure to confirm

Once I’m finished with the above, I have a few preferences I always double-check. In Window – Preferences:

  • General – Show Heap
  • Quick Diff – Pristine SVN Copy
  • Local History – at least 180 days
  • Key Bindings – Alt-A for ANT view, Alt-S for CFEclipse Snip Tree View, and Alt-Y for Mylyn Task List view
  • Appearance – Colors and Fonts – Basic Text --  Consolas 12pt
  • CFEclipse / ColdFusion Builder Snippets path (I point it to a dropbox location)

 

If you have any quick tips for making migrating from one Eclipse installation to another less time-consuming, please share them.

MXUnit 2.0 Released

Friday, July 9, 2010

Once again, Los Hombres at MXUnit.org are delivering a new batch of the crack cocaine of unit testing for ColdFusion--MXUnit 2.0.  Yes, it's true.  Once tasted, a life of uncontrollable and desperate automated testing will surely ensue. This particular batch has some especially addictive features:
  1. New Open Source License: MIT. Changing from GPL to MIT effectively allows you to integrate MXUnit into any product with little restriction (other than honoring the No Whining clause).
  2. New built-in mocking framework: Simply call the new mock() method to create a new mocked object and inject that into your component under test.
  3. New integrated HTML view: This replaces the existing HTML and ExtJS view and is backward compatible.
  4. New beforeTests() and afterTests() for component-level set up and tear down.
  5. New and improved documentation and bug tracking at http://wiki.mxunit.org and http://jira.mxunit.org/secure/IssueNavigator.jspa?reset=true&mode=hide&pid=10000
  6. Ant task improvement: now you can send arbitrary URL parameters to your custom runners.
  7. New Ant build.xml examples and Hudson-friendly examples.
  8. More Eclipse snippets!
  9. More Dataprovider improvements.
  10. Eclipse plugin data compare tool.
  11. Multiple Github fork(s) (http://github.com/virtix/mxunit).
  12. Office Hours every other Monday at 12:00pm US Eastern Time. Join in via Adobe Connect and bring any testing or other technical questions or topics: http://bit.ly/MXUnitOfficeHours.
MXUnit couldn't deliver the kind of product it is without the generous help of many talented and dedicated programmers. This particular release saw significant contributions from these chefs:

Tim Farrar
Peter Farrell
Patrick McElhaney
Randy Merrill
Bob Silverberg
John Whish

Cop the latest and greatest at http://mxunit.org/download.cfm and get involved http://groups.google.com/group/mxunit
Test and be Happy!
theguys at mxunit.org

Your CFML Wish List

Monday, June 21, 2010

For years, Adobe ColdFusion has added feature after feature that has dramatically improved productivity for CFML developers. With CF8, support for struct and array literals was added as well as improvements for operators (ability to use <= instead of LTE, ++ for incrementing, etc). With CF9, they added support for full-script CFCs. Well done, Adobe.

I’d like to hear from you: what other enhancements would you like to see to the core language? What drives you nuts that you wish you could change (var scope, cough cough). What is missing? What’s half-baked? I’m not talking about features or new tags or functionality … purely language-level stuff. As a coder, what do you wish you could do with CFML that you can’t do today? Perhaps you’ve worked in other languages and encountered semantic constructs that you miss when working with CFML?

This is strictly for my curiosity: I don’t work for Adobe, and I have exactly Zero Pull (tm). I have a list of enhancements I’d like to see made to CFML, and I’m curious how your wish list compares with mine.

Thanks!

A New Eclipse Timesaver for Flex, Java, and [insert language here] Developers


CFML developers using CFEclipse (and  more recently ColdFusion Builder) have long enjoyed the benefits of Snippets and the Snip Tree View, a way to create customized, variable-driven chunks of code which you can drop into your source with a single keyboard combination. I wrote about them a long time ago, Matt Gifford recently wrote what has become the de facto guide to snippets, and lo many years back Mark Drew made this video which is still relevant today.

To add to the general awesomeness of snippets, you can share them amongst your computers or even other developers. This shows you how to do so with DropBox.

In my experience, once a developer becomes snippet-infected, they tend to bemoan their absence when editing other types of source code. Unfortunately, Snippet insertion never worked when editing other files like Flex, and even when it did work, you had to install the entire CFEclipse plugin which some developers don’t want to do. Until now.

Who’s the target audience?

Flex, Java, JavaScript, Groovy, Scala, [insert your language here] developers who use Eclipse and who do not have ColdFusion Builder installed.* It’s also important that you like to save time.

*ColdFusion Builder snippets should already work with other sources! Good job, CFB team.

How do I install it?

The Eclipse Update Site is at http://cfeclipse.org/snippets/update/. In Eclipse 3.5 and later, you’d use “Help – Install New Software”. Then click the “Add” Button. Then add that URL into the URL field. Follow through to the end.

What will this install into my Eclipse?

This will install a standalone Snippet Tree View and corresponding key binding into Eclipse. By default, the key binding is “Ctrl-Shift-I”. Note that this will be different from the binding mentioned in the above articles, although you can reassign it to whichever key combination you like. In FlashBuilder, I immediately reassigned mine to the familiar Ctrl-J sequence.

Who’s responsible for bringing such Joy unto the world?

We’d be remiss if we didn’t thank the CFEclipse founding fathers. Rob Rohan and Spike Milligan will most likely never know that the work they did still continues to improve the lives of developers around the world. Mark Drew has led CFEclipse for years and many credit him with helping make it a mature, stable platform on which to build CFML applications. And Robert Blackburn added the SnipEx support into the Snippet Tree View. Thanks to all you wonderful people!

For this release -- separating Snippets into their own plugin and refactoring so that they’d be useful for other languages on the Eclipse platform --  Denny Valliant (github) gets all the credit. Denny’s one of those guys you don’t hear much about, but he’s brought inestimable joy into developer lives through all the work he’s done on CFEclipse and other projects. Thank you, Denny.

What to do next?

  1. Install the Snippets Plugin
  2. Read one or more of the links above explaining how to use snippets.
  3. Open up the Snippet Tree View and add some snippets (don’t forget the “trigger text”!)
  4. Go into your editor and type the trigger text for one of the snippets you added. Hit Ctrl-Shift-I to insert the snippet
  5. Repeat Steps 3 and 4 and rejoice in all the time this will save you

Creating a Hybrid ColdFusion – Java Project in Eclipse

Sunday, May 23, 2010

On more than one occasion recently I’ve wanted to incorporate Java libraries into ColdFusion applications. You can do this in your CFML, but it usually involves the following:

  1. CFML code littered with createObject(“java”,”whatever.Whatever”);
  2. Zero content assist for the Java objects
  3. Optionally, Putting jar files in your CF installation’s lib directories and deploying those to all servers (dev, test, staging, prod) and developer machines

1 and 2 are the worst problems because 3 is solved with Mark Mandel’s javaloader (more on that later).

Ideally, I’d be able to write Java code in Java source files, compile it and test it in Eclipse, and fairly seamlessly use it in my CFML… in the same project. In this post, I’ll show you how to set it up in ColdFusion Builder. Note that these same steps apply to CFEclipse as well. In a follow-up post, I’ll show a more real-world example

Create your CFML project

  1. In CFBuilder or CFEclipse, either create a new project or use an existing one.
  2. Create a directory named “java”
    1. under there, create “src”, “bin”, and “lib” directories
    2. Download javaloader from Mark’s site, and drag the “javaloader” directory into the root of your project (or put it in your webroot)
    3. If you put it into your project, add this to your Application.cfc: this.mappings["/javaloader"] = getDirectoryFromPath(getCurrentTemplatePath());

By now, your project should look something like this:

HybridCFJavaStep1

Apply the Java Nature

  1. Close the project: right click – “Close Project”
  2. From the file system, open the project’s “.project” file in a text editor
  3. In the “<natures>” element, add this: <nature>org.eclipse.jdt.core.javanature</nature>
  4. In the “<buildSpec>” element, add the following:

<buildCommand>
	<name>org.eclipse.jdt.core.javabuilder</name>
	<arguments>
	</arguments>
</buildCommand>

Back in Eclipse, open the project (right click -- “Open Project”). Once you do that, it’s going to look very strange… something like this:

HybridCFJavaAllPackages

 

Configure the Java Build Path

Your project now looks funky because it’s treating everything as a Java source folder. Let’s fix that.

  1. On the project, right click, select “Build Path”, then “Configure Build Path”
  2. In the “Source” tab, remove any entries
  3. In the same tab, select “Add Folder” and navigate to your project’s “java/src” folder
  4. Down at the bottom, in “Default output folder” text field, browse to your project’s “java/bin” directory

Now, your project should look something like this:

HybridCFJavaStep3

That’s better.

 

Create a simple Java file

Note in that screenshot above that you have “java/src” with a package decorator… that’s where you’ll be working. Ignore the “java” directory that you see in that screenshot… we don’t care about it for now.

  1. In the “java/src” directory, right click, select “New – Package”. Name it “hello”.
  2. In that (now empty) package, right click, select “New – Java Class”. Name it “Hello”
  3. This will open a new Hello.java in a java editor. Let’s create a simple “echo” method. For now, just use a “main” method to drive it in Eclipse… we don’t need to get fancy with unit tests just yet:

package hello;

public class Hello {
	
	public String echo(String input){
		return "Hello. You said: " + input;
	}
	
	public static void main(String[] args) {
		Hello h = new Hello();
		System.out.println(h.echo("marc"));
	}
	
}

If all goes well, you should be able to run this file and see output in the console. To run it, select “Hello.java” in the Project Explorer and hit the green “Play” button in the toolbar, or right click in Hello.java and select “run as – java application”, or hit “Alt-Shift-X, J"

Use it in your CFML

To use it in your CFML, you’ll want to use javaloader. Conceptually, you simply tell javaloader where your compiled classes are, where any additional .jar files live, and then use it to create objects. Here’s what it looks like in practice. For demo purposes, I just created a file in my project root; thus, all paths you see in here are relative to that file in the root.

<!--- set up javaloader --->
<cfset binDir = expandPath("java/bin")>
<cfset libDir = expandPath("java/lib")>
<cfset jars = directoryList(libDir)>
<cfset arrayAppend(jars,binDir)>
<cfset loader = createObject("component","javaloader.JavaLoader").init(jars)>

<!--- run it --->
<h1>Hello!</h1>

<h2>Echo example</h2>
<cfset hello = loader.create("hello.Hello")>
<cfoutput>#hello.echo("marc")#</cfoutput>

If you’ve done everything right, when you run this in your browser you should see the expected output. If you go back into your java file, make a change, and hit refresh in the browser, the  changes you made should be reflected.

Final Thoughts

For years, folk have praised the ability to integrate Java into CFML. However, the workflow has always been complicated and the tooling nonexistent. CFMLers who’ve worked for years without content assist on their own Components most likely have no idea just how powerful an ally their IDE can be. So we suffer, typing “whatever = createObject(“java”, “some.Java”); whatever.NowWhatWasThatMethodAgain(AndWhatWereThoseArgumentsAgain)”, not realizing that if we were writing our java in a “real” editor, you’d get all the richness the IDE can offer. In other words, most CFMLers don’t know what they’re missing when they have to incorporate java into their projects.

I am not saying that when you create Java objects in your CFML code that you’re going to get content assist; rather, what I’m saying is that if you have more than a few lines of Java code in your CFML, then perhaps it’s best to put that code into its own Java sources – inside the same project, as I’ve described above – and simplify the work you have to do with Java without sacrificing workflow and deployment speed.

It also opens up some other nice possibilities: If you’ve a Groovy fan, or have a problem that would be better suited for Groovy – yes… even if the thing you want to do is simply more enjoyable in that language --- then you could do very similar steps to turn your CFML project into a hybrid Groovy project. Create your Whatever.g sources, and use Barney Boivert’s excellent CFGroovy to run your Groovy sources.

If you need to write some java of your own, and you need to incorporate it into your CFML projects, then this IDE setup can help you.

Coming soon: a real-world example.

A Fun Bug in VMWare Workstation Installer

Friday, May 7, 2010

I hit this fun bug this morning and wanted to share it. It’s quite unlikely that you’ll hit it yourself, so the value here is probably as much in the debugging as it is in helping folks down the road fix this should they find it via Googling.

The Problem

I clicked to install VMWare workstation, and was greeted with this:

vmware

Yes, you’re seeing that correctly. Rather than seeing a normal installer window, I was looking at a Disney Vacation site. At first, I thought I must’ve had a virus on my computer but ruled that out pretty quickly. If it were a virus, I’d have been seeing pr0n or warez or some other such thing, not a Disney site… especially not a “static” Disney site.

Debugging the problem

The programmer in me isn’t thinking “Why isn’t this working?”. Instead, I’m thinking “What would cause an installer to display a Disney html file?”

  1. Some virus is hijacking the file and replacing it with the Disney file
  2. The VMWare installer is hosed
  3. The Real Answer

I wanted to explore the idea of something hijacking the file first. The question is… what file? This was easy to find. I simply looked in the VMWare workstation installer log and looked at what files it was unpacking and writing. Here’s a snippet:

20100507074429:INFO CPackageManager::GetFile: index.htm 20100507074429:INFO CHtmlUI::SetHtmlFile: Navigating from '' to 'C:\Users\Marc\AppData\Local\Temp\vmware_1273232669\index.htm' 20100507074429:INFO CHtmlDialog::NavigateToFile: Loading file C:\Users\Marc\AppData\Local\Temp\vmware_1273232669\index.htm?lang=1033&locale=1033

I opened that index.htm file and sure enough, it was the Disney html. So, off to see what activity was happening around index.htm. To do that, I used Sysinternals Process Monitor. This simply involved firing it up and adding a filter for index.htm to get rid of the copious noise that Process Monitor spits out by default.

Looking at the output, the answer became obvious. The first instance of an index.htm was in c:\<path_to_my_downloads>\index.htm.  Then I saw the index.htm in the temp directory. Ahhh…. so the installer was creating a file in the same directory in which it lived and then copying it into the temp directory.

I’m sure you see where this is going.

I headed to my downloads directory, and there she was… index.htm, Disney-fied.

How does this happen?

You might be wondering how in the heck that Disney index.htm file might have gotten in my downloads folder. The answer is simple: I have kids. If you’ve ever watched a kid use an internet browser, you’ll see them mousing around and doing all manner of weird draggy things that inevitably involves downloading a bunch of web files (usually images, but occasionally they can manage html files) into wherever you have configured downloads to go. It’s usually harmless.

In this case, you can probably imagine the code in the installer: “if !fileExists…, write index.htm” …. “copy index.htm to temp\vmware_blahblah\index.htm”

But why would you, the installer writer (or the program that emits the installers), fail to handle the case when there could already be a file like that in the place where downloads go?  It’s a stretch, and that’s why this is such a fun bug.

BOFs: An Opinion

Wednesday, April 28, 2010

Most conferences nowadays have BOFs, “Birds of a Feather” sessions usually held after-hours on one or more nights of the conference. These are informal get-togethers where folk sit around and talk about a topic. These topics are usually set in advance, either by conference organizers or existing speakers. Like most conference sessions, attendance varies. This is my experience with BOFs, at any rate.

This year, at cf.Objective, Bob Silverberg asked if I’d coordinate a Test-Driven-Development (TDD) BOF with him. I accepted. I expected a handful of people. I was wrong in this expectation. It started small but quickly got way too big for normal BOF comfort. See, the problem isn’t with the number of people who attend: I was thrilled to see so many people. I do not know “how well” we did but I give us a “C”. The reason for this mediocre assessment is the subject of this post.

A BOF should be a place where you, the attendee, go with either A) some interest or B) a burning question. If you’re in Camp A, then all you should expect from a BOF is exposure to ideas. If you’re in Camp B, then I think you should get something approximating an answer to that question. If not “the answer”, then at least guidance. But when BOFs get too big, it’s unlikely you’ll get that. Lots of things stand in your way, probably the most prominent of which is one or two topics (and people) dominating the conversation. It’s what humans do, and I won’t put upon a BOF some expectation that it transcend humanity.

In our BOF, we had at least three burning questions:

  1. What is TDD and how do I get started?
  2. How do I test database interaction (and perhaps other network-bound services)?
  3. How does TDD improve API design? (this is what I wanted to discuss, by the way)

A fourth lingering one was “How do I test ‘the entire app’?”, i.e. how does unit testing differ from integration testing (note that this has nothing to do with TDD at all).

This is simply too many needs to be met in an hour in a traditional BOF.

What a BOF should be

So what should a BOF be? If you’re in Camp B, it should be small and focused. BOFs sprung up lo those many years ago as a reaction to typical eyes-forward conference sessions. They’re a way to bring people together around a topic where everyone gets a chance to talk, not just a speaker. They are a discussion. They attempt to imbue a sense of the “hallway conversation” that conference-goers love to rave about. When BOFs get too big, they have failed this mission. Why is this? Perhaps it’s simply that anything that gets too successful becomes a victim of its own success. Let’s fix this.

How BOFs should be organized

BOFs should not be organized ahead of time, especially by conference organizers or speakers. Oh, I’ll  make an exception for “Meet the Team” events that you get at large conferences like Adobe MAX. Otherwise, they should be organic. This is simpler than it sounds. Here’s a recipe:

  1. At the beginning of the conference, put a chalkboard or whiteboard out in some open space. At smaller conferences like cf.Objective, this is in the lobby adjacent to the conference rooms. In a larger conferences such as MAX, this is … the same thing.
  2. Promote the chalkboard ahead of time, in emails to attendees, signage, Twitter, and other means. Make it obvious that this chalkboard thing is where you go to suggest BOFs
  3. Organizers can put headers on the Chalkboard: D1, D2, D3, C1, C2, “The Bar”, “The Bar with fancy Tequilas”… etc.  These are the available spaces. Call them D1:8pm and D2:9pm if you have multiple time slots
  4. People interested in a topic can write it under one of the slots. People who see a topic they’re interested in can put a line or some other marker underneath a topic to signify their interest in attending. Nothing fancy. Numbers don’t matter. A BOF of two is just as important as a BOF of 10.
  5. At the time of each BOF session, people meet in the room and ask around to see who’s here for what BOF. My gut says self-organization at start time will take no more than 5 minutes

In our TDD BOF, I wish we had course-corrected immediately… I wish we had realized the interests in the room and asked people if they wanted to break out into smaller groups. Unfortunately, at that time, it probably would’ve been too late. We’d have first had to figure out what those interests were and then hope that a leader emerged (by leader, I mean “the person who says ‘let’s go over to this set of chairs’).  If we were more prepared, we could have had an idea of what kinds of things people might be interested in and when we saw the group get large (this didn’t happen until about 10 minutes in, by the way), we could’ve thrown out those topics for show-of-hands and then broken out. But you should already see why this is a failure in the making: it’s an inappropriate time for such a thing, considering by the time “real talk” started, we’d have been 15 minutes into it because ad-hoc organization is always more chaotic than if the organization had been happening – on the chalkboard – all week long.

There is a precedent

If this sounds strange to you… if this violates some sense of control that you feel needs to be exerted by those-in-charge, know that what I’m proposing here isn’t an original thought, and it’s not untested. In fact, entire conferences are run this way (Google “open space conference”). The entire Java Posse roundup is largely run this way, and it’s a smashing success (not because of attendance numbers, but by a far more important criteria… attendee reaction).

Imagine

You go to an eyes-forward conference and you have a list of topics to attend during normal hours. But you also have a burning question. You put it on a board. One other person comes. You talk for an hour about your shared interest. You might learn something, teach something, make a friend, make an acquaintance, learn “I can’t stand this person”, learn “I want to start a business with this person”. Maybe you yank out a laptop and code for an hour together. You never know where it might lead. It’s unpredictable, and energetic.

That’s the kind of spontaneity that is the hallmark of a great BOF.

Conference organizers: make it happen.

Changing ColdFusion Builder file encoding

Thursday, April 1, 2010

A few of our source code files contain Spanish text strings and smart quotes (i.e. curly quotes) copied from MSWord and pasted into Eclipse. These “special characters” have never caused problems in CFEclipse, but they were showing up as little boxes in CFBuilder:

cfbuilder_encoding_1

I knew it was a file encoding issue but couldn’t solve it. The default text file encoding (window – preferences – general – workspace -– Text file encoding) was Cp1252, which was the same as CFE. However, viewing the properties of a file showed that the file was UTF-8 in CFBuilder but still Cp1252 in CFEclipse.

To get CFBuilder to behave like CFEclipse with respect to file encoding:

  1. Window – preferences – general – Content Types
  2. Expand the “Text” tree
  3. Select “CFML Source File”
  4. Down at the bottom, change the Default encoding

cfbuilder_encoding

Warning: I wouldn’t change this setting unless you’re experiencing this problem yourself. To be clear, this falls into the “if you must do dumbass stuff like copy text from Word into Eclipse and retain the funky characters, then here’s how to fix it”

Jira: Creating a custom description template


It’s hard work getting your team to enter bugs/issues into your issue tracker (“can’t I could just email you?”), and it’s even more difficult getting them to provide enough description to make the issue summary helpful. As the person who’s job it is to report issues to you, they need to “transfer context”. They know this bug intimately, either because they found it themselves or a customer/user reported it to them.

You – our heroic developer – don’t know anything about the issue. They want you to fix it quickly, and you want to fix it quickly… so why is it so damn hard to get them to understand that the more detail they provide, the faster you both get what you want?

I don’t have any good answers to that question, but I’m hoping this tip can help you incent them to give you more of what you need.

Editing the Description textarea

Often, you want users to enter the following:

  1. a link to the page that’s causing troubles
  2. relevant IDs (order ID, for example)
  3. a description of the behavior they expected
  4. a description of the actions they took that resulted in the unexpected behavior

Here’s what my description template looks like:

jira_description

You probably have others. To Pre-populate your with a customized template:

  1. Navigate to your jira install directory. Drill down to WEB-INF\classes\templates\jira\issue\field
  2. Save a copy of description-edit.vm (to be safe)
  3. Edit description-edit.vm, like so:
#controlHeader ($action $field.id $i18n.getText($field.nameKey) $fieldLayoutItem.required $displayParameters.get('noHeader'))

## setup some additional parameters
$!rendererParams.put("rows", "12")
$!rendererParams.put("wrap", "virtual")

## marc's custom hoogie
#macro( setDescription )
-- All your custom stuff goes here --
SYSTEM: Dev  |  Test   |   Staging |  PROD

LINK TO DEMONSTRATE BEHAVIOR:

ACTUAL BEHAVIOR:

EXPECTED BEHAVIOR:

STEPS TO REPRODUCE:
-- your custom stuff ends here --
#end

## let the renderer display the edit component

#if ($description=="" || !$description)
#set ($description = "#setDescription()")
#end

$rendererDescriptor.getEditVM($!description, $!issue.key, $!fieldLayoutItem.rendererType, $!field.id, $!field.name, $rendererParams, false)

#controlFooter ($action $fieldLayoutItem.getFieldDescription() $displayParameters.get('noHeader'))

Restart Jira

That’s it!

You can read more about customizing Jira templates here.

Mylyn: Creating new Issues from TODO comments

Wednesday, March 3, 2010

On Twitter, the Eclipse PDE lead commented on a neat feature of Mylyn that I hadn’t seen before: the ability to add issues/bugs into your issue tracker directly from the “Problems” view. I wanted to see if you could do this from the “Tasks” view if you entered “TODO” comments into your CFML, and sure enough, it works. As of this writing, CFEclipse supports TODO tasks but ColdFusion Builder does not. Please consider voting for this feature request.

What I love about this feature is that you can fairly seamlessly create tasks and attach your context for that new task in less than a minute. When executives yammer on about “Work Smarter, Not Harder”, Mylyn features such as this exemplify the “work smarter” mentality. The point here is that you reduce friction in two areas: 1) creating the task with relevant information, 2) sharing your context with the developer to whom you’re assigning the task.

Reduced friction == Increased Productivity.

Here’s how:

In Words:

  1. In CFEclipse, enter a TODO comment in your source code, Something like <!--- TODO: make this thing actually work --->
  2. Open the “Tasks” view – notice your TODO is now in the that view as a new task
  3. Right click on that table row, and select “New Task from Marker”
  4. This will bring up the screens necessary to add the issue to your issue tracker (or enter as a “Local task” if not using an issue tracker)

To then attach that file as the “context” for the issue:

  1. Activate the new task
  2. Navigate back to your file that contains the “TODO”. This file will now be part of the context for the issue
  3. In the Issue editor, go to the “context” tab and click the “Attach Context…” link. Follow the steps to completion
  4. Note that this is the same thing I wrote about previously

Now, when the developer to whom the issue is assigned (even if it’s you) opens this issue, they’ll be able to retrieve the context and get working on the file you want them to work on without having to navigate a single tree.

If this ain’t Jedi effect smoothness, I don’t know what is.

Happy Coding.

Mylyn and Jira: Sharing Context with Another Developer

Tuesday, March 2, 2010

When working on a team of developers, it sometimes is useful to reassign an issue to another developer. In Jira, you simply hit the “Reassign” link; this is standard amongst all issue trackers worth their salt.

Wouldn’t it be nice if you could also copy your Mylyn context? If you could say “I’ve been working on these 5 files, and when I reassign this issue to you, you’re going to get the same view of the world as me so you don’t have to figure out what files are involved in this issue”?

Here’s how:

In Words

  1. In ColdFusion Builder or Eclipse, In the Issue editor for a given issue, go to the “Context” tab
  2. It will show you all the elements associated with your context
  3. In the upper left, Click the “Attach Context” link. Follow to completion. This will attach your context to the Jira issue
  4. When the other developer working on the issue activates it, Mylyn will recognize that they do not have any context for the issue yet and will prompt them to open your context.
  5. When they do so, it’ll open up just the files you had attached to the context

Awesome!

Big Caveat: This relies on both developers having projects that are named the same

Mylyn and Jira: A Short Tutorial

Monday, March 1, 2010

Recently, I wrote about why I believe Mylyn is an indispensable tool for developers on the Eclipse platform – this includes CFEclipse and ColdFusion Builder users. I also wrote about my favorite Mylyn-related toolbar item.

Today, I created a screencast that quickly shows how to link Mylyn to a Jira instance:

In Words:

In Eclipse or ColdFusion Builder:

  1. Window – Show View – Task Repositories
  2. Right click in the view and select “Add Task Repository”
  3. Select “Jira”. If it’s not in the list, hit the “Install More Connectors” button and install the Atlassian  Connector from there
  4. Hit “Next”
  5. Enter the URL to your jira install, label it, and enter your credentials
  6. Expand “Additional Settings”.
  7. I like to set the “Refresh Configuration Automatically” checkbox and I limit the search results to 100. Do whatever you like
  8. Hit the “Validate Settings” button at the bottom. Then hit “Finish”
  9. It’ll prompt you to pull in a Query from Jira. These will be your saved filters, which will include Jira’s default filters in addition to any custom filters you’ve created
  10. Select a filter or create  a new query. Hit enter and wait for them to load.

Exult!

 

Once you’ve done that initial bit of setup, you’re ready to rock. You can now work with Mylyn from the “Task list” view (this will be your main Mylyn view). If you want to include other filters, do this:

  1. From the “Task List” view, right click and select “New Query”
  2. Select your jira install, and hit Next
  3. You can create a new query with the query builder form, OR:
  4. You can use a saved filter from your Jira Install. I like this method
  5. Select the “use saved filter” radio button, and select a filter. If you’ve added one that doesn’t show up in the list, hit the “Update from repository” button
  6. Hit “Finish”

Your filter will now show up as a new tree item in the Task List view

Happy Mylyn-ing!