Wednesday, December 30, 2009

Nexus One: Buy from Google, not T-mobile

I just spoke with my friendly T-Mobile customer care specialist. She was direct and helpful. Point blank I asked to pre-order a Nexus One and sign up for the matching phone plan. As expected, she could not help me with that. But she did tell me some interesting tidbits:

  • T-mobile considers it an HTC phone, not a Google one
  • T-mobile has not yet given customer service details on the phone, but my specialist did know about it
  • T-mobile will not be selling the phone directly; she said I needed to order it from Google, not T-mobile

Anticipation is a great selling device.

Android load webby

My first Android project, AndroidLoad, is very simple. It reads /proc/loadavg every second and and updates a table with the data.

Achieving this much in a single day of browsing and code noodling, I hope to make something more interesting with it soon. So far, Android+IDEA has been a real pleasure to develop with, and I expect the IDE integration to continue improving.

Monday, December 28, 2009

Chocolate sausages: not programming

My 12-year old son sent me a delightful email:

Today, grandma and I made some chocolate sausages and they turned
out great. Here is the recipe so you and Rebecca can replicate it,
but do not attempt without me. Ingredients: 200 grams of good butter 3 tablespoons of sugar 3 tablespoons of water 2 tablespoons of cocoa 50 grams of 90% and up dark chocolate 300 grams tea biscuits 1 egg 5 tablespoons of walnuts chopped wax paper Instructions: Melt butter, cocoa, chocolate, butter, water, and sugar over low heat. Bring to a boil. Turn off heat. Let it sit for 2 minutes. Remove excess water. Mix in eggs, biscuits, and walnuts. Place 2-3 tablespoons on sheet of wax paper and roll up. Repeat until there is no more filling. Freeze for minimum of 2 hours. Enjoy!

This is my one non-serious post for the year. Follow my son's advice: enjoy!

Sunday, December 27, 2009

All I want for Christmas is a Google Phone

I made a simple Christmas wish list for my wife:

  1. A Google phone

Yep, that's it, if I can bear the delayed gratification. And then there are the naysayers, ye of little faith.

Would I be a Android developer with a Nexus One? In a heartbeat—time to get started! I've got faith.

UPDATE: Rumor has it, Nexus One by invitation only. Will code for invite!

Saturday, December 26, 2009

New Ioke release

Ola Bini announced a new release of Ioke. Why is Ioke interesting? From the home page:

 
Ioke = LanguageExperiment with(
  goal: :expressiveness, 
  data: as(code), 
  code: as(data), 
  features: [
    :dynamic, 
    :object_oriented, 
    :prototype_based, 
    :homoiconic, 
    :macros 
  ], 
  runtimes: (JVM, CLR), 
  inspirations: set(Io, Smalltalk, Ruby, Lisp)
)
 
hello = method(name, 
  "hello, #{name}!" println)
 
Ioke inspirations select(
  features include?(:object_oriented)
) each(x, hello(x name))

Saturday, December 19, 2009

Code repository

I used Google Code to setup a Subversion repository for this blog under binkley. So far there are only two items: Soapy and MagicBus. Feedback encouraged.

Thursday, December 17, 2009

Vacation: BlockingIterable

I love vacation: a chance to stretch my coding fingers free of work! Here is a code snack I thought of while daydreaming today—enjoy!

public final class BlockingIterable {
    public static <E> Until<E> over(final BlockingQueue<E> queue) {
        return new Until<E>(queue);
    }

    public static class Until<E> {
        private final BlockingQueue<E> queue;

        private Until(final BlockingQueue<E> queue) {
            this.queue = queue;
        }

        public Iterable<E> until(final E poison) {
            return new Iterable<E>() {
                @Override
                public Iterator<E> iterator() {
                    return new Iterator<E>() {
                        private E next = poison;

                        @Override
                        public boolean hasNext() {
                            try {
                                return poison != (next = queue.take());
                            } catch (final InterruptedException e) {
                                currentThread().interrupt();
                                next = poison;
                                return false;
                            }
                        }

                        @Override
                        public E next() {
                            if (poison == next)
                                throw new NoSuchElementException();
                            return next;
                        }

                        @Override
                        public void remove() {
                            throw new UnsupportedOperationException();
                        }
                    };
                }
            };
        }
    }
}

Monday, December 14, 2009

Gmail smarter than I am

I was typing a personal mail to family members and using Gmail's address completion feature to just type a few characters for each recipient when I got to filling in the message body. I looked up and saw a warning about the To: list. It asked if I really meant to mail PQT, perhaps I really meant PQR? And it was right.

Gmail recognized that I mispicked one of the recipients while using completion, and that I would prefer a relation rather than a friend for this mail. Gmail is smarter than I am.

Thursday, December 10, 2009

How to release software

The wrong way

  • Have no master plan
  • Practise nothing ahead of release day
  • Prepare only on release day
  • Build release packages on release day
  • Have dissimilar production and test environments
  • Hand edit configuration during release
  • Keep no backups of previously working configuration
  • Use trial-and-error to fix configuration

The right way

Do the opposite of everything done the wrong way. Wasn't that simple?

Some elaboration

As much as possible, clone the production environment to your test environment. Any number of weird, unexpected, troubling problems will crop up. Fix them all. Do not release if your test environment is not pristine.

Make complete release packages as early as you can, and release them to the test environment just as you would to production. Do not release if you cannot deploy smoothly.

Keep the entire test environment under release control: everything including binaries, symlinks, logs. Do not release if there are uncommitted changes; do not release if you do not understand the changes since last release.

Above all, have a plan! Discuss it with your team, assign roles and check that everyone understands what they do. Practice the release; practice rollback should something break. Obey the Scout motto: Be prepared.

Postscript

What is the penalty for the wrong way? Eight hours spent with your cell phone glued to your ear during vacation while you fix a slow-moving train wreck of a release. Your family will thank you for the right way.

UPDATE:

And in the comments:

  • Release very seldom with a big bang approach

This is very apropos. Management prefers a few large releases to smaller, more frequent releases. My opinion is that large releases look better to upper management (demonstrates you can deliver large widgets) even though it hurts in cost and quality.

Wednesday, December 02, 2009

Epic fail with agile, or winning the battle but losing the war

Dave Nicolette posts one of the most depressing but realistic outcomes of successful agile engagements: retrenchment by anti-agile forces.

I utterly hate the case studies, but I hate them precisely because they are real.

Friday, November 27, 2009

Extension methods: the case for language-level delegates in Java

Extension methods

In There's not a moment to lose!, Mark Reinhold announces something completely different: Java 7 will have closures after all. Huzzah! And in that announcement, he lists enabling language changes for them:

  • Literal syntax
  • Function types
  • Closure conversion
  • Extension methods

I want to look at extension methods closely. Alex Miller does an admirable task of summarizing JDK7 changes; that's a good place to start. And some code:

public final class Filtering {
    public static <T, C extends Collection<T>> C filterInto(
            Collection<T> input, C output, Filter<T> filter) {
        for (T item : input)
            if (filter.keep(item))
                output.add(item);

        return output;
    }

    interface Filter<T> {
        boolean keep(T element);
    }
}

Given extension methods, a coder can write:

// static imports
Collection<String> names = asList("Bob", "Nancy", "Ted");
List<String> bobNames = names.filterInto(
        new ArrayList<>(), // new diamond syntax
        #(String name) "Bob".equals(name)); // new closure syntax

And some magic means will find Filtering#filterInto(Collection, Collection, Filtering.Filter) and transform the instance method call on Collection into a static method call on Filtering. Rules for finding Filterable vary. (Did you read Alex Miller's link?)

Here is an alternative.

Delegation

I am a fan of delegates and have writen about them often: I'd like them in Java. With delegates, the magic for finding #filterInto is less magical, and more under the control of the coder, but just as clean to use:

public final class FilteringCollection<T>
        implements Collection<T>, Filtering {
    // Some literate programming sugar for the static importers
    public static <T> FilteringCollection<T> filtering(
            Collection<T> input) {
        return new FilteringCollection(input);
    }

    public FilteringCollection(final Collection<T> input) {
        this = input; // the delegation proposal
    }

    public <C extends Collection<T>> C filterInto(
            C output, Filter<T> filter) {
        for (T item : this)
            if (filter.keep(item))
                output.add(item);

        return output;
    }
}

Usage now looks like:

// static imports
FilteringCollection<String> names = filtering(asList("Bob", "Nancy", "Ted"));
List<String> bobNames = names.filterInto(
        new ArrayList<>(), // new diamond syntax
        #(String name) "Bob".equals(name)); // new closure syntax

What's the difference?

Key here is that for the coder the only difference is delegation uses a static factory method to wrap input. This is not a drawback: it is an advantage. Less magic makes Java programs easier to maintain. There is no loss here in power.

Why bother with the delegation proposal?

Would you like to write the boilerplate forwarding methods of Collection? I wouldn't! It gets even worse as you move down the inheritance tree for Collection.

Postscript

How would you move down Collection's inheritance tree any how?

Beyond any current proposals, some javac author could implement type erasure for base classes (very carefully) in context of delegation:

public final class FilteringCollection<T, D extends Collection<T>>
        implements D, Filtering {
    // Only factory/constructor changes
    public static <T, D extends Collection<T>> FilteringCollection<T>
            filtering(D input) {
        return new FilteringCollection(input);
    }

    public FilteringCollection(D input) {
        this = input;
    }
}

Because the coder need not implement the dozens of forwarding methods, neither does he need to know what they are! The compiler sets the type of D to the precise collection used in the factory/constructor, and the resulting object provides all public methods.

But this is well beyond the scope of delegation. Go code Scala, or something.

UPDATE: Food for thought on extension methods from Rémi Forax.

UPDATE #2: This just gets more interesting: in Extension methods vs. method currying, Stefan Schulz discusses the alternative of currying.

Wednesday, November 18, 2009

A future for Java after all?

One of my favorite bloggers, Alex Miller, opens today with Apparently Mark Reinhold announced that closures would be added to JDK 7 at Devoxx today.

When I realized JDK7 would have no closures, I mentally wrote Java off as a language destined to be COBOL or FORTRAN or C: important in a practical way, but not to be where my heart was. (I'm looking around; Scala is likely my next language of choice.)

And, lo! Closure—in Java! Java may remain after all the language I prefer most. What a surprising turn.

UPDATE: Stephen Colebourne posts more details.

Thursday, November 12, 2009

Frankie says, don't do it (but does anyway)

Aleksander Kmetec explains Acme::Dont implemented in Scala.

Is it scarier that I can follow along, or that I recognize the Perl don't pragma? (Naturally Damian Conway is to blame.) Funny I ran across this post while reading Bytecodes meet Combinator: invokedynamic on the JVM.

Wednesday, November 11, 2009

How are your algorithms?

A fabulous post by Peteris Krumins summarizing MIT's Introduction to Algorithms lectures. It's like having a little Knuth in your browser.

A new programming language: Go

Time to brush up my resume and add a new programming language: Go, say 3 years experience?

I chuckle as I type this, but I have interviewed candidates for my present employer with an equally tenuous grasp on Java at variance with their resumes.

Thursday, October 15, 2009

More mana from the Czech lands: IntelliJ IDEA open-sourced

Take THAT, Eclipse!

UPDATE: This announcement is so popular, the JetBrains site is down. Never seen that before.

Tuesday, October 06, 2009

Surprisingly, there really is more to life than programming

Since I started this blog I have stuck consistently to programming topics. But I feel like posting a touch more broadly. Here are some of my favorite links:

And when I'm not browsing the Internet, I write classical music, cook freestyle, and thoroughly enjoy Rebecca, Greg and Ben.

Friday, September 25, 2009

Keeping a current timestamp in a Java concurrent map

Tricker than I like: In Java, how do you keep a map with the values being the "most recent timestamp" for the key? How do you do this for a concurrent map with multiple threads updating?

boolean isLatest(final K key, final long newTimestamp,
        final ConcurrentMap<K, Long> map) {
    Long oldTimestamp = map.putIfAbsent(key, newTimestamp);

    // If we are first, there is no previous to compare
    // with
    if (null == oldTimestamp)
        return true;

    // Make sure we are still the most recent
    while (newTimestamp > oldTimestamp) {
        if (map.replace(key, oldTimestamp, newTimestamp))
            // No other thread has updated, we are most
            // recent
            return true;

        // Another thread got here first, recheck
        oldTimestamp = map.get(key);
    }

    // Another thread put in a newer update, we are not
    // most recent
    return false;
}

As with all multi-threaded coding, bugs are easy to make and hard to spot. If I have made one, please let me know!

UPDATE: Fixed a typo. Thanks, David!

Sunday, September 06, 2009

Fast reflection, a cool post

"Coding Masters" (sorry, I didn't find his name) posts an interesting dissection of reflection and tunes until it is as quick as normal code. This is one for my toolbox.

Thursday, September 03, 2009

More on favorite idioms

lambdaj does a much better job than I did:

List<Integer> biggerThan3 = filter(greaterThan(3), asList(1, 2, 3, 4, 5));

Qi4j 1.0-RC1

Qi4j realizes much of the promise of annotations. Mixins and aspects without code or bytecode generation, what's not to love?

Monday, August 31, 2009

Design, Don't do it

Are you designing a thread-safe front to a single-threaded resource? Relax.

The wrong way

Write layers and layers of complexly interacting abstraction over an object pool, letting the object pool (hopefully) protect you from threading concerns.

The right way

Use the JDK:

public class FooService {
    private final UnsafeResource resource;
    private final ExecutorService service;

    public FooService(final UnsafeResource resource) {
        this.resource = resource;
        service = createPoolFor(resource);
    }

    public <T, E extends Exception> Future<T> submit(
            final Work<T, E> work) {
        return service.submit(new Callable<T>() {
            T call() throws E {
                return work.use(resource);
            }
        });
    }

    public interface Work<T, E extends Exception> {
        T use(final UnsafeResource resource) throws E;
    }

    // Good place for an extension point depending on your needs
    private static ExecutorService createPoolFor(final UnsafeResource resource) {
        return newSingleThreadExecutor(new ThreadFactory() {
            public Thread newThread(final Runnable r) {
                return new Thread(r,
                        FooService.class.getSimpleName() + ": " + resource);
            }
        });
    }
}

Wednesday, August 26, 2009

Comments on Hipp's A Lesson In Low-Defect Software

Thanks to Alecco Locco for useful comments on Hipp's A Lesson In Low-Defect Software. the full title:

A Lesson In Low-Defect Software
-or-
A Journey From A Quick Hack
To A High-Reliability Database Engine

and how you can use the same techniques to reduce
the number of bugs in your own software projects

Those comments got me to read the paper.

Tuesday, August 25, 2009

A favorite functional idiom in Java

Ok, two favorite functional idioms in Java:

public abstract class Option<T>
        extends Cursorable<T> {
    public static <T> Option<T> some(final T value) {
        return new Option<T>() {
            @Override
            public int size() {
                return 1;
            }

            @Override
            public T get() {
                return value;
            }
        };
    }

    public static <T> Option<T> none() {
        return new Option<T>() {
            @Override
            public int size() {
                return 0;
            }

            @Override
            public T get() {
                throw new IllegalStateException();
            }
        };
    }

    public abstract int size();

    public abstract T get();

    public final boolean isEmpty() {
        return 0 == size();
    }

    @Override
    public final Iterator<T> iterator() {
        return new Iterator<T>() {
            private boolean empty = isEmpty();

            @Override
            public boolean hasNext() {
                return !empty;
            }

            @Override
            public T next() {
                if (empty)
                    throw new NoSuchElementException();
                empty = true;
                return get();
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}

public abstract class Cursorable<T>
        implements Iterable<T> {
    public static <T> Cursorable<T> over(
            final Iterable<T> it) {
        return new Cursorable<T>() {
            @Override
            public Iterator<T> iterator() {
                return it.iterator();
            }
        };
    }

    public final Cursorable<T> select(
            final Select<T> select) {
        return new Cursorable<T>() {
            @Override
            public Iterator<T> iterator() {
                return new Iterator<T>() {
                    private final Iterator<T> it
                            = Cursorable.this.iterator();

                    private Option<T> current = none();

                    @Override
                    public boolean hasNext() {
                        while (it.hasNext()) {
                            final T next = it.next();
                            if (!select.accept(next))
                                continue;
                            current = some(next);
                            return true;
                        }
                        current = none();
                        return false;
                    }

                    @Override
                    public T next() {
                        if (current.isEmpty())
                            throw new NoSuchElementException();
                        return current.get();
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

    public final <U> Cursorable<U> project(
            final Project<T, U> project) {
        return new Cursorable<U>() {
            @Override
            public Iterator<U> iterator() {
                return new Iterator<U>() {
                    private final Iterator<T> it
                            = Cursorable.this.iterator();

                    @Override
                    public boolean hasNext() {
                        return it.hasNext();
                    }

                    @Override
                    public U next() {
                        return project.on(it.next());
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

    public interface Select<T> {
        boolean accept(final T input);
    }

    public interface Project<T, U> {
        U on(final T input);
    }
}

And a demo:

public class SelectAndProjectMain {
    public static void main(final String... args) {
        for (final Integer number : over(asList(1, 2, 3, 4))
                .select(new Cursorable.Select() {
                    @Override
                    public boolean accept(final Integer input) {
                        return 0 == input % 2;
                    }
                })) {
            System.out.println("Even: " + number);
        }

        for (final String number : over(asList(1, 2, 3, 4))
                .project(new Cursorable.Project() {
                    @Override
                    public String on(final Integer input) {
                        return Integer.toBinaryString(input);
                    }
                })) {
            System.out.println("Binary: " + number);
        }
    }
}

Produces:

Even: 2
Even: 4
Binary: 1
Binary: 10
Binary: 11
Binary: 100

Although I am afraid to add this to my project at work. I worry for the maintainer after me.

UPDATE: A coworker called me to the mat for extreme terseness. Demonstrating a more fluent style, I refactored the demo code:

public class SelectAndProjectMain {
    public static void main(final String... args) {
        final List<Integer> numbers = asList(1, 2, 3, 4);

        for (final Integer number : over(numbers).select(evens()))
            System.out.println("Even: " + number);

        for (final String number : over(numbers).project(binaries()))
            System.out.println("Binary: " + number);
    }

    static class Evens
            implements Cursorable.Select<Integer> {
        static Evens evens() {
            return new Evens();
        }

        @Override
        public boolean accept(final Integer input) {
            return 0 == input % 2;
        }
    }

    static class Binaries
            implements Cursorable.Project<Integer, String> {
        static Binaries binaries() {
            return new Binaries();
        }

        @Override
        public String on(final Integer input) {
            return Integer.toBinaryString(input);
        }
    }
}

UPDATE: And lastly, more on Option from the land of Scala.

Monday, July 27, 2009

Where is a tool for parsing date ranges in Java?

I'd like to turn this 20090701,20090703-20090710 into a list of dates in Java. It's not hard to do, but I hate writing code like this when I am just certain there's already a library for this.

Except I can't find one.

Any pointers for an open-source library to parse date ranges in Java would be much appreciated. I'm embarrassed to reinvent this whell.

Monday, July 20, 2009

Shell gotcha: when comments execute

The problem: a colleague has a script which dies early, something like this (with the -x flag):

+ [ 2 -eq 2 ]
+ break
+ exit

The corresponding shell (KSH, but same results in BASH):

if [ $cond1 -eq $cond2 ]
then
   break
fi

# Lots of commented out code

more commands ...

The curiosity: why the early exit? The logic does not have an exit anywhere nearby; the commands following do not call exit.

Follow Sherlock Holmes' dictum, How often have I said to you that when you have eliminated the impossible, whatever remains, however improbable, must be the truth? (The Sign of the Four) The only thing left is the commented out code.

Sure enough:

# Blah, blah
# Something with $(hidden command) buried inside
# More blahbage

I had completely forgotten that the shell expands variables even inside comments! In this case, the expanded $(hidden command) blew up and caused the shell to exit prematurely. Caveat plicator.

Tuesday, June 23, 2009

A pleasant read: call/cc

Here's a pretty good explanation of call/cc.

Dataflow concurrency for Java

I ran across this interesting Scala class by Vaclav Pech which makes the data concurrent rather than the code (if I understood the author correctly). The ~ (extraction) and << (insertion) operators looked nifty.

Looking to do the same in Java, I see four key requirements:

  1. Insertion can happen only once.
  2. Extraction is idempotent (infinitely repeatable, non-modifying).
  3. Extraction blocks until insertion has completed.
  4. Insertion and extraction are both atomic.

With these in mind, I write this:

public class DataFlowReference<T> {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private volatile T item;
    private volatile boolean set = false;
    private volatile boolean called = false;

    public T get()
            throws InterruptedException {
        lock.lockInterruptibly();
        try {
            while (true) {
                if (set)
                    return item;

                if (!called) {
                    called = true;
                    onFirstGet();
                    continue;
                }

                condition.await();
            }
        } finally {
            lock.unlock();
        }
    }

    public void setOnce(final T value) {
        lock.lock();
        try {
            if (set)
                return;

            set = true;
            item = value;

            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    protected void onFirstGet() {
    }

    // Object

    @Override
    public boolean equals(final Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        final DataFlowReference that = (DataFlowReference) o;

        return set && item.equals(that.item);
    }

    @Override
    public int hashCode() {
        return set ? item.hashCode() : super.hashCode();
    }

    @Override
    public String toString() {
        return "(" + set + ':' + item + ')';
    }
}

Use of DataFlowReference follows the examples from Vaclav's page: declare dataflow references, create threads whose runables use setOnce() and get(), invoke them all together.

onFirstGet() supports "just in time" supply of item and would call setOnce(T) with a fresh value.

UPDATE: The original version of this class had a horrible, obvious race condition. Caveat plicator.

Thursday, June 11, 2009

Deep understanding of the JVM

Gary Benson posts a deep understanding of the JVM from the team at RedHat porting it to non-x86 architectures.

HTTPS, blow by blow

Jeff Moser presents a blow-by-blow account of HTTPS. I knew most of this stuff in a hand-waving chalkboard way. Now I feel less ignorant about what actually happens when I connect to a secure web site.

Wednesday, April 22, 2009

Jumping the work queue in Executor

My server has an ExecutorService for job scheduling. It came up that we need to have some jobs "jump the queue", that is, go to the front of the line waiting for the next free thread. What to do?

A web search came up empty. After hemming and hawing, and polling other teams, I went with this solution (below). Comments and improvements welcome.

public class PriorityExecutor
        extends ThreadPoolExecutor {
    public PriorityExecutor() {
        super(0, Integer.MAX_VALUE, 60L, SECONDS,
                new PriorityBlockingQueue<Runnable>(11,
                        new PriorityTaskComparator()));
    }

    public PriorityExecutor(final ThreadFactory threadFactory) {
        super(0, Integer.MAX_VALUE, 60L, SECONDS,
                new PriorityBlockingQueue<Runnable>(11,
                        new PriorityTaskComparator()), threadFactory);
    }

    public PriorityExecutor(final RejectedExecutionHandler handler) {
        super(0, Integer.MAX_VALUE, 60L, SECONDS,
                new PriorityBlockingQueue<Runnable>(11,
                        new PriorityTaskComparator()), handler);
    }

    public PriorityExecutor(final ThreadFactory threadFactory,
            final RejectedExecutionHandler handler) {
        super(0, Integer.MAX_VALUE, 60L, SECONDS,
                new PriorityBlockingQueue<Runnable>(11,
                        new PriorityTaskComparator()), threadFactory, handler);
    }

    @Override
    protected <T> RunnableFuture<T> newTaskFor(final Callable<T> callable) {
        if (callable instanceof Important)
            return new PriorityTask<T>(((Important) callable).getPriority(),
                    callable);
        else
            return new PriorityTask<T>(0, callable);
    }

    @Override
    protected <T> RunnableFuture<T> newTaskFor(final Runnable runnable,
            final T value) {
        if (runnable instanceof Important)
            return new PriorityTask<T>(((Important) runnable).getPriority(),
                    runnable, value);
        else
            return new PriorityTask<T>(0, runnable, value);
    }

    public interface Important {
        int getPriority();
    }

    private static final class PriorityTask<T>
            extends FutureTask<T>
            implements Comparable<PriorityTask<T>> {
        private final int priority;

        public PriorityTask(final int priority, final Callable<T> tCallable) {
            super(tCallable);

            this.priority = priority;
        }

        public PriorityTask(final int priority, final Runnable runnable,
                final T result) {
            super(runnable, result);

            this.priority = priority;
        }

        @Override
        public int compareTo(final PriorityTask<T> o) {
            final long diff = o.priority - priority;
            return 0 == diff ? 0 : 0 > diff ? -1 : 1;
        }
    }

    private static class PriorityTaskComparator
            implements Comparator<Runnable> {
        @Override
        public int compare(final Runnable left, final Runnable right) {
            return ((PriorityTask) left).compareTo((PriorityTask) right);
        }
    }
}

Some points:

  • In JDK5 you will need to add three of:
        @Override
        public Future<?> submit(final Runnable task) {
            if (task == null)
                throw new NullPointerException();
            final RunnableFuture<Object> ftask = newTaskFor(task, null);
            execute(ftask);
            return ftask;
        }
    
    These extension points were added in JDK6.
  • It might be useful to include a ThreadFactory which gives important threads higher scheduling priority. It should reuse a factory from the constructor.
  • Remember to take advantage of NORM_PRIORITY and his cohorts.

Callers create their own Runnable and Callable classes which implement Important to communicate their priority. Then simply submit instances of these as usual. Jobs with the highest priority jump to the front of the work queue in the executor waiting for the next free thread.

Monday, April 20, 2009

Fluent assertions, bonus questions

Alex Ruiz tipped me off to an update to FEST, a fluent assertion library. Thanks, Alex!

Bonus questions. Everyone know this idiom:

<K, V> V get(final K key) {
    final V value = concurrentMap.get(key);
    if (null != value) return value;
    concurrentMap.putIfAbsent(key, factoryMethodForV());
    return concurrentMap.get(key);
}

Easier question: How do you support valid null values for the concurrent map? (Hint: monads)

Harder question: Suppose factoryMethodForV() is expensive. How do you guarantee it is only ever called once for a given key?

UPDATE: Fixed some typos.

Tuesday, March 31, 2009

Trivial for-each sugar

A snippet of for-each syntatic sugar for Java loops:

for (final Person person : each (ALICE, BOB, CAT))
    person.say("Hello!");

And elsewhere:

public static <T> T[] each(final T... array) {
    return array;
}

Wednesday, March 25, 2009

Java code beautifier

Where are the Java code beautifiers? My criteria:

  1. Formats in standard SUN Java style
  2. Works on JDK5+ Java code
  3. No licensing required—free as in beer

Not very many criteria! And yet … very little turned up that did not violate one requirement or the other. I came up with exactly one match: Jacobe, personal edition.

Wednesday, March 04, 2009

Two miracle utilities: rlwrap and screen

Two miracle utilities: rlwrap and screen.

rlwrap

Ever wish you had nice command-line editing like BASH but the tool you are using is hopeless? rlwrap is the tool for the job: it is a readline wrapper for any program that reads from stdin. A classic use case is wrapping sqlplus.

screen

Say you have an on-again, off-again shell session you come back to throughout the day. You could keep a shell window open all day. But what if you change machines, say from a laptop to a desktop and back again? screen is the tool for the job: it is a full-screen window manager for terminal sessions. Disconnect from the current session, keep screen running in the background, and reconnect later at your convience. Nothing is lost.

Tuesday, February 17, 2009

To agile, or not to agile

Two of my favorite authorities on programming disagree over agile. This is hardly surprising as they are Joel Spolsky and Robert Martin ("Uncle Bob"), both men known for their strong and well-supported opinions, and neither suffer fools gladly.

Monday, February 09, 2009

Friday, February 06, 2009

Speeding up Cygwin login

On Windows I use Cygwin extensively. So I open a lot of login shells. However these shells are sometimes slow to load, especially when my host is busy with other jobs.

While editing my ~/.bash_profile I noticed code like this:

if [ -d "some path element" ]; then
    PATH="some path element:$PATH"
fi

This is a common idiom. However, it is making a separate fork to /bin/test every time.

A simple improvement:

if [[ -d "some path element" ]]; then
    PATH="some path element:$PATH"
fi

A little trying it out and the verdict: Wow, big improvement.

Tuesday, January 27, 2009

Distributed OSGi: a caution by Roger Voss

Not a new article, but made newly relevant to me as I begin planning a new, distributed project, Roger Voss has sage words in Distributed OSGi - Tilting at Windmills: Don't do it. But if you are going to do it, take precautions.

I have heard the same advice all my career starting with C and UNIX, yet Roger can still point out how often non-veteran developers founder between Scylla and Charybdis.

KDE on Windows

Try KDE 4.2 on Windows. Do it for the children.

Monday, January 26, 2009

Stumbled on: GuiceyFruit

While trying out mvnbrowser I stumbled on GuiceyFruit, a value-add to Guice by James Strachan and Willem Jiang (no blog?).

GuiceyFruit hits the right notes for me: integration of Guice into lots of nice places, especially that EJB3/J2EE business some of my coworkers talk about. Spring-to-Guice converter is cute.

And a bonus: a nice Maven repo tracking Guice 2.x development.

Friday, January 23, 2009

Formatter and new machines

Why is this code broken?

public class Stringifier {
    private final DateFormatter formatter = new SimpleDateFormatter("YYYMMDD");

    public String toYYYMMDD(final Date date) {
        return formatter.format(date);
    }
}

Here's the fixed code which makes the answer obvious:

public class Stringifier {
    private final DateFormatter formatter = new SimpleDateFormatter("YYYMMDD");

    public String toYYYMMDD(final Date date) {
        synchronized(formatter) {
            return formatter.format(date);
        }
    }
}

I checked recently and the lowest-powered servers my company buys have 8 cores. There is no such thing as single-threaded code. See the bug now?

Thursday, January 22, 2009

BDD v. TDD: an example

Following up on my last post, one of my secondary goals in talking about fluent interfaces for testing in Java is to showcase the difference between a traditional TDD approach and a BDD approach:

// In SamTest.java
@Test
public void testIsVisibleAfterGettingTheOneRingAndWearingIt() {
    sam.getItems().add(THE_ONE_RING);
    try {
        THE_ONE_RING.setWorn(true);
    } catch (final GameOverManException ignore) {
    }
    assertThat(sam.isVisible(), is(false));
}

// In TheOneRingTest.java:
@Test(expected = GameOverManException.class)
public void testSetWornForSam() {
    new Sam().getItems().add(THE_ONE_RING);
    THE_ONE_RING.setWorn(true);
}

Contrast:

// In WhenPossessingTheOneRing.java:
@Test
public void samShouldBeInvisibleAfterWearingIt() {
    assertThat(sam().after().gettingTheOneRing().and().puttingItOn(), is(
            not(visible())));
}

@Test
public void samShouldNeverWearIt() {
    assertThat(sam().after().gettingTheOneRing().and().puttingItOn(), is(
            corrupted()));
}

(Given, of course, a suitable fluent testing DSL. Opinion question: I put the DSL in PosessingTheOneRing.java and followed the convention of naming the support class by dropping When from the test class name. Is this good practice?)

Monday, January 19, 2009

Presenting at Houston Tech Fest

I have been invited to fill in for a last minute speaker cancellation at Houston Techfest. I will be presenting this coming Saturday (Jan 24) at 10:15am on the UH main campus.

My presentation is entitled, Fluent Interfaces for Testing in Java, something I worked with Rod Coffin on at work.

I did have different titles originally; it was an iterative process to settle on this one. Previous titles:

  • LOTRO in a Nutshell - too dated
  • LOTRO in Action - too fashionable
  • LOTRO for Dummies - copyright issues

I hope to see some familiar faces on Saturday! Sample code for the talk:

public class WhenPossessingTheOneRing {
    @Test
    public void frodoShouldBeInvisibleAfterWearingIt() {
        assertThat(frodo().after().gettingTheOneRing().and().puttingItOn(),
                is(not(visible())));
    }

    @Test
    public void gandalfShouldNeverGetIt() {
        assertThat(gandalf().after().gettingTheOneRing(),
                is(corrupted()));
    }

    @Test
    public void samCanGetIt() {
        assertThat(sam().after().gettingTheOneRing(),
                is(not(corrupted())));
    }

    @Test
    public void samShouldBeInvisibleAfterWearingIt() {
        assertThat(sam().after().gettingTheOneRing().and().puttingItOn(),
                is(not(visible())));
    }

    @Test
    public void samShouldNeverWearIt() {
        assertThat(sam().after().gettingTheOneRing().and().puttingItOn(),
                is(corrupted()));
    }
}

Friday, January 09, 2009

@Ignore still has life

A nicely thought out post from Ben Rady why @Test(expected = AssertionError.class) is better than @Ignore for JUnit 4 failed tests.

Two reasons I still like @Ignore:

  1. @Ignore includes a string parameter which I use to explain why the test is ignored. It really stands out.
  2. My editor and maven both make special note of ignored tests, and I can find uses of @Ignore to easily jump to any ignored tests.

Demonstrating the first point:

@Ignore("Ship broken in release 1.2.3, fix for next release")
@Test
public void testSign() {
    assertThat(fixture.compute(123), is(not(lessThan(0))));
}

The best choice still remains: Fix the test.

UPDATE: I thought about this more and Ben has a point I overlooked: by expecting {@code AssertionError}, it is true you lose in clarity and documentation compared to {@Ignore}, but the test will start failing once the original problem is fixed:

@Test(expected = AssertionError.class)
public void testSignIsBroken() {
    assertThat(fixture.compute(123), is(not(lessThan(0))));
}

Now you can go and write a proper test against the fixed code.