AWS Lambda NoClassDefFoundError

AWS Lambda NoClassDefFoundError

我在使用基于 Java 的 Lambda 函数设置来接收来自 SNS 的消息时遇到困难。我的函数如下所示:

package com.mycompany;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.events.SNSEvent;

public class LambdaHandler {  
    public void Handler(SNSEvent event, Context context) {
        //Process the event
    }
}

它编译得很好,将 jar 文件上传到 Lambda(通过 Web 控制台)没有任何问题。

但是,当我使用 JSON 表示 SNSEvent 模型向它发布(通过 SNS 到订阅的 Lambda 函数)时,Lambda 函数抛出以下异常:

Error loading method handler on class com.mycompany.LambdaHandler: class java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: com/amazonaws/services/lambda/runtime/events/SNSEvent at

java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) at java.lang.Class.privateGetPublicMethods(Class.java:2902) at java.lang.Class.getMethods(Class.java:1615) Caused by: java.lang.ClassNotFoundException: com.amazonaws.services.lambda.runtime.events.SNSEvent at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

我使用 Maven + Netbeans,它是一个 Maven Java 应用程序项目。我从 Lambda 控制台下载了函数并确认,jar 有一个 lib/ 目录,其中包含所有用于导入的 jar,包括 aws-lambda-java-events-1.1.0.jar,它本身包括 /com/amazonaws/services/lambda/runtime/events/SNSEvent.class 文件。

为什么运行时无法找到肯定在 jar 文件中的 class?还有什么我需要做的,设置任何环境变量等吗?

如有任何帮助,我们将不胜感激!

编辑 1 我尝试降级到 aws-lambda-java-events 1.0.0,它仍然报告相同的异常。根据要求,下面是我的 POM 文件(只是更改了项目名称)。我不知道如何告诉 Maven 将库放在树结构中。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.app</groupId>
    <artifactId>Handler</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-lambda</artifactId>
            <version>1.10.6</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-events</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
</project>

使用 maven-shade plugin 以便 JAR 包含 uber-jar 中的依赖项。

因此,将此添加到您的 pom.xml

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <createDependencyReducedPom>false</createDependencyReducedPom>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

来源:http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html

您可能遇到这个问题 https://github.com/aws/aws-lambda-java-libs/issues/2,需要降级到 aws-lambda-java-events-1.0.0.jar

在 pom.xml 的插件部分,添加 Apache Maven Shade Plugin。它在构建过程中使用。此插件用于打包 jar 以创建一个独立的 .jar.The maven-shade-plugin 将采用 package goal 生成的工件(jars),并创建一个包含编译代码和已解析依赖项的独立 .jar来自 pom.xml.

<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>

有时您必须再次上传您的 lambda。我也遇到了我用 pom.xml:

解决的同样问题
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

   <dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-bom</artifactId>
      <version>1.11.83</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>

 </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

   <build>
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <configuration>
      <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
 </build>
</project>

=== 如果这个问题在包含阴影 jar 之后仍然存在 ===

如果你在使用 shaded jar 后仍然有这个问题,那么这个问题应该与 aws-lambda-java-events 包版本有关(应该是一些不兼容在 AWS lamda 版本和较新的 aws-lambda-java-events 版本之间)。即我在 aws-lambda-java-events 包的最新版本 (2.0.2) 中遇到了这个问题,我必须将版本降级到 1.3.0.

似乎较新的 aws-lambda-java-events 版本没有很多依赖项。

如果你有<scope>provided</scope> 在 aws-lambda-java-events 工件中,删除它。

每当我们尝试将基于 java 的 Jar 或 Zip 上传到 AWS lambda 控制台时,我们都必须处理一些基本的事情,例如,

代码 URI,存在于 SAM 模板或 template.yml 文件中。 例如:

例如:runwayDetails - 包裹名称 应用程序 - class 名称 handleRequest - lambda 处理程序方法。

语法应该是这样的 - packageName.className::methodName

它将解决错误