I am recursively getting below error when it's going to init the bean extends from MicronautRequestHandler
. But it's not the case for other regular beans.
My simplified version of the Handler class as below : (I removed all the injected services as well to simplify)
package org.example;
import com.amazonaws.services.lambda.runtime.events.S3Event;
import io.micronaut.function.aws.MicronautRequestHandler;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
@Singleton
public class Handler extends MicronautRequestHandler<S3Event, Void> {
@Inject
public Handler() {
// NOP
}
@Override
public Void execute(S3Event input) {
System.out.println("Received S3 event: " + input);
return null;
}
}
To re-create this locally without Lambda, I created this main method. This is the minimal version of the main LocalRunner class, which still cause the issue.
package org.example;
import io.micronaut.context.ApplicationContext;
public class LocalRunner {
public static void main(String[] args) {
// Start the Micronaut application context
try (ApplicationContext context = ApplicationContext.run()) {
// Instantiate your handler class
Handler handler = context.getBean(Handler.class);
}
}
}
I am getting the same error when it deploy to Lambda and trigger with a S3Event
.
My build gradle file:
plugins {
id("application")
}
version = "0.1"
group = "org.example"
repositories {
mavenCentral()
maven { url "https://s01.oss.sonatype.org/content/repositories/releases/" }
}
dependencies {
annotationProcessor("io.micronaut:micronaut-http-validation:3.10.0")
annotationProcessor("io.micronaut:micronaut-inject-java:3.10.0")
implementation('io.micronaut.aws:micronaut-function-aws:3.18.0')
implementation("io.micronaut:micronaut-inject:3.10.0")
implementation("io.micronaut:micronaut-http-server-netty:3.10.0")
implementation("io.micronaut:micronaut-json-core:3.10.0")
implementation("io.micronaut:micronaut-jackson-databind:3.10.0")
implementation("jakarta.inject:jakarta.inject-api:2.0.1")
implementation("com.amazonaws:aws-lambda-java-events:3.11.0")
implementation("software.amazon.awssdk:s3:2.29.0")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.16.0")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.0")
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
implementation 'org.slf4j:slf4j-api:1.2.13'
//https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl
runtimeOnly("org.apache.logging.log4j:log4j-to-slf4j:2.18.0")
//JDBC
implementation 'com.amazon.redshift:redshift-jdbc42:2.1.0.9'
implementation 'commons-dbcp:commons-dbcp:1.4'
}
configurations {
all*.exclude group: 'ch.qos.logback'
all*.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j'
}
java {
sourceCompatibility = JavaVersion.toVersion("17")
targetCompatibility = JavaVersion.toVersion("17")
}
piece of the error log (repeating it many times):
Path Taken: new Handler()
... 1024 more
Caused by: io.micronaut.context.exceptions.BeanInstantiationException: Bean
definition [org.example.Handler] could not be loaded:
//...
at org.example.Handler.<init>(Handler.java:12)
at org.example.$Handler$Definition.build(Unknown Source)
at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2354)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2305)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2251)
at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3016)
at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:80)
at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2918)
at io.micronaut.context.DefaultBeanContext.loadContextScopeBean(DefaultBeanContext.java:2746)
at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1915)
at io.micronaut.context.DefaultApplicationContext.initializeContext(DefaultApplicationContext.java:249)
at io.micronaut.context.DefaultBeanContext.readAllBeanDefinitionClasses(DefaultBeanContext.java:3326)
at io.micronaut.context.DefaultBeanContext.finalizeConfiguration(DefaultBeanContext.java:3684)
at io.micronaut.context.DefaultBeanContext.start(DefaultBeanContext.java:341)
at io.micronaut.context.DefaultApplicationContext.start(DefaultApplicationContext.java:194)
at io.micronaut.function.executor.AbstractExecutor.startEnvironment(AbstractExecutor.java:124)
at io.micronaut.function.aws.MicronautRequestHandler.buildApplicationContext(MicronautRequestHandler.java:222)
at io.micronaut.function.aws.MicronautRequestHandler.<init>(MicronautRequestHandler.java:108)
at org.example.Handler.<init>(Handler.java:12)
at org.example.$Handler$Definition.build(Unknown Source)
at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2354)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2305)
at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2251)
at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3016)
at io.micronaut.context.SingletonScope.getOrCreate(SingletonScope.java:80)
at io.micronaut.context.DefaultBeanContext.findOrCreateSingletonBeanRegistration(DefaultBeanContext.java:2918)
at io.micronaut.context.DefaultBeanContext.loadContextScopeBean(DefaultBeanContext.java:2746)
at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1915)
at io.micronaut.context.DefaultApplicationContext.initializeContext(DefaultApplicationContext.java:249)
at io.micronaut.context.DefaultBeanContext.readAllBeanDefinitionClasses(DefaultBeanContext.java:3326)
at io.micronaut.context.DefaultBeanContext.finalizeConfiguration(DefaultBeanContext.java:3684)
at io.micronaut.context.DefaultBeanContext.start(DefaultBeanContext.java:341)
at io.micronaut.context.DefaultApplicationContext.start(DefaultApplicationContext.java:194)
at io.micronaut.function.executor.AbstractExecutor.startEnvironment(AbstractExecutor.java:124)
at io.micronaut.function.aws.MicronautRequestHandler.buildApplicationContext(MicronautRequestHandler.java:222)
at io.micronaut.function.aws.MicronautRequestHandler.<init>(MicronautRequestHandler.java:108)
at org.example.Handler.<init>(Handler.java:12)
resolveByBeanFactory()
is trying again to initialize the constructor , so it's recursively go in the circle.
UPDATE
I was able to re-create the issue with a fresh IntelliJ-Micronaut default project (Java 17, Micronaut 4.4.2) with 3 simple steps.
implementation('io.micronaut.aws:micronaut-function-aws')
implementation("com.amazonaws:aws-lambda-java-events:3.11.0")
Application.java
after Micronaut.runpublic class Application {
public static void main(String[] args) {
Micronaut.run(Application.class, args);
try (ApplicationContext context = ApplicationContext.run()) {
Handler handler = context.getBean(Handler.class);
}
}
}
I finally found the issue. A tiny little mistake cause this all :-(
Never Use @Singleton
on the Lambda Handler class!
Here’s why:
In Micronaut, @Singleton registers the class as a bean in the application context, which works well for services and other components. However, the Lambda Handler class (which extends MicronautRequestHandler here) shouldn’t be a singleton, as it is treated differently from other beans. Using @Singleton on the handler can lead to initialization issues and cause dependency injection to fail.
Solution:
Simply remove the @Singleton annotation from your handler class, and let Micronaut handle it as a Lambda function rather than as an application bean.