2017-01-17 7 views
5

コンテキスト:this libraryを使用してInfluxDBにデータを書き込むSparkストリーミングジョブに取り組んでいます。ここに環境があります。async-http-clientによって引き起こされたSparkのIllegalAccessError

  • スカラ座2.11.8
  • スパーク2.1.0(Dockerizedスタンドアロンクラスタ)

関連の依存関係:

"org.apache.spark" %% "spark-core" % "2.1.0" % "provided", 
"org.apache.spark" %% "spark-streaming" % "2.1.0" % "provided", 
"org.apache.spark" %% "spark-streaming-kafka-0-8" % "2.1.0", 
"com.paulgoldbaum" %% "scala-influxdb-client" % "0.5.2" // which uses "org.asynchttpclient" % "async-http-client" % "2.0.24" 

すべてがコンパイルされ、自分のローカルコンピュータ上で正常に動作しますが、私はSparkクラスタにアセンブリの瓶を提出すると、私はドライバでこのエラーが発生します:

Exception in thread "main" java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.spark.deploy.worker.DriverWrapper$.main(DriverWrapper.scala:58) 
    at org.apache.spark.deploy.worker.DriverWrapper.main(DriverWrapper.scala) 
Caused by: java.lang.IllegalAccessError: tried to access field io.netty.handler.ssl.JdkSslContext.SUPPORTED_CIPHERS from class io.netty.handler.ssl.NettySslPackageAccessor 
    at io.netty.handler.ssl.NettySslPackageAccessor.jdkSupportedCipherSuites(NettySslPackageAccessor.java:24) 
    at org.asynchttpclient.config.AsyncHttpClientConfigDefaults.defaultEnabledCipherSuites(AsyncHttpClientConfigDefaults.java:85) 
    at org.asynchttpclient.DefaultAsyncHttpClientConfig$Builder.<init>(DefaultAsyncHttpClientConfig.java:635) 
    at org.asynchttpclient.DefaultAsyncHttpClient.<init>(DefaultAsyncHttpClient.java:67) 
    at com.paulgoldbaum.influxdbclient.HttpClient.<init>(HttpClient.scala:21) 
    at com.paulgoldbaum.influxdbclient.InfluxDB$.connect(InfluxDB.scala:16) 
    ... 

InfluxDBに書き込むためのコードを削除すると問題が消えます。

私が学んだことは、クラスio.netty.handler.ssl.NettySslPackageAccessorが実際にasync-http-clientライブラリに属していることです。 io.netty.handler.ssl.JdkSslContextの保護されたメンバーにアクセスするためのハッククラスのようです。

私は数日間この問題を悩ましました。私がそれを動作させるための解決策は、問題のコードを含まない以前のバージョンにasync-http-clientを上書きすることです。

dependencyOverrides ++= Set("org.asynchttpclient" % "async-http-client" % "2.0.12") 

質問:はなぜIllegalAccessErrorのみクラスタではなく、私の地元のランで起こっているのでしょうか?この問題を解決する良い方法はありますか?

私のSBTがうまくコンパイルできる場合、そのようなIllegalAccessErrorは存在しないはずです。つまり、私のローカルコードとクラスタコードの間に違いがあります。おそらくprovidedスパークの依存関係ですが、クラスターとして

私はそれをそのまま残すことができますが、新しいバージョンを使用することができれば良いでしょう。あるいは、少なくとも私はこの問題がなぜ発生するのかを理解し、将来それを避けたいと思っています。

答えて

1

今日同じ問題が発生しましたが、問題を説明しているgithubにthis issueが見つかりました。基本的には、Spark

を使用している場合、複数のクラスローダを持っており、io.netty.handler.ssl.NettySslPackageAccessorと io.netty.handler.ssl.JdkSslContextは異なる のClassLoaderによってロードされています。

このような場合は、パッケージ・プライベートフィールドは クラスローダレベルでの「スコープ」されているため、試行アクセスパッケージプライベート 静的フィールドJdkSslContext.SUPPORTED_CIPHERSは ないIllegalAccessErrorで失敗します。

ああ、あなたのソリューションも私のために働いてくれてありがとう。

+0

意味があります。私はそれについて何もできないように見えます。しかたがない。ありがとう。 – tamatama

0

これは、クラスパスにio.netty:nettyorg.asynchttpclient:async-http-clientの両方があるために発生します。もしあなたがnettyとassync-http-clientを使いたいなら、あなたのgradleに以下の依存関係を追加してください。xml)ビルドスクリプト:

compile 'org.asynchttpclient:async-http-client:2.0.38' compile 'org.asynchttpclient:async-http-client-netty-utils:2.0.38'

関連する問題