Upgrade from Quarkus 1.2.1 to 1.4.1

Stormy Clouds – Coimbra, PT by myself.

Background

Sometimes it’s not easy to find time to update libraries. Quarkus fast pace, requires frequent attention and upgrades. You should allocate time for that…

This particular upgrade was triggered by a Quartz integration bug, which was quickly fixed, btw. By now, 1.5.1 is already out with less pain than the 1.3.x series, where most of the described issues came from. This post tells you the upgrade adventures and I hope it’s useful to you.

Changes

Tests

On Quarkus 1.3.0 the classloading was totally re-implemented, fixing some test issues. Unfortunately some problems were introduced on test scenarios using Mockito and other JUnit 5 extensions. One easy fix was just not to use the JUnit extension and make de setup using the @BeforeAll and @AfterAll hooks. The Quarkus team, in the meantime, has been creating a few integrations to tackle this problem. One of them is this quarkus mockito extension:

 <dependency>
     <groupId>io.quarkus</groupId>
     <artifactId>quarkus-junit5-mockito</artifactId>
     <scope>test</scope>
 </dependency>

You will be able to use @InjectMock instead of @Mock on integration tests. No need for @InjectMocks. You should remove mockito-core dependency, it comes included. Please take a look at this help page for more.

New way to inject MP REST clients on tests:

@InjectMock 
@RestClient 
WonderfulClient wonderfulClient;

The MicroProfile REST client definition must also be annotated with @ApplicationScoped.

JWT

The smallrye-jwt upgrade broke property compatibility. You cannot define multiple Algorithms anymore and your authentication might start to fail.

Use new for runtime code:

smallrye.jwt.verify.algorithm=RS256 #Instead of:

smallrye.jwt.whitelist.algorithms=RS256,...

Check this page for the current details.

Docker

  • There was this Quarkus bug affecting our docker images. Build worked locally, but failed inside the docker container because the path is simply /app and when trying to search for the parent pom.xml, we get a null pointer exception. Should have been fixed on version 1.5.0 already.
  • You must use Maven 3.6.2+. Please update your docker base images.

Datasources

Use the new properties for datasources that are not backwards compatible:

quarkus.datasource.db-kind=postgresql #Mandatory! 

quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/my_db?current_schema=public

The db-kind property from above will autodetect the driver. It’s not mandatory to use the driver property any longer.

The URL property has changed as well. They’ve done this to support multiple datasources and reactive drivers.

Additional notes

  • Use localhost instead of 0.0.0.0 for local addresses.
  • If you use Quarkus-Camel, please upgrade to 1.0.0-M6

Hope this was useful to you!

TomEE vs SpringBoot vs Quarkus

moinhos.jpg

 

There’s a new framework in the Java world. Quarkus. I’ve decided to compare how it behaves in relation to Apache TomEE and Spring Boot. I’m going to measure artefacts size, compilation, test and deploy times while using Java 8 and Maven.

To compare the frameworks I will create an application with a realistic set of features. It will use REST endpoints, Fault Tolerance and an in memory database with JPA. The source code is available on Github at the java-framework-compare project.

The starting point for each of the subprojects:

The Apache TomEE 8.0.0-M2 Microprofile flavour comes from the MicroProfile Starter by selecting Config and Fault Tolerance APIs.

The Spring Boot 2.1.3 application comes from the Spring Initializr page by adding web, jpa and H2 dependencies.

The Quarkus 0.11.0 app starting point is humbler. It comes from the rest-json example bundled in the quarkus-quickstarts bundle.

The baseline

All starter projects have different bundled dependencies. Just for curiosity these are the sizes, build and startup times out of the box, without an application running:

Platform Build Time (s) Start Time (s) Size (MB)
Apache TomEE 8.0.0-M2 5,454 3,789 44
Spring-boot 2.1.3 2,248 2,936 16,7
Quarkus 0.11.0 1,890 0,623 10,5

This is important to later evaluate the impact of our changes to the baseline, in a  realistic project.

The application

To start, I used the implementation coming from the Quarkus rest-json quick-start example. This bundles a set of tests and rest endpoints I was able to successfully port to SpringBoot and TomEE.

The Integration tests are using RestAssured and JUnit 5 Jupiter and are equivalent across the 3 projects. They needed some tweaks on SpringBoot. Getting the random port and configuring the RestAssured serialization was not obvious.

On TomEE I had to use JUnit 4 because Arquillian, the integration test framework commonly used there, does not support JUnit 5 yet.

I’ve added Timeout and Fallback Fault tolerance features to a method. On both Quarkus and TomEE using MicroProfile and to SpringBoot using Netflix’s Hystrix. Hystrix, commonly used in SpringBoot is on maintenance mode I’m not aware of a replacement on the Spring side. As a comparison, the Microprofile Spec has added support for CompletionStage and will be doing work around reactive code soon.

I tried to use JPA with H2 database but couldn’t make it in Quarkus so I also dropped it in the others but kept all dependencies. The documentation is still sketchy and I need more research time.

 

Conclusions

Platform Build Time (s) Build Time with tests (s) Start Time (s) Size (MB)
Apache TomEE 8.0.0-M2 6,178 15,304 4,993 44
Spring-boot 2.1.3 3,358 13,348 6,799 46,9
Quarkus 0.11.0 2,533 7,153 0,767 23.4

It looks like build time without tests increased by ~1s in all projects.

The build with tests with Quarkus takes half the time from the other 2. Artefact size is also half of the other two. Start time is almost one order of magnitude bellow. This is very significant. Please note that this start time can be further reduced by using native code with GraalVM.

SpringBoot startup time and uber war size increase very significantly (>2x) when you add real functionality to it.

TomEE starts faster than SpringBoot and the uber jar size is very stable for this use case. No Change.

The online resources on Quarkus are rare if compared with TomEE or SpringBoot leading to a lot of trial and error.

 

Further work

Make JPA with H2 work and measure the performance impact.

Add docker and kubernets and measure deployment times in the cloud.

Generate native artefacts for Quarkus and measure the effect.

 

Tech notes

Build time is calculated as the average of 3 consecutive executions of the base project using “mvn clean install -DskipTests

Start time is calculated as the average of 3 consecutive executions of the generated uber jar/war. In the case of Quarkus it’s the runner+lib folder. Example: “java -jar target/spring-boot-0.0.1-SNAPSHOT.war

The size is of the generated uber jar/war. In the case of Quakus it’s the runner+lib folder.

All this was executed on a Lenovo Thinkpad T460 with an Intel I7, 32GB ram and 1/3 empty 512GB SSD.

Photo taken on Saturday near Penacova, Portugal

New Blog hosting

IMG_2223Decided to move my blog from Tumblr to WordPress.com and revive it a bit.

Yeah, I know, Tumblr was never the tech enthusiast platform. Currently it was getting on my nerves for overriding all links with tracking redirects. Not cool.

I’ve added summaries for the posts I published at Tomitribe.com/blog and linked to them. I haven’t transferred my old posts in Portuguese, though. They can be found in the old blog here.

Photo from Figueira da Foz, Portugal a few days ago.