运行带有库的AWS Lambda函数时出现NoClassDefFoundError错误

4
我们正在开发一个项目,使用由API Gateway请求触发的Lambda函数来处理文件。然后,该函数从S3存储桶中获取文件并开始读取。在此之前,一切都像预期的那样工作,但是当文件读取开始时,我们收到以下错误信息:
(...)
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-3.b13.24.amzn1.x86_64/jre/lib/rt.jar: error reading zip file
2017-02-06 19:15:06 <9025af71-eca0-11e6-82d2-9ff4b9184005> ERROR JRestlessHandlerContainer:339 - container failure
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-3.b13.24.amzn1.x86_64/jre/lib/rt.jar: error reading zip file
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-3.b13.24.amzn1.x86_64/jre/lib/rt.jar: error reading zip file
END RequestId: (some id)
REPORT RequestId: (some id)  Duration: 3047.44 ms    Billed Duration: 3100 ms        Memory Size: 1536 MB    Max Memory Used: 94 MB  

Exception in thread "main" java.lang.Error: java.lang.NoClassDefFoundError: java/lang/Throwable$WrappedPrintWriter
    at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:59)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:94)
Caused by: java.lang.NoClassDefFoundError:     java/lang/Throwable$WrappedPrintWriter
    at java.lang.Throwable.printStackTrace(Throwable.java:721)
    at lambdainternal.UserFault.trace(UserFault.java:43)
    at lambdainternal.UserFault.makeUserFault(UserFault.java:26)
    at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:290)
    at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:57)
    ... 3 more
START RequestId: (some id) Version: $LATEST
END RequestId: (some id)

为了满足我们自己的需求,我们使用了自己编写的文件读取/处理库(一个Java项目),并通过Maven将其添加到了我们的项目中。我们使用Maven Shade插件生成了lambda jar包:

<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>

在本地测试项目时,一切正常,我们可以获取文件信息。我们的代码使用JAX-RS和Spring来处理API网关(我们不确定这是否会影响结果)。但是,到目前为止,我们无法解决在lambda上运行项目时出现的问题。在我们的测试中,我们故意增加了函数超时时间和内存限制,但无论限制如何,错误仍然存在。

提前感谢您。


你能展示你的整个pom.xml文件吗?你看过这个吗: http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html - Zigglzworth
这里显示的“容器故障”确实可能表明错误出现在AWS方面。您应该向他们的支持团队或AWS论坛寻求帮助。 - user7401700
嗨@JeshanBabooa,这也是我们怀疑的。我们已经在AWS论坛上发布了此问题,但到目前为止我们还没有得到答案,所以决定在这里发布。 - Hime
嗨@Zigglzworth,很抱歉我不能发布整个pom.xml文件,但在我们添加文件处理库之前,我们的函数运行良好,并且建议使用的插件来生成jar文件与我们正在使用的相同。 - Hime
当您构建项目时,是在本地计算机上进行的(对吗?),但可能某些地方使用了本地依赖项。因此,请尝试启动Amazon Linux EC2实例并在那里构建Java项目。然后将其上传到Lambda函数。 - Zigglzworth
我会尝试这个@Zigglzworth - Hime
2个回答

1
使用日志技术、调试我们的代码并联系AWS支持,我们发现我们的一个库正在创建被禁止的目录中的文件,就像这里所解释的那样:https://aws.amazon.com/lambda/faqs/,因此Lambda函数失败了。
他们解释说,如果需要创建文件,则必须使用/tmp目录,我们在遇到这个问题之前没有注意到这一点。我们反复阅读文档,但仍然犯了这个错误,我想这种情况时有发生。无论如何,在更改库中的内容后,该函数现在按预期完美执行。
感谢大家的帮助。

你能指出FAQ中的一个具体问题吗?我浏览时找不到它。 - Sridhar Sarnobat
1
好的,我也找不到它(这很奇怪,但我相信自从我上次看到它以来他们已经更新了页面)。无论如何,我找到了另一个链接可能会有帮助: https://docs.aws.amazon.com/lambda/latest/dg/limits.html 搜索类似于“/tmp目录可用于...”的内容。 - Hime

0
你还遇到这个问题吗?可能是Lambda服务正在维护你所使用的特定区域。这个错误告诉我JRE已经损坏,无法访问rt.jar提供的库。如有必要,请联系支持团队。你可以在这里检查AWS健康状况。

嗨,是的,错误仍然存在。我们仍在寻找解决方案。 - Hime
不确定为什么会被踩。我们过去也遇到过Lambda的类似问题,但它们最终都自行解决了。就像我说的,如果您使用服务时收费并出现错误,请联系支持团队。 - Nektie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接