Nginx gzip compression and load balancing.

To tune performance of my REST endpoints in past I have enabled Gzip compression in my nginx server configuration. So technically a large json response becomes gzipped and the network latency as a result goes down.

There is a good documentation of this feature on the nginx website which does a pretty good job.

However there is a catch which prevents this technique from working on local development system (while the same config works in production linux instance). I finally found an answer as to why this doesn’t work in some of my local environment.

To do static load balancing I use the upstream concept of nginx which is documented again on the nginx website. The performance is reasonable and the implementation is quite simple for a requirement which needs a simple failover implementation. However for advanced implementation we can always go to haproxy which is very good open source load balancer.

Issues Faced While Upgrading to JDK 11 and Spring Boot 2.2.5

I had a old project which was running on JDK 8 and Spring Boot 1.5.x which I just upgraded to JDK 11 and Spring Boot 2.2.5. I faced some hiccups in the process but it is finally done and the application is up and running. I will be documenting some of the issues faced in this process.

Spring Data
All instances of findOne() had to be replaced with findByID() which returns Optional<Entity> reference. I ended up removing lots of null checks by leveraging the Optional features of “orElse”, “orThrow” and “ifPresent” methods provided by Optional interface. It definitely is a better way to handle null.

JAXB runtime error
After migration the application booted up fine but on doing some specific operation I observed this error on console

java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter

It seems this class has been moved out of the core library in JDK. This error kind of stumped me as some posts on internet suggested adding the following entry in pom.xml

<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
<scope>runtime</scope>
</dependency>

However this didn’t help and I ended up using the following library to finally get rid of this issue:

<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>

Apache POI / Tika Library
This is another runtime issue faced during this application operation.

WARNING: An illegal reflective access operation has occurred
 WARNING: Illegal reflective access by org.apache.poi.openxml4j.util.ZipSecureFile$1 (file:/Users/562320/.m2/repository/org/apache/tika/tika-app/1.15/tika-app-1.15.jar) to field java.io.FilterInputStream.in
 WARNING: Please consider reporting this to the maintainers of org.apache.poi.openxml4j.util.ZipSecureFile$1
 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
 WARNING: All illegal access operations will be denied in a future release
 Jun 29, 2020 3:14:17 AM org.apache.catalina.core.StandardWrapperValve invoke
 SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Fail to save: an error occurs while saving the package : class org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream cannot be cast to class java.util.zip.ZipFile$ZipFileInputStream (org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream is in unnamed module of loader 'app'; java.util.zip.ZipFile$ZipFileInputStream is in module java.base of loader 'bootstrap')] with root cause
 java.lang.ClassCastException: class org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream cannot be cast to class java.util.zip.ZipFile$ZipFileInputStream (org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream is in unnamed module of loader 'app'; java.util.zip.ZipFile$ZipFileInputStream is in module java.base of loader 'bootstrap')
     at java.base/java.util.zip.ZipFile$ZipFileInflaterInputStream.available(ZipFile.java:480)

This issue got resolved after upgrading the Apache Tika, Apache POI to latest version. I also had to upgrade the apache-commons-lang package to apache-commons-lang3 package.

Progress Bar implementation in Java for Terminal application

Th e”\r” character basically reverts the current cursor back to the 1st column in the current line. This concept should basically work on Mac, Linux and Windows. So to test it I wrote a quick hack and it worked properly:

public class ProgressBar {

    public static void main(String[] args) {
        int size = 10;
        for (int i=1; i<size; i++) {
            try {
                Thread.sleep(500);
                System.out.print("|" + "=".repeat(i) + ">" + " ".repeat(size-i) + "|\r");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.print("|" + "=".repeat(size) + "|\r");
    }
}

// Initial Output
// |=>        |
// Final Output
// |==========|

I got the desired output and a humble do nothing progress bar did come up on terminal. To further this idea I did some internet search and I ended up finding this repo on GitHub. It basically allows you to implement beautiful progress bars for terminal based Java application. The basic concept is the same but it provides much more functionality.

Block a shell script till a server boots up

This small script blocks a shell script / docker compose command script till a dependent server boots up.

#!/usr/bin/env bash

while :
do
  response=$(curl --write-out %{http_code} --silent --output /dev/null -X GET "$1")
  if [[ "$response" -ne 200 ]] ; then
    echo "Server is not yet up >> $1 >> $response"
    sleep 1
  else
    echo "Server is up >> $1 >> $response"
    exit 1
  fi
done

Spring Cloud Configuration Issue

For a new project I was trying to setup a config server to connect my services together. Although the spring-cloud-config server works fine, I am not able to make my service talk to the config-server which is really strange as I am fairly well versed with Spring Cloud and usually setting up a dev environment is a no-brainer.

I have described my issue in stackoverflow to get help and I am debugging in parallel as well.

Bye Bye Hystrix

Hystrix used to be my tool of choice for implementing circuit breakers in my Spring Boot application. However there has been literally no commits in Hystrix github repo for past 1 year. It seems Netflix has moved on to resilience4j which will be actively maintained.

Resilience4j commit log is quite active and a lot of active work is going on in it.

However it should be noted that there is another mature library named Sentinel which seems to be quite feature rich and very well supported. It has been battle tested by Alibaba which is huge. In my next project I would be considering both Sentinel and Resilience4J in my choice for a reliable circuit breaker for my application.

Taking backup zip from multi-module Java project

I like to keep an archive of my code on a monthly basis. I wrote a small bash script to create zip out of my multi module Java projects. It gets the job done and can be improved to include resources and test folders as well. As of now I am only interested in the Java code zip backup.

!/bin/bash
 if [ -d "combined" ]; then
     echo "Removing existing zip files in combined .."
     rm combined/*.zip
 else
     echo "Creating combined folder.."
     mkdir combined
 fi
 for d in */ ; do
     if [ -d "$d/src/main/java" ]; then
         var="$(echo $d | sed 's/.$//')"
         echo "Processing $var .."
         cd $d/src/main/java
         zip -r ../../../../combined/$var.zip com
         cd ../../../..
     else
         echo "Ignoring .. $d"
     fi
 done