Excepción de tiempo de ejecución java.lang.NoSuchMethodError: com.google.common.base.Optional.toJavaUtil()L con conector Spark-BigQuery

Actualmente estoy tratando de conectarme a BigQuery desde Spark. He construido un archivo de frasco de grasa usando sbt assembly plugin e intentar lanzar el trabajo en modo local utilizando spark-submit. Estoy observando. java.lang.NoSuchMethodError: com.google.common.base.Optional.toJavaUtil()Ljava/util/Optional; excepción tan pronto como se inicie el trabajo de Spark.

A continuación está el rastro de excepción,

Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Optional.toJavaUtil()Ljava/util/Optional;
    at com.google.cloud.spark.bigquery.SparkBigQueryConfig.getOption(SparkBigQueryConfig.java:265)
    at com.google.cloud.spark.bigquery.SparkBigQueryConfig.getOption(SparkBigQueryConfig.java:256)
    at com.google.cloud.spark.bigquery.SparkBigQueryConfig.lambda$getOptionFromMultipleParams$7(SparkBigQueryConfig.java:273)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1812)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
    at com.google.cloud.spark.bigquery.SparkBigQueryConfig.getOptionFromMultipleParams(SparkBigQueryConfig.java:275)
    at com.google.cloud.spark.bigquery.SparkBigQueryConfig.from(SparkBigQueryConfig.java:119)
    at com.google.cloud.spark.bigquery.BigQueryRelationProvider.createSparkBigQueryConfig(BigQueryRelationProvider.scala:133)
    at com.google.cloud.spark.bigquery.BigQueryRelationProvider.createRelationInternal(BigQueryRelationProvider.scala:71)
    at com.google.cloud.spark.bigquery.BigQueryRelationProvider.createRelation(BigQueryRelationProvider.scala:45)
    at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:340)
    at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:239)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:227)
    at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:174)
    at com.bigquery.OwnDataSetReader$.delayedEndpoint$com$$bigquery$OwnDataSetReader$1(OwnDataSetReader.scala:18)
    at com.bigquery.OwnDataSetReader$delayedInit$body.apply(OwnDataSetReader.scala:6)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.App$$anonfun$main$1.apply(App.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.App$class.main(App.scala:76)
    at com..bigquery.OwnDataSetReader$.main(OwnDataSetReader.scala:6)
    at com..bigquery.OwnDataSetReader.main(OwnDataSetReader.scala)
    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.JavaMainApplication.start(SparkApplication.scala:52)
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:894)
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:198)
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:228)
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:137)
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

Después de hacer algunas investigaciones sobre la excepción, encontré que esta excepción puede suceder debido a la versión múltiple de guava biblioteca. Me aseguré de que no haya tales conflictos en el tarro de construcción final, también lo verifiqué descomponiendo mi archivo de tarro. No se observaron conflictos, pero la cuestión persiste:(. A continuación se muestra el build.sbt Snippet,

name := "bigquer-connector"

version := "0.1"

scalaVersion := "2.11.8"
test in assembly := {}

assemblyJarName in assembly := "BigQueryConnector.jar"

assemblyMergeStrategy in assembly := {
  case x if x.startsWith("META-INF") => MergeStrategy.discard
  case x =>
    val oldStrategy = (assemblyMergeStrategy in assembly).value
    oldStrategy(x)

}

libraryDependencies += ("com.google.cloud.spark" %% "spark-bigquery" % "0.18.0")
  .exclude("com.google.guava", "guava")
  .exclude("org.glassfish.jersey.bundles.repackaged", "jersey-guava")

libraryDependencies += "com.google.guava" % "guava" % "30.0-jre"

libraryDependencies += ("org.apache.spark" % "spark-core_2.11" % "2.3.1")
  .exclude("com.google.guava", "guava")
  .exclude("org.glassfish.jersey.bundles.repackaged", "jersey-guava")


libraryDependencies += ("org.apache.spark" % "spark-sql_2.11" % "2.3.1")
  .exclude("com.google.guava", "guava")
  .exclude("org.glassfish.jersey.bundles.repackaged", "jersey-guava")

A continuación está la clase principal,

object OwnDataSetReader extends App {

  val session = SparkSession.builder()
    .appName("big-query-connector")
    .config(getConf)
    .getOrCreate()

  session.read
    .format("com.google.cloud.spark.bigquery")
    .option("viewsEnabled", true)
    .option("parentProject", "my_gcp_project")
    .option("credentialsFile", "")
    .load("my_gcp_data_set.my_gcp_view")
    .show(2)

  private def getConf : SparkConf = {
    val sparkConf = new SparkConf
    sparkConf.setAppName("biq-query-connector")
    sparkConf.setMaster("local[*]")

    sparkConf
  }
}

Comando utilizado para lanzar el Spark en mi terminal local: spark-submit --deploy-mode client --class com.bigquery.OwnDataSetReader BigQueryConnector.jar. Estoy usando la versión de chispa 2.3.x en mi máquina local

Pregunta hecha hace 3 años, 4 meses, 26 días - Por cybermage


4 Respuestas:

  • Pude solucionar el problema. Fue con estrategia de fusión en mi build.sbt archivo.

    assemblyMergeStrategy in assembly := {
      case x if x.startsWith("META-INF") => MergeStrategy.discard
      case x =>
        val oldStrategy = (assemblyMergeStrategy in assembly).value
        oldStrategy(x)
    
    }
    

    Estaba descartando los archivos META-INF carpeta. Los archivos de configuración dentro META-INF carpeta de spark-bigquery El conector se utiliza durante el arranque de la biblioteca. Así que, en lugar de descartar, cambiar la estrategia como abajo funcionó para mí.

    case PathList("META-INF", xs @ _*) =>
        (xs map {_.toLowerCase}) match {
          case ("manifest.mf" :: Nil) | ("index.list" :: Nil) | ("dependencies" :: Nil) | ("license" :: Nil) | ("licence.txt" :: Nil) | ("notice.txt" :: Nil) | ("notice" :: Nil)=>
            MergeStrategy.discard
          case ps @ (x :: xs) if ps.last.endsWith(".sf") || ps.last.endsWith(".dsa") || ps.contains("license") || ps.contains("notice") =>
            MergeStrategy.discard
          case "plexus" :: xs =>
            MergeStrategy.discard
          case "services" :: xs =>
            MergeStrategy.filterDistinctLines
          case _ => MergeStrategy.last
        }
    

    Respondida el Dec 19, 2020 a las 10:17 - por compilerhero

    Votos positivos: 0 | Votos negativos: 0

  • Probablemente es debido a la versión desajuste entre bibliotecas dependientes de com.google.cloud.spark:spark-bigquery_2.11:0.18.1. Se resolvió para mí usando com.google.cloud.spark:spark-bigquery-with-dependencies_2.11:0.18.1 que trae todas las libs dependientes.

    Respondida el Dec 19, 2020 a las 10:24 - por devdynamox

    Votos positivos: 0 | Votos negativos: 0

  • El error java.lang.NoSuchMethodError: com.google.common.base.Optional.toJavaUtil()Ljava/util/Optional; que estás experimentando puede ser causado por una diferencia en las versiones de las bibliotecas que estás utilizando en tu aplicación. Aunque has hecho un buen trabajo al excluir y especificar las versiones de las dependencias en tu archivo build.sbt, parece que todavía persiste el problema.

    Una posible solución que podrías intentar es excluir explícitamente el uso de la versión de Guava incluida en la biblioteca spark-bigquery y en su lugar usar la versión de Guava que tú has especificado en tu archivo build.sbt. Para hacer esto, puedes intentar modificar tus dependencias de la siguiente manera:

    scala
    libraryDependencies += ("com.google.cloud.spark" %% "spark-bigquery" % "0.18.0")
      .exclude("com.google.guava", "guava")
      .exclude("org.glassfish.jersey.bundles.repackaged", "jersey-guava")
      .exclude("com.google.guava", "guava-jdk5") // Nueva exclusión
    
    libraryDependencies += "com.google.guava" % "guava" % "30.0-jre"
    

    Con la nueva exclusión que hemos agregado en el primer bloque de código, estamos excluyendo cualquier posible conflicto con la versión de Guava que proporciona spark-bigquery, y especificamos la versión que queremos usar en su lugar.

    Después de realizar estos cambios, vuelve a compilar tu aplicación con sbt assembly y vuelve a ejecutarla con spark-submit. Con suerte, esta solución te ayudará a resolver el error que estás enfrentando.

    Respondida el Dec 20, 2020 a las 10:17 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error java.lang.NoSuchMethodError: com.google.common.base.Optional.toJavaUtil()Ljava/util/Optional; indica que estás intentando utilizar un método que no existe en la versión de la biblioteca guava que estás utilizando.

    Existen algunas opciones para resolver este problema:

    • Actualiza la versión de `guava`: La versión de `guava` que estás utilizando puede ser demasiado antigua. Actualiza a la última versión disponible y vuelve a intentarlo.
    • Asegúrate de que `guava` está en tu ruta de clase: Verifica que el JAR de `guava` esté incluido en la ruta de clase de tu aplicación. Puedes usar el comando `jar -tf` para verificar el contenido del JAR.
    • Evita conflictos de versiones: Es posible que tengas múltiples versiones de `guava` en tu ruta de clase, lo que puede provocar conflictos. Asegúrate de que solo haya una versión de `guava` en tu ruta de clase y vuelve a intentarlo.
    • Utiliza una versión compatible de Spark: La versión de Spark que estás utilizando puede no ser compatible con la versión de `guava` que estás utilizando. Intenta utilizar una versión compatible de Spark.
    • Revisa tu código: Revisa tu código para asegurarte de que no estás llamando accidentalmente al método `toJavaUtil()` en una versión antigua de `guava`.

    Si has intentado todas estas opciones y el problema persiste, puedes proporcionar más información sobre tu configuración, como las versiones específicas de Spark, guava y el conector Spark-BigQuery que estás utilizando.

    Respondida el Dec 20, 2020 a las 10:23 - por Gemini

    Votos positivos: 0 | Votos negativos: 0