Tuesday, June 25, 2013

Spring singletons - a potential source of error

When you create a Spring bean and do nothing special it will be a singleton as described in the documentation. Such a declaration might look like this:

package org.saabye_pedersen.kim;

@Component
public class ExampleBean {
    
    public String getMessage() {
        return "Hello world!";
    }

}
With a XML config like this:



 


If we run this code:
public class Main {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("file:src/main/resources/META-INF/spring/app-context.xml");
        ExampleBean bean = ctx.getBean(ExampleBean.class);
        String message = bean.getMessage();
        System.err.println(message);


        ExampleBean beanAgain = ctx.getBean(ExampleBean.class);
        message = beanAgain.getMessage();
        System.err.println(message);
    }

}
the output will be:
Hello World!
Hello World!
So far so good. Everything is fine and dandy. But what happens if we change the class to this:
@Component
public class ExampleBean {

    private int aMember = 1;

    public String getMessage() {
        String tmp = "Hello world! " + aMember++;
        return tmp;
    }
}
What will main method of the Main class print this time? The answer is:
Hello world! 1
Hello world! 2
Did you expect this instead?:
Hello world! 1
Hello world! 1
The result is hopefully not surprising, yet I have seen much code with singletons containing code that manipulates instance members in a way that will fail. For instance this will only work in the first invocation:
@Component
public class AnotherExampleBean {

    private int sum = 0;

    public int calcSumOfProvidedInts(int[] intsToSum) {

        for (int i : intsToSum) {
            sum += i;
        }

        return sum;
    }
}

Sunday, May 5, 2013

Spring annotation on interface or class implementing the interface??

A returning question with regard to Spring is whether to annotate interfaces or concrete classes with for instance the @Transactional annotation (and similar annotations, e.g. @Cacheable).

In the Spring documentation it states the following:

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.

But what does that really mean? Let me illustrate with a simple example:
public class Main {

    public static void main(String... args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("file:src/main/resources/META-INF/spring/app-context.xml");
        WithAnnotation bean = ctx.getBean(WithAnnotation.class);
        bean.someMethod();
    }
}


// I 'll play around with this
// @Transactional
interface WithAnnotation {
    void someMethod();
}

// I 'll play around with this
// @Transactional
@Component
class ConcreteClass implements WithAnnotation {

    public void someMethod() {
        System.err.println("In some method: " + TransactionInterceptor.currentTransactionStatus());
    };
}

Default configuration: proxy-target-class="false"

With a transaction configuration like this (the default):







If we run the program with the @Transactional uncommented on the interface we get:
...
In some method: org.springframework.transaction.support.DefaultTransactionStatus@5c76911d1
...

If we run the program with the @Transactional uncommented on the class (commenting out @Transactional on the interface again) we get:
...
In some method: org.springframework.transaction.support.DefaultTransactionStatus@5c76911d
...

In both cases the code executes in a transactional context as we would expect.

Non default configuration: proxy-target-class="true"

Now let's change the transaction configuration to this (the non default):


If we run the program with the @Transactional uncommented on the interface (commenting out @Transactional on the class again) we get:
...
Exception in thread "main" org.springframework.transaction.NoTransactionException: No transaction aspect-managed TransactionStatus in scope
 at org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus(TransactionAspectSupport.java:110)
...

If we run the program with the @Transactional uncommented on the class (commenting out @Transactional on the interface again) we get:
...
In some method: org.springframework.transaction.support.DefaultTransactionStatus@4869a267
...

What have we learned?

If Spring can't create a JDK proxy (or we force it to create a cglib proxy by setting the proxy-target-class to "true") then the code will not execute in a transactional context (just like the Spring documentation stated).

A warning: if you remove the call to TransactionInterceptor.currentTransactionStatus() the code will run without trowing an exception, but it will not run in a transactional context. Yes, you read it: no exception, no warning and no transactional context even though you have got the @Transactional annotation on the interface. I guess that is what is meant by ...the object will not be wrapped in a transactional proxy, which would be decidedly bad :)

Saturday, April 20, 2013

Java 8 lambda walkthrough

For work I have made a presentation about Java 8 project lambda and of course also some simple code illustrating some of the points. The overall reasons for Java 8 are:
  • More concise code (for classes that have just one method & collections). “We want the reader of the code to have to wade through as little syntax as possible before arriving at the "meat" of the lambda expression.” – Brian Goetz (http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html)
  • Ability to pass around functionality, not just data
  • Better support for multi core processing
All examples are runnable on the following version of Java 8 downloaded from here:
openjdk version "1.8.0-ea"
OpenJDK Runtime Environment (build 1.8.0-ea-lambda-nightly-h3876-20130403-b84-b00)
OpenJDK 64-Bit Server VM (build 25.0-b21, mixed mode)


The simplest case:

public class ThreadA {

    public static void main(String[] args) {

        new Thread(new Runnable() {

            @Override
            public void run() {
                System.err.println("Hello from anonymous class");
            }
        }).start();

    }

}

public class ThreadB {

    public static void main(String[] args) {
        new Thread(() -> {
            System.err.println("Hello from lambda");
        }).start();

    }

}
Note the syntax, informally as
()|x|(x,..,z) -> expr|stmt
The arrow is a new operator. And note the conciseness of the second piece of code compared to the more bulky first piece.

Collections:


First let me introduce an simple domain and some helpers
public class Something {


    private double amount;

    public Something(double amount) {
        this.amount = amount;
    }

    public double getAmount() {
        return amount;
    }

    public String toString() {
        return "Amount: " + amount;
    }
}

public class Helper {

    public static List<Something> someThings() {
        List<Something> things = new ArrayList<>();
        things.add(new Something(99.9));
        things.add(new Something(199.9));
        things.add(new Something(299.9));
        things.add(new Something(399.9));
        things.add(new Something(1199.9));
        return things;
    }

}

public interface Doer<T> {

    void doSomething(T t);

}


Lets do some filtering and sorting Java 7 style:

public class CollectionA {

    public static void main(String... args) {

        List<Something> things = Helper.someThings();

        System.err.println("Filter");
        List<Something> filtered = filter(things);
        System.err.println(filtered);

        System.err.println("Sum");
        double sum = sum(filtered);
        System.err.println(sum);

    }

    public static List<Something> filter(List<Something> things) {
        List<Something> filtered = new ArrayList<>();
        for (Something s : things) {
            if (s.getAmount() > 100.00) {
                if (s.getAmount() < 1000.00) {
                    filtered.add(s);
                }
            }
        }
        return filtered;
    }

    public static double sum(List<Something> things) {
        double d = 0.0;
        for (Something s : things) {
            d += s.getAmount();
        }
        return d;
    }


}


And now Java 8 style - streaming:

import java.util.stream.Collectors;

public class CollectionB {

    public static void main(String... args) {

        List<Something> things = Helper.someThings();

        System.err.println("Filter lambda");
        List<Something> filtered = things.stream().parallel().filter( t -> t.getAmount() > 100.00 && t.getAmount() < 1000.00).collect(Collectors.toList());
        System.err.println(filtered);

        System.err.println("Sum lambda");
        double sum = filtered.stream().mapToDouble(t -> t.getAmount()).sum();
        System.err.println(sum);

    }

}


The import java.util.function.* interfaces & method references

public class CollectionC {

    public static void main(String... args) {

        List<Something> things = Helper.someThings();

        System.err.println("Do something");
        doSomething(things, new Doer<Something>() {

            @Override
            public void doSomething(Something t) {
                System.err.println(t);
            }
        });
    }

    public static void doSomething(List<Something> things, Doer<Something> doer) {
        for (Something s : things) {
            doer.doSomething(s);
        }
    }

}


Replace our Doer interface with the standard Consumer interface (previously known as Block)

import java.util.function.Consumer;

public class CollectionD {

    public static void main(String... args) {

        List<Something> things = Helper.someThings();

        System.err.println("Do something functional interfaces");
        consumeSomething(things, new Consumer<Something>() {

            @Override
            public void accept(Something t) {
                System.err.println(t);
            }
        });

        System.err.println("Do something functional interfaces, using lambda");
        consumeSomething(things, (t) -> System.err.println(t));

        System.err.println("Do something functional interfaces, using lambda method reference (new operator ::) ");
        consumeSomething(things, System.err::println);

        System.err.println("Do something functional interfaces, using stream");
        things.stream().forEach(new Consumer<Something>() {

            @Override
            public void accept(Something t) {
                System.err.println(t);
            }
        });

        System.err.println("Do something functional interfaces, using stream and method reference");
        things.stream().forEach(System.err::println);
    }

    public static void doSomething(List<Something> things, Doer<Something> doer) {
        for (Something s : things) {
            doer.doSomething(s);
        }
    }

    public static void consumeSomething(List<Something> things, Consumer<Something> consumer) {
        for (Something s : things) {
            consumer.accept(s);
        }
    }

}

Map, reduce, lazy & optional

import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;

public class Various {

    public static void main(String... args) {

        List<Something> things = Helper.someThings();

        //Map
        System.err.println(things.stream().map((Something t) -> t.getAmount()).collect(Collectors.toList()));

        //Reduce
        double d = things.stream().reduce(new Something(0.0), (Something t, Something u) -> new Something(t.getAmount() + u.getAmount())).getAmount();
        System.err.println(d);

        //Reduce again
        System.err.println(things.stream().reduce((Something t, Something u) -> new Something(t.getAmount() + u.getAmount())).get());

        //Map/reduce
        System.err.println(things.stream().map((Something t) -> t.getAmount()).reduce(0.0, (x, y) -> x + y));

        //Lazy
        Optional<Something> findFirst = things.stream().filter(t -> t.getAmount() > 1000).findFirst();
        System.err.println(findFirst.get());

        //Lazy no value
        Optional<Something> findFirstNotThere = things.stream().filter(t -> t.getAmount() > 2000).findFirst();
        try {
            System.err.println(findFirstNotThere.get());
        } catch (NoSuchElementException e) {
            System.err.println("Optional was not null, but its value was");
        }
        //Optional one step deeper
        things.stream().filter(t -> t.getAmount() > 1000).findFirst().ifPresent(t -> System.err.println("Here I am"));

    }

}