【问题标题】:AWS Lambda Java to S3 - java.lang.ClassNotFoundException on com.amazonaws.services.s3.AmazonS3ClientBuilderAWS Lambda Java 到 S3 - com.amazonaws.services.s3.AmazonS3ClientBuilder 上的 java.lang.ClassNotFoundException
【发布时间】:2018-08-07 19:20:36
【问题描述】:

我尝试在本地运行以下代码(作为 IntelliJ 中的 maven 项目)并且运行正常。当我尝试将它作为 Lambda 函数运行时,我总是得到一个 java.lang.NoClassDefFoundError。不知何故,lambda 做到了,所以当我在下面包含 AmazonS3 行时找不到该类。

package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

public class ParserLambda implements RequestHandler<Object, Object> {
    @Override
    public Object handleRequest(Object input, Context context) {
        String retval = "";
        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
        } catch (Exception ex) {
            return "{'status':'error', 'retval': '" + ex.getMessage() + "'}";
        }
        return "{'status':'done', 'retval': '" + retval + "'}";
    }
}

如果我注释掉以下行

//AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();

它给出:"{'status':'done', 'retval': ''}"。这是一个有效的结果。

未注释时

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();

我明白了:

{
  "errorMessage": "com/amazonaws/services/s3/AmazonS3ClientBuilder",
  "errorType": "java.lang.NoClassDefFoundError",
  "stackTrace": [
    "example.ParserLambda.handleRequest(ParserLambda.java:11)",
    "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
    "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
    "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
    "java.lang.reflect.Method.invoke(Method.java:498)"
  ],
  "cause": {
    "errorMessage": "com.amazonaws.services.s3.AmazonS3ClientBuilder",
    "errorType": "java.lang.ClassNotFoundException",
    "stackTrace": [
      "java.net.URLClassLoader.findClass(URLClassLoader.java:381)",
      "java.lang.ClassLoader.loadClass(ClassLoader.java:424)",
      "java.lang.ClassLoader.loadClass(ClassLoader.java:357)",
      "example.ParserLambda.handleRequest(ParserLambda.java:11)",
      "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
      "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
      "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
      "java.lang.reflect.Method.invoke(Method.java:498)"
    ]
  }
}

我的 pom 文件包括:

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.11.286</version>
</dependency>

我也试过了:

AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion(Regions.US_EAST_1).withForceGlobalBucketAccessEnabled(true).build();

但没有成功。

【问题讨论】:

    标签: java amazon-web-services amazon-s3 aws-lambda aws-sdk


    【解决方案1】:

    我遇到了同样的问题,经过几次不同的尝试后解决了。

    在我的pom.xml 中调整以下依赖项是不够的(注意&lt;scope&gt;provided&lt;/scope&gt;aws-java-sdk 依赖项):

    <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk -->
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk</artifactId>
        <version>1.11.664</version>
        <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-s3</artifactId>
        <version>1.11.664</version>
    </dependency>
    

    原来我在pom.xml 中缺少以下插件:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>3.2.1</version>
          <configuration>
            <createDependencyReducedPom>false</createDependencyReducedPom>
          </configuration>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
    

    而且我以错误的方式构建 jar 文件。构建 jar 文件的最佳方法是使用终端或命令提示符导航到项目目录并执行以下命令:

    mvn package
    

    这包括您的 jar 文件中所有必要的依赖项。您的 jar 文件将位于 ./target 目录中。


    来源:https://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html

    【讨论】:

    • 感谢您指出最后一步!知道为什么 Intellij IDEA 不能正确构建包吗?
    【解决方案2】:

    我认为问题在于 aws-java-sdk-s3 没有作为 aws-java-sdk 的一部分提供给 lambda 函数,因此您必须将其明确包含在您的 .jar 中。

    我的 pom 看起来像这样清除错误:

            <dependencies>
                <dependency>
                    <groupId>com.amazonaws</groupId>
                    <artifactId>aws-java-sdk</artifactId>
                    <version>1.11.297</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>com.amazonaws</groupId>
                    <artifactId>aws-java-sdk-s3</artifactId>
                    <version>1.11.297</version>
                </dependency>
    

    【讨论】:

      猜你喜欢
      • 2021-07-02
      • 1970-01-01
      • 2020-02-08
      • 2017-07-30
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 2016-01-11
      • 2021-02-12
      相关资源
      最近更新 更多