At 25 Constants, we’re constantly starting new Java projects all the time, and every time starts with the same process of putting together a bunch of POMs, fixing up the classpath (cause Jar hell is real), making sure all the libraries play nice, configuring logging… ad infinitum… It can be pretty time consuming. So… we decided to create a “living” starter project that we’ll be using to bootstrap our Java projects going forward. That means we’ll be maintaining it, upgrading the libraries, adding new modules, keeping the cobwebs off it, etc… AAAAND… we’ve decided to make it available so that we can spare YOU all that pain. And sure yea there’s other ones out there, but they’re usually either for a specific use case/framework integration, missing a lot of the extra common stuff that every project needs (logging?), or just plain outdated. What we wanted to do was not just have a barebones starter, but a serious starter with a bunch of the basics already in place along with examples of integrations with other common components like a database, caching, web etc… So… we loaded ours up with all the latest and greatest libraries/frameworks/modules/bells and whistles we could think of, and that we think might be included in most serious Java projects. Well… maybe not quite ALL of them just yet but it’s a work in progress. Here’s what we wanted to accomplish:

  1. As stated, we wanted a starter project we could use as a template we could easily copy/paste modules from to get new Java projects off the ground quickly using the latest set of libraries for logging, testing, infrastructure, etc… all working together along with the latest version of Java (which happens to be 13 at the time of this writing).

  2. Some simple use cases and code exercising the various frameworks/libraries that are included, which any developer could use to get moving quickly whether that be a new developer coming on board or a developer that we pulled in from another project to help out.

  3. A repository to house mini example projects of whatever new tech was used for the latest project, as well as a place to keep our libraries up to date and verify interoperability. This also gives us the perfect playground to experiment with new features and libraries that come out.

So here’s what we came up with… (drumroll…) project Amoeba: https://github.com/25constants/amoeba.

Let’s dig in shall we?

Project Structure

So, the BOM (bill of materials) POM (bom pom… lol), or root POM if you will, contains a <properties> section, which we’ll use to manage all the versions of all the dependencies (among a few other things). It looks something like this:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>13</java.version>
    <maven.compiler.source>13</maven.compiler.source>
    <maven.compiler.target>13</maven.compiler.target>

    <spring-boot.version>2.2.2.RELEASE</spring-boot.version>
    <testcontainers.version>1.8.3</testcontainers.version>
    <swagger2.version>2.9.2</swagger2.version>
    <logstash-logback.version>4.9</logstash-logback.version>
    <jackson.version>2.10.1</jackson.version>

...

</properties>

So far standard stuff. This is where you can change the version of Java that you’re using in the <java.version> and <maven.compiler.xxx> tags (1.8? Seriously? For a NEW project?? Oof…).

As far as dependencies go, all the modules make heavy use of Spring Boot, so we import Spring Boot’s BOM in the dependencyManagement section (instead of going the parent POM route that almost all the other boilerplates and examples use):

<dependencyManagement>
    <dependencies>
        <!-- BOM for spring boot dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <type>pom</type>
            <version>${spring-boot.version}</version>
            <scope>import</scope>
        </dependency>

...

</dependencyManagement>

The dependencies contains a few libraries that we figure every project will need to pull in such as logging and test utilities. Speaking of logging… we decided to go with log4j2, and included the log4j2 binding for slf4j since sl4j is used liberally throughout so many libraries. We included a log4j2.xml config file.

Finally, let me explain how we decided to handle all the various properties and configuration files. We had 2 requirements:

  1. KISS. Properties and configs get hairy real quick but since this is just a starter and any derived project will have its own requirements anyway, it wouldn’t be worth the time to come up with some whiz-bang one-size-fits-all solution.

  2. We wanted to have all the configuration housed in the same place so we wouldn’t have to go around chasing config files in various resource directories.

So… all our config files can be found under the root /config directory, with each module having its own subdirectory, along with a special ‘filters’ directory that contains files used by the Maven resources plugin for filtering resources. The build works by doing the following:

  1. For each module, copy the files directly under /config to the target directory. For now there’s just a default log4j2 config file that every module gets.

  2. For each module, copy the files from the subdirectory under /config with the same name.

This process uses the filters under the /config/filters directory, which contains a filter for each Maven profile; the default profile being ‘dev.’ Step 2 allows any common configuration file to get overridden by a module-specific one.

Modules

Alright so… in addition to a “standard” module which contains standard Hibernate-based database access and a “web” module for a simple API, we’re releasing with these:

And we’ve got more coming! Let us know if there’s any in particular you’d like to see.

Setup

One of the cool things about Amoeba is that getting it up and running is super easy thanks to Docker. (You DO use Docker don’t you?) We’ve included a docker-compose.yml file to easily deploy all those different components the various modules rely on. Just fire them all up and you’re ready to build and deploy. Of course, you can go the old fashioned route and download/install everything yourself, it’ll just take a bit more setup time. Everything you need should be detailed in the README.

Libraries

Here’s a list of some of the libraries we use:

  • Lombok: For reducing boilerplate. Apparently it’s making Java cool again.

  • Log4j2: Our choice for logging as mentioned above.

  • Spring Boot: Cause… duh.

  • Faker: Java port of a pretty cool Ruby library to generate fake data that looks real. Even has Chuck Norris Facts.

  • Testcontainers: For Docker containers for testing.

  • Junit Jupiter: Cause it sounds cooler than saying Junit 5.

  • Swagger: For the REST API stuff.

And finally… here’s the link again for those that just scrolled all the way to the bottom for this: https://github.com/25constants/amoeba. You know who you are.

ENJOY! And hit us up with any comments/questions/suggestions.