Контекст: я работаю над заданием потоковой передачи Spark, которое записывает данные в InfluxDB, используя эта библиотека. Вот окружающая среда.
- Скала 2.11.8
- Spark 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"
Все компилируется и работает нормально на моем локальном компьютере, но когда я отправляю jar сборки в кластер 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
, но это та же версия, что и кластер.
Я согласен оставить все как есть, но было бы лучше, если бы можно было использовать более новые версии. Или, по крайней мере, я хочу понять, почему возникает эта проблема, и избежать ее в будущем.