My existing project I am trying to convert to make to deploy using AWS lambda. And when I modified pom.xml dependencies and added handler class and deploying to lambda function, I am getting the following error,
{
"errorMessage": "Class not found: com.cicdpipeline.LambdaHandler",
"errorType": "java.lang.ClassNotFoundException"
}
I added following dependencies in pom.xml
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-spring</artifactId>
<version>1.9.1</version>
</dependency>
and added following plugin,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.apache.tomcat.embed:*</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
My main application file,
package com.cicdpipeline;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CicdpipelineApplication {
public static void main(String[] args) {
SpringApplication.run(CicdpipelineApplication.class, args);
}
}
Lambda Handler class I added the same place where main app resides (com.cicdpipeline)
package com.cicdpipeline;
import javax.ws.rs.core.Application;
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class LambdaHandler implements RequestStreamHandler {
private static SpringLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringLambdaContainerHandler.getAwsProxyHandler(CicdpipelineApplication.class);
} catch (ContainerInitializationException e) {
// Re-throw the exception to force another cold start
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
handler.proxyStream(inputStream, outputStream, context);
// just in case it wasn't closed by the mapper
outputStream.close();
}
}
And In Lambda function Runtime settings I added package.class.method like the following,
com.cicdpipeline.LambdaHandler::SpringLambdaContainerHandler
How to resolve the problem while converting existing springboot project to support aws lambda deployment? or any good documentation for reference?
looks like configuration not happening correctly, here is rough sample code to kick start your application,
your pom.xml with all complete all needed must have dependencies:
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- AWS Lambda Core -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
<!-- AWS Lambda Events -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.11.1</version>
</dependency>
<!-- AWS Serverless Java Container -->
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-spring</artifactId>
<version>1.9.1</version>
</dependency>
</dependencies>
use correct plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.cicdpipeline.CicdpipelineApplication</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Fix your LambdaHandler java class
package com.cicdpipeline;
import com.amazonaws.serverless.exceptions.ContainerInitializationException;
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
import com.amazonaws.serverless.proxy.spring.SpringBootLambdaContainerHandler;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class LambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(CicdpipelineApplication.class);
} catch (ContainerInitializationException e) {
// Re-throw the exception to force another cold start
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
throws IOException {
handler.proxyStream(inputStream, outputStream, context);
}
}
Update your main java class in your case is Spring Boot App right,
package com.cicdpipeline;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@SpringBootApplication
public class CicdpipelineApplication {
@Bean
public HandlerMapping handlerMapping() {
return new RequestMappingHandlerMapping();
}
@Bean
public HandlerAdapter handlerAdapter() {
return new RequestMappingHandlerAdapter();
}
public static void main(String[] args) {
SpringApplication.run(CicdpipelineApplication.class, args);
}
}
The Lambda handler setting in AWS Console must be look like such only,
com.cicdpipeline.LambdaHandler::handleRequest
instead of that your i seen wrong typo thing,
com.cicdpipeline.LambdaHandler::SpringLambdaContainerHandler
pplication.propeties file in src/main/resources:
spring.main.web-application-type=servlet
spring.main.banner-mode=off
logging.level.root=INFO
Build the project:
mvn clean package
controller:
package com.cicdpipeline.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@GetMapping("/test")
public String test() {
return "Hello from Lambda!";
}
}
try to setup like This should work with no issues, Ref. https://docs.aws.amazon.com/codedeploy/latest/userguide/applications-create-lambda.html