为什么在 lambda 层中调用 class 文件会抛出错误?
Why invocation of class file in lambda layer throwing error?
我正在尝试使用 java 实现 lambda 层。我为下面的 lambda 层创建了一个项目,代码如下:
图层代码
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>
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>
我正在尝试使用 java 实现 lambda 层。我为下面的 lambda 层创建了一个项目,代码如下:
图层代码
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>
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>