Ever since I published Microservices using Spring Boot, Jersey, Swagger and Docker, I had entertained the idea of making Package the service into a Docker image section its own blog post.
Back then I used Spotify’s docker-maven-plugin, which required connecting to a Docker host. Also felt it would have been almost identical to the section mentioned.
It was nice to learn Google released an open source tool named Jib aimed at easing containerizing Java applications. No need for a
Dockerfile, no need for a Docker daemon, and actually no need for container expertise.
Although you could use Jib to build to a Docker daemon, this post focuses on building a Docker image for Spring Boot applications without requiring a Docker host.
Let’s say your organization is splitting the big monolithic application in multiple, smaller and more specialized microservices. Some of them will interact with a relational database and a message broker while others will communicate with a NoSQL database for instance.
This is a great opportunity to standardize the new deliverables in your company. You might want to develop some custom Spring Boot starters responsable for providing common Java application components, logging, tracing, metrics, monitoring, resilience, RDBMS and APIs implementation support, helping with the application bootstrapping process and reducing common boilerplate code in each Spring Boot-based service.
Once you are using these Spring Boot starters in an application, how would you use them in a new service? Copy and paste and change the artifact ID? Removing unused dependencies? Clean up properties files and Java classes? Although this process works, it involves manual labor which is always tedious and error-prone.
In this guide I describe how to implement and use a custom Maven archetype, which uses a custom Spring Boot starter, integrated in a multi-module Maven setup to automate new projects generation.
1. USING AN AWS S3 BUCKET AS YOUR MAVEN REPOSITORY
An Amazon Web Services S3 bucket is an inexpensive option to store your Maven or other binary artifacts. It’s an alternative to feature-rich Maven repository managers like Nexus and Artifactory when you don’t have the resources to install and maintain a server with the required software or the budget to subscribe to a hosted plan.
One choice I wouldn’t recommend is to store the binary artifacts in the SCM.
This “how to” post covers configuring Maven and setting up an AWS S3 bucket to store deployed Java artifacts.
1. ADDING FEATURE TOGGLES TO SPRING BOOT APPLICATIONS USING TOGGLZ
Features toggles help developers to make smaller, faster and less risky changes to software. Let’s say a requirement that will take a significant amount of effort to complete is going to be implemented. Two popular approaches are:
Branch the source code and develop for the next quarter or so. Once the implementation is completed you might likely face problems merging back this long-lived branch. You might end up asking your peers to stop committing changes or the SCM might get locked for the next 2-3 weeks until all the conflicts are resolved. Possibly delaying bug fixes and new features from being released to clients.
Implement the requirement in trunk / main / master branch, hiding incomplete functionality behind a development or release toogle. This allows the development team to work in the same code base, avoids the complexity of maintaining multiple branches, reduces the release cycle while getting a timely feedback when paired with a CI / CD pipeline.
This tutorial introduces implementing feature flags in Spring Boot applications using Togglz and togglz-spring-boot-starter Spring Boot starter. How to configure and use them, some tradeoffs and a word of caution.
1. IMPLEMENTING AND CONFIGURING SERVLETS, FILTERS AND LISTENERS IN SPRING BOOT APPLICATIONS
Let’s say you find yourself modernizing a legacy Java web application, not just the UI libraries but also the middleware. And let’s say that Spring Boot was the selected framework to get the job done because of its many advantages:
- Allows teams getting started quickly reducing boilerplate code.
- Provides starter projects which extremely reduces Maven configuration, especially dependencies management.
- Production ready actuator endpoints reporting metrics, health check.
- Provides opiniated autoconfiguration out of the box flexible enough to be overriden when needed.
- Seamless integration with the Spring ecosystem.
How can a Filter, a Servlet and a Listener be added to a Spring Boot application now that it lacks the
web.xml file descriptor? This post answers this question also covering injecting dependencies to a Filter, Servlet or Listener.
1. MICROSERVICES SIDECAR PATTERN IMPLEMENTATION USING POSTGRES, SPRING CLOUD NETFLIX AND DOCKER
What’s a Sidecar? A Sidecar is a companion application of the main service, typically non-JVM, either developed in-house or a 3rd party service (eg Elastic Search, Apache Solr, etc.) where it’s desirable for them to take advantage of other infrastructure services such as service registration and discovery, routing, dynamic configuration, monitoring, etc..
This post covers implementing a Sidecar Java application attached to a Postgres database bundled in a Docker image and a Demo client application connecting to the database after retrieving the Postgres metadata (eg host, port) from a Eureka registry.
1. AN ALTERNATIVE APPROACH TO THREADLOCAL USING SPRING
In a blog post published sometime ago, Multitenant applications using Spring Boot JPA Hibernate and Postgres I included some code to set to and to retrieve from, the tenant identifier (a discriminator for selecting its associated datasource) using a ThreadLocal reference:
- A context holder class for holding the tenant data:
- A Spring MVC interceptor (which could have been also done using a servlet filter) to set and clear such tenant identifier:
- And somewhere in the application:
I normally try to avoid using ThreadLocal and would also advise to limit their usage. They can be handy, solve difficult problems but can also introduce memory leaks.
In this post I discuss how to use Spring’s ThreadLocalTargetSource to prevent dealing directly with the dangerous ThreadLocal while practicing dependency injection and proper mocking in unit tests.
1. DISABLING REDIS AUTO-CONFIGURATION IN SPRING BOOT APPLICATIONS
I was recently working on a Spring Boot web application where it was decided to reduce external services dependencies to speedup development, caching using Redis in this specific case.
The interaction between the web application and a Redis server is done using Spring’s RedisTemplate, an implemention of the Template design pattern, used similarly to RestTemplate, JdbcTemplate, JmsTemplate, etc..
A RedisTemplate and related beans are auto-configured by Spring Boot when including spring-boot-starter-data-redis as a dependency for the application. This posts covers some tips to prevent such connection from being auto-configured.
1. ROUTING REQUESTS AND DYNAMICALLY REFRESHING ROUTES USING SPRING CLOUD ZUUL SERVER
Having covered infrastructure services Spring Cloud Config server here with Refreshable Configuration here and Registration and Discovery here with Multi-versioned service support here, in this post I’ll cover the Spring Cloud Netflix Zuul server, another infrastructure service used in a microservice architecture.
Zuul is an edge server that seats between the outside world and the downstream services and can handle cross-cutting concerns like security, geolocation, rate limiting, metering, routing, request / response normalization (encoding, headers, urls). Developed and used by Netflix to handle tens of billions of requests daily, it has also been integrated for Spring Boot / Spring Cloud applications by Pivotal.
A core component of the Zuul server is the Zuul filters, which Zuul provides four types of:
|pre filters||Executed before the request is routed.|
|routing filters||Handles the actual routing of the request.|
|post filters||Executed after the request has been routed.|
|error filters||Executed if an error happens while handling the request.|
This post shows how to configure a Spring Cloud Netflix Zuul server to route requests to a demo downstream service using the provided
routing filter RibbonRoutingFilter and how to dynamically refresh the Zuul routes using Spring Cloud Eureka and Spring Cloud Config servers.
1. FIXING LOGGERFACTORY NOT A LOGBACK LOGGERCONTEXT BUT LOGBACK IS ON THE CLASSPATH, SPRING BOOT-COBERTURA ERROR
A few days ago I was working on a new Spring Boot web application where some dependencies version and common Maven plugins configuration were inherited from a parent pom. Everything was just fine, APIs would work as intended, Unit and Integration Tests were passing except when generating the Cobertura code coverage report. It didn’t matter how minimalist this Spring Boot app could get, code coverage was just failing attempt after attempt.
This posts describes troubleshooting a Spring Boot application and Cobertura dependencies to fix multiple SLF4J bindings - found in the classpath - Failed to load ApplicationContext.