简体   繁体   English

AWS Lambda:ClassNotFoundException

[英]AWS Lambda: ClassNotFoundException

I currently get a ClassNotFoundException whenever I try to test my Lambda function on AWS Lambda.目前,每当我尝试在 AWS Lambda 上测试我的 Lambda 函数时,都会收到 ClassNotFoundException。 The exception is shown here:此处显示异常:

https://i.imgur.com/nD2OUOJ.jpg

I've searched online, including this link here: AWS Lambda: class java.lang.ClassNotFoundException , to no avail.我在网上搜索过,包括这里的链接: AWS Lambda: class java.lang.ClassNotFoundException ,但无济于事。

I am working in Android Studio and created a JAR file (using this link: How to make a .jar out from an Android Studio project ) to use to upload the class to the AWS Lambda console.我在 Android Studio 中工作并创建了一个 JAR 文件(使用此链接: How to make a .jar out from an Android Studio project )用于将类上传到 AWS Lambda 控制台。

Below is the structure of my project:以下是我的项目结构:

https://i.imgur.com/CFC8cA4.jpg

When I upload my JAR file to the AWS Lambda console, the Configuration tab looks like this:[当我将 JAR 文件上传到 AWS Lambda 控制台时,配置选项卡如下所示:[https://i.imgur.com/s9kovF7

I was previously told that it could have been because my JAR file was not an executable JAR file with a MANIFEST.MF file, but I definitely have that.之前有人告诉我,这可能是因为我的 JAR 文件不是带有 MANIFEST.MF 文件的可执行 JAR 文件,但我确实有。

Any other reason as to why this error consistently pops up and how to fix it?关于为什么会不断弹出此错误以及如何修复它的任何其他原因?

Your handler needs to include the full Java package.您的处理程序需要包含完整的 Java 包。 In your example, you need to have the handler be:在您的示例中,您需要将处理程序设为:

edu.csulb.android.riseandshine.Dynamodb::handleRequest

This is configured on the Lambda screen where you currently have Dynamodb::handleRequest这是在您当前拥有Dynamodb::handleRequest的 Lambda 屏幕上配置的

EDIT编辑

My "hello world" Lambda in looks like the following.我的“hello world”Lambda 如下所示。 Note that this is a maven project so the code has to live where maven expects it.请注意,这是一个 maven 项目,因此代码必须位于 maven 期望的位置。 At the "root" of the directory where you're developing is the pom.xml file (below) and the Java file needs to live in src/main/java/com/hotjoe/aws/lambda/hello/handler .在您正在开发的目录的“根”处是 pom.xml 文件(如下),Java 文件需要位于src/main/java/com/hotjoe/aws/lambda/hello/handler

Once you have that and maven installed, run mvn clean package .一旦你安装了它并安装了 maven,运行mvn clean package The deployable jar will be target/hello-world-lambda-1.0-SNAPSHOT.jar .可部署的 jar 将是target/hello-world-lambda-1.0-SNAPSHOT.jar I deployed this to Lambda just now and can run it with the test:我刚刚将它部署到 Lambda 并可以通过测试运行它:

{
  "key3": "value3",
  "key2": "value2",
  "key1": "value1"
}

which is the default for the Lambda tests.这是 Lambda 测试的默认设置。 This is all taken from the AWS docs on creating a deployment.这一切都取自有关创建部署的AWS 文档 In my example, the Lambda handler is com.hotjoe.aws.lambda.hello.handler.HelloWorldLambdaHandler::handleRequest .在我的示例中,Lambda 处理程序是com.hotjoe.aws.lambda.hello.handler.HelloWorldLambdaHandler::handleRequest

The code I've used is below.我使用的代码如下。

HelloWorldLambdaHandler.java HelloWorldLambdaHandler.java

package com.hotjoe.aws.lambda.hello.handler;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;


@SuppressWarnings("unused")
public class HelloWorldLambdaHandler implements RequestHandler<HelloWorldLambdaHandler.InputObject, String> {

    public String handleRequest(InputObject inputObject, Context context) {

        System.out.println( "got \"" + inputObject + "\" from call" );

        return "{\"result\": \"hello lambda java\"}";
    }

    public static class InputObject {
        private String key1;
        private String key2;
        private String key3;

        public String getKey1() {
            return key1;
        }

        public String getKey2() {
            return key2;
        }

        public String getKey3() {
            return key3;
        }

        public void setKey1(String key1) {
            this.key1 = key1;
        }

        public void setKey2(String key2) {
            this.key2 = key2;
        }

        public void setKey3(String key3) {
            this.key3 = key3;
        }

        @Override
        public String toString() {
            return "InputObject{" +
                    "key1='" + key1 + '\'' +
                    ", key2='" + key2 + '\'' +
                    ", key3='" + key3 + '\'' +
                    '}';
        }
    }
}

pom.xml: 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hotjoe.aws.lambda.hello</groupId>
    <artifactId>hello-world-lambda</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-lambda-java-core</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>

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

The stack trace indicates that the Java runtime cannot find a class named "Dynamodb".堆栈跟踪表明 Java 运行时找不到名为“Dynamodb”的类。 There is no such class in the AWS SDK for Java .. the correct class name is "DynamoDB". AWS SDK for Java 中没有这样的类。正确的类名是“DynamoDB”。 Notice the difference in case between your class from the exception stack trace and the correct name.请注意异常堆栈跟踪中的类与正确名称之间的大小写差异。

I fixed my issue by following below link.我通过以下链接解决了我的问题。 Basically need to run mvn "package shade:shade" command to include all depending jars.基本上需要运行 mvn "package shade:shade" 命令来包含所有依赖的 jars。 https://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-and-eclipse.html (Later experiments showed that just do mvn package would be enough as long as the shade plugin defined in pom.xml file.) https://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-and-eclipse.html (后来的实验表明,只要做 mvn package 就足够了,只要阴影pom.xml 文件中定义的插件。)

The next challenge I faced is the jar too big.我面临的下一个挑战是罐子太大了。 I followed the below link to include dynomaDB, S3, ec2 components instead of the entire sdk.我按照以下链接包含 dynomaDB、S3、ec2 组件而不是整个 sdk。 https://aws.amazon.com/blogs/developer/managing-dependencies-with-aws-sdk-for-java-bill-of-materials-module-bom/ . https://aws.amazon.com/blogs/developer/managing-dependencies-with-aws-sdk-for-java-bill-of-materials-module-bom/

Then I need to use EnvironmentVariableCredentialsProvider to deploy to lambda function.然后我需要使用 EnvironmentVariableCredentialsProvider 部署到 lambda 函数。

It's not an answer to the original question.这不是原始问题的答案。 But I was facing the same issue of class not found and solved it by placing pom.xml at the correct location in the directory structure.但是我遇到了同样的问题,找不到类,并通过将 pom.xml 放在目录结构中的正确位置来解决它。 In Android Studio, "src/main/java/.." lives in the Application folder inside the root directory.在 Android Studio 中,“src/main/java/..”位于根目录下的 Application 文件夹中。 I was wrongly placing the xml file in the root directly.我错误地将xml文件直接放在根目录中。

When I created a separate directory structure outside of Android Project and placed the xml file as described here , the problem was resolved.当我在 Android 项目之外创建了一个单独的目录结构并按照这里的描述放置了 xml 文件时,问题就解决了。

I know it's late to share the solution,我知道现在分享解决方案为时已晚,

but the same problem I was facing in Apr, 2021 and none of these answers worked in my case.但我在 2021 年 4 月面临的同样问题,这些答案都不适用于我的案例。 so I'm sharing how I fixed it, it may help someone.所以我正在分享我是如何修复它的,它可能会对某人有所帮助。

I got it resolved by adding following maven plugin with spring-boot-thin-layout to create a thin jar.我通过添加以下带有spring-boot-thin-layout 的maven 插件来创建一个瘦 jar 来解决它。

<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot.experimental</groupId>
        <artifactId>spring-boot-thin-layout</artifactId>
        <version>1.0.26.RELEASE</version>
    </dependency>
</dependencies>
<configuration>
    <createDependencyReducedPom>false</createDependencyReducedPom>
    <shadedArtifactAttached>true</shadedArtifactAttached>
    <shadedClassifierName>aws</shadedClassifierName>
    <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>
    </transformers>
</configuration>

and then you can run然后你可以运行

./mvnw clean package ./mvnw 干净的包

or if you're using STS/Eclipse, then run Maven build.. with goals clean package或者,如果您使用的是 STS/Eclipse,则运行 Maven build.. with目标清理包

This will generate a jar file in KB in your target folder and you can use this JAR to deploy on AWS lambda code.这将在您的目标文件夹中生成一个以 KB 为单位的 jar 文件,您可以使用此 JAR 在 AWS lambda 代码上进行部署。

PS: PS:

  1. remove maven-shade-plugin删除 maven-shade-plugin
  2. I've refereed Official documentation of spring.cloud.io我已经参考了 spring.cloud.io 的官方文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS Lambda ClassNotFoundException - AWS Lambda ClassNotFoundException AWS Lambda Java 错误:ClassNotFoundException - AWS Lambda Java Error: ClassNotFoundException Lambda - ClassNotFoundException - Lambda - ClassNotFoundException Quarkus GraalVM 本机构建在 AWS Lambda 中失败并出现 ClassNotFoundException - Quarkus GraalVM native build fails in AWS Lambda with ClassNotFoundException AWS Lambda尝试访问dynamoDB时发生运行时错误-ClassNotFoundException - Runtime error when aws lambda trying to access dynamoDB - ClassNotFoundException 无法从AWS Lambda连接到AWS RDS MySql DB。 ClassNotFoundException:com.mysql.jdbc - Not able to connect to AWS RDS MySql DB from AWS Lambda. ClassNotFoundException: com.mysql.jdbc ClassNotFoundException ...$$Lambda$172 - ClassNotFoundException …$$Lambda$172 使用 Bitbucket Pipelines 更新 AWS Java Lambda 函数时出错 - java.lang.ClassNotFoundException - Error when update AWS Java Lambda Function using Bitbucket Pipelines - java.lang.ClassNotFoundException java.lang.ClassNotFoundException 同时在 AWS CDK 代码中引用 Lambda 代码 - java.lang.ClassNotFoundException while referencing Lambda code in AWS CDK code 带有Java的AWS Lambda抛出由ClassNotFoundException引起的NoClassDefFoundError,该异常未在本地抛出 - AWS Lambda with java throwing NoClassDefFoundError caused by ClassNotFoundException which isn't thrown locally
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM