Sunday, June 5, 2016

Swift for the Java Guy: Part 2 - The basics.

In Part 1 of this series we looked at how to get Swift up and running. In this part we will look the Differences between Java and Swift at a language level by creating the Swift classes and comparing them to Java.  For this article we will go over the basic of class construction.

Firstly; Whats the same.

Both languages are fundamentally statically typed class based OO languages with single inheritance and interfaces. Furthermore Swift includes the normal set of features that Java has including:
  • Try-Catch style Exception handling
  • C-Style syntax
  • Generics
  • First class and high order functions

Whats different

Swift is very different in a key set of areas including
  • Reference based memory management using Automated Reference counting as opposed to a garbage collector.
  • Swift classes don't inherit from a base object class.
  • Swift classes do not need to be declared in a file that follows the Namespace and Class name pattern.
  • All methods in Swift are functions, Void in Swift is essential a type alias for an empty Tuple.
  • Swift only has three access modifiers, private and public which behave similarly to the Java equivalents. It also has internal which is Swifts equivalent of default access, Swift however has no protected modifier.
  • Swift interface (or protocols as they are called in Swift parlance) cannot have default implementations (although you can achieve the same effect with extensions).
  • Enums in Swift are "different". The best way I can describe is that Swift Enums are basically a set named Tuples which are grouped together in a Enum declaration, each one can declare it's own structure.

What Swift has that Java does not.

Swift has a range of features that Java does not have
  • Value Types (Structs)
  • Tuples
  • Extension types
  • Operator overloading
  • Type inference
  • Language level optional monads and strict null checking
  • Properties
  • Destructors
  • Values and variables as opposed to just variables ala Scala
  • Nested functions (AKA functions inside functions)
  • Pattern matching

Declaring your first Class in Swift

For this example I create simple class called "Animal" with a single void method makeSound

class Animal {
  func makeSound() -> Void {
    print("Roar!!")
  }
}
Animal().makeSound()

A few observations:
  • Swift methods are explicitly declared with the func keyword and have the return type after the "->" operator which is the opposite order of Java approach in terms of declaration.
  • The last line creates a new instance of Animal and calls the makeSound method. Note that Animal also has an implicit no-args constructor, also there is no new keyword.

Adding a property

So obviously not all animals roar, to fix this we add a property sound to the class by adding the following

class Animal {
  var sound:String = "Croak"
  func makeSound() -> Void {
    print(sound)
  }
}
let animal = Animal()
animal.sound = "Roar"
animal.makeSound()

By default all variables (denoted by the var keyword) declared as members are properties. What isn't visible here is that when you set the sound property it's actually accessed via accessor methods that are created implicitly. Another point worth mentioning is that the animal variable is not a variable at all but rather a constant as indicated by the let keyword, the let keyword is Swift's equivalent of Scala's val keyword.

Constructors

In the previous example I set roar the default value of "Croak", It would be better if we could pass this information via a constructor and make the sound property immutable, to do this we change the class as follows:

class Animal {
  let  sound:String
  init(sound:String) {
    self.sound = sound
  }
  func makeSound() -> Void {
    print(sound)
  }
}
let animal = Animal(sound:"Roar")
animal.makeSound()

Constructors in Swift are slightly different to Java in terms of syntax in that they are defined inside inside a block defined with the keyword init. These blocks can take parameters as you would have in a Java constructor. I also changed the sound property from var to let, this means that the sound property cannot be reassigned once it's been assigned. Its also worth showing here that Swift requires you to use named parameters when you invoke the constructor, this will be familiar to anyone who has ever used Objective-C.

Adding an interface (or Protocol)

Since Animals aren't the only things that make sound, we can pull this functionality up into a Protocol called Audible which can be implemented by the Animal class.

protocol Audible {
  func makeSound() -> Void
}

class Animal:Audible {
  let sound:String
  init(sound:String) {
    self.sound = sound
  }
  func makeSound() -> Void {
    print(sound)
  }
}

let audible:Audible  = Animal(sound:"Roar")
audible.makeSound()

Here I added a protocol with a makeSound method, aside from the protocol keyword, this should look familiar to most Java developers. The only change to the Animal class is that it implements Audible. The syntax for extension and implementation is the colon syntax which works the same way as C#. I also explicitly typed my audible value to be of type Audible just to force an upcast.

Properties on Protocols

With property properties onto Protocols. For this example I created another Protocol called Named which just has a String property; name

protocol Named {
   var name:String {get set}
}
protocol Audible {
   func makeSound() -> Void
}

class Animal: Audible, Named {
  let sound:String
  var name:String
  init(sound:String, name:String) {
    self.sound = sound
    self.name = name
  }
  func makeSound() -> Void {
    print(sound)
  }
}
let animal  = Animal(sound:"Roar", name:"Lion")
print(animal.name)
animal.makeSound()

This example also shows mutability of the name property using the get and set keywords. Interestingly I still have to define the actual name variable on the Animal class. Keeping in mind that a Protocol defines behaviour, a property on a Protocol only indicates how the property is structured not how it's stored, that is the responsibility of the implementing class.

Inheritance

For our final addition lets create a class called LivingOrganism which implements Named and make Animal extend that. I also add a default constructor which takes the name property as a parameter

class LivingOrganism:Named  {
   var name:String
   init(name:String) {
     self.name = name
   }
}

class Animal: LivingOrganism, Audible {
  let sound:String
  init(sound:String, name:String) {
    self.sound = sound
    super.init(name:name)
  }
  func makeSound() -> Void {
    print(sound)
  }
}

Again note the C# style inheritance syntax. Another interesting thing to note is the use of the super keyword which behaves much like super in Java. In this case I invoked the super class init method inside Animal. One difference to Java is that Swift requires the local variables to be initialised first before invoking the super constructor, hence the call being the last line of Animal's constructor. This is the reverse of Java.

So there we have it, a basic overview of class construction in Swift. In the next part we will explore Some of the additional features of Swift such as Tuples and Strict Null checking with optional monads.

Saturday, May 28, 2016

Swift for the Java guy: Part 1 - Getting Started

It's been a while since I had to look at the Apple development Eco-system.

In fact the last time I did anything serious was back in 2009 when I tried to get in on the boom in apps at the time.

I honestly didn't have a lot of issues with Objective-C as a language per se. In fact if anything I much preferred that than if I had had to whack out code in C or C++.

I think my main objection - if I had one - was that the Xcode environment is nowhere close to the level of something like IntelliJ. Also the SDKs at the time were pretty limited compared to what you had on the full blown version of OSX.

Needless to say; I spent a lot of time doing a lot more boilerplate code than what I would have liked.

When Swift came out (almost two years ago now, can you believe it) I briefly looked at the language which I thought was quite nice but it didn't really interest me much. The biggest reason for this is that my world has been - for the most part - Server side Java running on some type *nix based platform.

Fast forward two years and suddenly Swift is OSS and companies like IBM are trying hard to make Swift feature in my world.

Ok but what can it do that Java cannot?

Well here's a few things to consider:

  • Docker is changing the landscape in terms of how we deploy software. In a lot of ways Docker is the new Application server and the new virtual machine.
  • Together with Docker we have the rise of Microservices and the need to create very small deployable units of code.
  • Swift is a native language, it's fast out the box and incurs very little overhead in terms of memory and startup time.
  • Swift is also a thoroughly modern and clean language.
  • The combination of these things potentially makes Swift a great platform to build Dockerised Microservices, perhaps better than a language which historically incurs a large cost with it's VM and dependent libraries.


Installing.

If you are you are using OSX the easiest way to get running is simply to get the latest version of Xcode from the App Store.

If you are running Ubuntu (14.04 or 15.04) I suggest you use the excellent swiftenv utility to install and manage Swift versions.

You can also install swiftenv for OSX via Homebrew. This is useful if you want to easily play around with the Swift 3.0 development builds.

The system I am using for this post is running Ubuntu 14.04 and I using the 2016-05-09-a version which is a Swift 3.0 development snapshot. 

Firstly I installed swiftenv as follows:

git clone https://github.com/kylef/swiftenv.git ~/.swiftenv
echo 'export SWIFTENV_ROOT="$HOME/.swiftenv"' >> ~/.bashrc
echo 'export PATH="$SWIFTENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(swiftenv init -)"' >> ~/.bashrc

Then I can go ahead and install the Swift development package.

swiftenv install DEVELOPMENT-SNAPSHOT-2016-05-09-a

That's it! Swift is now installed.

You can test the installation by running the Swift REPL

Building your first bit of Swift.

My first issue that I encountered on Linux is the complete lack of a decent IDE for the Linux environment. For this example I ended up using good old Vim. 

However I'm - somewhat ironically - playing around with Visual Studio Code which also seems to do a decent job.

For this example I will do the obligatory "Hello world"

I simply create a file "HelloWorld.swift" and I put the following code in it.

print("Hello world")

And that's it. Swift will basically run any code which is declared inline alla Ruby, Python, Groovy et-al.

You can now run this as follows:

swift HelloWorld.swift

at which point you see the output:

hello world

Wait a minute didn't I say this is compiled!?

Another really neat feature of Swift is that you can run code both in interpreted and compiled mode. 

To compile the code you simply run:

swiftc HelloWorld.swift

This spits out the Executable "HelloWorld" which you can simply execute as:

./HelloWorld

And there you have it! Swift is up and running. In the next post we will explore the language a bit.

Some Notes

swiftc didn't work the first time on my machine. It turns out that Swift relies on a version 3.6 of Clang on Ubuntu 14.04

I fixed this by doing the following:

apt-get install clang-3.6
update-alternatives /usr/bin/clang clang /usr/bin/clang-3.6 100
update-alternatives /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100





Wednesday, June 25, 2014

Type safe dependency injection using Java 8.0

So I sometimes really miss old school Dependency Injection. Back when Spring was still "lightweight" we happily configured all our beans in an application.xml file with the "learn-in-a-day" Spring bean xml configuration. The downsides to this were of course a loss of type safety. I can think of quite a few test cases whose sole purpose was to bootstrap the Spring configuration file and just see if the ApplicationContext starts up without going belly-up due to mis-wiring and correct resolution of included bean xml configuration files.

I may be a minority but I never liked the Spring Schema configuration. To me it feels a bit like configuration for configuration.

Annotations came along and improved things, with the caveat in that you have to import libraries for all those annotations. I like annotations but  there is a good case for having all your DI information in a central place so you can actually see how your app hangs together. Finally you sometimes need to create managed objects you can't annotate.

Java Spring configuration makes things better with compile time safety, but I had to rethink the way I did a lot of my wiring, as I had to be careful how I did my wiring as I  lost some of the lazy eval that you get in a Spring context as your Java code evaluates immediately when the ApplicationContext starts up.

So, Java based DI is nice but how can we use Java 8.0 to improve it?

Apply that Lambda Hammer

Right so this is the part of the post that starts applying the new hammer in Java 8.0: Lambdas.

Firstly Lambdas give a type safe way of deferring execution till it's needed.

So, lets first create a wrapper object called "ObjectDefinition" who's job it is to define how an object should be created and wired with various values. It works by instantiating the class we want to create and object from (In this case we have a class called "MyObject"). We also give it a list of java.util.function.BiConsumer interfaces which are mapped to a specific value. This list will be used to perform the actual task of setting values on the object.

ObjectDefintion then instantiates the object using normal reflection and then runs though this list of BiConsumer interfaces, passing the the instance of the concrete object and the mapped value.

Assuming we give our ObjectDefinition a fluent DSL we can do the following to define the object by adding the set() method which takes a BiConsumer and the value to set and populates the BiConsumer list as follows:


  MyObject result = new ObjectDefinition()
    .type(MyObject.class)
    .set((myObject, value)-> myObject.setA(value), "hello world")
    .set((myObject, value)-> myObject.setB(value), "hallo welt")
    .create();

The create() method simply instantiates a MyObject instance and then runs through the list of BiConsumers and invokes them passing the mapped value.

Method pointers??!! in Java??!! (Well Kinda)

Now, Another interesting feature in Java 8.0 is Method references, which is a feature where the compiler wraps a method in a functional interface provided that that method can map to the signature of that functional interface.

Method references allow you to map to an arbitrary instance of an object provided that the first parameter of that method is that instance value, and the subsequent parameters match it's parameter list.

This allows us to map a BiConsumer to a setter where the first parameter is the target instance and the second parameter is the value passed to the setter:

  
   MyObject result = new ObjectDefinition()
     .type(MyObject.class)
     .set(MyObject::setA, "hello world")

     .set(MyObject::setB, "hallo welt")
     .create();


Method references provide an interesting feature in that it provides a way of passing a reference to a method in a completely type safe manner. All the examples require the correct types and values to be set and the setter method needs to correspond to that type.

It's Container Time

So now we have  a nice little DSL for building objects, but what about sticking it into a container and allowing our ObjectDefinition to inject references to other values.

Well, assuming we have this container, which conveniently provides a build() method which provides a hook to add new ObjectDefinitions.

We now have a container we can use to inject different objects in that container:

     Container container = create((builder) -> {
          builder
              .define(MyObject.class)
              .set(MyObject::setA, "hello world");
     });
     String myString = container.get(MyObject.class);        



Our Container object has the define() method which creates an instance of an ObjectDefinition, which is then used to define how the object is created.

But what about dependencies?

Dependency Injection is no fun without being able to inject dependencies, but since we have a container we can now reference other objects in the container.

To this end we add the inject() method to our ObjectDefinition type, this can then be used to reference another object in the container by it's type:

   Container container = create((builder) -> {
      builder.define(String.class)
             .args("hello world");

      builder.define(MyObject.class)
             .inject(MyObject::setA,String.class);
   });
   MyObject myString = container.get(MyObject.class);


In this example we map an additional object of type String (the args() method here is method which can map values to the the constructor of an object). We then inject this String calling the inject() method.

Cycle of Life.

We can use the same approach of Lambdas and Method References to manage the life cycle of an object in the container.

Assuming we want to run an initialisation method after all the values have been set, we simply add a new Functional interface which is invoked after all the values are set.

Here we use the a java.util.function.Consumer interface where the parameter is the instance we want to call the initialisation code on.

    Container container = create((builder) -> {
      builder.define(MyObject.class)
             .set(MyObject::setA,"hello world")
             .initWith(MyObject::start);
    });
    MyObject myString = container.get(MyObject.class);



In this example we added a start() method to our MyObject class. This is then passed to the ObjectDefinition as a Consumer via the initWith() method.

Yet Another Dependency Injection Container

So all these techniques (and more) are included in the YADI Container, which stands for Yet Another Dependancy Injection Container.

The code is available on Github at https://github.com/jexenberger/yadi. And is licensed under an Apache License.

Tuesday, May 27, 2014

When writing too much code can kill you

So now that I lured you in with that provocative title I suppose I need to clarify. Well it's true; too much coding can kill you, the real question is "what is the reason?" and the answer to that is; Chronic Stress.

So why write about this; well it's personal. You see: it happened to me, and I'm hoping to tell other people that it could happen to them to.

"Holy Smokes Batman, do you mean it takes years"
So what is Chronic stress. To quote Wikipedia: Chronic stress  is the response to emotional pressure suffered for a prolonged period over which an individual perceives he or she has no control.

A few key observations:
  • Chronic stress is prolonged stress experienced over a long time, period often years.
  • There is a distinct physical effect on the body resulting in the continuous release of hormones meant to only be released for a temporary period of time.
  • When you are in state of prolonged stress, you may not recognise it or if you do, feel that you cannot do anything about it.

"Cortico...what!!??"
The Human body is designed to deal with stress, provided it's temporary. When you are under stress your body releases hormones most notably Adrenalin and Cortisol. Adrenalin boosts your heart rate and energy supplies. Cortisol increases glucose in the bloodstream and increases the bodies ability to produce glucose and ability to repair tissue.

If you were to compare is to a car, Cortisol is like Nitrous, Adrenalin is your Turbo.

Now Nitrous is meant for a short boost, running it permanently is not great for your engine. Adrenalin and Cortisol is pretty much the same. If you run it permanently it's not great for your body.

Here are a few highlights of what you might expect when you suffer from Chronic Stress.
  • Anxiety
  • Irritability
  • Recurring Insomnia
  • Headaches
  • Digestive disorders
  • Depression
  • Reliance on boosters such as caffeine
  • Spikes and drops in energy at odd times
  • Unexplained sudden weight gain
  • Increase in illness and difficulty in recovering from illness
And (The ones that can kill you):
  • Hypertension
  • Cardiovascular disease.
It's also worth noting that many of the symptoms have knock on symptoms. 

For me particularly I started suffering from Insomnia almost a year and a half before I was diagnosed with Chronic stress. The effect this had quite a negative effect on my mood and concentration. 

Developers are like Soylent green.
So Developers - contrary to popular belief - is people. In other words they are fallible limited creatures who have limitations in what they can do.

The problem is that we often subject ourselves to increased stress, because of crazy timelines, unrealistic expectations (both by our employers and also by ourselves) and no small amount of ambition.

This is complicated if you are a bit of an A-Type personality who has a tendency to take more and more things on.

The sad part is the more you take and the higher your stress levels become, the less productive you become.

The writing is on the wall
First chronic stress is not like a common cold, the symptoms develop after a long period of time and furthermore it's not something that really well understood.

The result is that it's that this type of thing that creeps up on you, and before you know it you are chronically stressed out and now you need treatment.

So here are some early warning signs that you can learn to identify it:
  • Recurrent episodes of insomnia.
  • Multiple people repeatedly tell you: "You look tired" or something similar.
  • Your buttons suddenly start being pushed often and you find yourself getting more easily aggravated at things.
  • You start becoming very negative and people tell you as much.
  • You suddenly realise you haven't engaged in a personal hobby or done something you like in quite some time.
  • You often have a headache and/or heartburn.
  • You struggle to turn off work and/or you're always anxious about a work.
  • You often work overtime because it's the only time you can get "flow" due to the multitude of distractions in your environment.
Deal with it!
There is quite a lot help out there with regards to reducing stress, but from a personal view there are a few things worth mentioning:
  • Ultimately no one actually forces you to be stressed out, If you don't find a way to deal with it no one else will.
  • Other people won't get it or recognise it unless they have first hand experience, you have to accept and deal with it yourself.
  • Acknowledge your limits.
  • Take stress seriously, it can damage your relationships, your career and your health.
  • Don't be afraid to get professional help.
  • Take that vacation.
  • Be careful when you blur work and pleasure, Especially if one of your hobbies is writing code.
So I hope this was informative and here's hoping to no more stress and - off course - staying alive.












Saturday, January 11, 2014

Builder pattern using Java 8

I work in an environment where a great deal of our day to day scripting tasks occur through calling remote services as opposed to working with the database.

For a lot of scripting tasks I've often used Groovy and one of the most useful features of Groovy specifically for that task has been it's built in fluent Builders.

Now Groovy builders exploit a few Groovy language features that are never going to make it into Java.

Most notably Groovy builders make use of Groovy's Meta programming features which isn't coming to Java any time soon.

However a key feature that Groovy builders have is their hierarchical approach to building constructs.

This allows the builders to neatly and safely create nested tree like constructs which can be used to model everything from UX form layouts to XML.

This approach we can at least model quite succinctly using Java 8 lambda expressions.

For my sample I decided to take a reasonably simple Maven pom file and see if I could create a builder to handle that.

All the code for the builder is available on Github here.

The pom.xml file is as follows:

 <?xml version="1.0" encoding="UTF-8"?>  
 <project xmlns="http://maven.apache.org/POM/4.0.0"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
   <modelVersion>4.0.0</modelVersion>  
   <groupId>com.github</groupId>  
   <artifactId>lambda-builder</artifactId>  
   <version>1.0-SNAPSHOT</version>  
   <dependencies>  
     <dependency>  
       <groupId>junit</groupId>  
       <artifactId>junit</artifactId>  
       <version>4.11</version>  
     </dependency>  
     <dependency>  
       <groupId>commons-beanutils</groupId>  
       <artifactId>commons-beanutils</artifactId>  
       <version>1.7.0</version>  
     </dependency>  
   </dependencies>  
   <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-compiler-plugin</artifactId>  
         <configuration>  
           <source>1.8</source>  
           <target>1.8</target>  
           <fork>true</fork>  
           <compilerArgument>-proc:none</compilerArgument>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  

Here is the sample code for the builder to build this model:

     MarkupBuilder pom = new XmlMarkupBuilder(true, "pom")  
         .at("xmlns", "http://maven.apache.org/POM/4.0.0")  
         .at("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")  
         .at("xsi:schemaLocation", "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd");  
     pom.el("modelVersion", "4.0.0");  
     pom.el("groupId", "com.github");  
     pom.el("artifactId", "lambda-builder");  
     pom.el("version", "1.0-SNAPSHOT");  
     pom.el("dependencies", () -> {  
       pom.el("dependency", () -> {  
         pom.el("groupId", "junit");  
         pom.el("artifactId", "junit");  
         pom.elx("version", version::get);  
       });  
       pom.el("dependency", () -> {  
         pom.el("groupId", "commons-beanutils");  
         pom.el("artifactId", "commons-beanutils");  
         pom.elx("version", version::get);  
       });  
     });  
     pom.el("build", () -> {  
       pom.el("plugins", () -> {  
         pom.el("plugin", () -> {  
           pom.el("groupId", "org.apache.maven.plugins");  
           pom.el("artifactId", "maven-compiler-plugin");  
           pom.el("configuration", () -> {  
             pom.el("source", 1.8);  
             pom.el("target", 1.8);  
             pom.el("fork", true);  
             pom.el("compilerArgument", "-proc:none");  
           });  
         });  
       });  
     });  


A few notes on this in general:

  • I created a special form of some the methods which takes a java.util.function.Supplier as a parameter, and allows you to delay evaluation of a value until you traverse the builder.
  • I eschewed method chaining (although I catered for it in the builder). Trying both methods I personally felt this was a lot cleaner.
  • Java doesn't have all syntax sugar that Groovy has, so I used a java.lang.Runnable for the functional interface which reduced the syntax creating a closure, with the downside that you have to have a handle on the initial builder object.
Nowhere as nice as Groovy builders but nevertheless a great step forward. Can't wait for Java 8.





Thursday, November 14, 2013

Adding Java 8 Lambda goodness to JDBC

Data access, specifically SQL access from within Java has never been nice. This is in large part due to the fact that the JDBC api has a lot of ceremony.

Java 7 vastly improved things with ARM blocks by taking away a lot of the ceremony around managing database objects such as Statements and ResultSets but fundamentally the code flow is still the same.

Java 8 Lambdas gives us a very nice tool for improving the flow of JDBC.

Out first attempt at improving things here is very simply to make it easy to work with a java.sql.ResultSet.

Here we simply wrap the ResultSet iteration and then delegate it to Lambda function.

This is very similar in concept to Spring's JDBCTemplate.

NOTE: I've released All the code snippets you see here under an Apache 2.0 license on Github.

First we create a functional interface called ResultSetProcessor as follows:

@FunctionalInterface
public interface ResultSetProcessor {

    public void process(ResultSet resultSet, 
                        long currentRow) 
                        throws SQLException;

}

Very straightforward. This interface takes the ResultSet and the current row of the ResultSet  as a parameter.

Next we write a simple utility to which executes a query and then calls our ResultSetProcessor each time we iterate over the ResultSet:

public static void select(Connection connection, 
                          String sql, 
                          ResultSetProcessor processor, 
                          Object... params) {
        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            int cnt = 0;
            for (Object param : params) {
                ps.setObject(++cnt, param));
            }
            try (ResultSet rs = ps.executeQuery()) {
                long rowCnt = 0;
                while (rs.next()) {
                    processor.process(rs, rowCnt++);
                }
            } catch (SQLException e) {
                throw new DataAccessException(e);
            }
        } catch (SQLException e) {
            throw new DataAccessException(e);
        }
}

Note I've wrapped the SQLException in my own unchecked DataAccessException.

Now when we write a query it's as simple as calling the select method with a connection and a query:

select(connection, "select * from MY_TABLE",(rs, cnt)-> {        System.out.println(rs.getInt(1)+" "+cnt)
});


So that's great but I think we can do more...

One of the nifty Lambda additions in Java is the new Streams API. This would allow us to add very powerful functionality with which to process a ResultSet.

Using the Streams API over a ResultSet however creates a bit more of a challenge than the simple select with Lambda in the previous example.

The way I decided to go about this is create my own Tuple type which represents a single row from a ResultSet.

My Tuple here is the relational version where a Tuple is a collection of elements where each element is identified by an attribute, basically a collection of key value pairs. In our case the Tuple is ordered in terms of the order of the columns in the ResultSet.

The code for the Tuple ended up being quite a bit so if you want to take a look, see the GitHub project in the resources at the end of the post.

Currently the Java 8 API provides the java.util.stream.StreamSupport object which provides a set of static methods for creating instances of java.util.stream.Stream. We can use this object to create an instance of a Stream.

But in order to create a Stream it needs an instance of java.util.stream.Spliterator. This is a specialised type for iterating and partitioning a sequence of elements, the Stream needs for handling operations in parallel.

Fortunately the Java 8 api also provides the java.util.stream.Spliterators class which can wrap existing Collection and enumeration types. One of those types being a java.util.Iterator.

Now we wrap a query and ResultSet in an Iterator:

public class ResultSetIterator implements Iterator {

    private ResultSet rs;
    private PreparedStatement ps;
    private Connection connection;
    private String sql;

    public ResultSetIterator(Connection connection, String sql) {
        assert connection != null;
        assert sql != null;
        this.connection = connection;
        this.sql = sql;
    }

    public void init() {
        try {
            ps = connection.prepareStatement(sql);
            rs = ps.executeQuery();

        } catch (SQLException e) {
            close();
            throw new DataAccessException(e);
        }
    }

    @Override
    public boolean hasNext() {
        if (ps == null) {
            init();
        }
        try {
            boolean hasMore = rs.next();
            if (!hasMore) {
                close();
            }
            return hasMore;
        } catch (SQLException e) {
            close();
            throw new DataAccessException(e);
        }

    }

    private void close() {
        try {
            rs.close();
            try {
                ps.close();
            } catch (SQLException e) {
                //nothing we can do here
            }
        } catch (SQLException e) {
            //nothing we can do here
        }
    }

    @Override
    public Tuple next() {
        try {
            return SQL.rowAsTuple(sql, rs);
        } catch (DataAccessException e) {
            close();
            throw e;
        }
    }
}

This class basically delegates the iterator methods to the underlying result set and then on the next() call transforms the current row in the ResultSet into my Tuple type.

And that's the basics done. All that's left is to wire it all together to make a Stream object. Note that due to the nature of a ResultSet it's not a good idea to try process them in parallel, so our stream cannot process in parallel.

public static Stream stream(final Connection connection, 
                                       final String sql, 
                                       final Object... parms) {
  return StreamSupport
                  .stream(Spliterators.spliteratorUnknownSize(
                          new ResultSetIterator(connection, sql), 0), false);
}

Now it's straightforward to stream a query. In the usage example below I've got a table TEST_TABLE with an integer column TEST_ID which basically filters out all the non even numbers and then runs a count:


     long result = stream(connection, "select TEST_ID from TEST_TABLE")
                .filter((t) -> t.asInt("TEST_ID") % 2 == 0)
                .limit(100)
                .count();
   
And that's it!, we now have a very powerful way of working with a ResultSet.

So all this code is available under an Apache 2.0 license on GitHub here. I've rather lamely dubbed the project "lambda tuples, and the purpose really is to experiment and see where you can take Java 8 and Relational DB access, so please download or feel free to contribute.

Sunday, December 30, 2012

New Years Resolutions for the Java Developer

So in closing on a rather eventful year for me personally it's always good to reflect and think and thus we apply the cliché of the new years resolutions - with a twist - in that they will be Geeky.

So without further ado here we go.

Use Spring Less.
I plan to use vastly less Spring this year.

Now Spring has pretty much become the de facto component framework in the Java ecosystem. This is not a bad thing; that is until every software nail must be nailed flat with the Spring hammer.

I been on the Spring Bandwagon now since about 2005 when Spring was still the breath of fresh air promising to save us from the evil Darth Ee-jay-bee. From about that time every developer with a glint in their eye and a will to type has tried to shoehorn everything to "integrate" into Spring.

Again this is not necessarily bad, however I work for a company where the perception is that anything prefixed with the word "Spring" is automatically better, sometimes coming at the cost of something that is actually better.

But lets not stop there...

  • I'm tired of the "For Real?" look I get from my developers when they are debugging Spring configuration and they ask my why Spring is better.
  • I'm tired of the massive War files I get and often the dependency clashes I have to fix because of the other stuff I need to pull in.
So this new year I plan to use Spring in it's pure simple form. 

Stop treating JPA/Hibernate as the one stop shop for Java based persistence.
I want to use something besides JPA/Hibernate to do persistence this year, I want to do this because of the following:
  • I want to have POJOs that are still POJOs at runtime.
  • I want to stop having weird hibernate exceptions that happen after we've been in production for a bit, and then have my customer stop screaming at me.
  • I want to stop having the rich domain model being so tantalisingly close to my grasp only to have it all come crashing down when the realities of ORM kick in.
  • In reference to the previous point: I hate DAOs; JPA/Hibernate don't make them go away (at least not completely).
  • I'm tired of the "For Real?" look I get from my developers when they are debugging JPA/Hibernate issues and I'm explaining to them how JPA/Hibernate simplifies things.
Now to fair a lot of the points listed is because JPA/Hibernate does a lot of complex heavy lifting on my behalf, but in many cases the power is just not needed.

Stop using Anonymous Inner classes and just bite the bullet and wait for 8.
I've been excited about the inclusion of closures in Java for a long, long time. I am a self confessed "closurist " and I fully plan to find as I many nails as I can when I get my closure powered hammer.

But I also have to accept that Java 8 especially in full production use is still going to be some ways away.

And before that I resolve to resist the temptation to butcher code with anonymous inner classes in order to recreate that style of coding.

Stop worrying about the procedural code.
Hah! bet you never saw that one coming. 

I've been looking at the code that we produce, typically I do a lot of SOAP web services in my job, and what I see a lot of is that while we normally try to stick to SOLID principles, I don't see a lot of value coming out of the abstractions we create.

We have an anaemic domain model and most of the work is done in the Service tier implementation delegating to DAOs for data operations (although I've started introducing newer patterns here).

I can't help feel that had I done this code in pure C it probably wouldn't feel massively different. To this end I sometimes wonder if all we do is procedural code with a bit of OO sauce on top.

I also wonder is this is necessarily a bad thing; the code works, it's simple to follow and read and is not burdensome to maintain, so this coming year I plan to to stop worrying about it :)