27 November 2012

See the new test fail

The Wikipedia article about Test-driven development describes the process of TDD. It says that after adding a new test, you should run all tests and see if the new one fails. This is part of the red-green-refactor cycle. During my remote pairing activities with Thomas I noticed that I tend to forget this step. To fix this I wrote a tiny Eclipse plugin that complains if a test run does not fail after adding a new test.

Alert! New Test Did Not Fail
The plugin attaches itself to the org.eclipse.jdt.junit.testRunListeners extension point and records the names of all tests during JUnit test execution. (See RedGreenListener.java) When the test session is finished, it compares these test statistics against the previous run. In fact the only thing we need to know is if any test cases have been added. (See TestStats.java) Based on the comparison the plugin decides if to show an annoying popup or not. (See TestRunDiff.java)

The current mechanism is simple and likely to be wrong for special cases:
public boolean firstTestOk() {
    return newAdded.size() == 0 || secondFailed;
}
but it works great on katas and small hobby projects.

The org.eclipse.jdt.junit.testRunListeners extension point is available in Eclipse Europa (version 3.3), but it does not work there. The schema testRunListeners.exsd for the extension point seems to be missing from the JDT/JUnit bundles. The situation changes in Helios (3.6) and JUnit starts to notify the declared listeners. As the current release of Eclipse is version 3.8/4.2, I believe that two versions of backwards-compatibility should be enough.

Download the plugin here. Copy it into your plugins folder and restart Eclipse.

23 November 2012

BaDaDam Testing Framework

DIY Cable ReleaseSome time ago I had a look into BDD - no, not Bullshit Driven Development ;-) - but Behaviour-Driven Development. I started with JBehave but it seemed heavyweight to me. Further it had more than ten dependencies to other libraries, some with possibly problematic licences. Still I wanted to know how that kind of framework worked, so instead of learning by taking it apart I decided to build my own.

For some time I struggled to find a nice name for the project and discussed my problem with Michael. I was mumbling as usual and he mistook BDD as BaDaDam. Voila - I present to you BaDaDam, a minimalistic BDD framework for Java. Obviously it follows the spirit of JBehave, is lightweight, self sufficient and depends only on JUnit. It allows you to write stories in plain text, implement them in Java classes and run them using JUnit. The first version is finished since some time and available in my Maven repository here.

28 October 2012

Java 7 aka Dolphin

DolphinFour years after the last major release, Java 7 was released July 28th 2011. It brought several new features, the most commonly mentioned were the Diamond Operator, using strings in switch statements, automatic resource management, numeric literals with underscores and improved exception handling. Further there were additions to NIO, the Fork/Join framework and invokedynamic. You have probably heard of all these things by now. There were also some minor additions, but the previous ones have been talked about since long before Java 7 was released.

A good start to check the new features of Java 7 is the presentation about the 55 New Features You (Probably) Didn't Hear About. It also covers some lesser known additions. For a complete list of all changes see the Java 7 Release Notes. They are really worth reading, and include links into the Java Tutorial for more complex topics.

Classlist
Always when a new version of Java comes out, I take a look at its new classes, using my Java Class File Parser. The list of new classes complements the list of new features. Java 7 adds 211 public classes to rt.jar, where Java 6 had 490 and Java 5 even added 547. So it looks like a smaller release.

invokedynamic
I heard that a lot of work went into the invokedynamic byte code instruction which was added to the JVM. It comes with a small, new package java.lang.invoke.
java.lang.invoke.CallSite
java.lang.invoke.ConstantCallSite
java.lang.invoke.MethodHandle
java.lang.invoke.MethodHandleProxies
java.lang.invoke.MethodHandles
java.lang.invoke.MethodType
java.lang.invoke.MutableCallSite
java.lang.invoke.SwitchPoint
java.lang.invoke.VolatileCallSite
java.lang.invoke.WrongMethodTypeException
While this package contains just ten classes, there are another 16 package access classes (not shown here), so invokedynamic is definitely more complex than it looks.

NIO Channels
A more practical addition are some new NIO channels, most noteworthy the AsynchronousChannels, which allow network and file access in an asynchronous way, together with their exceptions.
java.nio.channels.AcceptPendingException
java.nio.channels.AlreadyBoundException
java.nio.channels.AsynchronousByteChannel
java.nio.channels.AsynchronousChannel
java.nio.channels.AsynchronousChannelGroup
java.nio.channels.AsynchronousFileChannel
java.nio.channels.AsynchronousServerSocketChannel
java.nio.channels.AsynchronousSocketChannel
java.nio.channels.CompletionHandler
java.nio.channels.IllegalChannelGroupException
java.nio.channels.InterruptedByTimeoutException
java.nio.channels.MembershipKey
java.nio.channels.MulticastChannel
java.nio.channels.NetworkChannel
java.nio.channels.ReadPendingException
java.nio.channels.SeekableByteChannel
java.nio.channels.ShutdownChannelGroupException
java.nio.channels.WritePendingException

java.nio.channels.spi.AsynchronousChannelProvider
NIO.2
The new java.nio.file package is the largest addition, it contains a brand new API for file access together with file attributes like POSIX permissions, file system and file storage abstractions.
java.nio.file.AccessDeniedException
java.nio.file.AccessMode
java.nio.file.AtomicMoveNotSupportedException
java.nio.file.ClosedDirectoryStreamException
java.nio.file.ClosedFileSystemException
java.nio.file.ClosedWatchServiceException
java.nio.file.CopyOption
java.nio.file.DirectoryIteratorException
java.nio.file.DirectoryNotEmptyException
java.nio.file.DirectoryStream
java.nio.file.FileAlreadyExistsException
java.nio.file.Files
java.nio.file.FileStore
java.nio.file.FileSystem
java.nio.file.FileSystemAlreadyExistsException
java.nio.file.FileSystemException
java.nio.file.FileSystemLoopException
java.nio.file.FileSystemNotFoundException
java.nio.file.FileSystems
java.nio.file.FileVisitOption
java.nio.file.FileVisitor
java.nio.file.FileVisitResult
java.nio.file.InvalidPathException
java.nio.file.LinkOption
java.nio.file.LinkPermission
java.nio.file.NoSuchFileException
java.nio.file.NotDirectoryException
java.nio.file.NotLinkException
java.nio.file.OpenOption
java.nio.file.Path
java.nio.file.PathMatcher
java.nio.file.Paths
java.nio.file.ProviderMismatchException
java.nio.file.ProviderNotFoundException
java.nio.file.ReadOnlyFileSystemException
java.nio.file.SecureDirectoryStream
java.nio.file.SimpleFileVisitor
java.nio.file.StandardCopyOption
java.nio.file.StandardOpenOption
java.nio.file.StandardWatchEventKinds
java.nio.file.Watchable
java.nio.file.WatchEvent
java.nio.file.WatchKey
java.nio.file.WatchService

java.nio.file.attribute.AclEntry
java.nio.file.attribute.AclEntryFlag
java.nio.file.attribute.AclEntryPermission
java.nio.file.attribute.AclEntryType
java.nio.file.attribute.AclFileAttributeView
java.nio.file.attribute.AttributeView
java.nio.file.attribute.BasicFileAttributes
java.nio.file.attribute.BasicFileAttributeView
java.nio.file.attribute.DosFileAttributes
java.nio.file.attribute.DosFileAttributeView
java.nio.file.attribute.FileAttribute
java.nio.file.attribute.FileAttributeView
java.nio.file.attribute.FileOwnerAttributeView
java.nio.file.attribute.FileStoreAttributeView
java.nio.file.attribute.FileTime
java.nio.file.attribute.GroupPrincipal
java.nio.file.attribute.PosixFileAttributes
java.nio.file.attribute.PosixFileAttributeView
java.nio.file.attribute.PosixFilePermission
java.nio.file.attribute.PosixFilePermissions
java.nio.file.attribute.UserDefinedFileAttributeView
java.nio.file.attribute.UserPrincipal
java.nio.file.attribute.UserPrincipalLookupService
java.nio.file.attribute.UserPrincipalNotFoundException

java.nio.file.spi.FileSystemProvider
java.nio.file.spi.FileTypeDetector
The new abstraction for files is the Path, and the helper classes Files and Paths are the main entry points for using the new functionality. The good old java.io.File is not deprecated but considered legacy from now on. Now plain Java can do everything and we do not need to include commons-io any more.

JSR 166y Concurrency Additions
JSR 166y added the Fork/Join framework and a few concurrency related classes which did not make it into Java 5 on time, where the original JSR 166 went in.
java.util.concurrent.ConcurrentLinkedDeque
java.util.concurrent.ForkJoinPool
java.util.concurrent.ForkJoinTask
java.util.concurrent.ForkJoinWorkerThread
java.util.concurrent.LinkedTransferQueue
java.util.concurrent.Phaser
java.util.concurrent.RecursiveAction
java.util.concurrent.RecursiveTask
java.util.concurrent.ThreadLocalRandom
java.util.concurrent.TransferQueue
The main class is the ForkJoinPool together with its two workers, RecursiveAction and RecursiveTask.

Other Classes
There are several new classes all over the JDK,
java.awt.SecondaryLoop
java.beans.Transient
java.lang.AutoCloseable
java.lang.BootstrapMethodError
java.lang.ClassValue
java.lang.ReflectiveOperationException
java.lang.SafeVarargs
java.lang.management.BufferPoolMXBean
java.lang.management.PlatformLoggingMXBean
java.lang.management.PlatformManagedObject
java.net.ProtocolFamily
java.net.SocketOption
java.net.StandardProtocolFamily
java.net.StandardSocketOptions
java.nio.charset.StandardCharsets
java.security.AlgorithmConstraints
java.security.CryptoPrimitive
java.security.cert.CertificateRevokedException
java.security.cert.CRLReason
java.security.cert.Extension
java.security.cert.PKIXReason
java.sql.PseudoColumnUsage
java.util.IllformedLocaleException
java.util.Objects
javax.crypto.AEADBadTagException
javax.crypto.spec.GCMParameterSpec
javax.net.ssl.ExtendedSSLSession
javax.net.ssl.X509ExtendedTrustManager
javax.print.attribute.standard.DialogTypeSelection
javax.security.auth.kerberos.KeyTab
javax.sound.midi.MidiDeviceReceiver
javax.sound.midi.MidiDeviceTransmitter
javax.sql.rowset.RowSetFactory
javax.sql.rowset.RowSetProvider
javax.swing.border.StrokeBorder
javax.swing.JLayer
javax.swing.Painter
javax.swing.plaf.nimbus.AbstractRegionPainter
javax.swing.plaf.nimbus.NimbusLookAndFeel
javax.swing.plaf.nimbus.NimbusStyle
javax.swing.plaf.nimbus.State
javax.xml.bind.JAXBPermission
javax.xml.ws.EndpointContext
javax.xml.ws.spi.Invoker
javax.xml.ws.spi.http.HttpContext
javax.xml.ws.spi.http.HttpExchange
javax.xml.ws.spi.http.HttpHandler
The changes cover additions to UI capabilities, e.g. NimbusLookAndFeel, new security algorithms and updated JDBC, XML and WS packages. The most interesting classes are AutoCloseable for the new try-with-resources statement and Objects with its requireNonNull(T obj) method.

Summary
Java 7 has some nice additions to core Java, but still feels like a smaller release, not as ground breaking as Java 5. The most useful thing might be the Diamond Operator because it saves a lot of typing.

See the complete list of all classes available in Java 7. Each class name is annotated with [release] showing the release it first appeared, e.g. java.lang.annotation.Annotation [5]. Package access classes are indicated by a lowercase p, e.g. java.lang.CharacterName [7p].