'SpringBoot AWS Lambda application deployment issue-Class not found: com.abc.test.TestServiceHandler

Created a Spring boot application using Java 11 and trying to deploy in AWS Lambda. Encountering the following error in AWS Lambda. I see it is an issue with the way I am packaging the jar. Any help is greatly appreciated.

{
  "errorMessage": "Class not found: com.abc.test.TestServiceHandler",
  "errorType": "java.lang.ClassNotFoundException"
}

I am building the jar using the following maven commands:

  • mvn clean install
  • mvn package -P shade

Below is my pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.abc.test.store</groupId>
    <artifactId>test-service</artifactId>
    <version>${revision}</version>
    <packaging>jar</packaging>
    <name>Test-service</name>
    <description>Test Service</description>
    <properties>
        <revision>local-SNAPSHOT</revision>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring.boot.parent.version>2.6.4</spring.boot.parent.version>
        <commons.lang3.version>3.12.0</commons.lang3.version>
        <commons.collections.version>4.4</commons.collections.version>          <aws.sdk.secretsmanager.version>1.12.150</aws.sdk.secretsmanager.version>
        <jacoco.version>0.8.7</jacoco.version>
        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws.serverless</groupId>
            <artifactId>aws-serverless-java-container-spring</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sts</artifactId>
            <version>${aws.sdk.secretsmanager.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons.lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>${commons.collections.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>sonar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <sonar.coverage.exclusions>
                    **/test/model/**/*,
                </sonar.coverage.exclusions>
            </properties>
        </profile>
        <profile>
            <id>sbmp</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>shade</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-shade-plugin</artifactId>
                        <configuration>
                            <createDependencyReducedPom>false</createDependencyReducedPom>
                        </configuration>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>shade</goal>
                                </goals>
                                <configuration>
                                    <artifactSet>
                                        <excludes>                                              <exclude>org.apache.tomcat.embed:*</exclude>
                                            <exclude>*:spring-boot-devtools</exclude>
                                        </excludes>
                                    </artifactSet>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>


Solution 1:[1]

Please check following sample, save as src\main\java\com\abc\test\TestServiceHandler.java

package com.abc.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.lambda.runtime.LambdaLogger;

public class TestServiceHandler implements RequestStreamHandler {
  
  @Override
  public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
      LambdaLogger logger = context.getLogger();
      logger.log("Started up");
      return;
  }
}

Compile, and upload jar as you mentioned in question.

In aws lambda console code tab, under Runtime settings, Handler, edit it to com.abc.test.TestServiceHandler to call lambda.

Point from here says use RequestStreamHandler instead of RequestHandler which sample from doc used. It looks like importent.

Solution 2:[2]

Turns out my issue is related to my local machine (mac) that I am building my JAR from.From what I have debugged,the architecture used to build the jar is causing issues when deployed on Lambda. Building the jar from windows machine did not cause any issues.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 izayoi
Solution 2 Kodeffeminate