Despite all the tools and features available out there today to assist you in setting a project easily, there is yet still a lot to do to get it set up properly. This is certainly the case for me when i start a new Java project. Spinning up a new Java project these days might seem easy and painless (see section on Spring below) but there is definitely some extra work involved to get the project in a really good usable state that is releasable, deployable, production ready, and with good test setup.
In this article i am going to walk through my personal checklist of all the stuff i make sure i do and include in my new Java projects.
Without further a do, here it is:
1. Create your GitHub Repo
Following best software development practices you should always store your source code in a version control system (VCS). A common VCS most people use these days is GitHub as it is the worlds biggest online Source Control service provider.
Other common VCS in this area are GitLab, BitBucket etc.
But i tend to use GitHub a lot for both work and also my personal projects so i make sure one of the very first things i do when starting a new project of any kind is to create a new source code repository for it on GitHub.
2. Use Spring? setup Spring! — Don’t Use Spring? Then use Spring
If you are developing in Java, you most certain want to use an application framework. One of the most dominant Java application framework out there right now is Spring. So need to make sure to setup Spring!
This is very easy to do nowadays. Most people use Spring Boot for building Java web applications these days and i am not an exception whenever i need to start up a new Java web application.
There is no need to manually configure Spring dependencies in your Maven
pom file as you used to but there is nothing stopping you to if you really want to go down that route in using the Spring framework and not Spring Boot.
So assuming you also want to use Spring Boot for your Java project you can easily create a basic setup of a Spring Boot project by using Spring’s Spring Initializr.
Initializr generates spring boot project with just what you need to start quickly!
Spring Initialzer enables you to create a new Spring Boot project easily.
After you finish selecting the features you want for your Spring Boot application in Spring Initializr…
Click on the “Generate” button to download the project.
Project Directory Structure
This is the project directory structure when you unzip the downloaded zip.
colinbut@colins-mbp-2 $ /demo tree
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ └── DemoApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
As you can see from above; you already have a ‘ready made’ project for you to work on.
Moreover, it is ready to be spun up easily locally and you can take it to production as it is. Although it doesn’t have much at all as it is just a sample skeleton project.
3. Setup Unit Testing
To do unit testing in Java, you require the JUnit framework. In a Maven based project where you use a
pom file to manage your dependencies you can easily add the JUnit dependency to the list of dependencies.
Note 1: Spring Boot already does contain the JUnit dependency as a transitive dependency from one of its own Spring modules so you are not required to add the above. However, if you are not using Spring Boot for whatever reason then you can add the above. Also, if you are overriding a specific JUnit dependency version for whatever reason then make sure you are excluding the JUnit dependency from the existing Spring dependency that includes it.
Note 2: As a personal preference i like to use JUnit version 4 since that has been stable for many years and it has been my favoured. However, latest Spring Boot dependencies includes JUnit 5 and although JUnit 5 have been released publicly for a good few years now it is still not that stable in my personal opinion.
Additionally, I like to use Mockito for mocking so i also include the Mockito dependency as well.
Again, Spring Boot dependencies include Mockito as well.
Sometimes, i might need to use the Powermock library to assist me in mocking private and static methods. So i would include those as well if i need those libraries.
However, as a strewed reader in you, you might think why on earth would i use Powermock to mock private and static methods as mocking private and static methods hints at poor quality coding and bad code design. That is true and i certainly can not argue with you on that as i also share the same beliefs.
But, there are sometimes where such niche situation arises where you need to mock private and static methods to assist you in your unit tests (or integration tests).
Anyways, a discussion on whether to mock private and static methods or not is not within the scope of this article.
4. Setup Integration Testing
Integration Testing in general is very broad as it can span and cover many different dimensions. For instance, E2E testing and API Testing which i am going talk about in next 2 sections can also be categorized as Integration Testing too or at least a subset of Integration Testing.
If you are using Spring Boot (and i really encourage you to if you are not), then you can use the Spring Test framework that comes with Spring. It has many cool features that enables you to do Integration Testing with your Java based Spring Boot app.
One of the first thing i do is to ensure the Spring Test dependency is added:
I have already written an article on Integration Testing with Spring which explains this more:
5. Setup E2E Testing
This step can vary depending on what kind of tools you decide to use for doing ‘End 2 End’ (E2E) testing. It also depends on how you plan to do it. After all, E2E is a subset of the broader Integration Testing described above. And as you have just seen, Integration Testing can be really messy to setup depending on what tools, technology, software libraries, frameworks you decide to use.
For me, i like to categorize E2E Tests specifically as i mainly like to separate specific E2E Tests from more broader generic Integration Tests (the tests that sit in the middle of the traditional Testing Pyramid).
The framework i commonly use is Cucumber 🥒 .
Cucumber is a Behaviour Driven Design (BDD) Testing Tool. I won’t go into BDD too much but put simply, BDD aims to solve the problems TDD gave and BDD acts as a broader and more next level approach to a Test First approach where it aims at writing E2E Tests as Acceptance Criteria combining with writing those test specifications in a human readable English like language (that even a Business Analyst — BA can write) — a.k.a Gherkin in the Cucumber world.
Cucumber originated from Ruby. But since my project is Java, i use the Java port of Cucumber — namely Cucumber-JVM. Note that there are many other ports for other programming languages too.
Just like for Unit Testing where you include the JUnit library, with E2E testing where you use Cucumber-JVM you would just include the Cucumber-JVM dependency too.
So here’s some examples of adding the dependencies to the Maven
If you’re using Java 8:
And that is it.
6. Setup API Testing
In the era of Microservices, it is likely that you are developing a backend Java web based microservice that exposes a set of API endpoints enabling the microservice to act as a web service. Nevertheless, even if you are not, and you are just building a simple Java web based application, it is always good to put in place API Testing (if your application expose APIs that is).
By this point, we should already have the setup required for Unit Tests, Integration Tests, and End to End System Tests.
Since your API is the interface you give to your end consumers, it is a good idea to test them too.
To do that in Java, you can use the REST Assured library.
Testing and validating REST services in Java is harder than in dynamic languages such as Ruby and Groovy. REST Assured…
I quite like this library as it gives a very descriptive way to program your tests by using programming techniques like method chaining in Java and using the Fluent Interface.
7. Setup UI Testing — selenium
If you are developing purely a backend Java Spring Boot microservice then you can skip this step. This step is only applicable for Java web applications that include a UI/View. For example, if you are developing a monolithic Java web app that contains static resources such as HTML/CSS/JS embedded in your Java code base then it might be a good idea to put in place UI Testing.
A common UI software testing tool i have used in the past is Selenium.
Selenium is very heavy. To setup Selenium properly can be very tedious and fiddly.
I tend to use FluentLenium instead:
FluentLenium is a React ready website automation framework which extends Selenium to write readable, reusable, reliable…
And to include the dependencies required:
8. Good Quality Code with Static Code Analysis
As a developer in me, i like my code to be of good quality.
So i enable static code analysis for my Java project too. The tools in this space vary but the most popular is perhaps using Sonar from SonarQube.
Code Quality and Code Security | SonarQube
Thousands of automated Static Code Analysis rules, protecting your app on multiple fronts, and guiding your team. Catch…
I won’t go into too much detail on how to prep for Sonar as there are a few ways to skin this cat. After all, Sonar is quite a heavy duty tool.
But generally, i ensure that my CI tools of choice can run Sonar. Running Sonar is pretty easy with Maven as all you need is this command (assuming your Sonar configuration is all set up correctly):
9. Put in place CI/CD
Continuous Integration (CI) is a vast topic. There are so many CI/CD solutions out there such that i can not cover them all.
I normally just pick one (or two if it’s a personal side project of mine or when i want the flexibility to switch to another CI solution at a later date) CI solution put in place the necessary configuration.
Nowadays, with everyone adopting Pipeline as Code for CI (and CD as well), all you need for configuration is merely just a configuration pipeline definition file.
I normally chose Jenkins for my Java projects so i would put in a
Jenkinsfile like the following:
For some of my other more modern projects, i like to try out GitHub Actions as it comes bundles with GitHub (the VCS i use) with easy integration.
I would add a GitHub Actions workflow file like the following:
Note that from above example, i have modelled my application pipeline as a traditional ‘DevOps Pipeline’ just like the Jenkins’s
GitHub Actions best practice is probably to define each of the tasks you need to run as part of your SDLC pipeline as individual workflows.
Bottom line is that every CI/CD solution has its own way of doing things so vary your CI/CD configuration/pipeline code accordingly.
10. Configure logging
Any good application requires logging in place. You should use a logger to log messages rather than using
System.out.print in Java. In fact, this applies to any programming language and not just Java. For example, rather than using
logging core library.
If you are using Spring Boot then logging comes for free as Spring Boot imports the logging dependencies.
If you are not or you want to use a specific logging library or framework then you can directly add the dependency into your Maven
pom file. For example, i really like the use of SLF4J as an abstraction over Log4J as it allows me to easily swap away Log4J one day in the future if i wanted to use a different logging library (say, LogBack).
The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks…
Here are the dependencies i would add to my Maven
Sometimes you might require to override or provide custom logging settings. To do that, for instance, if you are using Log4j then you can insert the
log4j.properties configuration file into your project.
One of the good things about setting up a logger for logging messages is that you can configure your application to push your logs to a centralized logging solution such as the Elastic (ELK) Stack, Splunk, Sumo Logic, or any others…
11. Configure Metrics and Monitoring
In addition to logging, it is also important to setup metrics and monitoring capabilities for your application too. This is a step towards the direction of being ‘production ready’.
When using Spring Boot (which i really encourage you too if you are not), i always most certainly add the Spring Actuator dependency to my list of Spring dependencies purely because the Actuator provides a lot of the metrics and monitoring capabilities out of the box for you without much (or any) configuration at all. For instance, you can easily get health checks for your Java Spring Boot app for free without doing much work manually to setup health checks.
12. Setup Docker
By this point you have basically setup most of the things you require for your Java project. Also, it is production ready too. With Spring Boot, you can build an executable runnable jar where you can run on any server that has the JVM installed.
But there is one last step i feel that is required and that is to make your app releasable or more specifically: deployable.
One of the things to do is to package your application up inside a Docker Image where you have the required Operating System (OS) and the Runtime libraries (JVM) for running your Java app baked in. This enables you to run your application as a Docker Container.
Docker allows you to easily build and ship and run your application anywhere (well…, anywhere Docker is supported but practically everywhere supports Container technology like Docker as an Application Platform).
Another added benefit of this is that by using Docker you can ship your container to any environments and can be sure it runs the same. For example, if you were just deploying your app as an executable runnable jar then you can’t be sure it will run the same on different servers (you would need to ensure each environment is the same which can be a pain if you are not careful).
When i setup Docker for my Java applications, i just put in a
Dockerfile that contains the instructions to build the OS + Runtime + bundling the Java app inside it.
Here is an example of a common
Dockerfile i use for nearly all my Java projects:
It is very simple. In fact, it doesn’t need to be that complicated at all. For sure, i would vary accordingly to my needs on a per project basis.
All you really require is to find a base Docker image to base it from and copy your already built Java artifact (
.jar ) to the image plus the command to run your Java
.jar when you spin up a Docker container off from this built Docker image.
So that is it. That is all my steps i normally take to setup a completely new Java project from scratch.
Of course, you will need some additional effort to setup the external systems for integration with your Java project (e.g. CI tool of choice, your centralized logging solution of choice, your metrics and monitoring solution of choice, etc…).
My Checklist Steps:
- Create Your GitHub Repo
- Setup Spring
- Setup Unit Testing
- Setup Integration Testing
- Setup End 2 End Testing
- Setup API Testing
- Setup UI Testing
- Static Code Analysis
- Put in place CI/CD
- Setup Logging
- Setup Metrics and Monitoring
- Setup Docker
Whenever you next setup a new Java project (regardless whether it is a traditional monolithic Java Web Application or a modern Java backend web microservice) make sure to follow these steps in my checklist and in no time you have all the ingredients to have a production ready Java project that is readily deployable and releasable.
It comes with all the required monitoring and logging setup plus the underlying testing application infrastructure that your Developers, Engineers, SDETs, etc can start coding away…