Wide Awake Developers

The Dumbest Thing I’ve Seen Today

| Comments

I generally like Swing, but I just found something in the Metal L&F for JSlider that strikes me as a big WTF. The BasicSliderUI allows you to click in the "track" of the slider to scroll by a block. That’s either 10% of the span of the slider, or a minimum of 1 unit. The MetalSliderUI overrides that sensible behavior with a method that scrolls by just one unit. Period.

Here’s a quick fix:

JSlider slider = new JSlider(); 
slider.setUI(new MetalSliderUI() {
  protected void scrollDueToClickInTrack(int dir) {

Technorati Tags: java, swing

Programmer Productivity Measurements Don’t Work.

| Comments

Programmer productivity measurements don’t work.

The most common metric was discredited decades ago, but continues to be used: KLOC. Only slightly better is function points. At least it’s tied to some deliverable value. Still, the best function point is the one you don’t have to develop. Likewise, the best line of code is the one you don’t need to write. In fact, sometimes my most productive days are the ones in which I delete the most code. Why are these metrics so misleading?

Because they are counting inventory as an asset. Lines of code are inventory. Function points are inventory. Any metric that only measures the rate of inventory production is fatally flawed. We need metrics that measure throughput instead.

Technorati Tags: lean, agile

More Beanshell Goodness

| Comments

Thanks to the clean layered architecture in our application, we’ve got a very clear interface between the user interface (just Swing widgets) and the "UI Model". In the canonical MVC mode, our UI Model is part controller and part model. It isn’t the domain model, however. It’s a model of the user interface. It has concepts like "form" and "command". A "form" is mainly a collection of property objects that are named and typed. The UI interacts with the rest of the application by binding to the properties.

The upshot is that anything the UI can do by setting and getting properties (including executing commands via CommandProperty objects) can be done through test fixtures or automated interfaces. Enter beanshell.

After integrating beanshell, all of our forms and properties were immediately available. Today, I worked with one of my teammates to build a beanshell script to drive through the application. It creates a customer and goes through the entire workflow. Run the script a million times or so, and you’ve got a great pile of test data. Schema changes? Domain model changes? No problem. Just re-run the script (and wait an hour or so) and you’ve got updated test data.

Technorati Tags: java

Smalltalk Style Prototyping for Java?

| Comments

I’ve been eyeing Beanshell for some time now. It’s a very straightforward scripting language for Java. Its syntax is about what you would expect if I said, "Java with optional types and no need to pre-declare variables." So, a Java programmer probably needs all of about thirty seconds to understand the language.

What I didn’t expect was how quickly I could integrate it into my applications. Here’s an example. I’ve got a Swing desktop application for which I wanted to add a small command shell pane. I spent about an hour working with Swing’s JTextArea and rolling my own parser. It was late at night and I was short on bright ideas. Finally, about the time I realized I was going to need variables and flow control, I pulled the emergency stop cord and backed up.

After downloading the full beanshell JAR file (about 280K) and adding it to my build path, all I had to do was this:

JConsole console = new JConsole();   
frame.getContentPane().add(new JScrollPane(console), BorderLayout.SOUTH);  
Interpreter interpreter = new Interpreter(console);   
new Thread(interpreter).start(); 

Those four lines of code are literally all that is needed to get a beanshell prompt running inside of your application. From the prompt, you have access to every class and method within your application. If you’ve got some kind of object registry or namespace, or any kind of Singletons, then you’ll also have access to real object instances.

Beanshell has a built-in command called "desktop()". The one line will launch a Smalltalk-style IDE, with class browser and interpreter window. This desktop is still part of your application’s JVM. It lacks most of the power of Smalltalk’s library, which evolved together with the workspace to support highly dynamic programming. Nevertheless, the beanshell desktop retains the immediacy of working in Smalltalk.


  • Beanshell
  • Squeak - a Free, modern Smalltalk
  • Java Object Inspector - A simple Swing-based inspector, can be launched on any Java object from a Beanshell prompt. A great complement to Beanshell

Technorati Tags: agile, java

One of the Most Fun Features of My Current Project

| Comments

One of the most fun features of my current project is our "extreme feedback monitor". We’re using CruiseControl to build our entire codebase, including unit tests, acceptance tests, and quality metrics, every five minutes. To make a broken build painfully obvious, we’ve got a stoplight hanging on one wall of the room. (I may post some pictures later, if there’s interest.)

Kyle Larson found the stoplight itself in a gift shop (Spencer’s, maybe, I can’t remember… Kyle, help me out here). It had just one plug but you could push each light as a separate switch.

Well, it looks pretty dumb to walk over and push on the red light to show a broken build. It’s not pragmatic and it’s not automated. So, Kyle rewired it with two additional cords, so each lamp has its own plug.

I plugged each lamp into an X10 lamp module so each color could be turned on and off individually. I hooked a "FireCracker" wireless transmitter up to the serial port on the build box. With one switched receiver and two lamp modules, we were ready to go.

CruiseControl supports a publisher that is supposed to integrate directly with X10 devices over the serial port. Unfortunately, the installation and setup for Java programs to work with X10 devices on Linux is… problematic. First off, the JavaComm API appears to be totally stagnant. It does not support Linux at all, so you have to install the Solaris SPARC version, but supply an open-source Linux implementation of the API (www.rxtx.org), replacing a .properties file. Then you have to make sure that the user running your build loop is a member of the "tty" group. Then just cross your fingers.

I got all of the above to work from my Java test apps, but the X10 publisher built into CC still couldn’t open the serial port.

I finally gave up on the built-in publisher. I used wget, BottleRocket, and a shell script to check the build status web page every 30 seconds and change the lights accordingly.

Now, within a minute of a broken build, we can all see it. When the light is green, the build is clean.

If the red light means "broken build", and the green light means "good build", you might wonder what we use yellow for.

Yellow means that someone is in the process of synchronizing and committing code. Along with the FireCracker module, we also got a remote control. That normally sits in the middle of the tables in the lab. Whenever a pair needs to check in code, they grab the remote (i.e., take the semaphore) and turn on the yellow light. As an added "feature", the wireless switched receiver is the only module that makes an audible "click" when it switches. We use that one to control the yellow lamp, so we also have an auditory cue when a pair starts their commit dance.

After committing, the pair turns off the yellow light and replaces the remote, thus putting the semaphore and allowing the next pair to commit. In the event of multiple blocked pairs, FIFO behavior is not guaranteed. Semaphore holders have been known to be susceptible to flattery and bribery.

Technorati Tags: agile, automation, CruiseControl, pragmatic

I Forgot to Mention That I Will Be Speaking at OTUG

| Comments

I forgot to mention that I will be speaking at OTUG on April 19th! I will be speaking on "Living With Systems in Production: Avoiding Heartbreak in Long-Term Relationships With Your Code"

From the summary of the talk:

Everything changes after Release 1.0. One batch of consultants leave, key developers jockey to get themselves reassigned, and the free-wheeling development environment is replaced by the painful rigor of operations. Or, at least, it should be. Systems in production require a different kind of care and feeding. If you have to live with a system in production, your quality of life is largely determined by the things you put in place before Release 1.0. This talk covers the topics that will give you God-like powers over your production systems. If you are an architect or developer who has ever put a system in production–or expects to put a system into production–then this talk is for you.

Much of this will be derived from my experiences at Totality and Best Buy. Spending time in operations gave me a great education about building systems to run, instead of building them to pass QA.

Technorati Tags: operations, OTUG, speaking

Leaving AntHill for CruiseControl

| Comments

We’ve been using AntHill to do continuous builds. It has served us well, but we’re now moving away from it and towards CruiseControl.

There are a few main reasons for this. First and foremost, AntHill runs inside of Tomcat. This is billed as a feature, but for us, it was a big problem. There are two layers of Java containers between your OS and your build. Trying to get environment variables (like "DISPLAY=localhost:99.0") passed from an init script, to Tomcat, to AntHill, to ANT, was just becoming too burdensome.

We also experienced some serious classpath pollution. Some things just acted differently between ANT builds on our development boxes and ANT builds on the build box. That’s unacceptable, but we found that with AntHill it was impossible to eliminate the differences. Finally, through some jar file unpacking and decompilation, we found that our builds were picking up classes from AntHill’s ow n jars.

The ability to fix these things exists, but only in AntHill Pro. I downloaded CruiseControl today and spent an hour going through the quick start and FAQ. At the end of it, I had our build process replicated on CruiseControl.

I did run into a problem… the checkstyle task that we have been running as part of our build all along started failing. I assumed that it was something wrong with the build box, or with my project configuration for CruiseControl. After half an hour or so, I ran the same build on a dev box, but from the command line. It failed there, too. It turns out that checkstyle includes a version of the Jakarta commons-collections classes that is not compatible with the Jakarta digester version that we’ve added to our code base.

This problem existed all along. Running the build under CruiseControl was enough like running it from the command line that it uncovered a problem which had been present for over two weeks. For some reason, running under AntHill never revealed this problem.

Bottom line is, a CI server needs to be as close to running a command-line build as possible. If I have to spend time figuring out what environmental conditions the CI tool is imposing on my build, then it is defeating the purpose.

Now, I just have to figure out why in the hell checkstyle’s classpath is leaking into the classpath of the code it is checking.

Technorati Tags: agile, automation, CruiseControl, pragmatic

The Veteran and the Master

| Comments

The aged veteran said to the master, "See how many programs I have written in my labors. All of these works I have created needed no more than a text editor and a compiler." The master said, "I do have an editor; indeed, I have also a compiler."

Said the aged one, "Yet you shackle them within an ‘environment’. Why must your environment be integrated? My environment has never been integrated, yet I am a mighty programmer."

The master said, "You are truly a mighty programmer. I perceive that you, in your keen intellect, can hold entire class hierarchies in mind at once. Such abilities of apprehension are to be respected."

The veteran was well pleased and said, "It is true. Hence I am lead programmer."

The master nodded. "Sadly, I have not your powers of visualization. I cannot hold entire hierarchies in my minds eye at once. In my limited faculties, I must focus entirely on one class at a time. The tool remembers the rest, as I cannot."

Emboldened, the aged veteran boasted, "See the commands fly from my fingertips! I type faster than other programmers think!"

Again, the master nodded his agreement, "I am not so blessed with speed as you. It is a burden and a trial to move so slowly. Behold, this measure of the marvel of your fingers. Such is the flight of your keystrokes that in the time it takes you to execute a regex replace across thirty files; compile the project; note the errors; and edit the twelve files with failed replacements; I will have barely completed the ‘rename refactor’ which I started by typing shift-alt-r."

Brazen in his opponents weakness, the veteran cried, "While you sit meditating at the green bar, I pound out another four thousand lines of code!"

Again, the master nodded, "Yes. And worse, while you write the next thousand, I will surely erase a thousand more, leaving us barely past where we began. It is clear that I cannot long contend in this field against such as yourself."

The battle-scarred veteran, his opponent beaten, laughed aloud. Barely bothering to express his contempt, he sneered, "And what fine code it is, too! You write a fraction of the code a real programmer could produce. As a coward in the grain, you shrink from any real challenge. Fearing to tread where real programmers dwell, you trade in coin like a merchant, purchasing the work of others, or worse, living on the charity of those motley-clad coders who give away the fruits of their work."

"Again, your perspicacity has unmasked me," said the master. "Knowing myself to produce bugs in my code, I prefer to write little of it. I do rely upon the work of others who, if not being smarter than myself, are at least more numerous than I. Had I your fleet fingers, I might not need to download these gifts offered by others. Indeed, I am certain that your mighty editor would surely outpace my mere web browser, and you could then code a new SVG renderer long before I will finish downloading Batik to do the same work. Alas, lacking your skills, I must fend for myself as best I can by reusing that which I can. Since each line of code costs me so greatly, it behooves me to write little, and I must needs make use of what aids I can."

Shaking his head, the aged veteran stalked away, safely assured that he had gauged the so-called master truly. He returned to his labors, building a parser for the scripting language of his workflow engine. This would be placed inside of an application that would someday have users.

Shaking his head, the master returned his eye to the red bar of his users’ new acceptance tests. Reaching deliberately for the keyboard, he changed two methods and added one test case. In the serene green light of the test bar, he reflected a moment on the code he had added. Unruffled by the staccato typing in the direction of the veteran, he renamed four fields, extracted a method, and pulled it up into a new base class. Comforted by the tranquil green light, the master rested his hands a moment, then lifted them from the keyboard and walked away.

From the corner of his eye, the veteran observed the master leaving. "Charlatan," he snarled, as the regexes flew from his hands, long, long into the night.

Technorati Tags: agile, lean, pragmatic

On Relativism and Social Constructions

| Comments

The key operative precept of post-modernism is that all reality is a social construct. Since no institution or normative behavior stems from natural cause, and there is no objective, external reality, then all institutions and attitudes are just social constructs. They exist only through the agreement of the participants.

Nothing can be sacred, since sanctification comes from outside, by definition.

If nothing is sacred, and institutions have no more reality than a children’s amorphous game of ball, they deduce that any construct can be reconstructed through willful choice.

Even if you accept the precept that there is no objective, external (let alone universal) value system, you can still see the fundamental fallacy in this thinking.

Anyone who has ever tried to bring change into a hidebound organization knows that social constructs are far harder to change than any physical or legal structure. You can reorganize units, bring locations together, shuffle management, or get rid of half of the people. Still, underlying social organization will re-emerge as long as there is any vestige of continuity.

Much of the heat energy in the ongoing culture war arises from this inertia. Those who are so tiresomely labelled as "liberal", "progressive", the "Left", the "Cultural Elite", etc. represent a large force of people aimed at deliberately reconstructing every institution in Western life. They have decided, based on their own feelings, bereft of natural or religious law, that any institution observed by men for more than one hundred years cannot be endured. They are organized around the post-modern paradigm–armed with Hayakawa and Chomsky–and don’t accept that some hidebound Neanderthals will not welcome forceful re-education.

I suppose that I follow a third way. I can agree that our institutions are social cosntructs. That does not mean that they can, or should be, tampered with lightly. The concept of "natural law" teaches that certain modes of behavior, certain morals, generate a more successful society. Our social institutions–like marriage–have undergone the same forces of competitive pressures and differential reproduction that drive neo-Darwinian evolution. That means the institutions we observe today–such as preserving the integrity of personal property–are the ones that worked.

There is an argument to be made that I’m advocating cultural imperialism. It could perhaps be seen that way, though such is not my intent. Rather, just as we should justifiably be wary of changing our own genetic code, we should be wary of making large changes to our social institutions. We do not know what will result. There are many paths down the mountain, but only one upward. Most random mutations result in death. Even well-planned changes have unintended, sometimes catastrophic, effects.


An IKEA Weekend

| Comments

I’ve been building a new office in my downstairs space for quite a while now. It’s a "weekends" project for someone who doesn’t have very many weekends. In early December, I broke down and hired a contractor to install the laminate ("cardboard") flooring, which was the penultimate step in the master plan.

Last comes furniture, then moving in. (Which starts the chain of dominoes, as my eldest gets the bedroom which used to be my office, then my youngest takes her spot, which makes room for the new baby. The challenge is to finish with the hole migration before the new electron gets injected. No, that wasn’t a spelling error.)

So this weekend, I had thirty-six boxes of IKEA modular furniture from "Work IKEA" to assemble.

You have time to meditate on many lessons when you are assembling thirty-six boxes of IKEA modular furniture.

For example, I’ve never seen a company that makes it so difficult to purchase from them. I don’t really want to know that the six-shelf bookshelf I picked out from the design software actually comes as three separate SKUs. Just sell me the damn shelf.

I shouldn’t have to learn what a "CDO" is in order to pick out a bunch of stuff and have them deliver it on a specific day. I shouldn’t have to make three trips into the store because they cannot take my credit card number over the phone.

And can someone please explain why I have to remove items from my delivery order because the local store doesn’t have them in stock? In some fields of endeavor, timing is everything, but why should I have to call them every day to find out when the left-handed tabletop comes in, then rush to the store and place my order so the piece can be pulled from inventory?

It makes no sense to me. The whole process was implemented for the convenience of IKEA, not IKEA’s customers. They’ve made a business decision to optimize for cost control rather than customer satisfaction. IKEA is certainly free to make that choice, and they do seem to be making profits, but I’m not likely to choose them for future furniture purchases.

Exposing that much of your internal process to the customer–or end user–is never a good way to win the hearts and minds of your customers.

Most of the assembly went without incident, though I was often perplexed by trying to map the low-level components into the high-level items I designed with. IKEA offers zero-cost software for download to design a floorplan with their lines, but it works at a higher level of abstraction. I was often left wondering which item a particular component was supposed to construct.

The components were very well designed. Each piece can either fit together in only one way, or it is rotationally symmetric so either orientation works. In either case, I, the assembler, am not left with an ambiguous situation, where something might fit but does not work.

The toughest pieces were the desks. Desks can be configured in about eighty-nine different ways. The components are all modular and generally have the same interfaces. I have a lot of flexibility at my disposal, but at the expense of complexity. A significant number of sample configurations helped me understand the complexity of options and pick a reasonable structure, but I can’t help but wonder how the experience could be simplified.

The furniture is all assembled now, and the office sits expectantly waiting for its occupant, full of unrealized potential.