Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Monday, September 29, 2014

Postgres, JDBC, Time Zones

I've been banging my head against the wall, trying to get things to work correctly with JDBC and PostgreSQL ... ah, time zones, every programmer's nemesis.

Does this seem familiar?

  • Parse "1984-03-02" to a date, say #inst "1984-03-02T00:00:00.000-00:00"
  • Insert that date into the database, as a PostgreSQL date column
  • Read the value back from the database
  • Print it out and get #inst "1984-03-01T08:00:00Z"
  • Curse!

A little bit of digging shows that this is a pretty common problem unless both the client and the server are running in the UTC time zone. Now, it goes without saying that you are eligible for institutionalization unless you are running your servers in UTC, and that goes triple for your data store ... but the client? That really shouldn't matter.

Except it does; unless you use the full version of PreparedStatement.setTimestamp(int, Timestamp, Calendar), the PostgreSQL driver uses ... whatever the default client time zone is. Really, that's in the JDBC specification. So much for repeatable behavior!

My solution uses a dash of Joda Time (via clj-time):

This hooks into the clojure.java.jdbc library and extends the logic related to how a PreparedStatement is initialized for execution. It ensures the date or timestamp is interpreted in UTC.

Thursday, July 24, 2014

core.async article on Medium

I've just started writing on medium.com, here's my first article, about a clever design I came up with involving core.async.

Better Abstractions With core.async.

Wednesday, June 04, 2014

Subtle nicety on defrecord

I just stumbled on a rather nice feature of defrecord that I've missed in the past; perhaps you have as well?

I've been using Stuart Sierra's component library to manage startup of the server I'm building.

A big part of component is the use of records. You define a record that stores your own data and have the record extend component/Lifecycle; this is provided to the component library and it will assoc in any dependencies before invoking the start method.

Now, in practice, the values of the record's fields, execution-mode, active-connection, etc., don't change (at least, the component library doesn't change them). So the easiest thing is to just reference those symbols in the body of the start or stop method.

But what about other cases, where the field values may change? Do you need to to access the values via keyword? That is, if the field values are changed and you use the symbols, do you get the current value, or the value as passed to the record's constructor?

That will, of course, work ... but it's actually not necessary. From the defrecord documentation:

Note that method bodies are not closures, the local environment includes only the named fields, and those fields can be accessed directly.

Our answer is right there in this typically too-terse description. The method bodies look like closures over the initial values of the fields ... but they are not; they are translated into references to the actual fields.

Here's a simpler version of StateImpl, with a simple experiment to prove its behavior:

I haven't looked at the bytecode generated, but it appears that referencing a field in a method body is very similar to accessing a field in a normal Java object; the value retrieved is based on the this-like first parameter. In other words, it's designed to be very natural for Java developers. Even so, this behavior comes as a welcome surprise ... though I'm pretty sure any of the current books on Clojure have this information.

Friday, March 28, 2014

Google Docs Thinks You are Offline? Work around their bug!

... and so suddenly, and without warning, Google Docs stopped responding for me. My spreadsheet (my invoice spreadsheet without which I can't get paid) would load and then immediately tell me "You are offline" (there's an icon for that).

After trying all the obvious things ...

  • Clear my cache
  • Try it in FireFox instead of Chrome
  • Restart my computer
  • Try a different Internet connection

... I started hunting around the web. The problem has been around since at least 2012. This guy had a way to fix it that didn't work for me.

However, it did teach me about the Chrome's built in DNS information page where I could see 0.docs.google.com ERR_NAME_NOT_RESOLVED.

First I tried turning the Internal DNS client off (not on) ... that didn't help.

Then I did a hack. First I pinged docs.google.com and got 173.194.33.32 (due to the vagaries of DNS, you might get a different number).

Then I added a line to my /etc/hosts file:

173.194.33.32 0.docs.google.com

... which basically says: "don't use DNS, I've got your IP address right here".

Things seem to be working!

My guess is that this represents some kind of load balancing solution implemented by Google Docs ... and either the 0 server has failed, or its configuration got munged, or this is simply a bug in the Google Docs client-side software.

Thursday, February 20, 2014

Gradle: overruling third-party dependencies

We all hate dependency hell, and on any Java project of any size, you'll hit it eventually. My project, for Aviso, is a large Clojure code base, with tons of dependencies on third-party libraries, many of which are Java libraries with their own third-party dependencies. Despite using Gradle as our build tool, we don't get a free pass, we sometimes end up with conflicts.

It often plays out like this: module A as a dependency on library L, which has a transitive dependency on library Q. That's OK, module A has a consistent class path when it builds.

Meanwhile, module B has a dependency on library M, which has a transitive dependency on library Q ... but a different version. That's OK, module B also has a consistent class path when it builds.

However, inside IntelliJ, you see both version of library Q in the "External Libraries" folder of the Project explorer. That's unfortunate and can cause confusion when navigating your code.

Worse yet, in the final application, combining modules A and B, you will be executing one module with a different version of library Q than your tests. That alone makes me a touch nervous.

Fortunately, Gradle provides a quite reasonable way of dealing with this. The hard way would be to just turn off all transitive dependencies. But I consider that throwing out the baby with the bathwater.

Instead, we can selectively override transitive dependency, consistently across all modules. And we can do this in a single place, in our top-level build.gradle:

This one small change affects every child project; we have a single place to maintain and resolve these version conflicts and don't have to chase down which module (among the 37 currently in our overall project) is the culprit for introducing a conflict. When we see a conflict, we add a new mapping to versionOverrides and we are done.

This is a huge example of how powerful Gradle's Groovy DSL is; because the build script is also executable code, there's room to put logic in place that simply can't be defined declaratively.

Our change hooks into the dependency resolution logic associated with each Gradle configuration (a configuration is essentially a way of declaring the class path for compiling, testing, or executing Java code).

Gradle kindly exposes a step inside the overall process of analyzing the dependencies; this code hooks into this step. It sees the requested dependency, and if it's in the override map, forces the version number to a specific value. In fact, this mechanism is powerful enough to replace dependencies, but that's beyond our immediate needs.

This is one of the reasons I use Gradle in preference to Maven: Gradle has the tools to cleanly and easily address my specific problems and particular edge-cases.