Saturday, April 12, 2014

The Grails depedency injection inheritance pitfall

This blog post is about a small pitfall you should be aware of when combining dependency injection in Grails with inheritance.

I think the problem is best explained with a piece of example code. So let's look at the following two definitions of Grails controllers.
class FooController {
  TestService testService

  def foo() {
    // do something with testService
  }
}
class BarController extends FooController {
  TestService testService

  def bar() {
    // do something with testService
  }
}
Both controllers look nearly identical. The only difference is that BarController extends FooController. Now assume we have an instance of BarController and we want to call the methods bar() and foo() on it. Guess what happens?

The call of bar() works fine while the call of foo() throws a NullPointerException because testService is null.

testService is a standard Groovy property. This means that the testService fields will become private and getter / setter methods are generated for both controllers. The getter / setter of BarController override the getter / setter of FooController. So whenever the dependency is injected using setTestService() only BarController retrieves the TestService instance. This is nothing special about Grails controllers, it works the same for services and other Groovy classes.

The solution is easy: Remove the testService dependency from BarController. Whenever testService is accessed in BarController, it will use the appropriate getter of FooController and everything works.

In this simple example the problem is quite obvious and can be easily solved. However, if your classes become larger this can be a bit tricky to debug. Assume you have a base class with multiple sub classes. Whenever you want to add a new dependency to your base class, you have to check all the subclasses. If one of the sub classes already defines the same dependency you have to remove it or it will not be available in your base class.

Share this post using Facebook, Twitter or Google+

Saturday, April 5, 2014

Closure composition in Groovy

This is a short blog post about a feature of Groovy closures I discovered a few days ago: Closure Composition.

With Closure Composition we can chain closure calls within a single closure.

Assume we have the following three closures:
def square = { it * it }
def plusOne = { it + 1 }
def half = { it / 2 }
Now we can combine those closures using the << or >> operators:
def c = half >> plusOne >> square
If we now call c() first half() will be called. The return value of half() will then be passed to plusOne(). At last square() will be called with the return value of plusOne().
println c(10) // (10 / 2 + 1)² -> 36
We can reverse the call order by using the << operator instead of >>
def c = half << plusOne << square
Now square() will be called before plusOne(). half() will be called last.
println c(10) // (10² + 1) / 2 -> 50.5


Share this post using Facebook, Twitter or Google+

Friday, March 21, 2014

Java can finally join strings

I am sure you were in a situation in which you wanted to join multiple strings. If you were using a programming language other than Java you probably used the join() function provided by the programming language. If you were using Java you could not do this. There was no join() method. The Java Standard Class Library provided you tools for building GUI applications, accessing databases, sending stuff over the network, doing XML transformations or calling remote methods. A simple method for joining a collection of strings was not included. For this you needed one of various third party libraries.

Luckily this time is over now! In Java 8 we finally can join Strings!

Java 8 added a new class called StringJoiner. As the name suggests we can use this class to join strings:
StringJoiner joiner = new StringJoiner(",");
joiner.add("foo");
joiner.add("bar");
joiner.add("baz");
String joined = joiner.toString(); // "foo,bar,baz"

// add() calls can be chained
joined = new StringJoiner("-")
 .add("foo")
 .add("bar")
 .add("baz")
 .toString(); // "foo-bar-baz"
StringJoiner is used internally by the two new static join() methods of String:
// join(CharSequence delimiter, CharSequence... elements)
String joined = String.join("/", "2014", "10", "28" ); // "2014/10/28"

// join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
List<String> list = Arrays.asList("foo", "bar", "baz");
joined = String.join(";", list); // "foo;bar;baz"
There is also a joining Collector available for the new Stream API:
List<Person> list = Arrays.asList(
 new Person("John", "Smith"),
 new Person("Anna", "Martinez"),
 new Person("Paul", "Watson ")
);

String joinedFirstNames = list.stream()
 .map(Person::getFirstName)
 .collect(Collectors.joining(", ")); // "John, Anna, Paul"
So we do no longer need third party libraries for joining strings :-)

Share this post using Facebook, Twitter or Google+

Saturday, March 15, 2014

How you can benefit from Groovy Shell

This is a post about the Groovy Shell and how it can help you with your daily work (as long as you are working as software developer). You can benefit from the Groovy Shell no matter what programming language(s) or technologies you are using. The only real requirement is that you are able to write (and read) small pieces of Groovy code.

Getting started
I think the purpose of the Groovy shell is best described by the official documentation:
The Groovy Shell, aka. groovysh is a command-line application which allows easy access to evaluate Groovy expressions, define classes and run simple experiments.
The Groovy Shell is included in the distribution of the Groovy Programming language and can be found in <groovy home>/bin. To start the Groovy Shell simply run groovysh from the command line:
GROOVY_HOME\bin>groovysh
Groovy Shell (2.2.2, JVM: 1.7.0)
Type 'help' or '\h' for help.
--------------------------------------------------------------------
groovy:000>
Within the shell you can now run Groovy commands:
groovy:000> println("hu?")
hu?
===> null
groovy:000>
It supports variables and multi line statements:
groovy:000> foo = 42
===> 42
groovy:000> baz = {
groovy:001> return 42 * 2
groovy:002> }
===> groovysh_evaluate$_run_closure1@3c661f99
groovy:000> baz(foo)
===> 84
groovy:000>
(Note that you have to skip the def keyword in order to use variables and closures later)

A few words for Windows Users
I can clearly recommend Console(2) which is a small wrapper around the awkward cmd window. It provides Tab support, better text selection and other useful things.
Unfortunately the Groovy 2.2.0 shell has a problem with arrow keys on Windows 7/8 in some locales (including German). However, you can use CTRL-P and CTRL-N instead of UP and DOWN. As an alternative you can use the shell of an older Groovy Version (groovysh from Groovy 2.1.9 works fine).

So, for what can we use it?
The most obvious thing we can do is evaluating Groovy code. This is especially useful if you are working on applications that make use of Groovy.
Maybe you know you can use the << operator to add elements to lists, but you are not sure if the operator works the same for maps? In this case, you can start googling or look it up in the documentation. Or you can just type it into Groovy Shell and see if it works:
groovy:000> [a:1] << [b:2]
===> {a=1, b=2}
It works!
You are not sure if you can iterate over enum values?
groovy:000> enum Day { Mo, Tu, We }
===> true
groovy:000> Day.each { println it }
Mo
Tu
We
===> class Day
It works too!

It is a Calculator!
The Groovy Shell can be used for simple mathematical calculations:
groovy:000> 40 + 2
===> 42
groovy:000>
groovy:000> 123456789123456789 * 123456789123456789123456789
===> 15241578780673678530864199515622620750190521
groovy:000>
groovy:000> 2 ** 1024
===> 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
groovy:000>
As you can see Groovy can work well with numbers that would cause overflows in other programming languages. Groovy uses BigInteger and BigDecimal for these computations. By the way, you can verify this yourself very quickly:
groovy:000> (2 ** 1024).getClass()
===> class java.math.BigInteger
Note that Groovy math tries to be as natural as possible:
groovy:000> 3/2
===> 1.5
groovy:000> 1.1+0.1
===> 1.2
In Java these computations would result in 1 (integer division) and 1.2000000000000002 (floating point arithmetic).

Do more
Maybe you need the content of a certain web page? This can be easily accomplished with Groovy:
groovy:000> "http://groovy.codehaus.org".toURL().text
===> <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta name="description" content="Groovy Wiki"/>
    ...
Maybe you only want the <meta> tags for some reason?
groovy:000> "http://groovy.codehaus.org".toURL().eachLine { if (it.contains('<meta')) println it }
    <meta charset="utf-8"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta name="description" content="Groovy Wiki"/>
    <meta name="keywords"
    <meta name="author" content="Codehaus Groovy Community"/>
===> null
I am sure you were in a situation where you needed the url encoded version of some text:
groovy:000> URLEncoder.encode("foo=bar")
===> foo%3Dbar
Of course you do not need to remember the exact class and method names. Just type in the first characters and then press tab to get the possible options:
groovy:000> URL
URL                       URLClassLoader            URLConnection             URLDecoder                URLEncoder
URLStreamHandler          URLStreamHandlerFactory
It works with methods too:
groovy:000> URLEncoder.e
each(            eachWithIndex(   encode(          every(           every()

Customize it
To truly benefit from the Groovy Shell you should customize it to your needs and provide functions that help you in your daily work. For this you can add your custom Groovy code to $HOME/.groovy/groovysh.profile (just create the file if it does not exist). This file is loaded and executed when groovysh starts.

Let's assume you want to decode a piece of Base64 encoded text. A viable approach is to start googling for an online Base64 decoder. An alternative is to add a few lines to your groovysh.profile to accomplish the job:
encodeBase64 = { str ->
  return str.bytes.encodeBase64().toString()
}

decodeBase64 = { str ->
  return new String(str.decodeBase64())
}
Now you can use the encodeBase64() and decodeBase64() functions within Groovy Shell to do the job:
groovy:000> encoded = encodeBase64('test')
===> dGVzdA==
groovy:000> decodeBase64(encoded)
===> test
This approach might be a bit slower the first time you are using it but you will benefit from it the next time you need to encode/decode a Base64 message. Note that autocomplete also works on your own  methods, so you do not need to remember the exact name.

Another example function that can be useful from time to time is one that computes the MD5 hash from a passed string. We can use Java's MessageDigest class to accomplish this task in Groovy:
import java.security.MessageDigest

md5 = { str ->
  // thanks to https://gist.github.com/ikarius/299062
  MessageDigest digest = MessageDigest.getInstance("MD5")
  digest.update(str.bytes)
  return new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
} 
To compute a MD5 hash we then just have to call the md5() function:
groovy:000> md5('test')
===> 098f6bcd4621d373cade4e832627b4f6
But what if we want to compute the MD5 value of a file?
If the file is not that large getting the content of it is as simple as this:
new File('test.txt').text
We just have to pass this to the md5() function to compute the md5 hash of the file:
groovy:000> md5(new File('test.txt').text)
===> a4ba431c56925ce98ff04fa7d51a89bf
Maybe you are working a lot with date and times. In this case it can be useful to add Joda-Time support to your Groovy Shell. Just add the following lines to groovysh.profile:
@Grab('joda-time:joda-time:2.3') import org.joda.time.DateTime
import org.joda.time.DateTime
If you run groovysh the next time Joda-Time will be downloaded using Grape. Additionally the Joda DateTime class is imported so it can be used in Groovy Shell without prefixing the package name:
groovy:000> new DateTime().plusDays(42)
===> 2014-04-22T22:27:20.860+02:00
You commonly need to convert time values to/from unix timestamps?
Just add two simple functions for it and you no longer need your bookmark for an online converter:
import java.text.SimpleDateFormat
dateFormat = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss')

toUnixTimestamp = { str ->
  return dateFormat.parse(str).getTime() / 1000
}

fromUnixTimestamp = { timestamp ->
  return dateFormat.format(new Date(timestamp.toLong() * 1000))
}
Usage in Groovy Shell:
groovy:000> toUnixTimestamp('2014-04-15 12:30:00')
===> 1397557800
groovy:000> fromUnixTimestamp('1397557800')
===> 2014-04-15 12:30:00
Maybe you want to execute a command on a remote machine?
You only need another simple function to accomplish this task with Groovy Shell:
ssh = { cmd ->
  def proc = "ssh -i keyfile user@host $cmd".execute()
  proc.waitFor()
  println "return code: ${proc.exitValue()}"
  println "stderr: ${proc.err.text}"
  println "stdout: ${proc.in.text}" 
}
Usage:
groovy:000> ssh 'ls -l'
return code: 0
stderr:
stdout: total 1234
-rw-r--r-- 1 foo foo 7678563 Oct 28  2009 file
drwxr-xr-x 4 foo foo    4096 Mar  1 17:07 folder
-rw-r--r-- 1 foo foo      19 Feb 27 22:19 bar
...
In case you did not know: In Groovy you can skip parentheses when calling a function with one or more parameters. So ssh 'ls -l' is the same as ssh('ls -l').

Conclusion
Before I switched to the Groovy Shell, I used the Python shell for nearly the same reasons (even if I was not working with Python at all). Within the last year I used a lot of Groovy and I quickly discovered that the Groovy Web Console is a very valuable tool for testing and prototyping. For me the Groovy Shell replaced both tools. It is clearly a development tool I do not want to miss.

I think it is really up to you how much you let the Groovy Shell help you.

Share this post using Facebook, Twitter or Google+

Monday, February 24, 2014

A deeper look into the Java 8 Date and Time API

Within this post we will have a deeper look into the new Date/Time API we get with Java 8 (JSR 310). Please note that this post is mainly driven by code examples that show the new API functionality. I think the examples are self-explanatory so I did not spent much time writing text around them :-)

Let's get started!

Working with date and time objects
All classes of the Java 8 Date/Time API are located within the java.time package. The first class we want to look at is java.time.LocalDate. A LocalDate represents a year-month-day date without time. We start with creating new LocalDate instances:
// the current date
LocalDate currentDate = LocalDate.now();

// 2014-02-10
LocalDate tenthFeb2014 = LocalDate.of(2014, Month.FEBRUARY, 10);

// months values start at 1 (2014-08-01)
LocalDate firstAug2014 = LocalDate.of(2014, 8, 1);

// the 65th day of 2010 (2010-03-06)
LocalDate sixtyFifthDayOf2010 = LocalDate.ofYearDay(2010, 65);
LocalTime and LocalDateTime are the next classes we look at. Both work similar to LocalDate. A LocalTime works with time (without dates) while LocalDateTime combines date and time in one class:
LocalTime currentTime = LocalTime.now(); // current time
LocalTime midday = LocalTime.of(12, 0); // 12:00
LocalTime afterMidday = LocalTime.of(13, 30, 15); // 13:30:15

// 12345th second of day (03:25:45)
LocalTime fromSecondsOfDay = LocalTime.ofSecondOfDay(12345);

// dates with times, e.g. 2014-02-18 19:08:37.950
LocalDateTime currentDateTime = LocalDateTime.now();

// 2014-10-02 12:30
LocalDateTime secondAug2014 = LocalDateTime.of(2014, 10, 2, 12, 30);

// 2014-12-24 12:00
LocalDateTime christmas2014 = LocalDateTime.of(2014, Month.DECEMBER, 24, 12, 0);
By default LocalDate/Time classes will use the system clock in the default time zone. We can change this by providing a time zone or an alternative Clock implementation:
// current (local) time in Los Angeles
LocalTime currentTimeInLosAngeles = LocalTime.now(ZoneId.of("America/Los_Angeles"));

// current time in UTC time zone
LocalTime nowInUtc = LocalTime.now(Clock.systemUTC());
From LocalDate/Time objects we can get all sorts of useful information we might need. Some examples:
LocalDate date = LocalDate.of(2014, 2, 15); // 2014-02-15

boolean isBefore = LocalDate.now().isBefore(date); // false

// information about the month
Month february = date.getMonth(); // FEBRUARY
int februaryIntValue = february.getValue(); // 2
int minLength = february.minLength(); // 28
int maxLength = february.maxLength(); // 29
Month firstMonthOfQuarter = february.firstMonthOfQuarter(); // JANUARY

// information about the year
int year = date.getYear(); // 2014
int dayOfYear = date.getDayOfYear(); // 46
int lengthOfYear = date.lengthOfYear(); // 365
boolean isLeapYear = date.isLeapYear(); // false

DayOfWeek dayOfWeek = date.getDayOfWeek();
int dayOfWeekIntValue = dayOfWeek.getValue(); // 6
String dayOfWeekName = dayOfWeek.name(); // SATURDAY

int dayOfMonth = date.getDayOfMonth(); // 15
LocalDateTime startOfDay = date.atStartOfDay(); // 2014-02-15 00:00

// time information
LocalTime time = LocalTime.of(15, 30); // 15:30:00
int hour = time.getHour(); // 15
int second = time.getSecond(); // 0
int minute = time.getMinute(); // 30
int secondOfDay = time.toSecondOfDay(); // 55800
Some information can be obtained without providing a specific date. For example, we can use the Year class if we need information about a specific year:
Year currentYear = Year.now();
Year twoThousand = Year.of(2000);
boolean isLeap = currentYear.isLeap(); // false
int length = currentYear.length(); // 365

// sixtyFourth day of 2014 (2014-03-05)
LocalDate date = Year.of(2014).atDay(64);
We can use the plus and minus methods to add or subtract specific amounts of time. Note that these methods always return a new instance (Java 8 date/time classes are immutable).
LocalDate tomorrow = LocalDate.now().plusDays(1);

// before 5 houres and 30 minutes
LocalDateTime dateTime = LocalDateTime.now().minusHours(5).minusMinutes(30);
TemporalAdjusters are another nice way for date manipulation. TemporalAdjuster is a single method interface that is used to separate the process of adjustment from actual date/time objects. A set of common TemporalAdjusters can be accessed using static methods of the TemporalAdjusters class.
LocalDate date = LocalDate.of(2014, Month.FEBRUARY, 25); // 2014-02-25

// first day of february 2014 (2014-02-01)
LocalDate firstDayOfMonth = date.with(TemporalAdjusters.firstDayOfMonth());

// last day of february 2014 (2014-02-28)
LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());
Static imports make this more fluent to read:
import static java.time.temporal.TemporalAdjusters.*;

...

// last day of 2014 (2014-12-31)
LocalDate lastDayOfYear = date.with(lastDayOfYear());

// first day of next month (2014-03-01)
LocalDate firstDayOfNextMonth = date.with(firstDayOfNextMonth());

// next sunday (2014-03-02)
LocalDate nextSunday = date.with(next(DayOfWeek.SUNDAY));
Time zones
Working with time zones is another big topic that is simplified by the new API. The LocalDate/Time classes we have seen so far do not contain information about a time zone. If we want to work with a date/time in a certain time zone we can use ZonedDateTime or OffsetDateTime:
ZoneId losAngeles = ZoneId.of("America/Los_Angeles");
ZoneId berlin = ZoneId.of("Europe/Berlin");

// 2014-02-20 12:00
LocalDateTime dateTime = LocalDateTime.of(2014, 02, 20, 12, 0);

// 2014-02-20 12:00, Europe/Berlin (+01:00)
ZonedDateTime berlinDateTime = ZonedDateTime.of(dateTime, berlin);

// 2014-02-20 03:00, America/Los_Angeles (-08:00)
ZonedDateTime losAngelesDateTime = berlinDateTime.withZoneSameInstant(losAngeles);

int offsetInSeconds = losAngelesDateTime.getOffset().getTotalSeconds(); // -28800

// a collection of all available zones
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();

// using offsets
LocalDateTime date = LocalDateTime.of(2013, Month.JULY, 20, 3, 30);
ZoneOffset offset = ZoneOffset.of("+05:00");

// 2013-07-20 03:30 +05:00
OffsetDateTime plusFive = OffsetDateTime.of(date, offset);

// 2013-07-19 20:30 -02:00
OffsetDateTime minusTwo = plusFive.withOffsetSameInstant(ZoneOffset.ofHours(-2));
Timestamps
Classes like LocalDate and ZonedDateTime provide a human view on time. However, often we need to work with time viewed from a machine perspective. For this we can use the Instant class which represents timestamps. An Instant counts the time beginning from the first second of January 1, 1970 (1970-01-01 00:00:00) also called the EPOCH. Instant values can be negative if they occured before the epoch. They follow ISO 8601 the standard for representing date and time.
// current time
Instant now = Instant.now();

// from unix timestamp, 2010-01-01 12:00:00
Instant fromUnixTimestamp = Instant.ofEpochSecond(1262347200);

// same time in millis
Instant fromEpochMilli = Instant.ofEpochMilli(1262347200000l);

// parsing from ISO 8601
Instant fromIso8601 = Instant.parse("2010-01-01T12:00:00Z");

// toString() returns ISO 8601 format, e.g. 2014-02-15T01:02:03Z
String toIso8601 = now.toString();

// as unix timestamp
long toUnixTimestamp = now.getEpochSecond();

// in millis
long toEpochMillis = now.toEpochMilli();

// plus/minus methods are available too
Instant nowPlusTenSeconds = now.plusSeconds(10);
Periods and Durations
Period and Duration are two other important classes. Like the names suggest they represent a quantity or amount of time. A Period uses date based values (years, months, days) while a Duration uses seconds or nanoseconds to define an amount of time. Duration is most suitable when working with Instants and machine time. Periods and Durations can contain negative values if the end point occurs before the starting point.
// periods

LocalDate firstDate = LocalDate.of(2010, 5, 17); // 2010-05-17
LocalDate secondDate = LocalDate.of(2015, 3, 7); // 2015-03-07
Period period = Period.between(firstDate, secondDate);

int days = period.getDays(); // 18
int months = period.getMonths(); // 9
int years = period.getYears(); // 4
boolean isNegative = period.isNegative(); // false

Period twoMonthsAndFiveDays = Period.ofMonths(2).plusDays(5);
LocalDate sixthOfJanuary = LocalDate.of(2014, 1, 6);

// add two months and five days to 2014-01-06, result is 2014-03-11
LocalDate eleventhOfMarch = sixthOfJanuary.plus(twoMonthsAndFiveDays);


// durations

Instant firstInstant= Instant.ofEpochSecond( 1294881180 ); // 2011-01-13 01:13
Instant secondInstant = Instant.ofEpochSecond(1294708260); // 2011-01-11 01:11

Duration between = Duration.between(firstInstant, secondInstant);

// negative because firstInstant is after secondInstant (-172920)
long seconds = between.getSeconds();

// get absolute result in minutes (2882)
long absoluteResult = between.abs().toMinutes();

// two hours in seconds (7200)
long twoHoursInSeconds = Duration.ofHours(2).getSeconds();
Formatting and parsing
Formatting and parsing is another big topic when working with dates and times. In Java 8 this can be accomplished by using the format() and parse() methods:
// 2014-04-01 10:45
LocalDateTime dateTime = LocalDateTime.of(2014, Month.APRIL, 1, 10, 45);

// format as basic ISO date format (20140220)
String asBasicIsoDate = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE);

// format as ISO week date (2014-W08-4)
String asIsoWeekDate = dateTime.format(DateTimeFormatter.ISO_WEEK_DATE);

// format ISO date time (2014-02-20T20:04:05.867)
String asIsoDateTime = dateTime.format(DateTimeFormatter.ISO_DATE_TIME);

// using a custom pattern (01/04/2014)
String asCustomPattern = dateTime.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));

// french date formatting (1. avril 2014)
String frenchDate = dateTime.format(DateTimeFormatter.ofPattern("d. MMMM yyyy", new Locale("fr")));

// using short german date/time formatting (01.04.14 10:45)
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
    .withLocale(new Locale("de"));
String germanDateTime = dateTime.format(formatter);

// parsing date strings
LocalDate fromIsoDate = LocalDate.parse("2014-01-20");
LocalDate fromIsoWeekDate = LocalDate.parse("2014-W14-2", DateTimeFormatter.ISO_WEEK_DATE);
LocalDate fromCustomPattern = LocalDate.parse("20.01.2014", DateTimeFormatter.ofPattern("dd.MM.yyyy"));
Conversion
Of course we do not always have objects of the type we need. Therefore, we need an option to convert different date/time related objects between each other. The following examples show some of the possible conversion options:
// LocalDate/LocalTime <-> LocalDateTime
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTimeFromDateAndTime = LocalDateTime.of(date, time);
LocalDate dateFromDateTime = LocalDateTime.now().toLocalDate();
LocalTime timeFromDateTime = LocalDateTime.now().toLocalTime();

// Instant <-> LocalDateTime
Instant instant = Instant.now();
LocalDateTime dateTimeFromInstant = LocalDateTime.ofInstant(instant, ZoneId.of("America/Los_Angeles"));
Instant instantFromDateTime = LocalDateTime.now().toInstant(ZoneOffset.ofHours(-2));

// convert old date/calendar/timezone classes
Instant instantFromDate = new Date().toInstant();
Instant instantFromCalendar = Calendar.getInstance().toInstant();
ZoneId zoneId = TimeZone.getDefault().toZoneId();
ZonedDateTime zonedDateTimeFromGregorianCalendar = new GregorianCalendar().toZonedDateTime();

// convert to old classes
Date dateFromInstant = Date.from(Instant.now());
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles"));
GregorianCalendar gregorianCalendar = GregorianCalendar.from(ZonedDateTime.now());
Conclusion
With Java 8 we get a very rich API for working with date and time located in the java.time package. The API can completely replace old classes like java.util.Date or java.util.Calendar with newer, more flexible classes. Due to mostly immutable classes the new API helps in building thread safe systems.

The source of the examples can be found on GitHub.

Share this post using Facebook, Twitter or Google+

Thursday, February 6, 2014

Java 8 Type Annotations

Lambda expressions are by far the most discussed and promoted feature of Java 8. While I agree that Lambdas are a large improvement I think that some other Java 8 feature go a bit short because of the Lambda hype. In this post I want to show a number of examples from another nice Java 8 feature: Type Annotations.

Type Annotations are annotations that can be placed anywhere you use a type. This includes the new operator, type casts, implements clauses and throws clauses. Type Annotations allow improved analysis of Java code and can ensure even stronger type checking.

In source code this means we get two new ElementTypes for annotations:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface Test {
} 
The enum value TYPE_PARAMETER allows an annotation to be applied at type variables (e.g. MyClass<T>). Annotations with target TYPE_USE can be applied at any type use.

Please note that the annotations from the following examples will not work out of the box when Java 8 is released. Java 8 only provides the ability to define these types of annotations. It is then up to framework and tool developers to actually make use of it. So this is a collection of annotations frameworks could give us in the future. Most of the examples are taken from the Type Annotations specification and various Java 8 presentations.

Simple type definitions with type annotations look like this:
@NotNull String str1 = ...
@Email String str2 = ...
@NotNull @NotBlank String str3 = ...
Type annotations can also be applied to nested types
Map.@NonNull Entry = ...
Constructors with type annotations:
new @Interned MyObject()
new @NonEmpty @Readonly List<String>(myNonEmptyStringSet)
They work with nested (non static) class constructors too:
myObject.new @Readonly NestedClass()
Type casts:
myString = (@NonNull String) myObject;
query = (@Untainted String) str;
Inheritance:
class UnmodifiableList<T> implements @Readonly List<T> { ... }
We can use type Annotations with generic type arguments:
List<@Email String> emails = ...
List<@ReadOnly @Localized Message> messages = ...
Graph<@Directional Node> directedGraph = ...
Of course we can nest them:
Map<@NonNull String, @NonEmpty List<@Readonly Document>> documents;
Or apply them to intersection Types:
public <E extends @ReadOnly Composable<E> & @Localized MessageSource> void foo(...) { ... }
Including parameter bounds and wildcard bounds:
class Folder<F extends @Existing File> { ... }
Collection<? super @Existing File> c = ...
List<@Immutable ? extends Comparable<T>> unchangeable = ...
Generic method invocation with type annotations looks like this:
myObject.<@NotBlank String>myMethod(...);
For generic constructors, the annotation follows the explicit type arguments:
new <String> @Interned MyObject()
Throwing exceptions:
void monitorTemperature() throws @Critical TemperatureException { ... }
void authenticate() throws @Fatal @Logged AccessDeniedException { ... }
Type annotations in instanceof statements:
boolean isNonNull = myString instanceof @NonNull String;
boolean isNonBlankEmail = myString instanceof @NotBlank @Email String;
And finally Java 8 method and constructor references:
@Vernal Date::getDay
List<@English String>::size
Arrays::<@NonNegative Integer>sort

Conclusion
Type annotations are an interesting addition to the Java type system. They can be applied to any use of a type and enable a more detailed code analysis. If you want to use Type annotations right now you should have a look at the Checker Framework.

If you want to continue reading about this topic you should check out the discussion on reddit.

Share this post using Facebook, Twitter or Google+