Posted by & filed under Java.

The absence of tuples in Java is often bemoaned. Tuples are collections of a variety of types. They might look like (“benji”,8,”weber”) – a 3-tuple of a string, a number, and another string. People often wish to use tuples to return more than one value from a method.

Often this is a smell that we need to create a domain type that is more meaningful than a tuple, but in some cases tuples are actually the best tool for the job.

We can pretty easily create our own tuple types, and now that we have Lambdas we can consume them pretty easily as well. There is a little unnecessary verbosity left over from type signatures, but we can avoid it in most cases.

If we want to return a tuple from a method, by statically importing an “tuple” method that is overloaded for each arity of tuple we can do

static TriTuple<String, Integer, String> me() {
    return tuple("benji",9001,"weber");
}

Other than the return type of the method it is fairly concise.

On the consuming side it would be nice to be able to use helpful names for each field in the tuple, rather than the ._1() or .one() accessors that are used in many tuple implementations.

This is easily realised thanks to lambdas. We can simply define a map method on the tuple that accepts a function with the same arity of the tuple, to transform the tuple into something else.

Using the above method now becomes

String name = me()
    .map((firstname, favouriteNo, surname) -> firstname + " " + surname);
 
assertEquals("benji weber", name);

We can even throw checked exceptions on the consuming side if we allow our map method to accept functions that throw exceptions.

String name = me()
    .map((firstname, favouriteNo, surname) -> {
        if (favouriteNo > 9000) throw new NumberTooBigException();
        return firstname;
    });

Of course we’d also like identical tuples to be equal to each other so that this is true.

assertEquals(tuple("hello","world"), tuple("hello", "world"));

The implementation looks like this, re-using the value-object pattern I described previously

public interface Tuple {
    //...
    static <A,B,C> TriTuple<A,B,C> tuple(A a, B b, C c) {
        return TriTuple.of(a, b, c);
    }
    //...
}
 
public interface TriTuple<A,B,C> {
    A one();
    B two();
    C three();
    static <A,B,C> TriTuple<A,B,C> of(A a, B b, C c) {
        abstract class TriTupleValue extends Value<TriTuple<A,B,C>> implements TriTuple<A,B,C> {}
        return new TriTupleValue() {
            public A one() { return a; }
            public B two() { return b; }
            public C three() { return c; }
        }.using(TriTuple::one, TriTuple::two, TriTuple::three);
    }
 
    default <R,E extends Exception> R map(ExceptionalTriFunction<A, B, C, R, E> f) throws E {
        return f.apply(one(),two(),three());
    }
 
    default <E extends Exception> void consume(ExceptionalTriConsumer<A,B,C,E> consumer) throws E {
        consumer.accept(one(), two(), three());
    }
}

Browse the full code on Github

Posted by & filed under Uncategorized, XP.

Can you afford not to do continuous deployment?

Continuous deployment is the practice of regularly (more than daily) deploying updated software to production.

Arguments in favour continuous deployment often focus on how it enables us to continually, regularly, and rapidly deliver value to the business, allowing us to move fast. It’s also often discussed how it reduces release-risk by making deployments an everyday event – with smaller, less risky changes, which are fully automated.

I want to consider another reason

Unforeseen Production Issues

It can be tempting to reduce the frequency of deployments in response to risk. If a deployment with a bug can result in losing a significant amount of money or catastrophic reputation damage, it’s tempting to shy away from the risk and do it less often. Why not plan to release once a month instead of every day? Then we’re only taking the risk monthly.

Let’s leave aside the many reasons why doing things less often is unlikely to reduce the risk.

There will always be things that can break your system in production that are outside your control, and are unlikely to be caught by your pre-deployment testing. If you hit one of these issues then you will need to perform a deployment to fix the issue.

Time-sensitive Bugs

How often do we run into bugs in software due to failing to anticipate some detail of time and dates. We hear stories of systems breaking on 29/02 nearly every leap year. Have you anticipated backwards time corrections from NTP? Are you sure you handle leap-seconds? What about every framework and third party service you are using?

Yes, most of these can be tested for in advance with sufficiently rigorous testing, but we always miss test cases.

Time means that we cannot be sure that software that worked when it was deployed will continue to work.

Capacity Problems

If you production system is overloaded due to unforeseen bottlenecks you may need to fix them and re-deploy. Even if you do capacity planning you may find the software needs to scale in ways that you did not anticipate when you wrote your capacity tests.

When you find an unexpected bottleneck in a production system, you’re going to need to make a change and deploy. How quickly depends on how much early warning your monitoring software gave you.

Third Party dependencies

That service that you depend on goes down for an extended period of time, suddenly you need to change your system to not rely on it.

Infrastructure

Do you handle all the infrastructure related issues that can go wrong? What happens if DNS is intermittently returning incorrect results? What if there’s a routing problem between two services in your system?

Third Party Influence

“Noisy Neighbours” in virtualised or shared hosting. Third party JavaScript in your page overwriting your variables or event listeners. In most environments, you can be affected by others over whom you have no control.

Response

Monitor Monitor Monitor

We cannot foresee all production issues and guard against them in our deployment pipeline. Even for those we could, in many cases the cost would not be warranted by the benefit.

Any of the above factors (and more) can cause your system to stop meeting its acceptance criteria at some point after it has been deployed.

The first response to this fact is that we need to monitor everything important in production. This could mean running your automated acceptance tests against your production environment. You can do this both for “feature” and “non-functional” requirement acceptance tests such as capacity.

If you have end-to-end tests feature tests for your system why not run them against your production app? If you’re worried about cluttering production with fake test data you can build in a cleanup mechanism, or a means of excluding your test data from affecting real users.

If you have capacity tests for your system why not run them against your production app? If you’re worried about the risk that it won’t cope at least you can control when the capacity tests run. Wouldn’t you rather your system failed during working hours due to an capacity test which you could just turn off, rather than failing in the middle of the night due to a real spike in traffic?

Be ready to deploy at any point

Tying this back to continuous delivery, I think our second response should be being ready to deploy at any point.

Some of these potential production issues you can prevent with sufficient testing, but will you have thought of every possible case? Some of these issues can be mitigated in production by modifying infrastructure configuration and or application configuration – but

  1. Should you be modifying those independently of the application? They’re just as likely to break your production system as code changes
  2. Not everything will (or should be) configurable

At the point you find yourself needing to do an emergency bug fix on production you have two scenarios when you have not been practising continuous delivery.

  1. You pull up the branch/tag of code last deployed to production a few weeks ago, make your changes, and deploy.
  2. You risk deploying what you have now. Weeks of changes which have not been deployed. Any of which may introduce new, subtle issues.

You may not currently even be at an integrable state. If you were not expecting to deploy why should you be? If you’re not then you need to

  1. Identify quickly what code is actually in production.
  2. Context-switch back to the code-base as it was then. Your mental model of the code will be as it is now, not as it was a few weeks ago.
  3. Create yourself re-integration pain when you have to merge your bugfix with the (potentially many) changes that have been made since. This may be fun if you have performed significant refactorings since.
  4. Perform a risky release. You haven’t deployed for a few weeks. Lots could have broken since then. Are your acceptance tests still working? Or do they have some of the same problems as your production environment? If you have fixed a time-sensitive bug in your tests since your last deploy you will now have to back-port that fix to the branch you are now making your changes on.

Summary

We’ll never be able to foresee everything that will happen in production. It’s eve more important to be able to notice and react quickly to production problems than to stop broken software getting into production.

Posted by & filed under Java, JavaScript.

Here’s a neat trick to transform JSON into Java objects that implement an interface with the same structure.

Java 8 comes with Nashorn – a JavaScript runtime that has a number of extensions.

One of these extensions allows you to pass a JavaScript object to a constructor of an interface to anonymously implement that interface. So for example we can do

jjs> var r = new java.lang.Runnable({ run: function() print('hello') });
jjs> r.run();
hello

n.b. the above uses a JavaScript 1.8 lambda expression, which is supported by Nashorn and allows us to omit the braces and “return” keyword in the function defintion. We could have also omitted the parentheses in the Runnable constructor call in this case.

Now let’s suppose we have a JSON file as follows

{
  "firstname":"Some",
  "lastname":"One",
  "petNames":["Fluffy","Pickle"],
  "favouriteNumber":5
}

and we want to to treat it as a Java interface as follows.

public interface Person {
  String firstname();
  String lastname();
  List<String> petNames();
  int favouriteNumber();
}

It’s trivial to convert the JSON to a JavaScript object with JSON.parse.

The only conceptual difference between the JavaScript object and the Java Interface is that in the interface the properties such as firstname and lastname are methods not literal strings. It’s easy to convert a JavaScript object such that each value is wrapped in a function definition.

We just need to define a function that iterates through each value on our JavaScript object and wraps each in a function.

// A function that takes a value and returns a function 
// which when invoked returns the original value
function createFunc(value) function() value 
// Wrap each property in a function
function iface(map) {
  var ifaceImpl = {}
  for (key in map) ifaceImpl[key] = createFunc(map[key]);
  return ifaceImpl;
}

Applying it to our JS object gives us the following

{
  "firstname":function() "Some",
  "lastname":function() "One",
  "petNames":function() ["Fluffy","Pickle"],
  "favouriteNumber":function() 5
}

This is now satisfies our Java Interface, so we can just pass it to the constructor. Putting it all together

var Person = Packages.Person; // Import Java Person Interface
var someoneElse = new Person(iface({ 
  "firstname":"Some",
  "lastname":"One",
  "petNames":["Fluffy","Pickle"],
  "favouriteNumber":5
}));
 
Person.print(someoneElse); // Pass to a Java method that accepts a Person instance.

If our JSON were originally in a text file we could use Nashorn’s scripting extensions to read the text file and convert it to an interface in the same way. This can be useful for bootstrapping a Java app without a main method – you can read a JSON config file, convert it to a typed Java interface, and start the app. This can free the Java app from dealing with JSON or argument parsing

#!/usr/bin/jjs
function createFunc(value) function() value
function iface(map) {
  var ifaceImpl = {}
  for (key in map) ifaceImpl[key] = createFunc(map[key]);
  return ifaceImpl;
}
var Settings = Packages.Settings;
var MyApplication = Packages.MyApplication;
 
// Backticks in Nashorn scripting mode works like in Bash
var settings = new Settings(iface(JSON.parse(`cat app_config.json`))); 
MyApplication.start(settings);
public interface Settings {
  String hostname();
  int maxThreads();
}
public class MyApplication {
  public static void start(Settings settings) {
    //
  }
}

One small annoyance with this is that jjs (Nashorn executable) does not seem able to accept a classpath parameter when used with a shebang #!/usr/bin/jjs . So for now you have to execute the JavaScript with

$ jjs -scripting -cp . ./example.js

There’s a complete example here

Posted by & filed under Java.

One of the language features many people miss in Java is pattern matching, and/or an equivalent of Scala case classes.

In Scala we can match on types and structure. We have “switch” in Java, but it’s much less powerful and it can’t even be used as an expression. It’s possible to simulate matching in Java with some degree of success.

Matching on Type

Here’s an example matching on type. Our description method accepts a shape which can be one of three types – Rectangle, Circle or Cube. It is a compile failure to not specify a handler for each of Rectangle/Circle/Cube.

@Test
public void case_example() {
    Shape cube = Cube.create(4f);
    Shape circle = Circle.create(6f);
    Shape rectangle = Rectangle.create(1f, 2f);
 
    assertEquals("Cube with size 4.0", description(cube));
    assertEquals("Circle with radius 6.0", description(circle));
    assertEquals("Rectangle 1.0x2.0", description(rectangle));
}
 
public String description(Shape shape) {
    return shape.match()
        .when(Rectangle.class, rect -> "Rectangle " + rect.width() + "x" + rect.length())
        .when(Circle.class, circle -> "Circle with radius " + circle.radius())
        .when(Cube.class, cube -> "Cube with size " + cube.size());
}
interface Shape extends Case3<Rectangle, Circle, Cube> { }
interface Cube extends Shape {
    float size();
    static Cube create(float size) {
        return () -> size;
    }
}
//...

If Java didn’t already have an Optional type we could use this to implement our own, although type-erasure causes us to need a hack to match on the raw (unparameterised) type – to convert from a Class<Some<String>> to a Class<Some> for matching.

@Test
public void some_none_match_example() {
    Option<String> exists = some("hello");
    Option<String> missing = none();
 
    assertEquals("hello", describe(exists));
 
    assertEquals("missing", describe(missing));
}
 
private String describe(Option<String> option) {
    return option.match()
        .when(erasesTo(Some.class), some -> some.value())
        .when(erasesTo(None.class), none -> "missing");
}
interface Option<T> extends Case2<Some<T>, None<T>>{ }

Matching on Structure

Another thing we might want to do is match on particular values. This means we’re be unable to ensure that all values are handled and need to provide a default case.

Here’s an example. The underscore character is used to denote any value, like in Scala.

@Test
public void constructor_matching_any() {
    Person so = person("Some", "One");
    Person an = person("Ann", "Other");
 
    String another = an.match()
        .when(person("Some", _), p -> "someone")
        .when(person(_, "Other"), p -> "another")
        ._("Unknown Person");
 
    assertEquals("another", another);
}

A more practical example might be handling command line arguments

@Test
public void parse_arguments_example() {
    applyArgument(arg("--help", "foo"));
    assertEquals("foo", this.helpRequested);
 
    applyArgument(arg("--lang", "English"));
    assertEquals("English", this.language);
 
    applyArgument(arg("--nonsense","this does not exist"));
    assertTrue(badArg);
}
 
private void applyArgument(Argument input) {
    input.match()
        .when(arg("--help", _), arg -> printHelp(arg.value()))
        .when(arg("--lang", _), arg -> setLanguage(arg.value()))
        ._(arg -> printUsageAndExit());
}

Decomposition

With a bit more effort we can even match on the structure of the type and pull out the bits we are interested in. Here’s an example. We match on certain attributes of Person and then consume the other attributes in the following function to build the result.

@Test
public void decomposition_variable_items_example() {
    Person a = person("Bob", "Smith", 18);
    Person b = person("Bill", "Smith", 28);
    Person c = person("Old", "Person", 90);
 
    assertEquals("first_Smith_18", matchExample(a));
    assertEquals("second_28", matchExample(b));
    assertEquals("unknown", matchExample(c));
}
 
String matchExample(Person person) {
    return person.match()
        .when(person("Bob", _, _), (surname, age) -> "first_" + surname + "_" + age)
        .when(person("Bill", "Smith", _), age -> "second_" + age)
        ._("unknown");
}

Making it Work

To implement this we create an interface for each number of cases we want to be able to match on, parameterised by the possible types it can take. This is effectively giving us the “Type A OR Type B” restriction. This interface provides a default method match() which returns a builder which lets you specify a handler for each and all of the cases.

When evaluated, match() compares its own type to the passed in Class<?>.

public interface Case3<T,U,V> {
    default MatchBuilderNone<T,U,V> match() {
        return new MatchBuilderNone<T, U, V>() {
            public <R> MatchBuilderOne<T, U, V, R> when(Class<T> clsT, Function<T, R> fT) {
                return (clsU, fU) -> (clsV, fV) -> {
                    if (clsT.isAssignableFrom(Case3.this.getClass())) return fT.apply((T)Case3.this);
                    if (clsU.isAssignableFrom(Case3.this.getClass())) return fU.apply((U)Case3.this);
                    if (clsV.isAssignableFrom(Case3.this.getClass())) return fV.apply((V)Case3.this);
 
                    throw new IllegalStateException("Match failed");
                };
            }
        };
    }
}

For the matching on parts of a value to work (as in the argument parsing example) we need equals/hashCode to work. This would be a lot easier with actual value type support.

We can extend the base Case interface to allow matching on value as well class, and then building on the autoEquals/Hashcode I explained previously add additional constructor functions that create value objects that ignore specific fields for equality checking.

This is still far more verbose than it should have to be, and it requires adding suitable constructors to each value type you want to use match() with, but I think it’s quite neat.

Here’s what a Person type that’s matchable on either firstname or lastname or both looks like.

interface Person extends Case<Person> {
    String firstname();
    String lastname();
 
    static Person person(String firstname, String lastname) {
        return person(firstname, lastname, Person::firstname, Person::lastname);
    }
    static Person person(String firstname, MatchesAny lastname) {
        return person(firstname, null, Person::firstname);
    }
    static Person person(MatchesAny firstname, String lastname) {
        return person(null, lastname, Person::lastname);
    }
    static Person person(String firstname, String lastname, Function<Person, ?>... props) {
        abstract class PersonValue extends Value<Person> implements Person {}
        return new Person() {
            public String firstname() { return firstname; }
            public String lastname() { return lastname; }
        }.using(props);
    }
}

Decomposition uses pretty much the same approach, but now the factory method has to record the properties that we want to capture as follows. .missing() is overloaded with different numbers of fields to return different types. This allows our .when() match method to also be overloaded based on how many fields we are extracting and therefore accept a lambda with the correct number of parameters. i.e. when(OneMissing, Function), when(TwoMissing, BiFunction)

static OneMissing<Person, String> person(String firstname, MatchesAny lastname, Integer age) {
    return person(firstname, null, age, Person::firstname, Person::age)
        .missing(Person::lastname);
}

Further reading

More examples and implementation on github

Posted by & filed under XP.

Tests, like any code, should be deleted when their cost exceeds their value.

We are often unduly reticent to delete test code. It’s easy to ignore the cost of tests. We can end up paying a lot for tests, long after they are written.

When embarking on a major re-factoring or new feature it can be liberating to delete all the tests associated with the old implementation and test-drive the new one. Especially if you have higher level tests that test important behaviour you want to retain.

This may seem obvious, but in practice it’s often hard to spot where tests should be deleted. Here’s some attributes to think about when evaluating the cost-effectiveness of tests.

Value

Let’s start with value. Good tests provide lots of value. They provide protection against regressions introduced as the software is refactored or altered. They give rapid feedback on unanticipated side-effects. They also provide executable documentation about the intent of code, why it exists, and which use cases were foreseen.

Redundancy

Unneeded Tests

If there multiple tests covering the same behaviours, perhaps you don’t need all of them. If there’s code that’s only referenced from tests, then you can probably delete that code along with its tests. Even if static analysis indicates code is reachable – is it actually being used in production? Or is it a dead or seldom used feature that can be pruned from your system.

Documentation and Duplicating Implementation

Some tests simply duplicate their implementation. This can happen both with very declarative code which has little behaviour to test, and with excessively mocked-out code where the tests become a specification of the implementation. Neither of these provide a lot of value as they tend to break during refactoring of the implementation as well as when the behaviour changes. Nor do they provide any significant documentation value if they are simply repeating the implementation.

Type System

Tests can also be made redundant by the type system. Simple tests on preconditions or valid inputs to methods can often be replaced by preconditions the type system can enforce.

e.g. if you have 3 methods that all expect an argument that is an integer between 1 and 11 why not make them accept an object of a type that can only be between 1 and 11? While you’re at it you can give it a more meaningful name than integer. onChange(VolumeLevel input) is more meaningful than onChange(int volumeLevel) and removes need for tests at the same time.

Risk

When evaluating the regression protection value that we get from a test we need to think about the risk of the behaviour under test being broken in production.

A system that processes money and could lose thousands of dollars a minute with a small tweak means a big risk of expensive regressions, even if they’re caught quickly in production.

Therefore tests on the behaviour of that system are going to have higher value than tests on a weekly batch log-analysis job that can just be re-run if it fails or produces the wrong results.

Outlived Usefulness

Is the test testing desired behaviour, or behaviour that’s really just a side effect of the chosen implementation approach? Some tests are really useful for “driving” a particular implementation design, but don’t provide much regression test value.

Does the tested behaviour still match what customers and or users want now? Usage patterns change over time as users change, their knowledge of the software changes, and new features are added and removed.

The desired behaviour at the time the test was written might no longer match the desired behaviour now.

Speed

Speed is one of the most important attributes of tests to consider when evaluating their value. Fast tests are valuable because they give us rapid feedback on unanticipated side effects of changes we make. Slow tests are less valuable because it takes longer for them to give you feedback.

This brings us nicely to…

Cost

Speed

Worse than being less valuable in and of themselves, slow tests in your test suite delay you from getting feedback from your other tests while you wait for them (Unless you parallelise every single test). This is a significant cost to having them in your test suite at all.

Slow tests can discourage you from running your suite of tests as regularly as you would otherwise, which can lead to you wasting time on changes that you later realise will break important functionality.

Test suites that take a long time also increase the time it takes to deploy changes to production. This reduces the effectiveness of another feedback loop – getting input from users & customers about your released changes. As test suites get slower it is inevitable that you will also release changes less frequently. Releases become bigger and scarier events that are more likely to go wrong.

In short, slow tests threaten continuous integration and continuous delivery.

There are ways of combating slow tests while keeping them. You can profile and optimise them – just like any other code. You can decompose your architecture into smaller, decoupled services so that you don’t have to run so many tests at a time. In some scenarios it’s appropriate to migrate the tests to be monitoring on your production environment instead of tests in the traditional sense.

However, if the cost imposed by slow tests is not outweighed by their value then don’t hesitate to remove them.

Brittleness

Have you ever worked on a codebase where seemingly any change you made broke hundreds of tests, regardless of whether it changed any behaviour? These brittle tests impose a significant cost on the development of any new features, performance improvements, or refactoring work.

There can be several causes of this. Poorly factored tests with lots of duplication between tests tend to be brittle – especially when assertions (or verifications of mock behaviour) are duplicated between tests. Excessive use of strict mocks (that fail on any unexpected interactions) can encourage this. Another common cause is tests that coupled to their implementation, such as user interface tests that have hard coded css selectors, copy, and x/y coordinates.

You can refactor tests to make them less brittle. You can remove duplication, split tests up so that each asserts only one piece of behaviour, and decouple tests from the implementation using a domain specific DSL or the page object pattern

Or, if the cost of continually fixing and or refactoring these tests is not outweighed by the value they’re providing you could just delete them.

Determinism

Non-deterministic tests have a particularly high cost. They cause us to waste time re-trying them when they fail. They reduce our faith in the test suite to protect us against regressions. They also tend to take a particularly long time to diagnose and fix.

Common causes include sleep() in the tests rather than waiting for and responding to an event. Any test that relies on code or systems that you do not control can be prone to non-determinism. How do your tests cope if your DNS server is slow or returns incorrect results? Do they even work without an internet connection?

Due to the high cost they impose, and the often high cost of fixing them, non-deterministic tests are often ideal candidates for deletion.

Measurement

These cost/value attributes of tests are fairly subjective. Different people will judge costs and risks differently. Most of the time this is fine and it’s not worth imposing overhead to make more data driven decisions.

Monitor Production

Code coverage, logging, or analytics from your production system can help you determine which features are used and which can be removed, along with their tests. As can feedback from your users.

Build Server

Some people will collect data from their build server test runs to record test determinism, test suite time and similar. This can be useful, but it ignores all the times the tests are run by developers on their workstations.

I favour a lightweight approach. Only measure things that are actually useful and you need to.

JUnit Rules

A method for getting feedback on tests that I have found useful is to use the test framework features themselves. JUnit provides a way of hooking in before and after test execution using Rules.

A simple Rule implementation can record the time a test takes to execute. It can record whether it’s non-deterministic by re-trying a failing test and logging if it passes a second time. It can record how often a test is run, how often a test fails, and information about why tests fails.

This data can then be logged and collected centrally for analysis with a log management tool, or published via email, dashboard or similar.

This approach means you can get visibility on how your tests are really being used on workstations, rather than how they behave when run in your controlled build server environment.

Final thoughts

Having so many tests that their speed and reliability becomes a big problem is a nice #firstworldproblem to have. You can also bear these cost/value attributes in mind when writing tests to help yourself write better tests.

Don’t forget, you can always get tests back from revision control if you need them again. There’s no reason to @Ignore tests.

So don’t be afraid to delete tests if their cost exceeds their value.

Posted by & filed under Java.

Java 8 not only gives us both default and static methods on interfaces. One of the consequences of this is you can create simple value objects using interfaces alone, without the need to define a class.

Here’s an example. We define a Paint type which is composed of an amount of red/green/blue paint. We can add operations that make use of these like mix which produces the result of mixing two paints together. We can also create a static factory method in lieu of a constructor to create us an instance of a paint.

interface Paint {
    int red();
    int green();
    int blue();
    default Paint mix(Paint other) {
        return create(red() + other.red(), green() + other.green(), blue() + other.blue());
    }
 
    static Paint create(int red, int green, int blue) {
        return new Paint() {
            public int red() { return red; }
            public int green() { return green; }
            public int blue() { return blue; }
        };
    }
}

This is what using it looks like

@Test
public void mixingPaint() {
    Paint red = Paint.create(100,0,0);
    Paint green = Paint.create(0,100,0);
 
    Paint mixed = red.mix(green);
 
    assertEquals(100, mixed.red());
    assertEquals(100, mixed.green());
}

While it may seem odd – there are advantages to doing this sort of thing. There’s a slight reduction in boilerplate due to not having to deal with fields. It’s a way of ensuring your value type is immutable because you can’t so easily introduce state. It also allows you to make use of multiple inheritance, because you can inherit from multiple interfaces.

There are also obvious disadvantages – we can only have public attributes and methods.

Adding equals/hashcode/toString is a bit harder because in an interface we cannot override methods defined on a class.

I’d like to be able to do the following, where equivalent paints are equal.

@Test
public void paintEquals() {
    Paint red = Paint.create(100,0,0);
    Paint green = Paint.create(0,100,0);
 
    Paint mixed1 = red.mix(green);
    Paint mixed2 = green.mix(red);
 
    assertEquals(mixed1, mixed2);
    assertNotEquals(red, green);
    assertNotEquals(red, mixed1);
}

The least-verbose approach I’ve managed so far (without resorting to reflection) requires us to override the equals/hashCode/toString methods in our anonymous inner class.

We can, however, avoid having to implement them there and move the implementation to some helper interfaces.

The only additional boilerplate required is implementing a props() method that returns the properties we want to include in our equals/hashcode/toString.

interface Paint extends EqualsHashcode<Paint>, ToString<Paint> {
    int red();
    int green();
    int blue();
    default Paint mix(Paint other) {
        return create(red() + other.red(), green() + other.green(), blue() + other.blue());
    }
 
    static Paint create(int red, int green, int blue) {
        return new Paint() {
            public int red() { return red; }
            public int green() { return green; }
            public int blue() { return blue; }
            @Override public boolean equals(Object o) { return autoEquals(o); }
            @Override public int hashCode() { return autoHashCode(); }
            @Override public String toString() { return autoToString(); }
        };
    }
 
    default List<Function<Paint,?>> props() {
        return asList(Paint::red, Paint::green, Paint::blue);
    }
 
}

This is still overly verbose. We can reduce it by moving the overrides to an abstract base class that we hide from the callers of our create() method. We simply move the equals/hashCode/toString overrides to a Value<T> base class, which provides a setter for the properties to use for the equals/hashCode.

This leaves us with the relatively consise

interface Paint {
    int red();
    int green();
    int blue();
    default Paint mix(Paint other) {
        return create(red() + other.red(), green() + other.green(), blue() + other.blue());
    }
 
    static Paint create(int red, int green, int blue) {
        abstract class PaintValue extends Value<Paint> implements Paint {}
        return new PaintValue() {
            public int red() { return red; }
            public int green() { return green; }
            public int blue() { return blue; }
        }.using(Paint::red, Paint::green, Paint::blue);
    }
}

You will notice that paint now extends both EqualsHashcode and ToString, where we place the implementation of auto(Equals|HashCode|ToString).

Let’s look at toString first as it’s simpler. We define a default method that takes the value of the properties returned by our props() method above, and concatenates them together.

interface ToString<T> {
    default String autoToString() {
        return "{" +
        props().stream()
            .map(prop -> (Object)prop.apply((T)this))
            .map(Object::toString)
            .collect(Collectors.joining(", ")) +
        "}";
    }
 
    List<Function<T,?>> props();
}

EqualsHashcode is similar. For equals we can apply the property functions to “this” and also the supplied object for comparison. We require all properties to match on both objects for equality. In the same way we can calculate a hashcode based on the supplied properties.

public interface EqualsHashcode<T> {
    default boolean autoEquals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        final T value = (T)o;
        return props().stream()
            .allMatch(prop -> Objects.equals(prop.apply((T) this), prop.apply(value)));
    }
 
    default int autoHashCode() {
        return props().stream()
            .map(prop -> (Object)prop.apply((T)this))
            .collect(ResultCalculator::new, ResultCalculator::accept, ResultCalculator::combine)
            .result;
    }
 
 
    static class ResultCalculator implements Consumer {
        private int result = 0;
        public void accept(Object value) {
            result = 31 * result + (value != null ? value.hashCode() : 0);
        }
        public void combine(ResultCalculator other) {
            result += other.result;
        }
    }
 
    List<Function<T,?>> props();
}

What other reasons are there this is a crazy idea? Is there a better way of implementing equals/hashCode?

Posted by & filed under Java.

Java 8′s default methods on interfaces means we can implement the decorator pattern much less verbosely.

The decorator pattern allows us to add behaviour to an object without using inheritance. I often find myself using it to “extend” third party interfaces with useful additional behaviour.

Let’s say we wanted to add a map method to List that allows us to convert from a list of one type to a list of another. There is already such a method on the Stream interface, but it serves as an example

We used to have to either

a) Subclass a concrete List implementation and add our method (which makes re-use hard), or
b) Re-implement the considerably large List interface, delegating to a wrapped List.

You can ask your IDE to generate these delegate methods for you, but with a large interface like List the boilerplate tends to obscure the added behaviour.



class MappingList<T> implements List<T> {
    private List<T> impl;
 
    public int size() {
        return impl.size();
    }
 
    public boolean isEmpty() {
        return impl.isEmpty();
    }
 
    // Many more boilerplate methods omitted for brevity
 
    // The method we actually wanted to add.
    public <R> List<R> map(Function<T,R> f) {
        return list.stream().map(f).collect(Collectors.toList());
    }
 
}

Guava gave us a third option

c) Extend the the Guava ForwardingList class. Unfortunately that meant you couldn’t extend any other class.

Java 8 gives us a fourth option

d) We can implement the forwarding behaviour in an interface, and then add our behaviour on top.

The disadvantage is you need a public method which exposes the underlying implementation. The advantages are you can keep the added behaviour separate, and it’s easier to compose them.

Our decorator can now be really short – something like

class MappableList<T> implements List<T>, ForwardingList<T>, Mappable<T> {
    private List<T> impl;
 
    public MappableList(List<T> impl) {
        this.impl = impl;
    }
 
    @Override
    public List<T> impl() {
        return impl;
    }
}

We can use it like this

// prints 3, twice.
new MappableList<String>(asList("foo", "bar"))
    .map(s -> s.length())
    .forEach(System.out::println);

The new method we added is declared in its own Mappable<T> interface which is uncluttered.

interface Mappable<T> extends ForwardingList<T> {
	default <R> List<R> map(Function<T,R> f) {
		return impl().stream().map(f).collect(Collectors.toList());
	}
}

The delegation boilerplate we can keep in its own interface, out of the way. Since it’s an interface we are free to extend other classes/interfaces in our decorator

interface ForwardingList<T> extends List<T> {
    List<T> impl();
 
    default int size() {
        return impl().size();
    }
 
    default boolean isEmpty() {
        return impl().isEmpty();
    }	
 
    // Other methods omitted for brevity
 
}

If we wanted to mix in some more functionality to our MappableList decorator class we could just implement another interface. In the above example we added a new method, so this time let’s modify one of the existing methods on List. Let’s make a List that always thinks it’s empty.

interface AlwaysEmpty<T> extends ForwardingList<T> {
    default boolean isEmpty() {
        return true;
    }
}
class MappableList<T> implements 
    List<T>, 
    ForwardingList<T>, 
    Mappable<T>, 
    AlwaysEmpty<T> { // Mix in the new interface
    // ...
}

Now our list always claims it’s empty

// prints true
System.out.println(new MappableList<String>(asList("foo", "bar")).isEmpty());

Posted by & filed under Java.

I’ve been thinking about how to express joins in my pure Java query library.

Hibernate and other ORMs allow you to map collection fields via join tables. They will take care of cascading inserts and deletes from multiple tables for you.

While this is nice and easy, it can to cause problems with bigger object graphs because it hides the performance implications of what it is going on from you. You may appear to be saving a single object but that might translate into modifying millions of rows.

There is still more complexity, as you can map the same relational structure into different Java datatypes. Different hibernate collections have different performance characteristics. Sets have a query performance penalty from ensuring uniqueness, Lists have an ordering penalty, and bags have a persistence cost from recreating the collection on save.

This complexity makes me think that transparently doing joins and mapping collection properties is not a good idea at least without a lot of thought.

The nice thing about what I had so far was that there were no Strings needed (Except for values). All properties were referred to as Java properties. There was also no code generation needed (Unlike JOOQ).

This is what I’ve come up with for creating and querying many to many relationships. Let’s say we have Person and Conspiracy entities. Persisted as per my last post.

class Person {
	String getFirstName();
	String getLastName();
	// ...
}
class Conspiracy {
	String getName();	
	// ...
}

A person can be in multiple conspiracies, and conspiracies can have many people involved, so we need another relationship table in the database schema.

I’ve got the following code creating a conspiracy_person table with appropriate foreign keys. It’s reasonably nice. Unfortunately we have to have separate fieldLeft and fieldRight methods for fields referencing the right and left hand side of the relationship. It’s type erasure’s fault as usual. We can’t have a methods that differ only by their generic type parameters.

create(relationship(Conspiracy.class, Person.class))
    .fieldLeft(Conspiracy::getName)
    .fieldRight(Person::getFirstName)
    .fieldRight(Person::getLastName)
    .execute(this::openConnection);

Equivalent to

CREATE TABLE IF NOT EXISTS conspiracy_person ( 
    conspiracy_name text, 
    person_first_name text, 
    person_last_name text 
);

We can delete in the same manner as we did with simple tables. Again I can’t see a way to avoid having left/right in the method names.

delete(relationship(Conspiracy.class, Person.class))
    .whereLeft(Conspiracy::getName)
    .equalTo("nsa")
    .andRight(Person::getLastName)
    .equalTo("smith")
    .execute(this::openConnection);

Equivalent to

DELETE FROM conspiracy_person WHERE conspiracy_name = ? AND person_last_name = ?;

Now for saving a collection. Saving all the items in a collection at once is something we’re likely to want to do. We can do the following and for each person in our conspiracy, persist the relationship between the conspiracy and the person. This is going to be slow, but at least we’ve made it obvious what we’re doing.

nsa.getMembers().forEach(agent -> {
    insert(nsa, agent)
        .valueLeft(Conspiracy::getName)
        .valueRight(Person::getLastName)
        .valueRight(Person::getFirstName)
        .execute(this::openConnection);
});

Equivalent to repeated

INSERT INTO conspiracy_person (
    conspiracy_name, 
    person_last_name, 
    person_first_name
) VALUES ( ?, ?, ? )

Finally, let’s query using our new join tables.

Mapper<Person> personMapper = Mapper.mapper(Person::new)
    .set(Person::setFirstName)
    .set(Person::setLastName)
    .set(Person::setFavouriteNumber);
 
Optional<Person> person = from(Person.class)
    .where(Person::getLastName)
    .equalTo("smith")
    .join(relationship(Conspiracy.class, Person.class).invert())
    .using(Person::getFirstName, Person::getLastName)
    .join(Conspiracy.class)
    .using(Conspiracy::getName)
    .where(Conspiracy::getName)
    .equalTo("nsa")
    .select(personMapper, this::openConnection);

This generates and executes the following SQL, and returns us an instance of a Person.

SELECT * FROM person 
JOIN conspiracy_person 
ON person.first_name = conspiracy_person.person_first_name 
AND person.last_name = conspiracy_person.person_last_name 
JOIN conspiracy 
ON conspiracy_person.conspiracy_name = conspiracy.name 
WHERE person.last_name = ? 
AND conspiracy.name = ?

There are some slightly clunky things. You have to specify any “where” conditions before joining to another table. This is so the type system can help you pass properties on the correct type. In the above example the first where call that takes a Person::getLastName would fail to compile if passed a Conspiracy::getName. This annoyingly means the query reads in a different order to the SQL generated.

You can also only join on tables in an chainable order. If you are querying table A you can only join to table B if there is a key to join to A with. If you query table A, then join to B, you can not then join to another table that could join to A. This is obviously a problem for many queries and needs addressing, but type erasure has made my head hurt enough for one afternoon :)

There’s lots of other things to think about too. e.g. More complex boolean join conditions. More complex join tables; One-to-many relationships; Pluggable naming conventions/Database support.

The code is on github here.

Posted by & filed under Conferences, XP.

This week I attended #pipelineconf, a new one-day continuous delivery conference in London.

I did a talk with Alex on how we do continuous delivery at Unruly, which seemed well received. The slides are online here

There were great discussions in the open space sessions, and ad-hoc in the hallways. Here’s a few points that came up in discussion that I thought were particularly interesting.

De-segregate different categories of tests

There are frameworks for writing automated acceptance tests, tools for automated security testing, frameworks and tools for performance testing, and tools for monitoring production systems.

We don’t really want to test these things in isolation. If there is a feature requested by a customer that we’re implementing, it probably has some non-functional requirements that also apply to it. We really want to test those along with the feature acceptance test.

i.e. for each acceptance test we could define speed and capacity requirements. We could also run http traffic from each test through tools such as ZAP that try common attack vectors.

Testing and monitoring shouldn’t be so distinct

We often think separately about what things we need to monitor in our production environment and what things we want to test as part of our delivery pipeline before releasing to production.

This often leads us to greatly under-monitor things in production. Therefore, we’re over-reliant on the checks in our pipeline preventing broken things reaching production. We also often fail to spot behaviour degradation in production completely.

Monitoring tools for production systems often focus on servers/nodes first, and services second.

We’d really like to just run our acceptance tests for both functional and non-functional requirements in production against our production systems in the same way that we do as part of our deployment.

This isn’t even particularly hard. An automated test from your application test suite can probably succeed, fail, or generate an unknown failure. These are exactly the states that tools like Nagios expect. You can simply get Nagios to execute your tests.

Monitoring your application behaviour in production also gives you the opportunity to remove tests from your deployment pipeline if it’s acceptable to the business for a feature to be broken/degraded in production for a certain amount of time. This can be a useful trade-off for tests that are inherently slow and not critically important.

Non-functional requirements aren’t

People often call requirements about resilience/robustness/security/performance “non-functional requirements” because they’re requirements that are not for features per se. However, they are still things our customers will want, and they are still things that a our stakeholders can prioritise against features – as long as we have done a good enough job of explaining the cost and risk of doing or not doing the work.

Technical people typically help with coming up with these requirements, but they should be prioritised along with our features.

There’s no point building the fastest, most secure system if no-one ever uses it because we haven’t tested our assumptions that there’s a market for our product. Similarly there may be a high risk to not completing a particular piece of security work is not completed.

Technical people often don’t like trusting non-technical people to make these decisions – partly because we’re often bad at articulating and providing evidence for the risks associated with delaying this work, but also because we sometimes understand the risks/benefits of “non-functional” requirements better than the feature requirements so don’t agree with their decisions.

Both are communication problems. Business-people are used to weighing up risks and costs of delay with normal features. There is always an opportunity cost to working on something that is not needed, and there is a risk of delay of features because a competitor might get to it first.

Green-first performance tests

This was some interesting insight from Dave Farley. When writing tests we usually write a failing test first, then make it pass, then refactor. With performance tests this approach can lead to you being unsure whether your test is failing because the implementation is too slow, or because your code is too slow.

If you make your test pass first using a stub implementation and then see it fail by switching to the real implementation then you will have confidence that the test is not the bottleneck.

Customer as the bottleneck

Let us suppose we have development practices that allow us to iterate quickly, automated deployments that let us deploy rapidly, and operations are following the same practices – allowing us to promote to production rapidly.

In this scenario the customer becomes the bottleneck. How quickly can we come up with new things to build. No matter how much we automate the rest of the process – talking to customers remains manual. It’s also one of the hardest things to improve because it requires skills that are difficult to teach and learn.

It’s all about the people

There seemed to be strong agreement in all discussions that for continuous delivery to work you need people to think in the right way and to foster the right culture. Tools can help, but ultimately the technical challenges aren’t actually very big.

You can do continuous delivery with very simple tools and scripts. To do continuous delivery well you need people to buy into the idea, and you need to break down barriers that introduce asynchronicity into your delivery pipeline.

However, tools can help with persuasion. If you can demonstrate how much quicker something can be with automation then it goes a long way to selling the idea.

It’s always worth sharing your experience

I was struck by how unusual some of our working practices were, and how useful some people found our ideas.

Similarly, I learnt a lot from others at the conference. It was especially interesting to hear people’s experience introducing continuous delivery into large organisations that were extremely slow in delivery and risk adverse.

It’s easy to become blind to things you do every day which may actually be useful and unknown to those outside your niche community.

Posted by & filed under Java.

There are different viewpoints on how to use exceptions effectively in Java. Some people like checked exceptions, some argue they are a failed experiment and prefer exclusive use of unchecked exceptions. Others eschew exceptions entirely in favour of passing and returning types like Optional or Maybe.

Whatever your view, you are likely to need to interact with libraries written by people with a different usage of Exceptions. This often leads to ugly code to translate failure conditions into your preferred approach.

This is likely to become more of a pain with Java 8, where the Streams api doesn’t play very nicely with methods that throw exceptions.

Fortunately, Java 8 also helps us translate between styles of exception usage more easily.

Using Streams with Exceptions

Using the streams api can become painful when you wish to use methods that throw exceptions as maps or filters.

Take this example. What happens if Example.duplicatesShortStrings throws a checked exception? It will fail to compile.

The map method on the stream interface expects a Function that takes an argument and returns a value without any exceptions in its method signature.

If map did accept functions that can throw exceptions then the whole chain of transformations would fail if that exception were thrown on any given element. In this example the string “booooo” is too long and will cause an exception, which means we wouldn’t get any results at all.

asList("foo", "bar", "baz", "booooo")
    .stream()
    .map(Example::duplicatesShortStrings) // This will fail to compile 
    .collect(Collectors.toList());
 
...
 
String duplicatesShortStrings(String input) throws InputTooLongException {
    if (input.length() > 3) throw new InputTooLongException();

How can we handle this kind of scenario better? In functional languages you might return either the result or an error from a function rather than having exceptions. The method from the example above might look more like.

Result<String, InputTooLong> duplicatesShortStrings(String input)

That’s all very well, and easier to work with, but we are likely to be consuming lots of existing code using exceptions which we are not able to re-write.

You’ll also notice that there both of these are basically equivalent

Result<String, InputTooLong> duplicatesShortStrings(String input)
String duplicatesShortStrings(String input) throws InputTooLong

What if we provide a way to translate both ways between these two styles. Then we could use streams without problems. It’s mostly possible to do this. Unfortunately, we can’t record all the possible failure conditions with generics due to lack of varargs for generic type parameters. We can, however, achieve the following.

List<String> result =
    asList("foo", "bar", "baz", "boooo")
        .stream()
        .map(Result.wrapReturn(Example::duplicatesShortStrings))
        .map(Result.wrap(s -> s.toUpperCase()))
        .filter(Result::success)
        .map(Result::unwrap)
        .collect(Collectors.toList());
 
assertEquals(asList("FOOFOO","BARBAR","BAZBAZ"), result);

Here we convert our method that throws an exception into a function that returns a Result type that encodes whether it is a success or failure and the type of failure. We can then continue to chain operations using the streams api, but as the stream is now a Stream<Result<String>> rather than a Stream<String> we need to wrap any functions that normally operate on Strings to operate on a Result<String> instead.

After we’ve finished we can filter out items that did not result in an error. We also have the option of handling the errors if we wished, e.g. to provide a default value.

Here we substitute the default “OhNoes” value for any entries in the stream for which a stream operation has resulted in an InputTooLongException.

String result = asList("foo", "bar", "baz", "boooo")
    .stream()
    .map(Result.wrapReturn(Example::duplicatesShortStrings))
    .map(
        Result.onSuccess((String s) -> s.toUpperCase())
              .on(InputTooLongException.class, s -> "OhNoes")
              .mapper()
    )
    .filter(Result::success)
    .map(Result::unwrap)
    .collect(Collectors.toList());
 
assertEquals(asList("FOOFOO","BARBAR","BAZBAZ", "OhNoes"), result);

To implement this we need a Result type that wraps our actual result, with two implementations – Success and Failure. Success taking a value and Failure taking an Exception

public interface Result<T> { ... }
class Success<T> implements Result<T> { ... }
class Failure<T> implements Result<T> { ... }

We then just need to provide a helper function that transforms a method that throws an Exception into a function that returns a Result.

public static <T, R, E extends Exception> 
    Function<T,Result<R>> wrapReturn(ExceptionalFunction<T,R,E> f) {
        return t -> {
            try {
                return new Success<R>(f.apply(t));
            } catch (Exception e) {
                return new Failure<R>(e);
            }
        };
    }

and a function that transforms a function that operates on unwrapped types and changes it to operate on wrapped types (for the middle of the stream)

public static <T, R> Function<Result<T>,Result<R>> wrap(Function<T,R> f) {
    return t -> {
        try {
            return t.map(f);
        } catch (Exception e) {
            return new Failure<R>(e);
        }
    };
}

Exception Handling Patterns

There are also a couple of very common exception handling patterns which we can make more concise.

Everything unchecked

This approach involves wrapping all checked exceptions in runtime exceptions. This can be useful in the case where we don’t have a good way to handle the checked exceptions thrown by code we are calling, nor is it important for anything higher up the callstack to handle them. It is also useful if you don’t wish to use checked exceptions at all.

Normally this would look something like

try {
    String foo = Example.methodThatThrowsCheckedException(THROW);
} catch (ACheckedExceptionIDontHaveAGoodWayToDealWith e) {
    throw new RuntimeException(e);
}

Now we can pull that out to a method that accepts a function and have something likely

@Test(expected = RuntimeException.class)
public void checked_to_unchecked_should_wrap_in_runtime_exception() {
    String foo = unchecked(() -> Example.methodThatThrowsCheckedException(THROW));
}

where unchecked looks something like the following (similar implementation for void methods)

public interface ExceptionalSupplier<T> {
    T supply() throws Exception;
}
 
public static <T> T unchecked(ExceptionalSupplier<T> supplier) {
    try {
        return supplier.supply();
    } catch (Error | RuntimeException rex) {
        throw rex;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Wrapping in domain specific exception

Another common pattern is catching all exceptions that may occur at a lower layer in the application and wrapping them in a more meaningful exception to consumers of your code.

This used to look like this

try {
    return Example.methodThatThrowsCheckedException(THROW);
} catch (ACheckedExceptionIDontHaveAGoodWayToDealWith e) {
    throw new Wrapped(e);
}

Again we can do the same and provide something like this, where we provide a reference to the constructor of the exception that we want to wrap exceptions in. Our wrapChecked method can now construct and throw the Wrapped exception.

@Test(expected = Wrapped.class)
public void wrapping_checked() throws Wrapped {
    wrappingChecked(() -> Example.methodThatThrowsCheckedException(THROW)).in(Wrapped::new);
}

Implementation and examples are on github as usual.