来自 org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus 的番石榴秒表 IllegalAccessError
IllegalAccessError to guava's StopWatch from org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus
我正在尝试 运行 小型 spark 应用程序,但遇到以下异常:
Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.mapreduce.lib.input.FileInputFormat
at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:262)
at org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat.getSplits(CombineFileInputFormat.java:217)
at org.apache.spark.rdd.NewHadoopRDD.getPartitions(NewHadoopRDD.scala:95)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:120)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:32)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:120)
相关的 gradle 依赖项部分:
compile('org.apache.spark:spark-core_2.10:1.3.1')
compile('org.apache.hadoop:hadoop-mapreduce-client-core:2.6.2') {force = true}
compile('org.apache.hadoop:hadoop-mapreduce-client-app:2.6.2') {force = true}
compile('org.apache.hadoop:hadoop-mapreduce-client-shuffle:2.6.2') {force = true}
compile('com.google.guava:guava:19.0') { force = true }
听起来你的 Guava 版本不匹配。
您的代码库中的某些内容正在尝试调用 Stopwatch
构造函数,但该构造函数已从 Guava 17.0 中删除,取而代之的是静态工厂方法(createStarted()
和 createUnstarted()
)在 Guava 15.0 中添加。
您应该更新任何试图使用构造函数的代码,改为使用静态工厂方法。
hadoop:hadoop-mapreduce-client-core
的 版本 2.6.2
不能与 guava
的新版本一起使用(我试过 17.0
- 19.0
)因为 guava
的 StopWatch
构造函数无法访问(导致上述 IllegalAccessError
)
使用 hadoop-mapreduce-client-core
的最新版本 - 2.7.2
(他们在上述方法中不使用 guava
的 StopWatch
,而是使用 org.apache.hadoop.util.StopWatch
) 解决了这个问题,需要两个额外的依赖项:
compile('org.apache.hadoop:hadoop-mapreduce-client-core:2.7.2') {force = true}
compile('org.apache.hadoop:hadoop-common:2.7.2') {force = true} // required for org.apache.hadoop.util.StopWatch
compile('commons-io:commons-io:2.4') {force = true} // required for org.apache.commons.io.Charsets that is used internally
注意:
有两个 org.apache.commons.io
包:
commons-io:commons-io(我们这里的),和
org.apache.commons:commons-io(旧的,2007 年)。确保包括正确的。
我在使用 Spark 1.6.1 时遇到了这个问题,因为我们的一个附加依赖项驱逐了 Guava 14.0.1 并将其替换为 18.0。 Spark 对 hadoop-client 的基本依赖为 2.2。请参阅 [Maven 回购] (https://mvnrepository.com/artifact/org.apache.spark/spark-core_2.10/1.6.1)
有效的解决方案是向 sbt libraryDependencies
添加以下内容:"org.apache.hadoop" % "hadoop-client" % "2.7.2"
在我的例子中,因为添加guava 21.0
导致错误。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
之后,我正在使用 guava 15.0
或删除上述依赖项。我的代码运行良好。
我刚刚将我的 guava 版本从 19.0 更改为 15.0,它可以正常工作。我目前使用的版本是 spark 2.2
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
</dependency>
看来是依赖库的问题
基本上,当您尝试将数据放入 hbase 时会遇到问题 table。
最初我用过<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.1.2</version> </dependency>
我遇到了和你类似的问题,后来我改成<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-shaded-client</artifactId> <version>1.1.2</version> </dependency>
,现在问题已经解决了。
解决方案
- guava.jar 文件的多个版本作为传递依赖项发生冲突,导致此异常。
- 确定冲突版本并在 pom.xml 中添加为排除项将解决此问题。
- 在我的例子中,添加 pmml-evaluator version 1.4.1 依赖导致了这个异常。
通过依赖层次结构识别并添加 Maven 排除解决了这个问题。
<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator</artifactId>
<version>1.4.1</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
如果您想在不重新构建 Spark 的情况下解决此问题,例如使用预构建的 Spark 发行版,那么我发现以下内容适用于 Apache Spark 2.3.0(即使用预构建的:'spark-2.3.0-bin-without-hadoop'):
- 从 Spark 'jars' 目录重命名或删除 'hadoop-mapreduce-client-core' jar 文件的错误版本(在我的例子中是 'hadoop-mapreduce-client-core-2.6.5.jar')。
- 将 'hadoop-mapreduce-client-core' jar 的兼容版本(从您的 Hadoop 安装)复制(或软 link)到 Spark 'jars' 目录中。
也可以通过更改类路径强制使用所需的 'hadoop-mapreduce-client-core' jar 文件(以便 Spark 从 Hadoop 中找到版本,而不是随 Spark 分发的版本)。
我们刚刚使用 IntelliJ 和 Spark 遇到了同样的情况。
使用时
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.1"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.3.1"
com.google.guava下载20.0,下载hadoop client 2.6.5。
最快的解决方案是将 guava 库强制升级到版本 15.0 (SBT)
dependencyOverrides += "com.google.guava" % "guava" % "15.0"
我正在尝试 运行 小型 spark 应用程序,但遇到以下异常:
Exception in thread "main" java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.mapreduce.lib.input.FileInputFormat
at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:262)
at org.apache.hadoop.mapreduce.lib.input.CombineFileInputFormat.getSplits(CombineFileInputFormat.java:217)
at org.apache.spark.rdd.NewHadoopRDD.getPartitions(NewHadoopRDD.scala:95)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:120)
at org.apache.spark.rdd.RDD.partitions(RDD.scala:217)
at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:32)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:219)
at org.apache.spark.rdd.RDD$$anonfun$partitions.apply(RDD.scala:217)
at scala.Option.getOrElse(Option.scala:120)
相关的 gradle 依赖项部分:
compile('org.apache.spark:spark-core_2.10:1.3.1')
compile('org.apache.hadoop:hadoop-mapreduce-client-core:2.6.2') {force = true}
compile('org.apache.hadoop:hadoop-mapreduce-client-app:2.6.2') {force = true}
compile('org.apache.hadoop:hadoop-mapreduce-client-shuffle:2.6.2') {force = true}
compile('com.google.guava:guava:19.0') { force = true }
听起来你的 Guava 版本不匹配。
您的代码库中的某些内容正在尝试调用 Stopwatch
构造函数,但该构造函数已从 Guava 17.0 中删除,取而代之的是静态工厂方法(createStarted()
和 createUnstarted()
)在 Guava 15.0 中添加。
您应该更新任何试图使用构造函数的代码,改为使用静态工厂方法。
hadoop:hadoop-mapreduce-client-core
的 版本 2.6.2
不能与 guava
的新版本一起使用(我试过 17.0
- 19.0
)因为 guava
的 StopWatch
构造函数无法访问(导致上述 IllegalAccessError
)
使用 hadoop-mapreduce-client-core
的最新版本 - 2.7.2
(他们在上述方法中不使用 guava
的 StopWatch
,而是使用 org.apache.hadoop.util.StopWatch
) 解决了这个问题,需要两个额外的依赖项:
compile('org.apache.hadoop:hadoop-mapreduce-client-core:2.7.2') {force = true}
compile('org.apache.hadoop:hadoop-common:2.7.2') {force = true} // required for org.apache.hadoop.util.StopWatch
compile('commons-io:commons-io:2.4') {force = true} // required for org.apache.commons.io.Charsets that is used internally
注意:
有两个 org.apache.commons.io
包:
commons-io:commons-io(我们这里的),和
org.apache.commons:commons-io(旧的,2007 年)。确保包括正确的。
我在使用 Spark 1.6.1 时遇到了这个问题,因为我们的一个附加依赖项驱逐了 Guava 14.0.1 并将其替换为 18.0。 Spark 对 hadoop-client 的基本依赖为 2.2。请参阅 [Maven 回购] (https://mvnrepository.com/artifact/org.apache.spark/spark-core_2.10/1.6.1)
有效的解决方案是向 sbt libraryDependencies
添加以下内容:"org.apache.hadoop" % "hadoop-client" % "2.7.2"
在我的例子中,因为添加guava 21.0
导致错误。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
之后,我正在使用 guava 15.0
或删除上述依赖项。我的代码运行良好。
我刚刚将我的 guava 版本从 19.0 更改为 15.0,它可以正常工作。我目前使用的版本是 spark 2.2
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
</dependency>
看来是依赖库的问题
基本上,当您尝试将数据放入 hbase 时会遇到问题 table。
最初我用过<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.1.2</version> </dependency>
我遇到了和你类似的问题,后来我改成<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-shaded-client</artifactId> <version>1.1.2</version> </dependency>
,现在问题已经解决了。
解决方案
- guava.jar 文件的多个版本作为传递依赖项发生冲突,导致此异常。
- 确定冲突版本并在 pom.xml 中添加为排除项将解决此问题。
- 在我的例子中,添加 pmml-evaluator version 1.4.1 依赖导致了这个异常。
通过依赖层次结构识别并添加 Maven 排除解决了这个问题。
<dependency> <groupId>org.jpmml</groupId> <artifactId>pmml-evaluator</artifactId> <version>1.4.1</version> <scope>test</scope> <exclusions> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> </exclusions> </dependency>
如果您想在不重新构建 Spark 的情况下解决此问题,例如使用预构建的 Spark 发行版,那么我发现以下内容适用于 Apache Spark 2.3.0(即使用预构建的:'spark-2.3.0-bin-without-hadoop'):
- 从 Spark 'jars' 目录重命名或删除 'hadoop-mapreduce-client-core' jar 文件的错误版本(在我的例子中是 'hadoop-mapreduce-client-core-2.6.5.jar')。
- 将 'hadoop-mapreduce-client-core' jar 的兼容版本(从您的 Hadoop 安装)复制(或软 link)到 Spark 'jars' 目录中。
也可以通过更改类路径强制使用所需的 'hadoop-mapreduce-client-core' jar 文件(以便 Spark 从 Hadoop 中找到版本,而不是随 Spark 分发的版本)。
我们刚刚使用 IntelliJ 和 Spark 遇到了同样的情况。
使用时
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.1"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.3.1"
com.google.guava下载20.0,下载hadoop client 2.6.5。
最快的解决方案是将 guava 库强制升级到版本 15.0 (SBT)
dependencyOverrides += "com.google.guava" % "guava" % "15.0"