/ Java Programming


5 Java power tools for 2023

I find modern Java really powerful these days but there are always tools to even further kill boilerplate and make Java programming more fun.

Here are the tools I find myself always sneaking in into projects.

1. JsonPath - Json parser for deep hierarchies

https://github.com/json-path/JsonPath

Are you tired of writing Jackson response models for your responses yet?

If you are working with deeply nested JSON structures you get for example with GraphQL responses then you know the pain.

An alternative to modelling the responses as classes is to use JsonPath to pull data from the response.

Say for example we have the following response json:

{
  "records": [
    {
      "department": "Engineering",
      "contact": {
         "name": "John",
         "details": {
            "age": 23,
            "address": {
               "city": "Marbella",
               "country": "Spain"
            }
         }
      }
    },
    ...
  ]
}

Say you now want to list all countries in the records?

Using plain Jackson class models you would probably define a model for root class as RecordsResponse, then further models for a single Record and then the nested Contact, Details and Address. The iterate the list of records using the Stream API to collect all the countries. But that is a lot of boilerplate!

With JsonPath we can do this without all the model boilerplate.

First we fetch the response as a nested Map and then we just use JsonPath to traverse the Map hierarchy to collect the countries.

Here is the same example with JsonPath:

Map<String,Object> response = client.get(..., Map.class);
List<String> countries = JsonPath.read(response, 	"$.records[*].contact.details.address.country")

No boilerplate, much more readable.

2. Lombok - Annotation driven magic

https://github.com/projectlombok/lombok

Love it or hate it, annotation driven development has come here to stay. And with good reason, Lombok is classic which kills more boilerplate code then any tool.

One of the most used examples I use it for is getting rid of boilerplate constructors and getters/setters in  classes.

Here is a short example:

@Slf4j
@RequiredArgsConstructor
class MyService {
    
    @Getter
    private final MyRepository repository;
    
    public doIt() {
        repository.clear();
        log.info("I did it! I am free!")
    }
}

3. Vavr - Super powers for collections

https://www.vavr.io

I love the Java Stream API. It made working with Java collections finally fun.

But Vavr takes it to another level altogether, it adds super powers to the collections!

A  quick example:

List.of(1,2,3,1,4,5,6)
        .distinct() // 1,2,3,4,5,6
        .groupBy(v -> v  % 2) // (1,3,5), (2,4,6)
        .mapValues(Traversable::sum) // (1,9), (0, 12)
        .head() // (1,9)
        .swap() // (9,1)
        ._1() // 9

It is really the missing peace in collection handling. You data buffs will love it!

Check out the user guide for more examples https://docs.vavr.io.

4. Awaitility - Testing async tasks and threads

http://www.awaitility.org

A real power tool when you want to test your code that executes tasks on separate threads.

Lets take this example, let's say that in your Spring Boot application you have the following service method:

@Async("myTaskExecutor")
public void executeBackgroundTask() {
    ... perform some logic ...
}

If you are familiar with this code then you will know that the @Async annotation will instruct Spring Boot to run this code on an thread pool defined by the executor named myTaskExecutor.

Writing a JUnit test for this can be a pain, as you cannot assume that when you call this method that the code is executed immediately as the execution is delayed and put on a queue.  

To solve Awaitility implements a polling framework you can use to check if the code ever executed by checking the code outcomes.

Here is how the code could look like:

  await()
    .atMost(5, SECONDS)
    .until(() -> myCondition == true);

The library is quite powerful and supports quite a lot of use-cases.

The documentation at https://github.com/awaitility/awaitility/wiki/Usage#reusing-conditions is quite good.

5. Spotless Google Java Format Gradle plugin

https://github.com/diffplug/spotless

We all know how hard it is to agree on correct source formatting when working in development teams. Why not just avoid the discussion and use Google best practices for source code and move on with your life?

For this an excellent choice is the Google Java Format library and Gradle plugin!

Just throw it in your project, configure the features you want and let it automatically format your source before you submit your code.

The plugin can be found here https://github.com/diffplug/spotless