The advantages of the monolith

Introduction

There are various possible ‘architectures’ to use in your application. Monoliths, micro-services and self-contained systems to name a few. When something is a hype, one can easily forget that there is no silver bullet, that we should use the best solution for your problem.

And these days, a lot of people forget that monoliths are powerful when used correctly, in certain use cases.

So let’s have a look at the simplicity, easy integration and consistency aspects of the monolith.

Simplicity

Monoliths are simple in structure. You just have 1 code source repository which is compiled and packaged in one command to produce your single artifact which you need to deploy.

So for a new team member, getting up and running is easily and fast. Get the link to the source code, download and package it and run it on the local machine. Even if you need an application server, it can be simple as executing a script which sets it up correctly.

This in contrast with micro-services for instance. You have several code repositories, different packaging systems because you have different development languages and frameworks, additional instances for the configuration service, API gateway, the discovery service and so one.

Easy / fast integration

In a bigger monolith, the integration between different parts is easy and efficient.

Since everything is running within the same JVM integration is as simple as calling another java method. There is no need that the data is converted to JSON for example. So it is faster and you have no pitfalls with the conversion which can happen in some corner cases.

And since everything is running in the same process, you don’t have to take into account the fallacies of the distributed computing. Which is forgotten by the developers anyway. So no issues with network failures, latency, bandwidth latency, changing topology and all those pitfalls which arise when your application is distributed between different machines.

Consistent

The consistency of your UI is very important for your end user. Each screen must be built in a similar manner with the same look and feel and layout. When the different parts of your application looks differently or behave differently, it is for the end user much more difficult to use it and makes it inefficient (and probably he will no longer use it)

With your monolith, you are using a single code language and the same framework for generating the UI. So with a bit of discipline of the developer (and a good UI/UX design), it is fairly easy to create uniform screens.

In the case of micro-services where you have maybe different frameworks for the UI for different parts of the application, it will be very difficult to achieve this uniformity.

Or even worse, you built a giant monolithic SPA on top of your fine-grained micro-services which breaks an important concept of the architectural vision, the independently deployable artifacts.

Monolith as the start

Since it is so easy to get started with a monolith, every application should begin as a monolith. You have your first production artifact ready much faster.

In the following phases, you can gradually split it up and evolve into a distributed system if your use cases mandate it.

Just be aware of your package structure within the monolith application. Make sure there is already a clean separation so that the extraction of the different pieces can be smooth.

Conclusion

The advantages of the monolith are often forgotten these days. However, it has all the features that can give you a quick first success with your application. And the time to market is in many cases shorter due to its simplicity and easy integration. And if you carefully pay attention to the structure of your code, you can even create large monolith successfully.

Have fun.

First release of Atbash Configuration project

Introduction

Although configuration is important and essential in any application, there is no real standardization available today.

There were several attempts to create a standard around it so that each application could read his parameters in a consistent way. But as of today, there is no final standardization, nor within Java SE, not within Java EE.

Since it is so important, The Eclipse MicroProfile project created a specification for reading parameters in their Micro-services architecture. And it was almost the first thing they did (which highlights the importance they gave it). That work is now continued under the wings of the JCP (as JSR-382) so that it can become a real standard within Java SE and Java EE.

Instead of using other frameworks and libraries which have support for reading configuration, I wanted to switch to the MicroProfile Config project. Because I wanted to be prepared for the feature but encountered a few issues.

Short version

Adapted the code of MicroProfile Config API and Apache Geronimo config to Java 7 and added my own extensions which compose Atbash Config.

The Maven artefacts are available on Maven Central and the user manual is here.

My issues with MicroProfile Config project

Issue is a heavy term, my requirements are not (yet) available within the Config project but the good thing is that they are planned within the JCP specification work.

I want to read configuration parameters

  1. With Java 7
  2. For any Java EE project, not limited to Eclipse MicroProfile applications.
  3. Use single artefact which contains the configuration parameters for different environments embedded in it (within different files)
  4. Use YAML structured configuration files.

And that is not possible for the moment because

  • The MicroProfile Config project is build using Java 8 code structures. So it is not possible to run it in a Java 7 environment.
  • The Apache Geronimo Configuration project implements the API and is a very good candidate to use in my Java EE programs. Because it is created as a standalone project (not as part of a server like other implementation such as Payara, KumuluzEE, WebSphere Liberty or others) and thus you can add this dependency to any Java EE application. But configuration file name is still related to MicroProfile (/META-INF/microprofile-config.properties).
  • MicroProfile Config project has support for overruling properties by specifying them in the environment or as JVM system parameters. But there is no feature to define multiple files nor the ability to define multiple files within the artefact for each environment.
  • Only properties files are supported. And when you have larger projects, it can be handy to use a YAML structure so that it is more clear which properties are closely related.

Solution

Adapt MicroProfile Config API and Apache Geronimo Configuration.

Except for the first issue, support for Java 7, my own configuration extension could be a solution for my requirements. So I had no other choice than to copy the code and adapt it. And although the code is licensed under the Apache OpenSource license (which allows me to do this) it doesn’t feel right. So I want to thank explicitly all those committers that created the code for their wonderful work and I also made explicitly a reference within the notice file and documentation.

Atbash configuration extension

The extension consist of a custom implementation of the ConfigSource interface. That way I’m able to register another source for reading configuration parameters and fulfill my other 3 requirements.

– Implement the BaseConfigurationName interface and define the class also for the ServiceLoader mechanism. Now I’m able to use any filename like demo.properties or demo.yaml when the value demo is specified as the base name.
– By specifying the environment with the JVM system parameter -S, I can add a prefix to the filename and supply additional or override parameters for a certain environment
– YAML file support is implemented with the use of Snakeyaml where the file is converted to key-value pairs.

For more information, you can read the manual.

Getting started

There are 3 ways how you can use the Maven artefacts

1. Use plain MicroProfile config with Java 7.

Add the adapted Geronimo config code to your project

<dependency>
   <groupId>be.atbash.config</groupId>
   <artifactId>geronimo-config</artifactId>
   <version>0.9</version>
</dependency>

2. Use the Atbash configuration extension with Java 7

You need the Geronimo config and atbash config project

<dependency>
   <groupId>be.atbash.config</groupId>
   <artifactId>geronimo-config</artifactId>
   <version>0.9</version>
</dependency>

<dependency>
   <groupId>be.atbash.config</groupId>
   <artifactId>atbash-config</artifactId>
   <version>0.9</version>
</dependency>

3. Use the Atbash configuration extension with Java 8

In this scenario, you don’t need the adapted code and can use the regular implementations

<dependency>
   <groupId>org.apache.geronimo.config</groupId>
   <artifactId>geronimo-config-impl</artifactId>
   <version>1.0</version>
</dependency>

<dependency>
   <groupId>be.atbash.config</groupId>
   <artifactId>atbash-config</artifactId>
   <version>0.9</version>
   <exclusions>
      <exclusion>
         <groupId>be.atbash.config</groupId>
         <artifactId>microprofile-config-api</artifactId>
      </exclusion>
   </exclusions>
</dependency>

Conclusion

MicroProfile Config is the first real standardization around reading parameters for configuration. They have built their implementations on top of Java 8.

So when you need a general usable library with Java EE 7 (which is using Java 7 as a base version), you can use the Atbash config code (adapted from the MicroProfile Config API and Apache Geronimo config as implementation) which has a few handy extensions.

This makes you future proof at the time JSR-382 will be adopted by the different application servers.

Thank you for reading until the bottom of this blog entry and have ave fun.