Deadlock that you can’t avoid

A seemingly innocent user report in the Hudson IRC channel turns into an interesting “discovery” (for me anyway) about JVM. Namely, if you got two threads initializing classes in the opposite order, you can get into a dead lock.

For this test, I wrote the following class. In this way, initialization of Foo results in the initialization of Bar:

package test;
public class Foo {
    static {
        try {
            System.out.println("Initializing Foo");
            Thread.sleep(3000);
            new Bar();
            System.out.println("Foo initialized");
        } catch (Exception e) {
            throw new Error(e);
        }
    }
}

I then wrote the Bar class that does the opposite:

package test;
public class Bar {
    static {
        try {
            System.out.println("Initializing Bar");
            Thread.sleep(3000);
            new Foo();
            System.out.println("Bar initialized");
        } catch (Exception e) {
            throw new Error(e);
        }
    }
}

Now, if you initialize them simultaneously from the opposite direction like this:

public class App {
    public static void main(String[] args) {
        new Thread() { public void run() { new Foo(); }
        }.start();
        new Thread() { public void run() { new Bar(); }
        }.start();
    }
}

And you’ll see that it deadlocks:

"Thread-1" prio=10 tid=0x0000000040696000 nid=0x2d6e in Object.wait() [0x00007ff087ce5000]
   java.lang.Thread.State: RUNNABLE
	at test.Bar.(Bar.java:11)
	at test.App$2.run(App.java:14)

"Thread-0" prio=10 tid=0x0000000040688000 nid=0x2d6d in Object.wait() [0x00007ff087de6000]
   java.lang.Thread.State: RUNNABLE
	at test.Foo.(Foo.java:11)
	at test.App$1.run(App.java:8)

Obviously, in production code, the path from initialization of class Foo to class Bar will be much longer, but you get the idea. I’m kind of surprised that this isn’t a real widespread problem in JavaEE. Developers don’t normally care about the class initialization, and on the server side you tend to have a lot of threads doing random things…

Hudson User Meet-up in Copenhagen/Oslo?

I’ll be in Copenhagen from 9/5-9/7 and in Oslo 9/8-9/9 to present in JavaZone. I’d like to take advantage of the opportunities and have user meet-up events in those cities. Depending on the number of participants, it could be just a drink in a bar, or a talk in a meeting room.

So if you are:

  1. in those cities,
  2. available in the evening of 9/6, 9/8, or 9/9, and
  3. willing to attend such an event,

… then please let me know.

Also, if you have an office in those cities and willing to provide a space for an event, that would be extra appreciated!

POTD: bridge method injector

I was working on Hudson yesterday which led me to develop this little tool called Bridge method injector.

When you are writing a library, there are various restrictions about the kind of changes you can make, in order to maintain binary compatibility.

One such restriction is an inability to restrict the return type. Say in v1 of your library you had the following code:

public Foo getFoo() {
    return new Foo();
}

In v2, say if you introduce a subtype of called FooSubType, and you want to change the getFoo method to return FooSubType.

public FooSubType getFoo() {
    return new FooSubType();
}

But if you do this, you break the binary compatibility. The clients need to be recompiled to be able to work with the new signature. This is where this bridge method injector can help. By adding an annotation like the following:

@WithBridgeMethods(Foo.class)
public FooSubType getFoo() {
    return new FooSubType();
}

… and running the bytecode post processor, your class file will get the additional “bridge methods.” In pseudo-code, it’ll look like this:

// your original definition
@WithBridgeMethods(Foo.class)
public FooSubType getFoo() {
    return new FooSubType();
}

// added bridge method
public Foo getFoo() {
    invokevirtual this.getFoo()LFooSubType;
    areturn
}

Such code isn’t allowed in Java source files, but class files allow that. With this addition, existing clients will continue to function.

In this way, you can evolve your classes more easily without breaking backward compatibility.

For more about how to use it in your Maven project, the project website.

Announcing Beta Availability of InfraDNA’s Certified Hudson CI (ICHCI) Server

I’m happy to announce the beta release of InfraDNA’s Certified Hudson CI (ICHCI) Server. ICHCI is a value-added distribution of Hudson, and here’s why I think it’s useful:

  • First, ICHCI is more stable sustaining release trains from Hudson; ICHCI is periodically branched off from a version of Hudson that was of particularly good quality. Its release cycle will be also much slower compared to the once-a-week cycle of Hudson. So it’s better suited for deployments where the stability is more important than rapid feature delivery.
  • Second, ICHCI provides a better out of the box user experience. Hudson’s plugin community is so successful that nowadays it’s actually getting difficult to find the plugins you can really benefit from. I often talk to Hudson users who tell me about a particular itch, and I immediately go “yeah, there’s a plugin for that!” — ICHCI improves this situation by bundling and a number of tested open-source plugins together, making it less of a hassle to run Hudson.
  • Third, ICHCI comes with commercial value-add plugins from InfraDNA. In this first beta release, for example, we put a plugin that automates regular automated backup of your configuration and build data. Going forward, ICHCI will be the primary vehicle in which we deliver value-add plugins from InfraDNA, and we have a lot of ideas about what we want to do!

60-day evaluation license for ICHCI is available to everyone. The full license is available as a part of the InfraDNA support subscription plans. Please try it out, and let us know what you think!

Cheers to the 5th anniversary of GlassFish

About 5 years ago in JavaOne, Sun announced to open-source GlassFish application server. Back then I was involved in JAXB, the databinding technology, and if my memory serves me, I think that was when we finally made JAXB source code available in CVS in a way people can check out anonymously (before that, it was under more problematic license that required a click-through.) I think the JAXB RI was since then well-received by the community, so I’m very happy with what I’ve done.

A lot has happened since then, but it seems to be that the GlassFish community as a whole has steadily grown since then, and it even survived the Oracle transition, despite rumors and FUDs. So my hats off to those who made it happen, and here’s to the next 5 years of GlassFish!

My Upcoming Presentations

I will be presenting Hudson (with a focus on its Selenium support/integration) at the upcoming San Francisco Selenium Meetup event on Jun 22nd in San Francisco. There are several Selenium-related plugins in Hudson, but running Selenium tests on Hudson involves some initial setup cost. I’d discuss those, plus general-purpose features in Hudson that really work well with Selenium.

In the week after that, from 30th to July 3rd, I’ll be in Israel, thanks to JFrog. This is my first visit to Israel, so I’m really excited. If there are any Hudson users there who’d like to meet up, please let me know, as I’m always interested in seeing different deployments of Hudson and learn from those. Or if you are interested in having me do a short on-site work, there won’t be any travel cost, so this would be a good opportunity ;-)

Further down the road, I’ll be speaking in JavaOne 2010. Historically we have a good number of Hudson committers/users in JavaOne, so we’ve been doing some get-together. I hope we can do it again, so please stay tuned as the details of the conference develops over the summer.

Auto-discovering Hudson in the network

When you are writing an application that interacts with Hudson, it is often convenient to be able to auto-discover Hudson deployments on the same network. This improves the overall user experience.

There are several ways to do this — one way to do this, which is supported for the longest time, since 1.282, is via the UDP broadcast to port 33848. You send an empty UDP datagram to 255.255.255.255 port 33848, and all the Hudson instances on the same network will reply an XML fragment UDP packet to you, that looks like this:

<hudson>
  <version>1.354</version><!-- version of the Hudson -->
  <url>http://server/hudson/</url><!-- the top page of the Hudson -->
  <slave-port>12345</slave-port><!-- TCP port number for slaves and CLIs to connect to -->
  ... more elements may appear here ...
</hudson>

Starting 1.335, Hudson started using IP multicast socket to listen to this broadcast, so you can discover them by sending a broadcast packet to 239.77.124.213 instead of 255.255.255.255 — depending on how the network is configured, this can also reach beyond the same subnet.

Starting the upcoming 1.359, you can also discover Hudson via DNS multi-cast at “_hudson._tcp.local”. This also defines a convention that enables wide-area discovery of Hudson — such as “_hudson._tcp.infradna.com” for the Hudson deployed for infradna.com. The same version, url, and slave-port parameters are available as the key/value pairs associated with this DNS record, so you can find the actual URL of Hudson instances that way.

As we the engineers use more and more server applications for software development, more seamless integrations between them get more important, and I think the auto-discovery is a very important part of this.

Introducing InfraDNA, the Hudson company

As I wrote in my farewell note, I was working on starting a new company around Hudson. It took longer than I initially anticipated, but it’s finally open for business!

The company will provide two things; one is support, so that I can answer your questions and problem reports in a timely fashion, and the other is consulting, so that I can help you develop custom plugins, or provide on-site support to work on some tricky problems.

The name of the company is InfraDNA because I think of Hudson more as an infrastructure on which all kinds of server-side automation/tools can be built/deployed, and because I think this stuff is built into me (as in DNA) — when I look back my career as a software engineer, I always somehow seem to come back to tooling. (Plus, the domain name was available!)

Looking forward to hearing from you.

POTD: GitHub API for Java

My project of the day (or “POTD”) is GitHub API for Java — a library for accessing GitHub programmatically.

As the Hudson community is embracing plugins developed in Git more and more, I needed to interact with GitHub as a part of the community infrastructure automation. I did a quick Google search to locate existing implementations, but unfortunately I couldn’t find anything good. So I decided to just write my own. Thanks to a reasonable API design of GitHub and a good documentation, it was very easy to do so. The trick is to use the right library, which handles most of the JSON/Java databinding.

The library so far only covers the part of the GitHub API that I care about, which is a small subset of the entire GitHub API. But hopefully this library is easy enough to extend so that other people can add the remaining APIs. The source code is available in GitHub.