Browsing articles in "Software"
Sep 19, 2008
John Wood

TravelAgent Gnome Do plugin in the wild

I’ve just completed the initial release of my second Gnome Do plugin. It’s called TravelAgent. TravelAgent allows you to kick off searches for flights, rental cars, and hotel rooms on select travel agency websites right from Do. To use TravelAgent, you tell Do what you want to search for (flights, cars, or hotels), provide Do a simple search query string (see the plugin’s wiki page for details), and specify which of the supported travel agencies you’d like to use to conduct the search. Do will then open up a web browser, bringing you to the search results page on the travel agency’s website.

Let me just state this right from the start. I have no idea who will use this plugin, or who, if anybody, will find it useful. This is just something I wanted to do. If others find it useful, then that’s great. But, that was not my main motivation. Searching for travel can be complicated, as there are many options to consider. Take flights for example. The number of passengers you’re looking to book a flight for, and the “types” of those passengers (adults, children, seniors, etc) can vary from search to search. The departure time, arrival time, and flight time is often very important to people. Some people only fly certain airlines or certain cabin classes (coach, first class, etc). Trying to sum all of this up into a Do plugin is difficult. Do’s interface is simple…it needs to be. That’s one of the reasons why Do rocks so much. So, using the plugin had to be just as simple. To do that, many assumptions were made about the search being conducted, greatly reducing the flexibility of the search as compared to doing the search right on the travel agency’s website.

So, what is it useful for then? Well, it’s a quick an easy way to do a price check. And if you’re interested in purchasing some travel, then you can always tweak the search right from the search results page, to get it just the way you want it, before continuing down the purchase path.

As for the list of agencies supported, they are all Orbitz Worldwide agencies. All of the agencies are also running our global travel platform, which means I can interact with all of them the same way. The plugin currently works by building a URL, which contains all of the necessary search criteria, and feeding that URL to the web browser. It was the simplest way to get up and running. So, where is Orbitz you ask? Well, Orbitz is still running the classic platform. It does not have pretty URLs, or any other type of publicly available web services that I could use to conduct a search. I could write a screen scraper to get the job done, but that was beyond the scope of this initial 0.1 release. Cheaptickets suffers from the same issue. Soon, we will be rolling some of the other Ebookers agencies onto the new platform. When those sites go on, I will add support for them in the plugin. Orbitz and Cheaptickets are still a ways out, so I may look into scraping those sites for the time being.

So, what’s next for the plugin? Here’s a short list of stuff I’d like to do:

  • Add support for additional OWW agencies
  • Add support for searching packages (flight + car rental, flight + hotel, flight + car rental + hotel)
  • Change the plugin to display the search results in Do, instead of on the agency’s search results page (but still giving the user the option to see the full search results page)
  • Add support for pre-configured search options, like cabin class, preferred airline, etc. This would give the user more control over the search, while keeping the search query string simple.

I’m sure more features will come up as time goes on. We’ll see where this heads. If you have any ideas for what you’d like this plugin to be able to do, I’m all ears.

Sep 13, 2008
John Wood

My first Gnome Do plugin

I just pushed the code for my first Gnome Do plugin. It is a plugin for Confluence, a popular wiki package, and allows you to search your wiki from within Gnome Do. Do will present you with the results, and selecting one of the results will open that page in a web browser.

I want to give a shout out to the Do developers. Because of their very powerful and flexible plugin architecture, writing the plugin was a snap. Very little code was required. I probably spent no more than 10 hours total on this plugin, and the majority of that time was spent learning the plugin architecture, and learning how to install and test my plugin.

The code is currently on its own branch, waiting to be merged with the Gnome Do community plugins branch. If interested, you can currently find the code at https://code.launchpad.net/~john-p-wood/do-plugins/confluence. Eventually, it will be merged to https://code.launchpad.net/~do-plugins/do-plugins/community.

Next up, I’m working on a Do plugin that will interact with the many Orbitz Worldwide travel websites. Stay tuned!

Sep 11, 2008
John Wood

Threading gotcha in C#

So, as I mentioned last time, Gnome Do rocks. So much in fact that I’m looking for ways to contribute to the project. I haven’t been this excited about a piece of software in quite some time. The nerd in me is giddy.

My first contribution was to fix a bug I opened against the JIRA Gnome Do plugin (an awesome plugin by the way). The bug was causing Gnome Do to crash at startup if the JIRA server could not be reached. The fix was pretty easy. Wrap the code throwing the exception that was causing the crash in a try/catch block, and simply log and swallow the exception. Gnome Do calls the plugin every 5 minutes to update its index, so once you eventually connected to the web or logged in to your company’s network and can see your JIRA server, the plugin will be able to index the JIRA issues and all will be peachy.

I tested the fix, and it worked like a champ. However, I started to think to myself that it was very odd that Gnome Do let a rogue plugin take it down. I figured it would be a good idea to isolate all calls to the plugins, and wrap them all in try/catch blocks, as a means to protect the core application. I did some digging in the code, and I found that Gnome Do was already doing exactly that. So why on earth did an exception in the plugin take down the core app?

I did some more digging, and in the JIRA plugin, the update takes place in a separate thread. The author of the JIRA plugin, knowing that the call from Do to update the plugin’s index was a blocking call, and knowing that the communication with JIRA may take a little while, decided to do the communication with JIRA in a different thread, and immediately return control to Do. It was this thread that was throwing the exception when the JIRA server could not be reached. This puzzled me. Could it be possible that an uncaught exception in a separate thread can take down the entire application? “No way in hell” I thought to myself.

I was wrong.

With Google by my side, I searched the web for “c# thread exception” and found this free e-book about threading in C#. At the very bottom of the page, read this:

From .NET 2.0 onwards, an unhandled exception on any thread shuts down the whole application, meaning ignoring the exception is generally not an option. Hence a try/catch block is required in every thread entry method at least in production applications in order to avoid unwanted application shutdown in case of an unhandled exception.

Holy crap! I showed this to a co-worker, who quickly whipped up a Java program that spawned a thread that threw an exception, to see what happened. We were pretty sure that only that thread would die, and that the JVM would continue to chug along as normal. Thankfully, we were right.

Why on earth would .NET behave this way? The e-book says “From .NET 2.0 onwards”, so I’m assuming that this wasn’t the case in .NET 1.0. I wonder what the reason was for this change. Now, any .NET application that allows itself to be extended by plugins is now at risk of being taken down, at any time, by a rogue plugin! Yikes!

Jun 13, 2008
John Wood

Overriding Java methods in Groovy for unit testing

Lately, I’ve been experimenting with writing unit tests in Groovy to test our Java code at Orbitz. Groovy provides many nice language features that have the potential to dramatically reduce the amount of test code that you have to write, and to decrease the maintenance burden of that test code. Since it makes tests easier to write and maintain, hopefully more people will do it! :)

One of the features of Groovy that immediately caught my attention was the ability to specify a new implementation for a method of a given class at runtime. I was first introduced to such power by Ruby, and have been wanting it elsewhere ever since. I immediately thought that this would be great for testing our legacy code, where stubbing methods is difficult, yet often necessary to avoid major refactoring work. Changes involving major refactoring take much more time and increase the possibility of introducing more bugs. This codebase is in the middle of being swapped out with a new one, so a major refactoring isn’t really worth the effort (it would however be worth the effort in the new codebase). Currently, to stub out private methods buried in our codebase, we’ve been widening the accessibility of the method to protected, and subclassing the class to override the functionality. I’m sure this seems hacky, but it’s really less risky/evil then some of the alternatives. The code under test in this case is back end code that is not available outside of our team. Obviously, widening the scope on a method of a released API or library would be a different scenario entirely. So, I was really excited to think that Groovy could possibly help us with this nastiness.

Sound too good to be true? Well, it is.

This great feature is only available for Groovy objects! Java objects need not apply. You can add methods to Java classes, but you can’t change them. Bummer.

While scouring the web to see if there was any other way to do this, I stumbled upon JMockit, a library that helps with unit testing in Java. JMockit lets you do exactly what I want to do; provide a new implementation for any method on a class! Private methods, static methods…no sweat. JMockit to the rescue!

Right? Wrong.

Exception in thread "main" mockit.RealMethodNotFoundForMockException:
Corresponding real methods not found for the following mocks:
groovy.lang.MetaClass getMetaClass(),
Object invokeMethod(String, Object),
Object getProperty(String),
void setProperty(String, Object),
void setMetaClass(groovy.lang.MetaClass)

With JMockit, the mock object containing the new implementation must not include any new methods that are not on the original class. The problem here is that all objects in Groovy contain several methods that are not on java.lang.Object. So, even though you are not programmatically adding methods to the mock that aren’t on the original, since your object is automatically a GroovyObject, it has these new Groovy methods, whether you want them or not. And, specifically extending java.lang.Object doesn’t help either. So, back to square one.

But, all hope is not lost. Sure, it sucks that we’re reduced back to widening the accessibility of a method so it can be stubbed out in a subclass, but at least doing this is much easier in Groovy. Take the following Java class for example:

public class Book {
    public String read() {
        return getLine();
    }   

    private String getLine() {
        return "Damn this is a long book!";
    }
}

What if we want to have getLine return something different? Well, first we have to make it protected:

    protected String getLine() {
        return "Damn this is a long book!";
    }

Then, we have to subclass Book and provide the new implementation. The easiest way to do this in Java would be with an anonymous inner class:

Book b = new Book() {
    protected String getLine() {
        return "Short book";
    }
};
assertEquals("Short book", b.read());

This is much more concise in Groovy, thanks to closures, map coercion, and the fabulous “as” keyword:

def b = [ getLine: { "Short book" } ] as Book
assert "Short book" == b.read()

Not only is it less code, but it also protects us from interface changes to getLine! getLine can be changed to take a parameter or throw a new checked exception, and our test would remain unchanged, lessening the maintenance burden of our test case. Very nice.

So, although this is not ideal, it still has benefits over its Java counterpart.

May 27, 2008
John Wood

I’m spoiled

Wow, I’m spoiled. Spending the past several years working with Java, Ruby, Erlang, and some others, I’ve grown accustomed to the hoards of free libraries and tools out there just begging to be used. IDEs, code analysis, continuous integration, frameworks, profiling, testing…pretty much anything you could ever want. This rings especially true for Java, since it has been in the limelight for so long. So, I was shocked to find out that there doesn’t appear to be a free comprehensive code coverage tool out there for .NET.

As I’ve mentioned before, I’m writing a test suite for Shotokan Karate of America‘s new membership administration system. The application is written in C#. The pace of development has picked up lately, and new code is being released for testing about every couple of weeks. I’m not too involved with the development of the application, so I don’t have much insight as to what has changed from release to release. So, I’ve been looking for a good code coverage tool to show me areas of the application’s code that I may be overlooking in my tests.

I wanted something like Cobertura for Java, which has a rich set of features, and a set of easy to read code coverage reports. But, the only thing I could find that even came close to Cobertura was NCover. Free? Nope. Try $149 a license. Oh…wait, you want the one with the HTML reports? That’s $299.

I’m new to .NET, so naturally this raises a bunch of questions. Is this the status quo in the .NET community? Is everything pay to play? How does this affect the community? If Joe Developer has a library that he thinks others might find useful, does he slap a price tag on it simply because that’s the way things are? How do free open source software projects in .NET (I’m assuming there are some) get started? Does this type of model encourage or discourage community involvement in a project?

Is it just me, or does anybody else think that it sucks to not have these tools freely available to the development community?

I should note that I am a giant tight wad. Don’t believe me? Ask my wife.

GitHub