LoginSignup
1

More than 5 years have passed since last update.

EMR5.7でAmazonDynamoDBClientBuilderが上手く使えない対応

Last updated at Posted at 2017-08-15

環境

EMRは5.7。
aws-java-sdk-dynamodbのバージョンは下記。

build.sbt
libraryDependencies += "com.amazonaws" % "aws-java-sdk-dynamodb" % "1.11.170"

sbt assembly で固めたFAT-JARをEMR上にデプロイ&実行するとエラーが発生。
ローカルでは上手く動くので原因がわからず少し困った。

事象

EMR5.7にて AmazonDynamoDBClientBuilder を利用すると NoClassDefFoundError
AmazonDynamoDBClientBuilder はパスを通している(FAT-JARに含まれている)ので、ClassNotFoundException では無いだろうと思っていたが、原因が特定できず戸惑った。

エラー1
17/08/14 10:17:39 INFO Client:
    (略)
java.lang.NoClassDefFoundError: Could not initialize class com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder
        at SparkApp$$anonfun$main$1$$anonfun$1.apply(SparkApp.scala:58)
        at SparkApp$$anonfun$main$1$$anonfun$1.apply(SparkApp.scala:51)
        at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1$$anonfun$apply$23.apply(RDD.scala:797)
        at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1$$anonfun$apply$23.apply(RDD.scala:797)
        at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:323)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:287)
        (略)

しばらく動かしたりログを探すと、IllegalAccessErrorがでていた。
どうやらこれが原因なようだ。

エラー2
17/08/14 11:04:29 INFO Client:
    (略)
java.lang.IllegalAccessError: tried to access class com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientConfigurationFactory from class com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder
        at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder.<clinit>(AmazonDynamoDBClientBuilder.java:27)
        at SparkApp$$anonfun$main$1$$anonfun$1.apply(SparkApp.scala:58)
        at SparkApp$$anonfun$main$1$$anonfun$1.apply(SparkApp.scala:51)
        at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1$$anonfun$apply$23.apply(RDD.scala:797)
        at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1$$anonfun$apply$23.apply(RDD.scala:797)
        at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)
        at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:323)
        at org.apache.spark.rdd.RDD.iterator(RDD.scala:287)

調査

調べるといくつか出てきた。

どうやら、EMR5.7はaws-java-sdkのバージョンが 1.10.75.1 までしか対応していないとのこと。現在(※2017/08/15)は1.11系が出ているので、けっこう古い。というか本当なのか?

ということで、公式のドキュメントを調べると...

AWS SDK for Java が 1.10.75 にアップグレード
* http://docs.aws.amazon.com/ja_jp/emr/latest/ReleaseGuide/emr-whatsnew.html

と書いてあり、1.10.75 までは対応していることは見つけたが、それ以降のバージョンについては述べていない。うーむ、信頼できるのか?

対応

ということで、半信半疑ながらSDKのバージョンをダウングレードした。

build.sbt
libraryDependencies += "com.amazonaws" % "aws-java-sdk-dynamodb" % "1.10.75.1"

そうすると、AmazonDynamoDBClientBuilderが利用できないので、今ではdeplicatedになっているAmazonDynamoDBClientを利用して書き換えすることに。

OLD_dynamodbサンプル.scala
    val client = AmazonDynamoDBClientBuilder.standard
      .withRegion("ap-northeast-1")
      .build
    val dynamoDB = new DynamoDB(client)

こちら↑をすこし編集するのみで動いてくれた。

NEW_dynamodbサンプル.scala
    val client = new AmazonDynamoDBClient()
    client.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1))
    val dynamoDB = new DynamoDB(client)

実行結果

実行すると...
上手く動いてくれた。さすがStackOverFlow!

なぜ IllegalAccessError が出てしまうかだが、EMR上でもaws-java-sdkがロードされていると思うので、かみ合わせが悪いのか?このあたりよく分かっていない。

まとめ

EMRでDynamoDBに書き込む時は、SDKのバージョンに気をつけよう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1