java AWS Lambda:ClassNotFoundException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46943897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AWS Lambda: ClassNotFoundException
提问by avu95
I currently get a ClassNotFoundException whenever I try to test my Lambda function on AWS Lambda. The exception is shown here:
目前,每当我尝试在 AWS Lambda 上测试我的 Lambda 函数时,都会收到 ClassNotFoundException。此处显示异常:
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:
以下是我的项目结构:
When I upload my JAR file to the AWS Lambda console, the Configuration tab looks like this:[
当我将 JAR 文件上传到 AWS Lambda 控制台时,配置选项卡如下所示:[
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?
关于为什么会不断弹出此错误以及如何修复它的任何其他原因?
采纳答案by stdunbar
Your handler needs to include the full Java package. In your example, you need to have the handler be:
您的处理程序需要包含完整的 Java 包。在您的示例中,您需要将处理程序设为:
edu.csulb.android.riseandshine.Dynamodb::handleRequest
edu.csulb.android.riseandshine.Dynamodb::handleRequest
This is configured on the Lambda screen where you currently have Dynamodb::handleRequest
这是在您当前拥有的 Lambda 屏幕上配置的 Dynamodb::handleRequest
EDIT
编辑
My "hello world" Lambda in looks like the following. Note that this is a maven project so the code has to live where maven expects it. 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
.
我的“hello world”Lambda 如下所示。请注意,这是一个 maven 项目,因此代码必须位于 maven 期望的位置。在您正在开发的目录的“根”处是 pom.xml 文件(如下),Java 文件需要位于src/main/java/com/hotjoe/aws/lambda/hello/handler
.
Once you have that and maven installed, run mvn clean package
. The deployable jar will be target/hello-world-lambda-1.0-SNAPSHOT.jar
. I deployed this to Lambda just now and can run it with the test:
一旦你安装了它并安装了 maven,运行mvn clean package
. 可部署的 jar 将是target/hello-world-lambda-1.0-SNAPSHOT.jar
. 我刚刚将它部署到 Lambda 并可以运行它进行测试:
{
"key3": "value3",
"key2": "value2",
"key1": "value1"
}
which is the default for the Lambda tests. This is all taken from the AWS docson creating a deployment. In my example, the Lambda handler is com.hotjoe.aws.lambda.hello.handler.HelloWorldLambdaHandler::handleRequest
.
这是 Lambda 测试的默认设置。这一切都取自有关创建部署的AWS 文档。在我的示例中,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>
回答by Feng Zhang
I fixed my issue by following below link. Basically need to run mvn "package shade:shade" command to include all depending 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.)
我通过以下链接解决了我的问题。基本上需要运行 mvn "package shade:shade" 命令来包含所有依赖的 jars。 https://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-and-eclipse.html(后来的实验表明只要做mvn包就够了,只要遮光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. https://aws.amazon.com/blogs/developer/managing-dependencies-with-aws-sdk-for-java-bill-of-materials-module-bom/.
我面临的下一个挑战是罐子太大了。我按照以下链接包含 dynomaDB、S3、ec2 组件而不是整个 sdk。 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 函数。
回答by Ajay
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. In Android Studio, "src/main/java/.." lives in the Application folder inside the root directory. I was wrongly placing the xml file in the root directly.
这不是原始问题的答案。但是我遇到了同样的找不到类的问题,并通过将 pom.xml 放在目录结构中的正确位置来解决它。在 Android Studio 中,“src/main/java/..”位于根目录下的 Application 文件夹中。我错误地将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 文件时,问题解决了。
回答by Scott Kronheim
The stack trace indicates that the Java runtime cannot find a class named "Dynamodb". There is no such class in the AWS SDK for Java .. the correct class name is "DynamoDB". Notice the difference in case between your class from the exception stack trace and the correct name.
堆栈跟踪表明 Java 运行时找不到名为“Dynamodb”的类。AWS SDK for Java 中没有这样的类。正确的类名是“DynamoDB”。请注意异常堆栈跟踪中的类与正确名称之间的大小写差异。