ColdFusion: Using Java Beans
Posted by Eric in ColdFusion, Programming on June 9th, 2009
A while back we were working on a huge new website in ColdFusion which was a rearchitecture of an extremely mature but very worn out code base. One of the biggest things we wanted to do was adopt a substantially more object oriented approach to development as the original site was started in the ColdFusion 4.5 days.
However we very quickly ran into the problem that many ColdFusion developers have faced (in fact there was even a session on this exact subject at CF.Objective() this year). ColdFusion objects have a substantial overhead to instantiation. Java programmers create hundreds or thousands of disposable objects for even fairly simple tasks. They create objects for things they don’t even realize they’re creating objects for (ints, Booleans, Strings, even lots and lots of Char objects as a string has a Char array in it with one object for each character in the string).
ColdFusion developers can’t be so cavalier with their object creation though. Of course under the surface of ColdFusion is its Java runtime, and so there are plenty of Java objects created under the hood, but when it comes to ColdFusion components, you really need to limit how many you create.
If you try a traditional bean approach to programming in ColdFusion (one data container object for each distinct thing you’re working with - eg one for each query row in a result set), you’ll discover that your application quickly crawls to a halt under any serious load. ColdFusion simply cannot afford the overhead of creating so many components.
There are two main approaches to solving this problem. One is aggressive use of caching of components, and sharing components between users. This is not really a bean approach, at best it could be considered “inspired by,” and it raises quite a few complications of its own, including increased memory footprint, and dangers introduced when one user is modifying a shared object while other users are using it.
The other (and the one I prefer, but it’s a bit less convenient) is to create your beans in Java. Here is a simple bean:
The advantage of this approach is that you can create tons and tons of disposable copies of this object with very little performance penalty. In fact it should be no more expensive than creating a Struct of properties - but you get the benefit of type safety and guaranteed properties. You can also add convenience functions like:
This way you can:
and get “A 1999 Chevy Cavalier. This was not my first car.” as your output.
Coming soon:
- How to build and bundle your beans
- Using the Java enum construct for enumerable properties
One Man’s View is Another Man’s Data
Posted by Eric in Frameworks, Programming, Software on May 19th, 2009
I think it’s common for a developer to get the idea in his or her head that developing under an MVC (Model View Controller) paradigm is ultra cut and dry: There is one Model, one View, and one Controller for a given task. Within a given layer of the software stack this may often (or even always) be true.
However: all software produces something (in its view) which is consumed by the next higher tier of the software stack as data, and thus is only part of the model for that next stack. All software produces something to be consumed by something else. What is to you a view is to someone else data.
So it’s important to avoid thinking that there’s something special about your particular view (no matter where you are in the stack) - as if it’s somehow magical and the view. You’re never the end of the line, it doesn’t matter how far down the line you really are. The end of the line is the brain of the human who will ultimately consume this data. Even then they’re not the end of the line, they process that data, make decisions based on it, and produce some output of their own - whether it’s using it to produce new data for the next action within the application, taking that data elsewhere as an input to a different process, or storing it to memory for later use as data for a future process.
Let’s look at an example from web development. The PHP/ColdFusion/ASP.NET/Ruby/FOTM developers I know tend to think of themselves as the end of the line (and I have too to a substantial extent). They’re producing something to be consumed (as they see it) by the end user. This is the guy who gets to make the HCI (Human-Computer Interaction) interface that either creates a positive experience for the user, or a negative one. Everything past him just follows the instructions he produces. Bold this, outline that, send this data there. What’s harder to see is that he’s just following the instructions he was given by the user and producing data in a format that other software later in the stack requires of him.
What the web developer calls data is actually just a view provided by lower down in the stack (a database typically, which in turn gets a view of stuff from the filesystem which it calls data, etc). A web developer’s view (HTML typically) is just data to the web browser. The web browser’s view (graphical representation) is just data to the display driver. The display driver’s view (bits of light on a computer monitor) is just data to the user.
The software stack starts and ends with the user. If anything is sacrosanct, the ultimate MVC, it’s the user. But as I’ve already said, the user ends up just starting the cycle again, maybe she uses that data to feed the computer again, or maybe she uses that data for another purpose.
So don’t get caught up in “HTML is the view, XML/SOAP is data,” it’s all data to someone, and therefore it’s all a view to you. Don’t think there’s something special about one way to structure data vs another way to structure data. Finally don’t create different channels depending on what consumes your data. Use the same data channels (Model/Controller) and provide a different View. That is after all what the purpose of a View is all about - consumer agnosticism.
CF.Objective() So Far
Posted by Eric in ColdFusion, Programming on May 14th, 2009
So far I’ve been to two really good sessions at CF.Objective(). The first I was dubious about, “Indiana Jones and the Server of Doom,” but I actually learned some things about low-level memory management within ColdFusion, and I can definitely say I’ve got something new to check out on production boxes when I get back to the office. I’ll post more on that later.
Also the session from Adobe where they were highlighting server administration in the upcoming ColdFusion 9 was fantastic. It’s almost like they took a list of the things which cost the most time when maintaining servers today, and created all-new functionality to make managing this much easier. I’m very excited by this, things that are being manually configured on many, many instances today will be able to be rapidly and widely deployed when ColdFusion 9 (Centaur) comes out.
As with all conferences there are going to be times when there’s not much directed at your skill level. This is because there are people of all walks here, from new developers to seasoned experts. I fall somewhere in between, and so I’m doing pretty well on finding good sessions overall.
Next up: Advanced Subversion Techniques (”Subversion for Smarties”). Here’s hoping it’s not review =)
ColdFusion Ordered Struct
Posted by Eric in ColdFusion, PHP, Programming on May 12th, 2009
As most readers probably already know, in ColdFusion, structs are associatively keyed storage structures similar to an array but where you get to use a string to key an entry rather than only a sequential number.
PHP only has array() which acts both like ColdFusion’s array and struct both. You can numerically key arrays or associatively key them, or both. One of the reasons it can get away with this is that it preserves the insert order. So if you do:
The output will be the values in the same order they were put into the structure. If you do the same thing in ColdFusion, you’ll get it back in a seemingly random order (or depending on the version some times you’ll get back in alphabetical order):
Instead if you need to preserve insert order, you can use a similar Java object from ColdFusion:
You can treat this like a struct in every way, including <cfdump>ing it (though cfdump will not show you the insert order for some reason). As you iterate over it, the contents will always come back in the same order they were inserted.
It’s important to note that LinkedHashMap keys are also case-sensitive while ColdFusion Struct keys are case insensitive. This may cause undesired results as you might have two keys that you believe are the same but differ in case; this may cause collisions when working with other objects that are not case sensitive.
CF.Objective() Here I Come
Posted by Eric in ColdFusion, Programming on May 12th, 2009
Heading off to Minneapolis tomorrow morning for CF.Objective(). This is the first conference I’ve been to in a while. Hoping we get to hear some about the next version of ColdFusion and the Bolt IDE (I’ve played with it some; I can’t say a lot, but I can say that it’s got some fanstastic features).
ColdFusion Including Sub-Applications
Posted by Eric in ColdFusion, Programming on May 30th, 2008
Ben Nadel has an interesting question on his blog about including sub-applications from within an existing CF application, and having the relevant sub-level Application.cfc fire off.
This is doable in a fairly simple manner but which relies on a barely-documented feature of ColdFusion, and the fact that the sub-level Application.cfc fires is completely undocumented, and may even be unintentional!
Here’s how you can do it, but because we’re wandering into a pretty hazy gray area here, I wouldn’t go using this unless you don’t have much other choice.
Application.cfc:
Then you can do the below and if it has an Application.cfc, that application.cfc will be invoked.
The caveat though is that CGI scope will still contain the variables from the source page - for example, CGI.SCRIPT_NAME will still be the script name in the URL. As a result, context-sensitive functions like ExpandPath() will operate relative to the root file being called - meaning you might not get the results you’re expecting.
Also the code above will only work 1 sub-application level deep; you’d have to tweak it if you wanted a sub-application within a sub-application, but by that point, zounds, what are you doing man?!?
The good news is that even if the sub-application executes a <cfabort>, execution will return to the calling page, so that sub-app can’t abort your own page.
Established Programmers Getting Started in Web Development
Posted by Eric in Programming on May 21st, 2008
An acquaintance of mine has recently graduated from college with a degree in computer science. Where he went, apparently they stressed theory over practice. He’s got some C++, Lisp, Java, and MySQL experience, but has never touched web development (neither HTML, nor even viewed source on a web page).
He’s hoping to get a job with a company that has him supporting Java applications with web front ends, so to do that he’ll need to get at least tolerable with HTML. He’s willing to go to training if there’s a course that’ll help, but the obvious concern is that he goes to a 5 day training and spends a significant amount of time covering “Web pages are viewed in web browsers” type material - that is to say, he’s concerned that intro to web development courses are going to be tailored to people looking to set up a family-newsletter or small-business-created-by-the-owner type site.
I’m recommending he start with the W3C tutorials: http://www.w3.org/2002/03/tutorials , which should get him a functional early level of knowledge. I suggested he could start out trying to make a personal site in HTML w/o leaning on a HTML editor, hopefully this gets him the rudimentary skills he needs. Other suggestions are welcome!
WebScarab-NG
Posted by Eric in Debugging, Programming on May 9th, 2008
WebScarab-NG is a really amazing tool that Brian introduced me to a few months back. It’s essentially a local proxy which you can use to capture the full details of HTTP requests traveling through it. It listens by default on port 8008 on your local address, and you can configure any software to use that port as a proxy.
If you choose, you can even configure it to intercept requests and responses, and it allow you to modify the data on the fly - really useful when you want to test fault circumstances.
How UTF-8 Encoding works
Posted by Eric in Programming on May 3rd, 2008
I spoke yesterday about Unicode, and the difference between the Unicode character set, and specific encodings of this character set. This post is a follow-up which describes in detail one particular and popular character set - UTF-8.
It’s imortant to understand that encoding is simply a means of representing a Unicode character in terms of bytes on a disk or in a network stream. In the same sense, the character λ can be encoded in HTML as one of: &lamda; , λ , or λ. These HTML entities are another form of character encoding.
To understand how UTF-8 encodings work, we have to be really certain that you have it in your head that a byte and a character are different things. Just like encoding special characters in HTML, a character in UTF-8 can be made up of one or more bytes. Such encoded characters are called muti-byte characters, because they require 16, 24, 32 (or sometimes but rarely more) bits to represent this character, corresponding of course to 2, 3, and 4 bytes.
Because each character is not made up of a fixed number of bytes, UTF-8 is called a variable-width encoding. Variable-width encodings are popular because they can reduce the storage size of the most common members of that encoding. For example, this page is encoded in UTF-8, and yet almost every character in its source code will only require a single byte.
The UTF-8 encoding is popular because especially for speakers of Latin-based languages (Europe, USA, et al.) it only requires one byte per character for our most common printed characters. Also, and unlike some other character encodigns, existing text encoded as ASCII (the old IBM PC days of 7 bits per byte - the first 128 characters in an ASCII table) translates into UTF-8 without any need for conversion. UTF-8 also supports a very large range of characters (its charater repertoir).
To understand the way UTF-8 works, we have to examine the binary representation of each byte. If the first bit (the high-order bit) is zero, then it’s a single-byte character, and we can directly map its remaining bits to the Unicode characters 0 - 127. If the first bit is a one, then this byte is a member of a multi-byte character (either the first character or some followup of it).
For a multi-byte character (any character whose Unicode number is 128 or above), we need to know how many bytes will make up this character. This is stored in the leading bits of the first byte in the character. We can identify how many total bytes will make up this character by counting the number of leading 1’s before we encounter the first 0. Thus, for the first byte in a multi-byte character, 110xxxxx represents a two-byte character, 1110xxxx represents a three-byte character, and so on.
For secondary bytes in a multi-byte UTF-8 encode character, the first two bits are reserved to indicate that this is a follow-up byte. All secondary and beyond characters are of the form 10xxxxxx. It may seem wasteful to sacrifice two bits of each follow-up byte since by the time we reach this byte, we already know that it’s part of a multi-byte character. Indeed, it is wasteful, but it is intentional, and intended to address systems which do not properly handle multi-byte character encodings. For example, this enables us to identify if a string was encoded with an alternate character encoding but is being parsed as UTF-8. It also enables us to identify strings which were incorrectly truncated.
So characters in UTF-8 can be represented in binary as:
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
If you’re interested in further reading regarding Unicode and character encodings, a good place to start would be Wikipedia:
http://en.wikipedia.org/wiki/Unicode
http://en.wikipedia.org/wiki/Character_encoding


Recent Comments