为什么在 lambda 层中调用 class 文件会抛出错误?

Why invocation of class file in lambda layer throwing error?

我正在尝试使用 java 实现 lambda 层。我为下面的 lambda 层创建了一个项目,代码如下:

图层代码

  1. pom.xml

     <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.i3l.layer</groupId>
         <artifactId>customlayer</artifactId>
         <version>1.1.0</version>
     </project>
    
  2. DataHandler.java

    package customlayer;
    
    public class DataHandler {
    
     public String getData(String input) {
        System.out.println("Inside Layer");
        return "Hello from Layer "+input;
     }
    }
    

函数代码: 我在 pom.xml 中添加了层依赖,例如:

<dependency>
    <groupId>com.i3l.layer</groupId>
    <artifactId>customlayer</artifactId>
    <version>1.1.0</version>
    <scope>provided</scope>
</dependency>

LambdaFunctionHandler.java

package com.amazonaws.lambda.userlayertest;

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

import customlayer.DataHandler;

public class LambdaFunctionHandler implements RequestHandler<RequestObject, String> {

@Override
public String handleRequest(RequestObject input, Context context) {
    
    System.out.println("call to layer");
    DataHandler dataHandler = new DataHandler();
    String data = dataHandler.getData(input.getBody());
    return data;
 }
}

我尝试将 jar 直接上传到图层并将 jar 放入 zip 中,然后将其上传到图层。在这两种情况下,我都收到错误:

"errorMessage": "customlayer/DataHandler",
"errorType": "java.lang.NoClassDefFoundError",

注意:我已经在 lambda 函数中添加了带有版本号的层。

如果有人能帮我弄清楚为什么 java class 在层中找不到,那就太好了。我已经从层下载了代码,我可以看到 class 文件在导入的正确路径中。

这里的问题出在目录结构上。层依赖项应该在特定目录中,它随运行时环境而变化。所以在这种情况下,customlayer-1.1.0.jar 应该在 java/lib 中,然后它将被存档。假设存档名称是 customlayer.zip 那么结构将是

customlayer.zip
└ java/lib/customlayer-1.1.0.jar

此结构会随运行时环境而变化。

更多详情:https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

此外,要自动创建它,可以创建一个如下所示的 assembly.xml。

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>bin</id>
    <baseDirectory>/</baseDirectory>
    <formats>
        <format>zip</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>/java/lib</outputDirectory>
            <includes>
                <include>${project.artifactId}.jar</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>

然后在您的 pom.xml 中添加插件并配置此 assembly.xml 文件。

        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <descriptors>
                    <descriptor>assembly.xml</descriptor>
                </descriptors>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id> <!-- this is used for inheritance merges -->
                    <phase>package</phase> <!-- append to the packaging phase. -->
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>