AWS Lambdaでcom.fasterxml.jackson.databind.JsonMappingExceptionが出た時の話

  • 2
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

概要

AWS Lambdaでテスト実行した時にこんなエラーが出ました。
その時の話です。
結論テストデータがおかしいだけです。

{
  "errorMessage": "An error occurred during JSON parsing",
  "errorType": "java.lang.RuntimeException",
  "stackTrace": [],
  "cause": {
    "errorMessage": "com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@2f7c7260; line: 1, column: 1]",
    "errorType": "java.io.UncheckedIOException",
    "stackTrace": [],
    "cause": {
      "errorMessage": "Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@2f7c7260; line: 1, column: 1]",
      "errorType": "com.fasterxml.jackson.databind.JsonMappingException",
      "stackTrace": [
        "com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)",
        "com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:835)",
        "com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:59)",
        "com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:12)",
        "com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1441)",
        "com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1047)"
      ]
    }
  }
}

行ったこと

1. ScalaでLambda処理するコードを書いた。

build.sbt

scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  "com.amazonaws" % "aws-lambda-java-core" % "1.0.0",
  "com.amazonaws" % "aws-lambda-java-events" % "1.1.0"
)

project/build.properties

sbt.version=0.13.11

project/plugins.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.13.0")

src/main/scala/com/ru/waka/Hello.scala

package com.ru.waka

import com.amazonaws.services.lambda.runtime.{RequestHandler, Context}

class Hello extends RequestHandler[String, String] {
  override def handleRequest(e: String, context: Context): String = {
    println(e)
    e
  }
}

2. jarファイル化した

sbt assembly するだけです。
https://github.com/sbt/sbt-assembly

$sbt
aassembly[info] Loading project definition from /path/to/repo/project
[info] Set current project to lambda-scala (in build file:/path/to/repo/)
> assembly
[info] Including from cache: aws-java-sdk-sns-1.11.2.jar
[info] Including from cache: aws-java-sdk-core-1.11.2.jar
[info] Including from cache: aws-java-sdk-sqs-1.11.2.jar
[info] Including from cache: commons-logging-1.1.3.jar
[info] Including from cache: jackson-databind-2.6.6.jar
[info] Including from cache: aws-java-sdk-cognitoidentity-1.11.2.jar
[info] Including from cache: jackson-annotations-2.6.0.jar
[info] Including from cache: jackson-core-2.6.6.jar
[info] Including from cache: jackson-dataformat-cbor-2.6.6.jar
[info] Including from cache: aws-java-sdk-kinesis-1.11.2.jar
[info] Including from cache: httpclient-4.5.2.jar
[info] Including from cache: joda-time-2.8.1.jar
[info] Including from cache: httpcore-4.4.4.jar
[info] Including from cache: commons-codec-1.9.jar
[info] Including from cache: aws-java-sdk-dynamodb-1.11.2.jar
[info] Including from cache: aws-lambda-java-events-1.1.0.jar
[info] Including from cache: aws-lambda-java-core-1.0.0.jar
[info] Including from cache: aws-java-sdk-kms-1.11.2.jar
[info] Including from cache: aws-java-sdk-s3-1.11.2.jar
[info] Including from cache: scala-library-2.11.8.jar
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF/DEPENDENCIES' with strategy 'discard'
[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-cognitoidentity/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-cognitoidentity/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-core/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-core/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-dynamodb/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-dynamodb/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-kinesis/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-kinesis/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-kms/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-kms/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-s3/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-s3/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-sns/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-sns/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-sqs/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-java-sdk-sqs/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-lambda-java-core/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-lambda-java-core/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-lambda-java-events/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.amazonaws/aws-lambda-java-events/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/com.fasterxml.jackson.dataformat/jackson-dataformat-cbor/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/commons-codec/commons-codec/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/commons-codec/commons-codec/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/commons-logging/commons-logging/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/commons-logging/commons-logging/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/joda-time/joda-time/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/joda-time/joda-time/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/org.apache.httpcomponents/httpclient/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/org.apache.httpcomponents/httpclient/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/maven/org.apache.httpcomponents/httpcore/pom.properties' with strategy 'discard'
[warn] Merging 'META-INF/maven/org.apache.httpcomponents/httpcore/pom.xml' with strategy 'discard'
[warn] Merging 'META-INF/services/com.fasterxml.jackson.core.JsonFactory' with strategy 'filterDistinctLines'
[warn] Strategy 'discard' was applied to 40 files
[warn] Strategy 'filterDistinctLines' was applied to a file
[info] Assembly up to date: /path/to/repo/target/scala-2.11/lambda-scala-assembly-0.1-SNAPSHOT.jar
[success] Total time: 2 s, completed 2016/05/19 23:07:53

3. Lambdaの設定をした。

画面から行ったので、結果だけ・・・
/path/to/repo/target/scala-2.11/lambda-scala-assembly-0.1-SNAPSHOT.jar をaws consoleからuploadして利用しています。

aws lambda list-functions
{
    "Functions": [
        {
            "Version": "$LATEST",
            "CodeSha256": "N6aPy8vRJU03qBBqFT4xqNN1jH8YCZr7O1KbpCWmb5I=",
            "FunctionName": "exec-test-in-java",
            "VpcConfig": {
                "SubnetIds": [],
                "SecurityGroupIds": []
            },
            "MemorySize": 512,
            "CodeSize": 13538601,
            "FunctionArn": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxx:role:function:exec-test-in-java",
            "Handler": "com.ru.waka.Hello::handleRequest",
            "Role": "arn:aws:iam::xxxxxxxxxxx:role/lambda_basic_execution",
            "Timeout": 15,
            "LastModified": "2016-05-19T13:54:51.210+0000",
            "Runtime": "java8",
            "Description": ""
        }
    ]
}

4. TestEventの入力してテスト実行。

TestEvent用のテストデータ

{
  "key3": "value3",
  "key2": "value2",
  "key1": "value1"
}

この状態でテストを実行すると冒頭のエラーが起きます。

原因

理由はTestEventの入力がJsonになってて、これがStringに変換出来ないからです。

class Hello extends RequestHandler[String, String] {
  override def handleRequest(e: String, context: Context): String = {
    println(e)
    e
  }
}

上記コードのhandleRequestの第一引数にテストデータがbindされます。
しかし、今回のテストデータはjsonになっていたため他のStringに変換出来ずエラーが出てしまったようです。
Stringではない、なんらかのObjectになっているように思えます。
なので、このjsonを文字列として受け取りたい場合は下記の様にテストデータを変更する必要があります。

"{\"key3\": \"value3\",\"key2\": \"value2\",\"key1\": \"value1\"}"

この状態でテストを実行するとこんなログが出力されてうまくいきました。

START RequestId: f6f75658-1dcb-11e6-881d-17638fffbcef Version: $LATEST
{"key3": "value3","key2": "value2","key1": "value1"}
END RequestId: f6f75658-1dcb-11e6-881d-17638fffbcef
REPORT RequestId: f6f75658-1dcb-11e6-881d-17638fffbcef  Duration: 991.64 ms Billed Duration: 1000 ms    Memory Size: 512 MB Max Memory Used: 90 MB  

めでたしめでたし。

参考