Dodging Dependency Nightmares with a Serialization Module

In Serializing POJOs with Jackson we looked at creating simple classes just for serialization. In this article, we pull those classes into their own module, DRY and ready to be reused. This is a little more work up front, but it’s more of an investment than a cost.

Starting Point

This is a popular starting module structure on my projects:

+ locomotives
|
|--- webservice
|--- acceptance-tests
starting point

Our new wrinkle from the previous post is we now have some classes that our web services want to return and our acceptance-tests want to create.

Options

Many folks immediately see only two options:

  • duplicate all of the serialization classes
  • introduce a dependency between acceptance-tests and webservice modules

It’s easy to have a knee-jerk reaction to violating the DRY principal by duplicating classes and instead add the rest of the application as a dependency.

the wrong way to share code

This must be avoided. Acceptance tests should be black-box tests, knowing nothing of the implementation. Allowing the acceptance tests to access the rest of the codebase easily spirals into a tangled mess. Suddenly our tests can taken any view of the world they like - including accessing datastores directly and skipping validations. The door is now wide open for testing low-value states of the system that aren’t even possible for users to create. Even worse, the tests can become so coupled to internal code that it becomes difficult to refactor and improve the application. All of these consequences work against the original intent of our tests - to be a safety net.

Solution

Adding a new module is the best option. We’re going to take our nice, new, dependency-free serialization classes and move them into their own module. The dropwizard folks recommend calling this api, and I think that’s a great idea.

+ locomotives
|
|--- webservice
|--- api
|--- acceptance-tests

Now we have a third module and our dependency tree looks much better.

a new module

Putting this kind of thought into a growing application is an important part of continuing to evolve a codebase efficiently, leaving little chance of introducing unwanted coupling to accidental dependencies.

Serializing POJOs with Jackson

Plain old Java objects dedicated to serialization help make life easy. This article looks at Jackson's built-in POJO serialization and how to create classes that define a serialization structure without specific library annotations.

Read More

How Do I Make Cross-Platform File Paths in Java?

It’s a lot easier to deploy your Java application cross-platform if you consider a few small details like file paths first.

Read More

5-Minute Intro to Gradle

A quick and painless introduction to setting up a gradle project with dependencies in IntelliJ IDEA.

Read More

How Do I Migrate My Gradle Dependencies To Be Transitive?

Lessons learned from a migration to gradle that explicitly defined every single dependency, transitive or not, and how we got to transitive dependencies.

Read More

Released: MavenCentral Gradle-Format Search

This greasemonkey script will let you paste gradle-formatted dependencies directly into http://search.maven.org. Hooray!

Read More

Why Am I Getting an OutOfMemoryError with my Ant Task?

Sometimes ant builds run out of memory right in the middle of a task. This article walks through setting up the ANT_OPTS environment variable.

Read More

How Do I Write a Jackson JSON Serializer & Deserializer?

Getting started with Jackson in Java could be more straightfoward. This article shows one way to serialize a class with a custom serializer.

Read More

  • 1