As a programming language Java has long been infamous for enforcing a rigid structure in class relationships, and in Java 9 it got even worse with a new feature for structuring relationships between larger blocks of code: modules.
Modules are great. They encourage a design that breaks down a large system into cohesive units that facillitate code reuse by encapsulating a business domain. After doing some serious work with Java modules I've found the resulting codebase to have among the most clear, coherent, and stable designs I've worked with. When you build a system with modules the overall structure of the codebase and the relationships in it are at the top of your mind, and that results in a design with strong, independent units that facillitate code reuse.
Getting there is not easy though. Gradle has some support for building modules, but there are a number of serious problems you will run into in the course of setting up your build that are not covered in the documentation, nor in easily googlable blogs and tutorials. You'll end up cobbling together some knowledge of how modules work from various different sources, experimenting with command line compilation options, and (shudder) building your own jars from dependencies that are incompatible with the module system due to clashing packages.
I aim for this post to be the guide I wish I had when I was setting up my first modular system. We'll be building a RESTful web service to manage authentication tokens using dropwizard, mysql, and hibernate. The system will be composed of three modules, as dropwizard recommands. This will give us the opportunity to create a system with non-trivial dependencies and internal module relationships.
The service will generate authentication tokens given a username and password, and determine if tokens are valid. We'll store a database of username and encrypted password pairs, and keep authentication tokens in an in-memory cache.
All of the example code in this blog is in a github repo, and each step will link to corresponding commits in the repo.