question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Document function dependency injection

See original GitHub issue

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

  • git clone https://github.com/micronaut-core-issues-test-app/function-dependency-injection
  • cd function-dependency-injection
  • ./gradlew check

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

  • Operating System: Linux
  • Micronaut Version: 2.1.0
  • JDK Version: 11 Corretto

Example Application

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

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:18 (13 by maintainers)

github_iconTop GitHub Comments

1reaction
sdelamocommented, Oct 16, 2020

@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.

0reactions
graemerochercommented, Oct 16, 2020

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

Read more comments on GitHub >

github_iconTop Results From Across the Web

Use dependency injection in .NET Azure Functions
Constructor injection is used to make your dependencies available in a function. The use of constructor injection requires that you do not use ......
Read more >
Dependency injection in Android
Dependency injection (DI) is a technique widely used in programming and well suited to Android development. By following the principles of DI, ...
Read more >
Dependency injection - Wikipedia
In software engineering, dependency injection is a design pattern in which an object or function receives other objects or functions that it depends...
Read more >
Dependencies - First Steps - FastAPI - tiangolo
"Dependency Injection" means, in programming, that there is a way for your code (in this case, your path operation functions) to declare things...
Read more >
Developer Guide: Dependency Injection - AngularJS: API
Dependency Injection (DI) is a software design pattern that deals with how components get hold of their dependencies. The AngularJS injector subsystem is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found