Easily convert and copy information using Morph

Ever since I first got started programming and was exposed to different computer languages I’ve been annoyed at how difficult it is to convert information from one type to another. Not only does every language have its own way of doing this, often even within the same language there are multiple different methods that need to be learned to do conversions properly. I can’t offer a solution for every programming language, but I can offer a solution for Java: the Morph framework. The main goal of Morph is to make it really easy to take information in one format and make it available in another format. I am including some examples along with this article to show how easy it is to do all sorts of conversions with Morph. You can get a full list of the conversions that come out of the box here.

Morph.convert allows you to convert an object from one type to another. Here are some examples:


Integer three = new Integer(3);
// code without Morph
String string = new Integer(three);
// or (without using Morph)
string = "" + three;
// code using Morph
String string = Morph.convertToString(three);


String three = "3";
// code without Morph
Integer integer = new Integer(three);
// code using Morph
Integer integer = Morph.convertToIntegerObject(three);


String three = "3";
// code without Morph
int i= new Integer(three).intValue();
// or (without using Morph)
int i = Integer.parseInt(3);
// code using Morph
int i = Morph.convertToInt(three);

Morph.copy allows information from one object to be copied to another object. The object to which information is copied may even be of a different type than the source object. A great example of when you need to do this type of thing is when you need the data in an HttpServletRequest to be available to lower tiers in your application but you don’t want to tie your entire application to the servlet API. For example, let’s say you are trying to get your data prepared for a method with a signature IServiceInterface.service(Map data):


// without Morph
Map data = new HashMap();
for (Enumeration e=request.getParameterNames(); e.hasNext(); ) {
String param = (String) e.next();
data.put(param, request.getParameter(param));
}
// with Morph
Map data = new HashMap();
Morph.copy(data, request);
// actually with this particular example could also do
Map data = (Map) Morph.convert(Map.class, request);

You Had Me at Softlinks

Last week Ubuntu 7.04 was released. I thought I’d contribute to the hype by talking about why I love Linux. Before I do though, I just want to say I am not a zealot. I believe in the right tool for the right job — and I’m even forgiving of not-quite-so-right-but-comfortable tool for the right job. I use Windows all the time, but when it comes to development, I prefer Linux hands down.

I’m relatively new to the party. A couple years ago I had been hired at a Linux-only development shop. Fortunately, even two years ago, it was relatively easy to transition from Windows to Linux. Which isn’t to say there isn’t much to learn — but even with a shallow knowledge of Linux it was easy for me to get around. Like many programmers though, I need more than shallow knowledge, and began delving into the OS’s nuances.

Its through this exploration that I began to appreciate Linux. These short, terse commands I entered at the command-line — these aren’t just tools, they are the collective wisdom of the ancients. My handy bash-scripting reference talks about the evolution of the “echo” command for two pages! Clearly, most of the basic concepts of Linux have been honed and polished for two decades, and truly I feel as if I’m standing on the shoulder of giants with each “sed” or “cat” invocation.

Granted, you don’t need to know how a car works to drive it, and Linux was the same for me. Indeed, I had been piping commands to each other for years before appreciating the holy trifecta of stdout, stdin, and stderr.

For those who want to get their feet wet, you can run Ubuntu entirely from CD. There are even instructions for running Ubuntu as a virtual machine using VMWare. But doing a full-on, dual-boot installation isn’t difficult (though disk partitioning is always harrowing for me), and I’d encourage anyone to give it a shot.

Here are some reasons, in no particular order, why I prefer to do development work on Linux:

  • Command-line Console. Slowly I’m becoming a command-line ninja, and find it much easier to navigate my filesystem, and perform other operations, by typing.
  • Warm fuzzies when using open source software.
  • Softlinks. Besides being a very handy way to organize my filesystem, it never fails to make me giggle when I compare it to window’s *.lnk (“Shortcut to…”) equivalent.
  • Appropriate Verbosity. Most unix commands (cp, mv, chmod) don’t provide any output upon completion. Type “man cp” though, and you have a couple pages of describing the simple command’s functionality.
  • Easy Package installation. How do I install MySQL? “sudo apt-get install mysql”
  • Multiple Desktops. One for my mail reader, one for log-viewing (via Chainsaw), and one for my IDE.

Undoubtedly there are dozens of other reasons, and I look forward to finding even more.

Networking with Virtual PC 2007

I wrote a post last month about how impressed I was with Virtual PC 2007 and how it has changed the way I work. This is a follow-up about a networking problem that I didn’t discover until it was almost too late, as well as how to fix it.

I decided to install Vista Business on my laptop a few months ago, and aside from a few application compatibility issues, I’ve been pretty happy with it so far. One of the main problems is that Oracle 9i doesn’t work with Vista, and that’s a database we need to develop against. So, I fired up my Windows XP virtual machine, installed Oracle, and then connected to Oracle on the virtual machine just like I would if it were installed on another server. Everything was working smoothly… or so I thought.

A little background: The default networking option for your virtual PC is “Shared Networking.” This allows the virtual PC to share your host PC’s internet connection, but doesn’t allow the host PC to talk to the virtual PC. So, instead of using shared networking, I set the virtual machine to directly use my wireless network. Both the host PC and the virtual PC got separate IP addresses from the router, and could therefore talk to each other. The only thing I didn’t think about was that the second my laptop lost its connection to my router, I couldn’t communicate with the virtual PC.

So, there I was, minutes before a demo with an important client, and my application server couldn’t talk to my database, even though they were both on the same laptop.

The solution was relatively simple, but for some reason the information was really hard to find. First install Microsoft’s Loopback Adapter on the host PC, and then tell the virtual PC to use it for its network access. The process is explained very well here.

Version Labeling and Continuous Frustration

I approach continuous integration (CI) servers in the same way I do my IDE — as a tool of convenience for performing tasks I could choose to perform manually. I would no more have a build system reliant upon a specific CI server than I would write code that was only recognized by a specific IDE. Thankfully the CI servers with which I’ve worked conform to my philosophy. They do not seek to replace your build system as much as provide much needed automation. There is one area, though, where I feel CI servers violate this ideal, and that’s creating a unique build/version label.

Out-of-the-box, most CI servers provide a simple numbering scheme in order to produce a unique label for each build. Generating a build/version label is a task I prefer to happen within the build itself, so that the build is truly self-contained. Take our builds, for example. I’ve made use of the ant task buildnumber, so, upon a build, ant reads and increments a build-number property file and appends it to the project’s “base version,” the result being a label like “1.9.0.6″, where “6″ would be the build number. I imagine this is a common scenerio — indeed its why the <buildnumber> ant task exists. Once I launch an official build via command-line, label generation happens automatically, and the repository is tagged “Build 1.9.0.6″.

Introduce the CI server, though, and suddenly I’m having to jump through hoops to accommodate this setup. At the crux of the problem is this: from the CI server’s perspective, a build starts upon checkout or update of a project, and therefore wants to know the build label prior to actually running the build. That’s putting the cart before the horse, in my opinion, although I do understand the reasoning. Should access to the repository fail, for example, the CI server is able to report “1.9.0.6 Build failed due to VCS unavailability”.

What I’ve done is create a small script whose sole duty is to fetch the next build label for the CI server — fortunately the CI servers with which I’ve worked allow for pre-build script execution in some manner or another. With CruiseControl, I use an “antbootstrapper” to invoke a small ant build named “get-next-version.xml”. CruiseControl passes the value generated from that to the official build, so ant is invoked like so: “ant package -Dbuild.label=1.9.0.6″.

However, my work isn’t done. I still must ensure that my build-number property file is accurate, even if the build.label is being provided instead of being generated. So, in addition to configuring CruiseControl in the manner described, I also must have my build.xml extract the build number from the passed label (in this case, “6″), and update the build-number file appropriately.

Granted, I imagine most folks don’t rely on ant to generate build numbers, and therefore the CI server provided functionality is a convenient mechanism. The minority of us who do, though, ought to be able to supply build labels to the server in an easier fashion.

Not upgraing to Internet Explorer 7? Why not?!?!

Whenever I hear about a government agency indefinitely postponing their upgrade to IE7, I cringe. We web developers plan on supporting IE6 for at least the foreseeable future, but any setback that delays the natural browser upgrade progress always stings a little. Yes, under the hood IE6 can do most of the stuff that IE7 can, but it does it badly and incompletely.

I listened to Chris Wilson’s talk (he’s IE’s program manager) at the Ajax Experience conference in Boston and he brought up a really good point. IE6 was a great browser when it was released in 2001. Since then the web has changed dramatically. Things are being done with DOM and JavaScript now that just weren’t on our radars six years ago.

Because of that, IE6 is seriously crippled for modern web apps. Aside from its incomplete support for CSS, IE6′s main problem is the execution time and garbage collection in its JavaScript engine. Recent tests show just how dismal the performance is.

I guess this will just be another challenge that we’ll have to work around, but it sure would be nice to hear that larger companies and government organizations are actively planning a browser upgrade.