Java 8 Functional JDBC Revisited

In a previous post I discussed making JDBC’s query and ResultSet into a Java 8 Stream. Having used that for a while, it occurred to me I ought to be able to make the row extraction more functional.

Traditionally to implement this the code you end up writing is a series of statements that call a method on ResultSet and copy the value into a bean.  You ought to be able to do that as a series of chained functions right? Well you can.

What are the basics of copying one value from the ResultSet to a instance variable? You have a “bean” with a setter, a ResultSet with it’s getter, and the index of the column. Let’s start with the “getter”.  We need a functional wrapper for a ResultSet getter:

That’s a BiFunction wrapping ResultSet’s getString and dealing with the Exception. That’s our getter. The setter is simple, so before we go there let’s look at how we’d use the getter.

So that will copy the value from a getter into a setter. How do we define the setter? That’s trivial with Java 8.

As you can see on line 12, the setter is just a matter of using an unbound method reference, i.e. Class::method.

The last ingredient needed is how to collect a set of these to use because you’re obviously going to pull a number of columns from the row. As a proof of concept I collected a set of these, and then did a forEach on the collection for each row. That worked but quickly I realized I could create one function out of the numerous ones by using andThen to compose a single function.

Pulling It All Together

So, to recap, the goal here is to use functional tactics to improve writing Extractors. I went with a factory approach, where the factory would gather everything you needed and return a usable Extractor. Here’s the public interface illustrated.

To use it you would:

Lines 12 through 15 above are where I use the factory to create an Extractor that pulls column one, as a string and calls Bean::setStr with it. The add method of the factory can be called repeatedly to add more extractions to the Extractor.

The Implementation

Here is the factories actual implementation:

In addition to the factory, I implemented all the basic getters for ResultSet as static final functions to avoid rewriting those. To see the entire implementation take a look at the project in github. There is room for cleaning and refactoring here, but my basic goal was achieved. You can easily create a straight forward Extractor with the factory, and the Extractor is fairly clean and efficient.

Performance

So having worked to keep the generated extractors efficient, a bit of testing was in order. I created a performance test that pitted a hand coded extractor against a generated one. The test was low tech, I simply created a mock ResultSet and then looped the two extractors against it and noted the times.  What did I find? Well generally the two extractors where on par with one another, with the coded one performing slightly better on average.  About as would have expected.

Experiences Migrating Micro Service to Wildfly

I’ve a light weight snippets service that wrote.  I use it almost daily, so it’s a live tool, but I also use it as a test bed, when applicable, for applying tech I’m trying to pick up.  Currently I’ve been using JBoss EAP professionally and so I was curious about Wildfly, which is JBoss’ project for rightsizing your web container.  To give Wildfly a go I decided to get my snippets service up in it.  Currently the service is very low impact, based on Jetty and Spark, with a disk footprint of about 14M.  I was eager to see what Firefly would make of it.

Making The Switch

Right off I was pushed towards taking a step back – Maven.  Gradle is my build tool of choice, but Wildfly was pretty biased towards  Maven.  All the examples, and the supported plugin were for Maven.  No doubt I could have worked out the Gradle path, but this was just a proof of concept and I didn’t want to commit too much effort to it.

Next set of issues were around getting Spark running in Wildfly.  I’m a fan of Spark and love it for creating small RESTful services.  Spark offered documents for running in “Other web server[s]”.  But the notes were terse and very generic.  JBoss, and so Wildfly do things a tad differently than the norm in terms of configuration.  With the application of some duct tape and bailing wire I got those issues worked out.

And then…. flatline.  Spark’s mechanism for serving static content didn’t work with content in Wildfly’s fat jar.  Okay  worked that out with a bit of tweaking and global replace.  That got it working.  The last hurdle would be to rethink how I configured the service which would need to change a fair bit for Wildfly.  But before I did that I decided to take a look at how big the “rightsized” jar was.  So the Wildfly swarm jar was 105M …. fail.

I decided to stop there.

Conclusion

Wildfly is okay.  The tools work and it’s not too hard to get things going.  It’s simpler than trying to right size JBoss on your own certainly.   That said, if you want a light weight service, and you’re not dependant on JBoss specifically,  I wouldn’t advocate Wildfly.