In the beginning there was only JVM
The JVM (Java Virtual Machine) is a virtual machine that acts as a runtime engine for running java applications and programs and programs in other languages compiled by Java bytecode. It has two main functions: optimizing program memory and allowing Java programs t run on any OS or device.
In 1995, when Java was released, programmers wrote all computer programs to specific operating systems; thus, it was the software developer’s job to handle memory management. When the JVM was released, it was a breakthrough.
However, JVM applications have a warm-up time, and they do not typically perform well during this time, and this is only made worse by the classes loading at runtime. Java frameworks such as Jakarta EE and Spring have been using classpath reflection and scanning, and this causes even longer startup times. And while this is not an issue with traditional application servers, it is with containers.
Longer startup times make the JVM even less relevant, and this situation is worse in serverless environments. To deal with this, Oracle offers SubstrateVM that allows JVM bytecode to be transformed into a native executable by compiling the bytecode AOT. Because of this, you will need to feed it information available on the JVM at runtime.
The result is that on one side, there is JVM leveraged by frameworks, and on the other side, native executables that need excessive build time and fine-tuned manual configuration.
The latest framework generation, such as Micronaut, aims to find a balance and generate AOT. Micronaut and other such frameworks create extra runtime classes that help avoid classpath scanning during startup time. The idea behind new frameworks like Micronaut is to avail as much code as possible at build time.
Migrating from Spring Boot to Micronaut? Here’s What You Need to Know
Java frameworks, such as Spring Boot and Micronaut, are platforms or bodies of pre-written codes that Java developers use to create java programs and applications. Below is an analysis of Spring Boot and Micronaut to give you a foundational understanding of these two frameworks.
Spring Boot
Spring Boot came as a natural evolution of the Spring Framework and is arguable the most popular Java framework. One reason for its popularity is that it has been on the market for quite some time. It runs on Tomcat by default, and the actuator gives excellent management and monitoring support. Spring Boot also offers a wide array of third-party libraries that cover topics such as service discovery, distributed configuration, and integration.
Annotations are also used extensively in Spring Boot, with no pre-processing happening during the compilation phase. This gives Spring Boot a faster startup time and a bigger memory footprint.
Micronaut
Provided by the Object Computing Company, Micronaut is among the latest Java frameworks. It was built from the ground to support working with serverless functions and microservices. Since it is a cloud-native stack (as advertised by its creators), several aspects of cloud deployment, such as startup, memory footprint, and service discovery, were considered during the design process. Startup times and memory usage are low, as is crucial when working with serverless functions.
The API in Micronaut is similar to the one in Grails and Spring since it is inspired to a great measure by those two frameworks. Micronaut is compatible with Kotlin, Java, and Groovy and can create services based on gRPC, REST, and GraphQL.
Although the migration process from Spring Boot to Micronaut is relatively easy, there are some factors to consider, as listed below.
- Spring Boot offers support for exposing the management interface on a port different from your web application’s. Micronaut does not offer such support.
- The default scope for a Bean in Spring Boot is Singleton, while the default scope for a Bean in Micronaut is Prototype.
Main Differences between Spring Boot and Micronaut
Although Micronaut draws inspiration from Spring, these two frameworks have some distinct differences. Below is a comparative analysis of various attributes between Spring Boot and Micronaut
1. Cloud-enabled
Micronaut describes itself as a framework for cloud-native app development, and it holds to this. It does not depend on third-party cloud services and supports the most popular cloud features by default.
The following cloud-specific features can be found integrated into its runtime directly.
- Client-side load balancing – you can use Netflix Ribbon
- Service discovery – supports Consul, Eureka, and Zookeeper servers
- Distributed tracing and configuration
- Serverless functions
- Kubernetes container
On the other hand, Spring Boot needs third-party cloud libraries or services to support the cloud-specific features discussed above, as it does not support them by default.
2. Security
Spring Boot and Micronaut have different default security mechanisms. The default security mechanisms supported by Micronaut are:
- Authentication provisions and strategies
- Sessions’ authentication
- Security controllers
- Security and IP pattern rules
- Intercept URL Map
The default security mechanisms supported by Spring Boot are:
- OAuth2
- MVC Security
- WebFlux security
- Actuator security.
3. Caching
The following caching providers are supported by Micronaut:
- Redis
- Caffeine (by default)
The following caching providers are supported by Spring Boot:
- Couchbase
- Redis
- Hazelcast
- Caffeine
- JCache
- EhCache 2. x
- Generic
4. Monitoring and Management
Micronaut mainly uses built-in endpoints and creates endpoints to monitor applications; and return details on your application.
Spring Boot also uses endpoints to monitor applications. However, it also uses a few different ways, including:
- Management and monitoring over HTTPS and JMS
- Customizing the management server ports, addresses, and endpoint paths.
- Disabling the HTTP endpoints
- Configuring SSL that are specific to management
5. Application Configurations
In Spring Boot, the properties are defined in application.yml or application.properties. These application files can also be overridden using environmental variables, JNDI attributes, and system properties.
You can use the following property files with Micronaut: application.properties, application.yml, and application.json. However, similar conventions are used to override properties.
Benefits of Migrating
There are several benefits of migrating from Spring Boot to Micronaut, as discussed below.
1. Faster Boot Time
As advertised, the startup time for Spring Boot was 24 seconds, while that of Micronaut was 4 seconds. This makes Micronaut about six times or 600% faster than Spring Boot.
2. Memory Usage
Although this depends to a degree on application usage, Micronaut uses less memory after booting than Spring Boot. While Spring Boot uses about 190MB, Micronaut uses about 160 MB. This makes the memory usage by Micronaut approximately 18% lower.
Initiate the Migration
Because Micronaut took several principles from Spring Boot, migrating to Micronaut is relatively easy.
The process is described below:
Check dependencies -Micronaut mandates adding an embedded server dependency to make an application a web app. The first step is to add the core maven dependencies for Micronaut:
// Spring Boot (pom.xml)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
// Micronaut (pom.xml)
<dependencies>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-http-server-netty</artifactId>
</dependency>
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-inject</artifactId>
</dependency>
</dependencies>
Code language: HTML, XML (xml)
Find correspondences between Spring Boot and Micronaut– Next, determine the Spring Boot starters that you are using and then replace them with the necessary Micronaut dependencies, and replace the annotations for Spring Boot with Micronaut’s. Since bytecode in Micronaut is generated at build-time, we should add an annotation processor during Micronaut compile:
// Spring Boot
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// Micronaut
import io.micronaut.runtime.Micronaut;
public class Application {
public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
}
Code language: JavaScript (javascript)
Fix compilation errors– Replace imports to fix any compilation errors. Spring and Micronaut generally use the same annotation names.
Fix your application. yaml configuration file– Although Spring Boot connects with the default parameters, you will need to configure it explicitly for Micronaut.
// Spring Boot (application.yml)
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: user
password: pass
// Micronaut (application.yml)
datasources:
default:
url: jdbc:mysql://localhost:3306/mydb
username: user
password: pass
Code language: JavaScript (javascript)
Run and test
Conclusions
The most difficult part of migrating from Spring Boot to Micronaut is the slight difference in implicitness. Micronaut offers several advantages over Spring Boot, such as faster booting time and lower memory use immediately after booting. If one knows the conventions gap between the two stacks, migrating is relatively straightforward.