AWS Lambda使用来自多版本JAR的不正确类文件?
问题描述
我有一个lambda在Java 8下运行了几年,我刚刚把它更新到Java 11。它立即坏了,给我这样的错误:
这个类并不特别令人兴奋,它有一个简单的静态初始化,这在我的类中很常见:
我以前遇到过这样的问题,当我将我的(非Lambda)Java服务器从8切换到11时;我需要将JAR的清单标记为Multi-Release: true
,因为我所依赖的ApacheLog4j构件为Java 8和9+中的org.apache.logging.log4j.util.StackLocator
类提供了替代实现。然而,我有点希望JVM只选择类的适当版本。是否有我必须在某个地方设置的配置?是否可能在某处将我的Lambda从Java 8->;Java 11切换为混淆了?
jar/META-INF/versions:
编辑:我发现some references表明,当AWS Lambda提取JAR时,他们不会提取META-INF目录,该目录包含MANIFEST.MF文件,该文件告诉JVM该JAR是多版本JAR。Lambda是否支持多版本JAR?
推荐答案
不完全是您问题的答案,但我希望这可能会有帮助。
您的分析是正确的-AWS lambda提取整个JAR文件。然后,运行lambda函数的JVM不再将代码识别为JAR文件,并且实际上会忽略整个META-INF目录。在我的例子中,我使用maven-shade-plugin
创建了一个包含lambda函数的所有依赖项的&uber";-jar。official AWS documentation中推荐使用这种方法。
现在--这一点很重要--maven-shade-plugin
提取所有JAR文件依赖项,并将它们重新打包到单个平面JAR文件中。如果您的一个依赖项是多版本JAR(就像log4j2一样),那么您可以配置maven-shade-plugin
以重新构建适当的META-INF目录,如果您将JAR作为JAR文件运行,那么一切仍然正常。
但是,因为AWS Lambda提取JAR,所以JVM不再看到META-INF目录,并且META-INF/版本中的任何内容都将被忽略。
要解决这个问题,我切换到maven-assembly-plugin
。它允许使用lambda的代码创建ZIP文件,并将依赖项添加为JAR文件。现在,当AWS Lambda解压缩此ZIP文件时,JAR保持完好,一切工作正常。
要进行配置,请创建一个文件assembly.xml
,如下所示:
然后您需要在pom.xml
中配置maven-assembly-plugin
:
现在,只需像往常一样将生成的压缩文件部署到AWS Lambda,就可以了!
作为备注-阴影JAR文件包含数千个单独的.class
文件,而汇编的ZIP文件只包含少数几个JAR文件。即使总体大小(以字节为单位)更大,文件的数量也会少得多,从而减少冷启动时间。我还没有在AWS Cloud上测试过这一点,但在我的LocalStack上,冷启动时间从大约1分钟降到了6秒--这绝对是一个很好的开发助推器。
这篇关于AWS Lambda使用来自多版本JAR的不正确类文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!