micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.09k stars 1.07k forks source link

Document function dependency injection #4284

Open ilopmar opened 4 years ago

ilopmar commented 4 years ago

I've created a Micronaut function:

mn create-function-app demo --features aws-lambda --test spock --jdk 11

Without modifying anything it is possible to deploy the current code on AWS Lambda and call the function. Package with ./gradlew shadowJar, create the AWS Lambda function and set the handler to demo.BookRequestHandler:

issue-03

issue-04

Now, I've created a service:

@Singleton
public class HelloService {

    public String hello() {
        return "Hello World!";
    }
}

And modified the provided BookRequestHandler class

//@Introspected
@Singleton
public class BookRequestHandler extends MicronautRequestHandler<Book, BookSaved> {

    @Inject
    HelloService helloService;

    @Override
    public BookSaved execute(Book input) {
        BookSaved bookSaved = new BookSaved();
        bookSaved.setName(helloService.hello());
//        bookSaved.setName(input.getName());
        bookSaved.setIsbn(UUID.randomUUID().toString());
        return bookSaved;
    }
}

When deploying again the app in AWS Lambda and sending the same request as before, it now fails:

issue-05

I've discovered that it also fails just running the test (that works with the provided code)

Steps to Reproduce

The test fails

Expected Behaviour

The test should pass

Actual Behaviour

The test fails:

12:48:53.520 [Test worker] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [function, lambda]

Bean definition [demo.BookRequestHandler] could not be loaded: failed to access class io.micronaut.function.executor.AbstractExecutor from class demo.$BookRequestHandlerDefinition (io.micronaut.function.executor.AbstractExecutor and demo.$BookRequestHandlerDefinition are in unnamed module of loader 'app')
io.micronaut.context.exceptions.BeanInstantiationException: Bean definition [demo.BookRequestHandler] could not be loaded: failed to access class io.micronaut.function.executor.AbstractExecutor from class demo.$BookRequestHandlerDefinition (io.micronaut.function.executor.AbstractExecutor and demo.$BookRequestHandlerDefinition are in unnamed module of loader 'app')
    at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1535)
    at io.micronaut.context.DefaultApplicationContext.initializeContext(DefaultApplicationContext.java:220)
    at io.micronaut.context.DefaultBeanContext.readAllBeanDefinitionClasses(DefaultBeanContext.java:2780)
    at io.micronaut.context.DefaultBeanContext.start(DefaultBeanContext.java:233)
    at io.micronaut.context.DefaultApplicationContext.start(DefaultApplicationContext.java:166)
    at io.micronaut.function.executor.AbstractExecutor.startEnvironment(AbstractExecutor.java:125)
    at io.micronaut.function.aws.MicronautRequestHandler.buildApplicationContext(MicronautRequestHandler.java:85)
    at io.micronaut.function.aws.MicronautRequestHandler.<init>(MicronautRequestHandler.java:48)
    at demo.BookRequestHandler.<init>(BookRequestHandler.java:11)
    at demo.BookRequestHandlerTest.setupServer(BookRequestHandlerTest.java:14)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeAllMethod(TimeoutExtension.java:68)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods$9(ClassBasedTestDescriptor.java:384)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:382)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:196)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:133)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalAccessError: failed to access class io.micronaut.function.executor.AbstractExecutor from class demo.$BookRequestHandlerDefinition (io.micronaut.function.executor.AbstractExecutor and demo.$BookRequestHandlerDefinition are in unnamed module of loader 'app')
    at demo.$BookRequestHandlerDefinition.<init>(Unknown Source)
    at demo.$BookRequestHandlerDefinition.<init>(Unknown Source)
    at demo.$BookRequestHandlerDefinitionClass.load(Unknown Source)
    at io.micronaut.context.AbstractBeanDefinitionReference.load(AbstractBeanDefinitionReference.java:62)
    at io.micronaut.context.DefaultBeanContext.loadContextScopeBean(DefaultBeanContext.java:2158)
    at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1533)
    ... 87 more

BookRequestHandlerTest > initializationError FAILED
    io.micronaut.context.exceptions.BeanInstantiationException at BookRequestHandlerTest.java:14
        Caused by: java.lang.IllegalAccessError at BookRequestHandlerTest.java:14
1 test completed, 1 failed

More info

This issues seems similar (although not exactly the same) to https://github.com/micronaut-projects/micronaut-core/issues/2789 that was fixed in Micronaut 1.3.1.

Environment Information

Example Application

https://github.com/micronaut-core-issues-test-app/function-dependency-injection

ilopmar commented 4 years ago

If I inject a Micronaut HTTP Client it works.

See https://github.com/micronaut-graal-tests/micronaut-function-aws-graal/blob/7e3c8ecd7a734f827d8c8d185ec8f790d3ae7fd2/src/main/java/example/micronaut/JokeRequestHandler.java#L11 and the test https://github.com/micronaut-graal-tests/micronaut-function-aws-graal/blob/7e3c8ecd7a734f827d8c8d185ec8f790d3ae7fd2/src/test/java/example/micronaut/JokeRequestHandlerTest.java.

It doesn't make sense because in the test we do a new JokeRequestHandler(), so how does dependency injection works in this case in JokeRequestHandler class? :thinking:

Please keep in mind that even though that app is using Micronaut 2.1.0 it's not using the new Gradle plugin (although that probably won't change anything).

rp199 commented 4 years ago

Is there any specific reason to add the singleton annotation to the BookRequestHandler class? I implemented something very similar to your example and manage to get it to work but I don't use that annotation on the handler class, just on the service one. The rest is basically the same.

Tested on my project to add the annotation like yours and got the same error. Can you test to remove it?

Manage to get several singletons to be injected into my handler. An issue that I've encountered was when I tried to build a multi module project... On my local test class, the injection works but when I deploy it, the lambda fails with the following error:

Failed to inject value for field [orderService] of class: com.xxxxx.xxxx.lambda.OrderLambdaHandler

Path Taken: OrderLambdaHandler.orderService: io.micronaut.context.exceptions.DependencyInjectionException

Being orderService the service from another module and OrderLambdaHandler my handler class

I'm using Kotlin with gradle btw

jameskleeh commented 4 years ago

The handler class is not supposed to be annotated with @Singleton

jameskleeh commented 4 years ago

That info I think applies to all functions. I'm not sure the best place to document it

ilopmar commented 4 years ago

I annotated the handler with @Service because the test was failing and I though that was the way to fix it. I've tried it now without @Service and everything works as expected. I don't know what changed and what I did wrong.

@jameskleeh I think we can close this for now.

ilopmar commented 4 years ago

I take that back. I've tried again with a new fresh 2.1 function and it fails when deploying to AWS Lambda:

on: $LATEST
08:15:28.768 [main] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [ec2, cloud, function, lambda]
Bean definition [com.example.IcndbClient$Intercepted] could not be loaded: Error instantiating bean of type [com.example.IcndbClient$Intercepted]: At least one @Introduction method interceptor required, but missing. Check if your @Introduction stereotype annotation is marked with @Retention(RUNTIME) and @Type(..) with the interceptor type. Otherwise do not load @Introduction beans if their interceptor definitions are missing!: io.micronaut.context.exceptions.BeanInstantiationException
io.micronaut.context.exceptions.BeanInstantiationException: Bean definition [com.example.IcndbClient$Intercepted] could not be loaded: Error instantiating bean of type [com.example.IcndbClient$Intercepted]: At least one @Introduction method interceptor required, but missing. Check if your @Introduction stereotype annotation is marked with @Retention(RUNTIME) and @Type(..) with the interceptor type. Otherwise do not load @Introduction beans if their interceptor definitions are missing!
    at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1549)
    at io.micronaut.context.DefaultApplicationContext.initializeContext(DefaultApplicationContext.java:220)
    at io.micronaut.context.DefaultBeanContext.readAllBeanDefinitionClasses(DefaultBeanContext.java:2780)
    at io.micronaut.context.DefaultBeanContext.start(DefaultBeanContext.java:233)
    at io.micronaut.context.DefaultApplicationContext.start(DefaultApplicationContext.java:166)
    at io.micronaut.function.executor.AbstractExecutor.startEnvironment(AbstractExecutor.java:125)
    at io.micronaut.function.aws.MicronautRequestHandler.buildApplicationContext(MicronautRequestHandler.java:85)
    at io.micronaut.function.aws.MicronautRequestHandler.<init>(MicronautRequestHandler.java:48)
    at com.example.JokeRequestHandler.<init>(JokeRequestHandler.java:9)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
Caused by: io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [com.example.IcndbClient$Intercepted]: At least one @Introduction method interceptor required, but missing. Check if your @Introduction stereotype annotation is marked with @Retention(RUNTIME) and @Type(..) with the interceptor type. Otherwise do not load @Introduction beans if their interceptor definitions are missing!
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1927)
    at io.micronaut.context.DefaultBeanContext.createAndRegisterSingletonInternal(DefaultBeanContext.java:2647)
    at io.micronaut.context.DefaultBeanContext.loadContextScopeBean(DefaultBeanContext.java:2183)
    at io.micronaut.context.DefaultBeanContext.initializeContext(DefaultBeanContext.java:1543)
    ... 12 more
Caused by: java.lang.IllegalStateException: At least one @Introduction method interceptor required, but missing. Check if your @Introduction stereotype annotation is marked with @Retention(RUNTIME) and @Type(..) with the interceptor type. Otherwise do not load @Introduction beans if their interceptor definitions are missing!
    at io.micronaut.aop.chain.InterceptorChain.resolveIntroductionInterceptors(InterceptorChain.java:267)
    at com.example.IcndbClient$Intercepted.<init>(Unknown Source)
    at com.example.$IcndbClient$InterceptedDefinition.build(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1898)
    ... 15 more

END RequestId: 7d29f146-17dd-4ff2-b6b0-d1e35a9d3644
REPORT RequestId: 7d29f146-17dd-4ff2-b6b0-d1e35a9d3644  Duration: 3647.96 ms    Billed Duration: 3700 ms    Memory Size: 512 MB Max Memory Used: 36 MB  
Unknown application error occurred
io.micronaut.context.exceptions.BeanInstantiationException
charlie-harvey commented 4 years ago

Same problem here. And I just tried with 2.1.1 since I saw that it was released. The problem seems to be injection, not sure why though.

FAILS!!

@Introspected
class BuildStatusRequestHandler @Inject constructor(private val s3Client: S3Client): MicronautRequestHandler<SNSEvent?, String?>() {

...

}

WORKS!!

@Introspected
class BuildStatusRequestHandler : MicronautRequestHandler<SNSEvent?, String?>() {

...

}

No need to package it up in a shadow jar and upload to AWS, it fails locally when I run JUnit.

2020-10-13 23:35:42,651 Test worker DEBUG Apache Log4j Core 2.13.3 initializing configuration XmlConfiguration[location=/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml]
2020-10-13 23:35:42,659 Test worker DEBUG Installed 1 script engine
Warning: Nashorn engine is planned to be removed from a future JDK release
2020-10-13 23:35:42,875 Test worker DEBUG Oracle Nashorn version: 11.0.8, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory
2020-10-13 23:35:42,876 Test worker DEBUG PluginManager 'Core' found 122 plugins
2020-10-13 23:35:42,877 Test worker DEBUG PluginManager 'Level' found 0 plugins
2020-10-13 23:35:42,882 Test worker DEBUG PluginManager 'Lookup' found 16 plugins
2020-10-13 23:35:42,888 Test worker DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout].
2020-10-13 23:35:42,897 Test worker DEBUG PluginManager 'TypeConverter' found 26 plugins
2020-10-13 23:35:42,907 Test worker DEBUG PatternLayout$Builder(pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n", PatternSelector=null, Configuration(/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null")
2020-10-13 23:35:42,908 Test worker DEBUG PluginManager 'Converter' found 44 plugins
2020-10-13 23:35:42,909 Test worker DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.ConsoleAppender].
2020-10-13 23:35:42,919 Test worker DEBUG ConsoleAppender$Builder(target="SYSTEM_OUT", follow="null", direct="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n), name="LogToConsole", Configuration(/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml), Filter=null, ={})
2020-10-13 23:35:42,921 Test worker DEBUG Starting OutputStreamManager SYSTEM_OUT.false.false
2020-10-13 23:35:42,922 Test worker DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin].
2020-10-13 23:35:42,923 Test worker DEBUG createAppenders(={LogToConsole})
2020-10-13 23:35:42,923 Test worker DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
2020-10-13 23:35:42,933 Test worker DEBUG createAppenderRef(ref="LogToConsole", level="null", Filter=null)
2020-10-13 23:35:42,933 Test worker DEBUG Building Plugin[name=logger, class=org.apache.logging.log4j.core.config.LoggerConfig].
2020-10-13 23:35:42,935 Test worker DEBUG createLogger(additivity="false", level="DEBUG", name="com.beable", includeLocation="null", ={LogToConsole}, ={}, Configuration(/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml), Filter=null)
2020-10-13 23:35:42,937 Test worker DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
2020-10-13 23:35:42,938 Test worker DEBUG createAppenderRef(ref="LogToConsole", level="null", Filter=null)
2020-10-13 23:35:42,938 Test worker DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger].
2020-10-13 23:35:42,939 Test worker DEBUG createLogger(additivity="null", level="ERROR", includeLocation="null", ={LogToConsole}, ={}, Configuration(/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml), Filter=null)
2020-10-13 23:35:42,942 Test worker DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin].
2020-10-13 23:35:42,943 Test worker DEBUG createLoggers(={com.beable, root})
2020-10-13 23:35:42,944 Test worker DEBUG Configuration XmlConfiguration[location=/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml] initialized
2020-10-13 23:35:42,944 Test worker DEBUG Starting configuration XmlConfiguration[location=/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml]
2020-10-13 23:35:42,945 Test worker DEBUG Started configuration XmlConfiguration[location=/Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml] OK.
2020-10-13 23:35:42,946 Test worker DEBUG Shutting down OutputStreamManager SYSTEM_OUT.false.false-1
2020-10-13 23:35:42,946 Test worker DEBUG OutputStream closed
2020-10-13 23:35:42,946 Test worker DEBUG Shut down OutputStreamManager SYSTEM_OUT.false.false-1, all resources released: true
2020-10-13 23:35:42,947 Test worker DEBUG Appender DefaultConsole-1 stopped with status true
2020-10-13 23:35:42,947 Test worker DEBUG Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@54d6bc39 OK
2020-10-13 23:35:43,009 Test worker DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc
2020-10-13 23:35:43,012 Test worker DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=StatusLogger
2020-10-13 23:35:43,013 Test worker DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=ContextSelector
2020-10-13 23:35:43,015 Test worker DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Loggers,name=
2020-10-13 23:35:43,016 Test worker DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Loggers,name=com.beable
2020-10-13 23:35:43,017 Test worker DEBUG Registering MBean org.apache.logging.log4j2:type=277050dc,component=Appenders,name=LogToConsole
2020-10-13 23:35:43,020 Test worker DEBUG org.apache.logging.log4j.core.util.SystemClock supports precise timestamps.
2020-10-13 23:35:43,022 Test worker DEBUG Reconfiguration complete for context[name=277050dc] at URI /Users/charlieharvey/workspace/samples/build-status-cruise-control/build/resources/main/log4j2.xml (org.apache.logging.log4j.core.LoggerContext@46e42228) with optional ClassLoader: null
2020-10-13 23:35:43,022 Test worker DEBUG Shutdown hook enabled. Registering a new one.
2020-10-13 23:35:43,024 Test worker DEBUG LoggerContext[name=277050dc, org.apache.logging.log4j.core.LoggerContext@46e42228] started OK.

failed to access class io.micronaut.function.executor.AbstractExecutor from class com.beable.$BuildStatusRequestHandlerDefinition (io.micronaut.function.executor.AbstractExecutor and com.beable.$BuildStatusRequestHandlerDefinition are in unnamed module of loader 'app')
java.lang.IllegalAccessError: failed to access class io.micronaut.function.executor.AbstractExecutor from class com.beable.$BuildStatusRequestHandlerDefinition (io.micronaut.function.executor.AbstractExecutor and com.beable.$BuildStatusRequestHandlerDefinition are in unnamed module of loader 'app')
    at com.beable.$BuildStatusRequestHandlerDefinition.<init>(Unknown Source)
    at com.beable.$BuildStatusRequestHandlerDefinition.<init>(Unknown Source)
    at com.beable.$BuildStatusRequestHandlerDefinitionClass.load(Unknown Source)
    at io.micronaut.context.AbstractBeanDefinitionReference.load(AbstractBeanDefinitionReference.java:62)
    at io.micronaut.context.DefaultBeanContext.lambda$findBeanCandidatesForInstance$40(DefaultBeanContext.java:1780)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.concurrent.ConcurrentLinkedQueue.forEachFrom(ConcurrentLinkedQueue.java:1037)
    at java.base/java.util.concurrent.ConcurrentLinkedQueue$CLQSpliterator.forEachRemaining(ConcurrentLinkedQueue.java:894)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    at io.micronaut.context.DefaultBeanContext.findBeanCandidatesForInstance(DefaultBeanContext.java:1782)
    at io.micronaut.context.DefaultBeanContext.inject(DefaultBeanContext.java:780)
    at io.micronaut.function.aws.MicronautRequestHandler.<init>(MicronautRequestHandler.java:49)
    at com.beable.BuildStatusRequestHandler.<init>(BuildStatusRequestHandler.kt:25)
    at com.beable.BuildStatusRequestHandlerTest.handlerTest(BuildStatusRequestHandlerTest.kt:24)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:133)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.base/java.lang.Thread.run(Thread.java:834)
jameskleeh commented 4 years ago

@charlie-harvey That makes sense. The handler itself is not a bean. It is simply injected from the context. The context is started as part of the handler being constructed, thus it's impossible to inject the constructor.

charlie-harvey commented 4 years ago

So if I do the following it will work?

@Introspected
class BuildStatusRequestHandler : MicronautRequestHandler<SNSEvent?, String?>() {

    @Inject private val s3Client: S3Client

}

What I struggle with so far is putting that into a context when running a unit test. Thanks!

jameskleeh commented 4 years ago

@charlie-harvey Yes. You can just new BuildStatusRequestHandler() in your test and call the method

graemerocher commented 4 years ago

It should be @Inject lateinit var s3Client: S3Client

ilopmar commented 4 years ago

I've been testing this again and I think it's because of the new Micronaut Gradle plugin.

I've created a new 2.1.1 micronaut-function and it fails again with the same error. Using the same build.gradle (with the plugin) and downgrading to 2.0.3 also fails. Modifying the build.gradle file to a one generated with 2.0.3 (I've included as old-build.gradle make it work again with 2.1.1 and 2.0.3

New repo: https://github.com/micronaut-core-issues-test-app/micronaut-core-4284

jameskleeh commented 4 years ago

@ilopmar I don't want to conflate this issue which is for documenting dependency injection in functions with whatever issue you're having. Can you create a new issue?

sdelamo commented 4 years ago

@ilopmar I think the issue is you need to specify

shadowJar {
    mergeServiceFiles()
}

https://github.com/micronaut-core-issues-test-app/mn-aws-function-error/pull/1

DI will work once you deploy with that change.

ilopmar commented 4 years ago

@jameskleeh I was in the middle of writing the new issue but Sergio provided the fix. I'll send a PR to starter to include that configuration back.

sdelamo commented 4 years ago

@ilopmar I've reopened the issue: https://github.com/micronaut-projects/micronaut-starter/issues/503

jameskleeh commented 4 years ago

@graemerocher I thought I remember you saying that configuration was applied as part of the plugin?

graemerocher commented 4 years ago

@jameskleeh it is, but as part of the application plugin not the library plugin, it seems maybe it needs applying to both.