Exponential Backoff with Java 8

Exponential backoff is an algorithm that uses feedback to multiplicatively decrease the rate of some process, in order to gradually find an acceptable rate. - Wikipedia

I recently used this strategy in work to deal with another service that we need to integrate. Sometimes, the service will just refuse the connection, without any reason. If I keep pushing, it will, someday, accept it.

So, I used Java 8 Functional Interfaces to implement this in a not-so-ugly way, also using a Fibonacci's Sequence to incremente the wait time:

The ExponentialBackOffFunction Functional Interface:

import java.rmi.RemoteException;

@FunctionalInterface
public interface ExponentialBackOffFunction<T> {
    T execute();
}

The ExponentialBackOff main class:

import static java.util.Arrays.asList;

import java.net.SocketTimeoutException;
import java.util.List;

import javax.net.ssl.SSLHandshakeException;

import lombok.extern.log4j.Log4j;

@Log4j
public final class ExponentialBackOff {
    private static final int[] FIBONACCI = new int[] { 1, 1, 2, 3, 5, 8, 13 };
    private static final List<Class<? extends Exception>> EXPECTED_COMMUNICATION_ERRORS = asList(
            SSLHandshakeException.class, SocketTimeoutException.class );

    private ExponentialBackOff() {

    }

    public static <T> T execute(ExponentialBackOffFunction<T> fn) {
    for (int attempt = 0; attempt < FIBONACCI.length; attempt++) {
            try {
                return fn.execute();
            } catch (Exception e) {
                handleFailure( attempt, e );
            }
        }
        throw new RuntimeException( "Failed to communicate." );
    }

    private static void handleFailure(int attempt, RemoteException e) {
        if (e.getCause() != null && !EXPECTED_COMMUNICATION_ERRORS.contains( e.getCause().getClass() ))
            throw new RuntimeException( e );
        doWait( attempt );
    }

    private static void doWait(int attempt) {
        try {
            Thread.sleep( FIBONACCI[attempt] * 1000 );
        } catch (InterruptedException e) {
            throw new RuntimeException( e );
        }
    }
}

Usage:

ExponentialBackOff.execute( () -> work() );

This will try to execute the work method incrementing the time between each call that fail with an expected error.

Comment this post here.

Elections, in Ruby

Updated with second round script in Oct 26, 2014.

Well, last sunday (Oct 5) was the brazilian elections. I was doing nothing, so I decided to write a simple ruby script to parse the results and show the top 3 candidates.

Besides the reverse clean-code done by the TSE (Superior Electoral Court), it was pretty easy:

Maybe the only interesting thing here is the metaprogramming in the String class.

Comment this post here.

Install JDK on OSX Yosemite

jdk

For some reason, Oracle blocked the installers to run only on a fixed OSX version range with a nice and explanatory error message. This range doesn't include Yosemite, which makes sense, since nobody running Yosemite will ever want to write some Java. Anyway, here is how to fix it.

First, download and open the JDK .dmg file. Then, unpackage and edit the Distribution file:

$ pkgutil --expand "/Volumes/JDK 7 Update 67/JDK 7 Update 67.pkg" /tmp/jdk7.unpkg
$ cd /tmp/jdk7.unpkg
$ vim Distribution

PS: I'm using vim, but you can use whatever editor you want, since it is vim.

Replace this function:

function pm_install_check() {
  if(!(checkForMacOSX('10.7.3') == true)) {
    my.result.title = 'OS X Lion required';
    my.result.message = 'This Installer is supported only on OS X 10.7.3 or Later.';
    my.result.type = 'Fatal';
    return false;
  }
  return true;
}

with this:

function pm_install_check() {
  return true;
}

just remove that if statement.

Then, just package and run the installer with:

$ pkgutil --flatten /tmp/jdk7.unpkg /tmp/jdk7.pkg
$ open /tmp/jdk7.pkg

The JDKs will be installed in the /Library/Java/JavaVirtualMachines/ folder.

You can also clean up your mess:

$ rm -rf /tmp/jdk7.*pkg

You can use this tip for JDK 8 too.

Comment this post here.

Java 8

Earlier this year, the new version of the Java Programming Language was released. Finally, it enters in the field of the "cool guys" with some features it should have since some years ago, like Lambdas.

"Java developers are now Hipsters again!"

Seen somewhere in the wild internet.

Anyways, I have been reading about and building simple algorithms with it since day one, but, now that I'm using it in a "real world" project, I would like to say some words about how the experience is going.

But firsts things first. The new features!

The new features!

Well, this version surelly have a lot of cool new features, so, I would like to point out my personal favorites!

1. Lambda Expression

This is really awesome. A lot of languages have this feature for years now, and for years I've been talking about how Java should have this. Now, finally, we have:

Runnable runnable = () -> System.out.println("Run forrest, run!");

Even if the implementation "behind the scenes" is not quite the best, in my humble opinion it is better than the interfaces with all that weird inner classes that we were using before:

Runnable runnable = new Runnable() {
  @Override
  public void run() {
    System.out.println("Run forrest, run!");
  }
};

2. The Stream collection types

I have to admit, this is awesome! We can do all sort of things with a DSL that is actually enjoyable to use:

Map<String, String> hash = new HashMap<>();
hash.entrySet().stream()
    .map(entry -> entry.getValue())
    .filter(entry -> entry.startsWith("C"))
    .distinct()
    .count();

There is also methods for parallel sorting and other stuff (parallelStream). Check also the IntStream class.

3. The new Date and Time API

This is another one that was required for years. Basically, they moved the Date/Time API to the java.time package and followed the Joda Time format, with the good thing that most classes are Threadsafe and immutable.

I just can't wait for Java 8 and the Money API! :moneybag:

4. String.join

I still can't believe that it taked so long...

System.out.println(String.join(". ", "FINALLY", "String", "joining"));
// FINALLY. String. joining

5. Optional

I posted about this in my Facebook timeline and it ends up becoming a little noisy. Anyway, I would really preffer a ruby-ish approach to this problem, but, well, this is better than nothing. I have used it in some filter calls like this, for example:

List<String> names = new ArrayList<>();
names.stream()
    .filter(entry -> entry.startsWith("C"))
    .findFirst() // returns an optional
    .get(); // tries to get its value (might throw NoSuchElementException)

Working with it in the wild

Update all the things! That's it.

I have to admit that I was expecting for this. Almost every library I was using before (with Java 6 or 7) had to be updated.

Some of them aren't even working, and needed some special attention, like openning a pull-request with the fixes and the deploy of custom version with the fix in local nexus repository until the new official version is released, but, nothing that can't be fixed.

This isn't really bad, it's just labor intensive... and a little tedious. Looking for the bright side, you always learn a little. :sparkles:

Resources

Well, you have probably read something about Java 8 already, but, if you didn't, or just want to read more, I recommend you to read the Java 8 Friday at the jOOQ's blog. They have plenty of good study material about this manner.

I could also recommend you a book that I have read: Java 8 Lambdas: Pragmatic Functional Programming. ?

If you want to read some Java 8 code, I have solved some katas using it just for fun. They are probably pretty bad, so feel free to suggest improvements. You can take a look at the source code here.

I have also ran a small Ruby Sinatra service with the last version of jRuby under JDK8 and it worked gracefully. You can take a look at it here.

Well, this is all for now. Feel free to ask anything you want in the comments box bellow!

Cheers!

Comment this post here.

Find the slowest tests of a Java project

I found that it's pretty hard to have a project with high test coverage and fast build... if the tests are slow, people will feel the need to skip them to speed up the build, and will probably write less tests than they should, afraid that the build will became even slower. You go out for a walk and when you come back no one is running or writing tests anymore...

One way to avoid that is to track down the slowest tests and fix them. The less dependencies your test have, the fast it will run. Just saying.

Paraphrasing Uncle Bob:

"The first rule about tests is that they should be fast. The second rule about tests is that they should be faster than that."

** Actually he said that about method sizing, but, I think this fits just fine.

To help with that, I wrote a small script to generate a list of the slowest JUnit tests. It should give you some direction in where to attack. The script is pretty simple, but it does the job.

git clone https://gist.github.com/9420690.git scripts
scripts/slowest-tests project/folder

You can also generate that list in CSV format by running:

scripts/csv-slowest-tests project/folder

More than that, you can use maven-profiler to find other slow parts of your build and fix them.

One last tip: if are having problems with low test coverage in your project, try coverage-maven-plugin, a maven plugin that will blame pull request with coverage bellow a specified amount.

That's it for today, happy hacking!

Comment this post here.