Aug 22, 2011

Update: Lion sleep woes solved

In my previous post I was complaining how my MacBook would no longer sleep. The sleep function worked well after installing Lion but then stopped working unexpectedly.
It turns out that this is not an uncommon problem with many people complaining of the same issue. Advice on how to fix it varies wildly with solutions including (but not limited to): SMC reset, PRAM reset, turn off preference X, delete folder Y - there are even 3rd party application to force your Mac to sleep.

However the advice that worked for me was actually fairly logical:

1. Use pmset to view the power management settings:
localhost:work teabot$ pmset -g
    ...
    disksleep	10
    sleep		0 (imposed by 46)
    hibernatemode	3
    ...

The interesting thing in the output is the line that states 'sleep 0' - presumably indicating that sleep mode is disabled. Further along this line we find 'imposed by 46'. This is actually telling us the id of the process (PID) that is blocking sleep mode.

2. List the process with the matching PID:
localhost:work teabot$ ps -ef | grep 46
    0  46  1 0 9:05pm ??  0:00.16 /usr/sbin/cupsd -l
    0 107 46 0 9:05pm ??  0:00.59 ipp://nano.local.:631/printers/HP_Photosmart_C4100_series 7...
    ...

So we can see that a queued print job is inhibiting sleep mode and in this case I resolved the issue by clearing my print queue at which point my MacBook was happy to sleep once more.

It's pretty bizarre that a queued print job should disable sleep mode. The action of me closing the MacBook lid should make clear my intention of wanting the computer to sleep. If the print job is so important - perhaps a warning dialog should be issued so that I might have some idea why sleep mode will not be activated?

I assume that other types of process may inhibit sleep mode. Thankfully the pmset command includes some unexpectedly useful output to help us figure out which process is responsible. I can't imagine how long it would've taken me to find the errant print job without it.

More OSX Lion woes

I having more small yet significant problems with OSX Lion. I'm running the latest version - 10.7.1 - on both my MacPro and MacBook.

My MacPro:
I find that I frequently lose the ability to resolve DNS names. This is only resolved by restarting the machine. Some Googling suggests that this issue may be due to a failing mDNSResponser process. I use this machine as a media server, so in practice I get up in the morning and try to tune some Internet radio only to find that I need to reboot my media server before I can do so. I'm going to try killing the process so that I don't have to restart the machine each time.

My MacBook:
Sometimes my MacBook just won't sleep. Closing the lid, Cmd-Alt-Eject, and the Apple menu option have no effect. It's really frustrating. Some people report that this can happen if Internet Sharing is enabled - it's not in my case. Apple's 'sleep' implementation used to be its crowning jewel. Coupled with OSX's stability I could: go months without rebooting my laptop, have a working system within seconds of opening the lid, happily sling my MacBook into a bag just moments after shutting the lid. I can't anymore...

When I wake this machine from sleep - when I can actually get it to sleep that is, I often find that the wireless card is in an unknown state. This makes it impossible to connect to a wireless network or switch the wireless off. The machine seems to sort itself out after a few minutes but it's quite annoying - especially if I'm trying to look something up in a hurry.

Summary: With this extremely poor OSX Lion release Apple has reminded us what it was like to run Windows XP on a cheap laptop in 2002.

Aug 10, 2011

Inheriting Maven profiles

I'm in the process of moving a number of projects from Ant/Ivy to Maven. Many of our projects use Thrift and we use a Maven Thrift plugin to conveniently compile our Thrift IDL. Given that all of our Thrift projects have the same setup, the plugin is declared in a our parent POM.
The plugin is declared in a profile that is only activated when a thrift source directory is present:
  <profile>
    <id>uses-thrift</id>
    <activation>
      <file>
        <exists>${basedir}/src/main/thrift</exists>
      </file>
    </activation>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.thrift.tools</groupId>
          <artifactId>maven-thrift-plugin</artifactId>
          ...

I actually have a number of plugins defined in such profiles so that they become active only when relevant source artefacts are present in the sub-project.

This all looks good, but in practice I found that the profiles were never activated in sub-modules that were being built from a parent project. It was as if the activation state was determined at the parent level, not on a per module basis.

It seems that profile inheritance does function as I expected in Maven 2. It does however work perfectly with Maven 3.

Jul 22, 2011

AFP failing between OSX Lion machines

I recently upgraded both my MacPro and MacBook to Lion. The upgrades went fine, but I now find that I cannot open a non-guest AFP connection between the two machines. On the client I see 'Connection Failed...' and in the server console I find:

22/07/2011 08:39:20.350 AppleFileServer: _Assert: /SourceCache/afpserver/afpserver-581/afpserver/AFPRequest.cpp, 2005
22/07/2011 08:39:20.354 AppleFileServer: _Assert: /SourceCache/afpserver/afpserver-581/afpserver/AFPRequest.cpp, 2005
22/07/2011 08:39:20.400 AppleFileServer: Calling ReadLock on lock < 0x2a833128 > while holding WriteLock
22/07/2011 08:39:20.524 ReportCrash: DebugSymbols was unable to start a spotlight query: spotlight is not responding or disabled.
22/07/2011 08:39:20.965 com.apple.launchd: (com.apple.AppleFileServer[424]) Job appears to have crashed: Illegal instruction: 4
22/07/2011 08:39:21.062 ReportCrash: Saved crash report for AppleFileServer[424] version ??? (???) to /Library/Logs/DiagnosticReports/AppleFileServer_2011-07-22-083921_localhost.crash
22/07/2011 08:39:22.389 com.apple.launchd: (com.apple.AppleFileServer) Throttling respawn: Will start in 8 seconds

I also have a crash report.

This is fairly annoying as my MacPro acts as the Time Machine backup for my MacBook. Has anyone experienced anything similar and are there any workarounds?

Update: I found a work around: I removed all folders from 'System Preferences/Sharing/File Sharing/Shared folders' and I can now connect. The unfortunate side effect of this workaround is that now the whole file system on the server is shared - subject to the authenticated user's privileges.

May 24, 2011

An ordered builder pattern

I was recently implementing the builder pattern for some immutable objects and was taking the approach described by Joshua Bloch in his excellent book 'Effective Java'. I particularly like the readability that the pattern provides when constructing complex objects and I think this arises because each property value is contextualized by the preceding method name:

  Person.Builder builder = new Person.Builder();
  Person person = builder.id(10).name("Jim").age(21)
    .pets("cat", "dog").build();

I also like working with builders in an IDE because the auto-complete process can nicely lead you through the object's construction with a few taps of Ctrl+Space. However, there are a few things that could be improved with the pattern:

Handling of mandatory state
There are two obvious ways we can enforce mandatory properties with the pattern. Firstly we could pass mandatory property values in the builder constructor. This gives us a compile-time enforcement of mandatory properties. However, for many mandatory properties it can suffer from the problem that the pattern was meant to avoid - telescoping constructors. Imagine that the id and name are mandatory:

  Person.Builder builder = new Person.Builder(1, "Jim");
  Person person = builder.age(21).pets("cat", "dog").build();

The second way we can enforce mandatory properties is by checking the builder state in the build() method. This preserves the readablility API but relegates the mandatory property checking to run-time - quite a penalty.

Redundant invocation paths
Normally a property setter method on a builder just returns the builder instance:

  public Builder id(int id) {
    this.id = id;
    return this;
  }

This means that on the returned value we can call any other builder method, including the one that we just invoked. We could - if we wanted to - chain many redundant calls that overwrite the builder state:

  Person person = builder.id(10).id(11).id(12).id(13).build();

While this isn't a likely to occur, it shows that the path we take through the building of the object isn't incredibly directed - it would be nice if we couldn't set the id more than once. We could do this at run-time but it would be far better if we were prevented from even writing such code! This lack of order also degrades our IDE auto-complete experience a little - imagine a builder with 20 properties - every time we see the auto-complete suggestions we have to mentally parse a list of 20 property setters - including those we've already set.

Adding order to the builder pattern
I had a go at addressing these (minor) short comings of the pattern and with some simple additions was able to create a builder that can lead you through the building process and enforce mandatory properties at compile-time in a nice contextualized way. The trick is to create a number of subordinate builder classes.

Consider an immutable value class:

  public class Person {
    private final int id; // MANDATORY
    private final String name; // MANDATORY
    private final int age; // OPTIONAL
    private final Set pets; // OPTIONAL
    ...

Now let's deal with the mandatory fields. It makes sense that you must first set the id property before doing anything else. Therefore the only possible method invocation from our builder class will be id(int id) - but what should this return? The next step in our builder sequence is to set the mandatory name, therefore we should return a builder class on which you can only invoke the name(String name) method, so we defined a subordinate builder class NameRequiredFieldBuilder, that only allows the name to be set and return this from the invocation of id(int id):

  public static class Builder {
    ...
    public NameRequiredFieldBuilder id(int id) {
      this.id = id;
      return requiredName;
    }
    ...

    public static class NameRequiredFieldBuilder {
      private final Builder builder;

      private NameRequiredFieldBuilder(Builder builder) {
        this.builder = builder;
      }

      public ? name(String name) {
        builder.name = name;
        return ?
      }

So we can now change the builder invocations like so: builder.id(10).name("Jim") - in fact we no option but to call these methods, in this order. Let's deal with providing the builder with the the optional fields. At this point we'd like to be able to call age(int age), pets(String... pets), or build(). and we'd like to do this using the object returned by name(String name). To achieve this we define a subordinate builder class for the optional fields and the build() method:

  public static class OptionalFieldsBuilder {
    private final Builder builder;

    private OptionalFieldsBuilder(Builder builder) {
      this.builder = builder;
    }

    public OptionalFieldsBuilder age(int age) {
      builder.age = age;
      return builder.optionalFields;
    }

    public OptionalFieldsBuilder pets(String... pets) {
      for (String pet : pets) {
        builder.pets.add(pet);
      }
      return builder.optionalFields;
    }

    public Person build() {
      return new Person(builder);
    }

  }

An instance of OptionalFieldsBuilder is then returned by NameRequiredFieldBuilder.name(String name):

  public OptionalFieldsBuilder name(String name) {
    builder.name = name;
    return optionalFields;
  }

So now we can call the builder property setters for the optional fields and then finally call the method to build an object instance. Full source code for this example.

Some observations
Breaking the builder into a number of subordinate builder classes allows us to introduce order into the build process. We can lead users of our API through the construction process, having them specify mandatory fields values first, only once, and potentially in order of importance. The modified pattern ensures that all mandatory fields are supplied at compile-time as it's not possible to invoke build() otherwise. The modified pattern does away with constructor supplied parameters and potential telescoping issues. Furthermore the subordinate builder classes limit method choices in our IDE's auto-complete mechanism to only the pertinent properties.

We could introduce additional structure to the invocations of the setters of the optional properties, however this might lead to a proliferation of subordinate builder classes. I feel that there is no need to dictate the order in which optional properties are set, and indeed how many times they are set.

From an implementation perspective, the overhead of creating subordinate builder classes for a few mandatory properties is small. A more scalable approach would be to use an annotation processor to generate the builder classes at compile time as had been done with Jan-Kees van Andel's make-builder tool.

Change of tack

It's been a while since I've developed anything for IOS and I'm not back working with Java again at Last.fm. I have been dabbling with C/C++ on some Arduino projects at the London Hackspace - but other than that I'm pretty much a full-time Java developer. However, I really enjoyed writing about my programming experiences and have missed jotting my thoughts down on a this blog. Rather than start a new blog for general programming posts I've decided to repurpose this one given that it already contains some possibly useful programming content.

Hopefully my (3) followers won't be too put out by this :-) I have updated the strap-line and description of this blog to reflect this new direction.

For the record, the most successful Swish Movement post was that relating to private methods in Objective-C - I still get comments on that post!