SpringBoot Lambda 部署问题 - EmbeddedServletContainer - java.lang.NoClassDefFoundError
SpringBoot Lambda deployment Issue - EmbeddedServletContainer - java.lang.NoClassDefFoundError
我正在尝试使用 RequestStreamHandler 在 AWS Lambda/API-Gateway 中部署一个简单的 spring 启动应用程序,但我不断收到以下错误。
查看互联网后发现,由于 spring-boot 包问题,所以包含了 shade 插件,但仍然没有成功。
{
"errorMessage": "Error loading class com.aws.lambda.testlambda.StreamLambdaHandler: org/springframework/boot/context/embedded/EmbeddedServletContainer",
"errorType": "java.lang.NoClassDefFoundError"
}
pom.xml
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-spring</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.aws.lambda.testlambda.TestlambdaApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
public class StreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(TestlambdaApplication.class);
// we use the onStartup method of the handler to register our custom filter
handler.onStartup(servletContext -> {
FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class);
registration.addMappingForUrlPatterns( EnumSet.of( DispatcherType.REQUEST), true, "/*");
});
} catch (ContainerInitializationException e) {
// if we fail here. We re-throw the exception to force another cold start
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
public StreamLambdaHandler() {
// we enable the timer for debugging. This SHOULD NOT be enabled in production.
Timer.enable();
}
@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();
}
}
非常感谢任何帮助。提前致谢。
AVAI!
这个问题我有一个猜测。
您可以检查在您的 Lambda 函数中定义的 Java 的版本吗?
我看到您正在使用 Java 8 您的应用程序。
您的 lambda 运行时应匹配此版本。
如果您在 lambda 上使用本地 Oracle JVM 和 AWS Coretto JVM,您可能还会遇到一些问题。
我能够解决这个问题,有几个问题需要解决并使其端到端工作。
下面提到了这个问题 url。
https://github.com/awslabs/aws-serverless-java-container
- 打包需要排除tomcat依赖。
- RequestStreamHandler 只需稍作修改即可处理请求和响应。
AwsProxyResponse resp = handler.proxy(req, context);
LambdaContainerHandler.getObjectMapper().writeValue(outputStream, resp);
- 部署到 API 网关时必须选择代理集成选项。
我正在尝试使用 RequestStreamHandler 在 AWS Lambda/API-Gateway 中部署一个简单的 spring 启动应用程序,但我不断收到以下错误。
查看互联网后发现,由于 spring-boot 包问题,所以包含了 shade 插件,但仍然没有成功。
{
"errorMessage": "Error loading class com.aws.lambda.testlambda.StreamLambdaHandler: org/springframework/boot/context/embedded/EmbeddedServletContainer",
"errorType": "java.lang.NoClassDefFoundError"
}
pom.xml
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-spring</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.aws.lambda.testlambda.TestlambdaApplication</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
public class StreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(TestlambdaApplication.class);
// we use the onStartup method of the handler to register our custom filter
handler.onStartup(servletContext -> {
FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class);
registration.addMappingForUrlPatterns( EnumSet.of( DispatcherType.REQUEST), true, "/*");
});
} catch (ContainerInitializationException e) {
// if we fail here. We re-throw the exception to force another cold start
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring Boot application", e);
}
}
public StreamLambdaHandler() {
// we enable the timer for debugging. This SHOULD NOT be enabled in production.
Timer.enable();
}
@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();
}
}
非常感谢任何帮助。提前致谢。
AVAI!
这个问题我有一个猜测。 您可以检查在您的 Lambda 函数中定义的 Java 的版本吗?
我看到您正在使用 Java 8 您的应用程序。 您的 lambda 运行时应匹配此版本。
如果您在 lambda 上使用本地 Oracle JVM 和 AWS Coretto JVM,您可能还会遇到一些问题。
我能够解决这个问题,有几个问题需要解决并使其端到端工作。
下面提到了这个问题 url。
https://github.com/awslabs/aws-serverless-java-container
- 打包需要排除tomcat依赖。
- RequestStreamHandler 只需稍作修改即可处理请求和响应。
AwsProxyResponse resp = handler.proxy(req, context);
LambdaContainerHandler.getObjectMapper().writeValue(outputStream, resp);
- 部署到 API 网关时必须选择代理集成选项。