In Micronaut 1.x, Micronaut would attempt to automatically deduce the thread pool to use based on the return type of the controller method.

    This approach caused some confusion and created a false association between reactive types and blocking operations.

    Micronaut 2.x now leaves it up to the user to specify the thread pool to schedule operations on, including blocking operations.

    If you are upgrading from Micronaut 1.x and have a controller that executes blocking I/O operations (such as JDBC or JPA) it is recommended that you add the annotation to execute the blocking operations on a different thread.

    Using @ExecuteOn

    Using @ExecuteOn

    1. import io.micronaut.http.annotation.*
    2. import io.micronaut.scheduling.TaskExecutors
    3. import io.micronaut.scheduling.annotation.ExecuteOn
    4. @Controller("/executeOn/people")
    5. class PersonController {
    6. private final PersonService personService
    7. PersonController(
    8. PersonService personService) {
    9. this.personService = personService
    10. }
    11. @ExecuteOn(TaskExecutors.IO) (1)
    12. Person byName(String name) {
    13. return personService.findByName(name)
    14. }
    15. }

    Using @ExecuteOn

    1. import io.micronaut.http.annotation.*
    2. import io.micronaut.scheduling.TaskExecutors
    3. import io.micronaut.scheduling.annotation.ExecuteOn
    4. @Controller("/executeOn/people")
    5. class PersonController (private val personService: PersonService) {
    6. @Get("/{name}")
    7. @ExecuteOn(TaskExecutors.IO) (1)
    8. fun byName(name: String): Person {
    9. return personService.findByName(name)
    10. }
    11. }

    Micronaut Cache Removed from Core

    The micronaut-runtime module in Micronaut 1.x included support for caching AOP with the @Cache annotation. The core caching library and a default implementation based on caffeine were included.

    If you are using the caffeine backed cache support, you must add a dependency to continue doing so. Add io.micronaut.cache:micronaut-cache-caffeine to your build to maintain the existing functionality. The new caffeine cache module no longer uses the internal shadowed caffeine version and declares its own normal dependency on caffeine. You may need to exclude the transitive dependency in order to prevent conflicts with other versions that may be being pulled in.

    The management endpoint for caches is no longer included by default in the micronaut-management module. If you would like to use the caches endpoint, add a dependency on io.micronaut.cache:micronaut-cache-management.

    Support for RxJava 1.x Removed from Core

    RxJava 1.x support is no longer included in core by default. You can re-enable support by adding the following dependency:

    1. implementation("io.micronaut.rxjava1:micronaut-rxjava1")
    1. <dependency>
    2. <groupId>io.micronaut.rxjava1</groupId>
    3. <artifactId>micronaut-rxjava1</artifactId>
    4. </dependency>

    Support for Reactor Removed from Core

    Reactor support is no longer included in core by default. You can re-enable support by adding the following dependency:

    1. implementation("io.micronaut.reactor:micronaut-reactor")
    1. <dependency>
    2. <groupId>io.micronaut.reactor</groupId>
    3. <artifactId>micronaut-reactor</artifactId>

    Loggers Endpoint Modifications Now Sensitive

    The method on the loggers endpoint to modify logging is now sensitive by default. To revert to the previous behavior, apply the following configuration:

    Server Side Content Negotiation May Require Test Changes

    The new support for server side content negotiation may require changes to tests. For example a test that that makes a call such as:

    1. String result = client.toBlocking().retrieve(
    2. HttpRequest.GET('/test')
    3. .accept("text/plain"), String
    4. )

    If the server implementation does not declare the route as @Produces("text/plain") the request will be rejected with a NOT_ACCEPTABLE HTTP status code.

    Server Filter Ordering

    In Micronaut 1.x almost all built in filters operated on order 0, meaning the order was non deterministic. That caused some compatibility issues with the metrics and security modules. A new class has been added ServerFilterPhase that defines the phases of server filtering and sets an order. Many filters have been updated to now have their order reflect the phase they participate in.

    Heartbeat Events No Longer Published if no Discovery Clients present

    A HeartbeatEvent is no longer published automatically if there are no instances present.

    This behaviour can be changed by setting micronaut.heartbeat.enabled to true explicitly in configuration.

    Several TypeConverters Are No Longer Beans

    Many TypeConverter instances that were previously beans are no longer beans and are deprecated including:

    These should not be injected directly but instead used through the ConversionService API.

    @Executable No Longer Stereotype of @Around

    In Micronaut 1.x the @Executable annotation was a meta-annotation specified on the and @Introduction annotations. This meant that an reference was generated for every usage of AOP advice which consumed additional memory unnecessarily.

    In Micronaut 2.x and above this is no longer the case and if you need an ExecutableMethod generated you should add the annotation to any custom AOP advice you specify otherwise the method will not be available via the BeanDefinition interface (using for example the method).

    The JSR-305 annotations library (com.google.code.findbugs:jsr305) is no longer a dependency (replaced by spotbugs-annotations). If you need this library you will need to add it manually.

    Events Renamed

    The following events were renamed to avoid confusion with other events of similar names:

    New Package for Netty Specific Classes of HTTP Client

    The HTTP client implementation classes including DefaultHttpClient (considered internal in Micronaut 1.x) have been moved to a sub-package called io.micronaut.http.client.netty.

    HTTP Clients No Longer Named Beans

    HTTP clients declared with micronaut.http.services (see Manual Service Discovery Configuration) are no longer named beans in the context and cannot be injected with javax.inject.Named, for example given the configuration:

    Manually configuring services

    1. micronaut:
    2. http:
    3. services:
    4. foo:
    5. urls:
    6. - http://foo1
    7. - http://foo2

    You can no longer inject an HTTP client with @Named("foo"):

    1. @Inject
    2. @Named("foo")
    3. RxHttpClient httpClient;

    Instead you should always use :

    1. @Inject
    2. @Client("foo")
    3. RxHttpClient httpClient;

    Source Retention Annotations No Longer Retained in Runtime Metadata

    In Micronaut 1.x annotations specified as source retention were still retained in the interface. As of Micronaut 2.x this is no longer the case with source retention annotations only available within the compiler APIs.

    If you wish to retain a particular source level annotation when upgrading you can write an AnnotationTransformer that alters the RetentionPolicy of the annotation.

    Iterable Beans No Longer Have An Implicit Primary

    In Micronaut 1.x injecting a single instance of an iterable bean without qualifiers would inject the first bean. An iterable bean is typically anything annotated with @EachProperty or @EachBean. Those beans typically are referenced from configuration. The first bean in this context is the first item in configuration that matches what the annotation expects.

    1. cars:
    2. ford:
    3. cylinders: 8
    4. subaru:
    5. cylinders: 4

    Requesting a single instance of that bean would result in the “ford” instance being injected. Because that behavior is surprising and inconsistent with other types of beans, that is no longer the case and a NonUniqueBeanException will be thrown.

    No Longer Possible to Return Null to Disable a Bean

    It is no longer possible to return null from a bean method to disable the bean. You should now throw DisabledBeanException instead.

    Invalid Configuration File Locations

    Specifying a file with micronaut.config.files, either through the system property or environment variable, that does not exist or cannot be read will now result in the application failing to startup. In previous versions of Micronaut a warning would be logged and the file would be ignored.

    PropertySourceLoader Changes

    Some default interface methods are no longer default and require implementation.

    Deprecation Removal

    Most if not all deprecated classes and methods have been removed.

    In Micronaut 1.x java.util.Map properties being bound from config were inconsistently bound as either a nested or flat. Now maps are bound as nested by default and the @MapFormat annotation’s default value for transformation has been changed to reflect that.

    For example given the config:

    1. persons:
    2. joe:
    3. age: 30
    4. age: 25

    A map property injected via @Property(name ="persons") may have been injected flat or nested depending on a couple factors.

    Flat

    Nested

    1. {"joe": {"age": 30}, "sally": {"age": 25}}

    To bind to a map with flat keys, add the annotation and set the transformation member.

    GraalVM BOM Entry

    The no longer used group for Graal is no longer part of the bom. While upgrading if you depend on Graal you may see Could not find com.oracle.substratevm:svm:.. To resolve the issue, change the dependency group to org.graalvm.nativeimage.

    @Retryable and @CircuitBreaker Exception Handling

    @Retryable and @CircuitBreaker in previous versions of Micronaut resolved includes and excludes explicitly. Any exception thrown had to exactly match one of the exceptions specified. This has been changed to now also include subclasses of the exception types specified.

    MessageSource API Changes

    The semantics of the getMessage method have been changed to also interpolate the message with any provided variables. In previous versions of Micronaut, the raw message was returned from the bundle. To support reading the raw message, a new method getRawMessage has been added.

    In addition, escaping of messages with single quotes is now implemented in accordance with the standard Java class. Messages that contain a single quote will now need escaping in order for the quote to output as it did previously. For example:

    1. my.message=We love Micronaut's documentation

    Would now be output as We love Micronauts documentation. To achieve the desired result, escape the single quote with another single quote.

    1. my.message=We love Micronaut''s documentation

    Environment Order Bugfix

    Environments specified through the application context builder have priority over environments deduced or supplied through the MICRONAUT_ENVIRONMENTS environment variable, or the equivalent system property. A bug in the logic however did not change the order of a specified environment if it previously was found or deduced. This issue manifested itself with @MicronautTest(environments = "test"). The test environment is already deduced for tests, so it retained the order of other deduced environments, and was able to be overriden by MICRONAUT_ENVIRONMENTS=dev. In Micronaut 1.x configuration for dev would have overridden test. In Micronaut 2.x test will override dev.

    Introspections and Inner Classes

    A bug in Micronaut 1.x caused bean introspections to be generated for inner classes of classes annotated with @Introspected. That also applies to classes where @Introspection is a meta annotation, like @Entity. This may have an impact for GraalVM users that rely on accesses to those classes without using reflection. For example:

    1. @Entity
    2. public class Pet {
    3. ...
    4. private PetType type = PetType.DOG;
    5. // getters & setters
    6. public enum PetType {
    7. DOG,
    8. CAT
    9. }
    10. }

    Previously a bean introspection would have been generated for PetType. That is no longer the case. If the type should be introspected, simply add the annotation.

    Executable Methods

    A bug in Micronaut 1.x caused bean definitions to be created for classes that only declared executable annotations on one or more methods. Classes with executable methods must now be explicitly declared as a bean with a scope annotation in order for a bean definition to be created.

    Super interfaces No Longer Searched for Fallbacks

    If the @Fallback annotation is used to specify a fallback for a interface, the super interfaces of the client will no longer be traversed to lookup the fallback to invoke.

    In this case it may be necessary to specify the api member of the @Recoverable annotation to ensure the fallback can be looked up. For example:

    Specifying the api to recover from

    1. @Client("/Books")
    2. @Recoverable(api = BookApi)
    3. interface BookClient extends BookApi {
    4. @Override
    5. Book get(Long id);
    6. }

    AWS FunctionClient Moved to AWS Module

    The AWS based function client has been made part of the Micronaut AWS project. If you need this functionality add the following dependency:

      LogLevel Enum Moved to io.micronaut.logging

      io.micronaut.management.endpoint.loggers.LogLevel enum has moved to package