IllegalAccessError в Spark, вызванный async-http-клиентом

Контекст: я работаю над потоковым заданием Spark, которое записывает данные в InfluxDB, используя эту библиотеку. Здесь среда.

  • Scala 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"

Все компилируется и работает нормально на моем локальном компьютере, но когда я отправляю сборочный файл в кластер 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 искровые зависимости, но это та же версия, что и у кластера.

Я вроде как оставляю все как есть, но было бы лучше, если бы можно было использовать более новые версии. Или, по крайней мере, я хочу понять, почему эта проблема возникает, и избегать ее в будущем.

2 ответа

Решение

Я столкнулся с той же проблемой сегодня и нашел эту проблему на github, которая объясняет проблему. В основном у вас есть несколько ClassLoaders при использовании Spark

и io.netty.handler.ssl.NettySslPackageAccessor и io.netty.handler.ssl.JdkSslContext загружаются различными загрузчиками классов.

В этом случае попытка доступа к частному статическому полю пакета JdkSslContext.SUPPORTED_CIPHERS завершится ошибкой с IllegalAccessError, поскольку частные поля пакета "ограничены" на уровне ClassLoader.

О, и ваше решение также сработало для меня, спасибо.

Это вызвано тем, что оба io.netty:nettyа также org.asynchttpclient:async-http-client в вашем классе Если вы хотите использовать netty и assync-http-client, добавьте следующие зависимости в ваш скрипт сборки gradle (аналогично maven pom.xml):

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

Другие вопросы по тегам