I have written an AWS Lambda using the Quarkus framework. The purpose of the lambda is to listen for DynamoDB Streams events and index the event using Elasticsearch. However, when I try to run a native build of the Lambda, I get an error.
My pom.xml looks something like this:
<project> <dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-amazon-dynamodb</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-amazon-lambda</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-elasticsearch-rest-high-level-client</artifactId> </dependency> </dependencies> </project>
I am able to build the native executable just fine, and can upload it to localstack for sandbox testing. However, when the lambda is invoked, I see the following errors in localstack:
2022-08-02T21:20:01.311:INFO:localstack.services.awslambda.lambda_executors: Running lambda: arn:aws:lambda:us-east-1:000000000000:function:MySearchIndexerLambdaNative 2022-08-02T21:20:02.263:INFO:localstack.services.awslambda.lambda_executors: writing log to file '/tmp/localstack/lambda_q_isog7m.log' 2022-08-02T21:20:02.279:INFO:localstack.services.awslambda.lambda_api: Error executing Lambda function arn:aws:lambda:us-east-1:000000000000:function:MySearchIndexerLambdaNative: Lambda process returned with error. Result: {"errorType":"java.lang.RuntimeException","errorMessage":"Error injecting org.elasticsearch.client.RestClient io.quarkus.elasticsearch.restclient.highlevel.runtime.ElasticsearchRestHighLevelClientProducer.restClient"}. Output: velClientProducer_ProducerMethod_restHighLevelClient_64f448fc39ae0b1beb55a790902ba52dd95aeae0_Bean.get(Unknown Source) at io.quarkus.elasticsearch.restclient.highlevel.runtime.ElasticsearchRestHighLevelClientProducer_ProducerMethod_restHighLevelClient_64f448fc39ae0b1beb55a790902ba52dd95aeae0_Bean.get(Unknown Source) at com.mycorp.lamba.search.DynamoDBSearchIndexEventHandler_Bean.create(Unknown Source) at com.mycorp.lamba.search.DynamoDBSearchIndexEventHandler_Bean.get(Unknown Source) at com.mycorp.lamba.search.DynamoDBSearchIndexEventHandler_Bean.get(Unknown Source) at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:468) at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:481) at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:285) at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:282) at io.quarkus.arc.runtime.BeanContainerImpl$1.create(BeanContainerImpl.java:36) at io.quarkus.arc.runtime.BeanContainer.instance(BeanContainer.java:19) at io.quarkus.amazon.lambda.runtime.AmazonLambdaRecorder$1.processRequest(AmazonLambdaRecorder.java:169) at io.quarkus.amazon.lambda.runtime.AbstractLambdaPollLoop$1.run(AbstractLambdaPollLoop.java:130) at java.lang.Thread.run(Thread.java:833) at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:704) at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202) Caused by: org.apache.commons.logging.LogConfigurationException: No suitable Log implementation at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:848) at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:541) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:657) at org.apache.http.impl.client.AuthenticationStrategyImpl.<init>(AuthenticationStrategyImpl.java:69) at org.apache.http.impl.client.TargetAuthenticationStrategy.<init>(TargetAuthenticationStrategy.java:50) at org.elasticsearch.client.PersistentCredentialsAuthenticationStrategy.<init>(PersistentCredentialsAuthenticationStrategy.java:44) at org.elasticsearch.client.RestClientBuilder.createHttpClient(RestClientBuilder.java:317) at java.security.AccessController.executePrivileged(AccessController.java:169) at java.security.AccessController.doPrivileged(AccessController.java:318) at org.elasticsearch.client.RestClientBuilder.build(RestClientBuilder.java:283) at io.quarkus.elasticsearch.restclient.lowlevel.runtime.ElasticsearchRestClientProducer.restClient(ElasticsearchRestClientProducer.java:31) at io.quarkus.elasticsearch.restclient.lowlevel.runtime.ElasticsearchRestClientProducer_ProducerMethod_restClient_4f53fa46bf0c1a6a8a72fa34e03284fcda35ecdc_Bean.create(Unknown Source) at io.quarkus.elasticsearch.restclient.lowlevel.runtime.ElasticsearchRestClientProducer_ProducerMethod_restClient_4f53fa46bf0c1a6a8a72fa34e03284fcda35ecdc_Bean.create(Unknown Source) at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:111) at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35) at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:32) at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26) at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69) at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:32) at io.quarkus.elasticsearch.restclient.lowlevel.runtime.ElasticsearchRestClientProducer_ProducerMethod_restClient_4f53fa46bf0c1a6a8a72fa34e03284fcda35ecdc_Bean.get(Unknown Source) at io.quarkus.elasticsearch.restclient.lowlevel.runtime.ElasticsearchRestClientProducer_ProducerMethod_restClient_4f53fa46bf0c1a6a8a72fa34e03284fcda35ecdc_Bean.get(Unknown Source) ... 35 more Traceback (most recent call last):
Any idea why this would be occurring? This error is a new one to me.
Advertisement
Answer
The problem is that you have an Apache Commons Logging implementation around and that it doesn’t support being part of a native executable (at least not natively, you would need some GraalVM metadata to make it work).
In Quarkus, you should use JBoss Logging and its adapters (and exclude the original implementation).
For Commons Logging, that would be:
<dependency> <groupId>org.jboss.logging</groupId> <artifactId>commons-logging-jboss-logging</artifactId> </dependency>
Note that if it’s a Quarkus extension bringing this Commons Logging implementation as a dependency, you should open an issue as it’s not normal. We usually take good care of excluding the logging implementations.
You can find more information in our reference documentation: https://quarkus.io/guides/logging#logging-adapters .