2017-02-16 8 views
3

ハイブテーブルでSparkSqlを実行しようとしています。しかし、私が理解できなかった問題。ここに私のコードは次のとおりです。OrcRelationはHadoopFsRelationに割り当てられません

import org.apache.spark.SparkConf; 
import org.apache.spark.api.java.JavaSparkContext; 
import org.apache.spark.sql.Row; 
import org.apache.spark.sql.SparkSession; 
import org.apache.spark.sql.hive.*; 
import org.apache.spark.sql.SQLContext; 
public class queryhive { 
public static void main(String[] args) 
{ 
    //SparkSession sc = new SparkConf().setAppName("SparkSessionZipsExample").setMaster("local"); 
    SparkConf sparkConf = new SparkConf().setAppName("SparkSessionZipsExample").setMaster("local"); 
     JavaSparkContext scon = new JavaSparkContext(sparkConf); 
      SQLContext sqlContext = new SQLContext(scon); 
     String warehouseLocation = "file:${system:user.dir}/spark-warehouse"; 
      SparkSession sc = SparkSession 
       .builder() 
       .appName("SparkSessionZipsExample") 
       .config("spark.sql.warehouse.dir", warehouseLocation) 
       .enableHiveSupport() 
       .getOrCreate(); 
      HiveContext hc = new org.apache.spark.sql.hive.HiveContext(sc); 
      hc.sql("select count(*) from SparkHive.health"); 
      Row[] results = (Row[]) sqlContext.sql("FROM src SELECT key, value").collect(); 
} 
} 

私が得る例外は次のとおりです。

17/02/16 16:36:51 INFO SparkSqlParser: Parsing command: select count(*) from SparkHive.health 
Exception in thread "main" java.util.ServiceConfigurationError: org.apache.spark.sql.sources.DataSourceRegister: Provider org.apache.spark.sql.hive.orc.DefaultSource could not be instantiated 
    at java.util.ServiceLoader.fail(ServiceLoader.java:232) 
    at java.util.ServiceLoader.access$100(ServiceLoader.java:185) 
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384) 
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) 
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480) 
    at scala.collection.convert.Wrappers$JIteratorWrapper.next(Wrappers.scala:43) 
    at scala.collection.Iterator$class.foreach(Iterator.scala:893) 
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1336) 
    at scala.collection.IterableLike$class.foreach(IterableLike.scala:72) 
    at scala.collection.AbstractIterable.foreach(Iterable.scala:54) 
    at scala.collection.TraversableLike$class.filterImpl(TraversableLike.scala:247) 
    at scala.collection.TraversableLike$class.filter(TraversableLike.scala:259) 
    at scala.collection.AbstractTraversable.filter(Traversable.scala:104) 
    at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSource(DataSource.scala:550) 
    at org.apache.spark.sql.execution.datasources.DataSource.providingClass$lzycompute(DataSource.scala:86) 
    at org.apache.spark.sql.execution.datasources.DataSource.providingClass(DataSource.scala:86) 
    at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:325) 
    at org.apache.spark.sql.execution.datasources.ResolveDataSource$$anonfun$apply$1.applyOrElse(rules.scala:58) 
    at org.apache.spark.sql.execution.datasources.ResolveDataSource$$anonfun$apply$1.applyOrElse(rules.scala:41) 
    at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan$$anonfun$resolveOperators$1.apply(LogicalPlan.scala:61) 
    at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan$$anonfun$resolveOperators$1.apply(LogicalPlan.scala:61) 
    at org.apache.spark.sql.catalyst.trees.CurrentOrigin$.withOrigin(TreeNode.scala:70) 
    at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan.resolveOperators(LogicalPlan.scala:60) 
    at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan$$anonfun$1.apply(LogicalPlan.scala:58) 
    at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan$$anonfun$1.apply(LogicalPlan.scala:58) 
    at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$5.apply(TreeNode.scala:331) 
    at org.apache.spark.sql.catalyst.trees.TreeNode.mapProductIterator(TreeNode.scala:188) 
    at org.apache.spark.sql.catalyst.trees.TreeNode.transformChildren(TreeNode.scala:329) 
    at org.apache.spark.sql.catalyst.plans.logical.LogicalPlan.resolveOperators(LogicalPlan.scala:58) 
    at org.apache.spark.sql.execution.datasources.ResolveDataSource.apply(rules.scala:41) 
    at org.apache.spark.sql.execution.datasources.ResolveDataSource.apply(rules.scala:40) 
    at org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1$$anonfun$apply$1.apply(RuleExecutor.scala:85) 
    at org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1$$anonfun$apply$1.apply(RuleExecutor.scala:82) 
    at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:124) 
    at scala.collection.immutable.List.foldLeft(List.scala:84) 
    at org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1.apply(RuleExecutor.scala:82) 
    at org.apache.spark.sql.catalyst.rules.RuleExecutor$$anonfun$execute$1.apply(RuleExecutor.scala:74) 
    at scala.collection.immutable.List.foreach(List.scala:381) 
    at org.apache.spark.sql.catalyst.rules.RuleExecutor.execute(RuleExecutor.scala:74) 
    at org.apache.spark.sql.execution.QueryExecution.analyzed$lzycompute(QueryExecution.scala:64) 
    at org.apache.spark.sql.execution.QueryExecution.analyzed(QueryExecution.scala:62) 
    at org.apache.spark.sql.execution.QueryExecution.assertAnalyzed(QueryExecution.scala:48) 
    at org.apache.spark.sql.Dataset$.ofRows(Dataset.scala:63) 
    at org.apache.spark.sql.SparkSession.sql(SparkSession.scala:592) 
    at org.apache.spark.sql.SQLContext.sql(SQLContext.scala:699) 
    at SparkHiveSql.sparkhivesql.queryhive.main(queryhive.java:27) 
Caused by: java.lang.VerifyError: Bad return type 
Exception Details: 
    Location: 
    org/apache/spark/sql/hive/orc/DefaultSource.createRelation(Lorg/apache/spark/sql/SQLContext;[Ljava/lang/String;Lscala/Option;Lscala/Option;Lscala/collection/immutable/Map;)Lorg/apache/spark/sql/sources/HadoopFsRelation; @35: areturn 
    Reason: 
    Type 'org/apache/spark/sql/hive/orc/OrcRelation' (current frame, stack[0]) is not assignable to 'org/apache/spark/sql/sources/HadoopFsRelation' (from method signature) 
    Current Frame: 
    bci: @35 
    flags: { } 
    locals: { 'org/apache/spark/sql/hive/orc/DefaultSource', 'org/apache/spark/sql/SQLContext', '[Ljava/lang/String;', 'scala/Option', 'scala/Option', 'scala/collection/immutable/Map' } 
    stack: { 'org/apache/spark/sql/hive/orc/OrcRelation' } 
    Bytecode: 
    0x0000000: b200 1c2b c100 1ebb 000e 592a b700 22b6 
    0x0000010: 0026 bb00 2859 2c2d b200 2d19 0419 052b 
    0x0000020: b700 30b0        

    at java.lang.Class.getDeclaredConstructors0(Native Method) 
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671) 
    at java.lang.Class.getConstructor0(Class.java:3075) 
    at java.lang.Class.newInstance(Class.java:412) 
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380) 
    ... 43 more 
17/02/16 16:36:55 INFO SparkContext: Invoking stop() from shutdown hook 
17/02/16 16:36:55 INFO SparkUI: Stopped Spark web UI at http://10.0.0.3:4040 

この出来事はなぜ私にはわかりません。このプログラムを実行する前に、私のHIVEは正常に動作していましたが、現在は動作していません。
上記のコードを実行する理由と理由は何ですか?
私はEclispe IDEを使用していますが、私のSparkバージョンは2.1.0です。

+0

関連:http://stackoverflow.com/questions/41516166/spark-2-0-datasourceregister-configuration-error-while-saving-dataframe-as-cvs –

+0

@G_H問題はありません。 –

+0

両方の質問でスタックトレースをチェックすると、根本原因が同じであることがわかります。 ServiceLoaderは、クラスパス上のDefaultSource実装が、期待される戻り値の型に対応しない型を返すコンストラクタを呼び出したことを検出します。 'HadoopFsRelation'が期待されるところで' OrcRelation'が返されますが、OrcRelationはHadoopFsRelationを実装しません。 2.1.0ではHadoopFsRelationを見つけることができず、古いバージョン(1.6.0など)ではHadoopFsRelationが見つからないため、バージョンの競合が発生する可能性があります。クラスパスに複数のSparkバージョンがあるか、Spark/Hiveが混在していますか? –

答えて

2

クラスパスにバージョン競合がある可能性があります。何が起きているのかを理解するために、Javaサービスプロバイダのメカニズムについて簡単に説明します。

Javaでは、サービスプロバイダのメカニズムにより、APIの実装がサブクラス化する必要がある(抽象的な)クラスを指定できます。 ServiceLoaderを使用して、プロバイダクラスの実装を見つけることができます。そのようなクラスの例は、Java APIのJAXBContextです。 JAXB自体はアプリケーションで使用するAPIですが、複数のJAXB実装(リファレンス実装とEclipseLink Moxy)があります。抽象クラス(この例ではJAXBContext)はAPIのエントリポイントです。サービスプロバイダのメカニズムが実装を見つける方法の1つは、クラスパス上の特別なフォルダのファイル(META-INF/services)です。通常、このようなフォルダはjarファイルにあります。 servicesフォルダーには、抽象プロバイダークラスの名前を持つファイルを含めることができます。このようなファイルが複数存在することがあります。各ファイルには、抽象クラスの実装である任意の数の特定のクラス名を含めることができます。

JAXBの場合、ファイル名がjavax.xml.bind.JAXBContextのjarファイルがあります。これは、抽象プロバイダクラスの名前です。ファイルには、JAXBContextの実装をリストする1つ以上の行が含まれます。この行は、そのプロバイダにエントリを提供するためにインスタンス化できます。

スタックトレースを見てみましょう。ある時点では、DataSourceというクラスは実装を見つけたいと考えています。これは、スタックにここに起こる:

at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSource(DataSource.scala:550) 
at org.apache.spark.sql.execution.datasources.DataSource.providingClass$lzycompute(DataSource.scala:86) 
at org.apache.spark.sql.execution.datasources.DataSource.providingClass(DataSource.scala:86) 
at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:325) 

java.util.ServiceLoaderクラスは、上記の機構を介して登録された実装を反復処理するために使用されます。これは、呼び出しコードのいくつかの基準に従って何かを見つけるまで実装のリストを調べます。それはここで起こります:

at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384) 
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) 
at java.util.ServiceLoader$1.next(ServiceLoader.java:480) 

これは、問題が起こる場所です。問題の詳細は、この部分にあります

Location: 
org/apache/spark/sql/hive/orc/DefaultSource.createRelation(Lorg/apache/spark/sql/SQLContext;[Ljava/lang/String;Lscala/Option;Lscala/Option;Lscala/collection/immutable/Map;)Lorg/apache/spark/sql/sources/HadoopFsRelation; @35: areturn 
Reason: 
Type 'org/apache/spark/sql/hive/orc/OrcRelation' (current frame, stack[0]) is not assignable to 'org/apache/spark/sql/sources/HadoopFsRelation' (from method signature) 
Current Frame: 
bci: @35 
flags: { } 
locals: { 'org/apache/spark/sql/hive/orc/DefaultSource', 'org/apache/spark/sql/SQLContext', '[Ljava/lang/String;', 'scala/Option', 'scala/Option', 'scala/collection/immutable/Map' } 
stack: { 'org/apache/spark/sql/hive/orc/OrcRelation' } 

それは掘削の少しかかりますが、あなたは、クラスorg.apache.spark.sql.hive.orc.DefaultSourceが容疑者の呼び出しが探しているものは実装していることを発見されたことをこのことから差し引くことができます。そのインスタンスが作成され、メソッドcreateRelationが呼び出されます。このメソッドは、少なくとも抽象クラスに応じて戻り値の型がorg.apache.spark.sql.sources.HadoopFsRelationです。しかし、返されるのはクラスorg.apache.spark.sql.hive.orc.OrcRelationです。 HadoopFsRelationのサブクラスであれば問題ありませんが、明らかにそうではありません。

これは、同じクラスの異なる実装がクラスパス上にあり、取得するメソッドの戻り値が異なる場合、または異なる(互換性のない)クラス階層を持つ場合です。

私はHadoopFsRelationクラスを探しました。これは、パッケージorg.apache.spark.sql.sourcesのバージョン1.6.3までのSpark upにあります。バージョン2.1.0ではそれはもはや存在しないので、私はそれが2.x APIから削除されていると思われます。バージョン1.6.3ではクラスorg.apache.spark.sql.hive.orc.OrcRelationも見つかり、そのバージョンでは実際にHadoopFsRelationを実装しています。

Sparkバージョン2.1.0になりました。クラスHadoopFsRelationはどこにもありません。 OrcRelationは以前と同じパッケージ(Spark 2.1.0ディストリビューションの一部であるjar spark-hive_2.11-2.1.0.jar)で見つかりました。今はクラスだけがHadoopFsRelationを実装していません。

これは何ですか。あなたはHiveであなたのコードにSparkを使用しようとします。作成したSQLContextクラスは、おそらくSpark 1.6.x(または2.xより古い他のバージョン)から読み込まれます。これは、DataSourceRegister実装(サービスプロバイダとしてリストされているクラス)を探し、META-INF/services/org.apache.spark.sql.sources.DataSourceRegisterファイル(または複数の可能性が高い)を検索します。それは必要なものが実装org.apache.spark.sql.hive.orc.DefaultSourceであることを決定します。クラスが見つけられ、インスタンス化されます。ここまでは順調ですね。 1.6.xコードは、createRelationを呼び出し、HadoopFsRelationの実装を想定しています。しかし、返されたorg.apache.spark.sql.hive.orc.OrcRelationは、クラスがHadoopFsRelationを実装していないバージョン2.1.0(または2以降)からロードされていました。

Spark 2.1.0をインストールしてライブラリを使用し、ダウンロードしたライブラリを追加した場合は、2.xより前のバージョンをダウンロードしている可能性があります。彼らはあなたのコードを実行するときにエントリポイントになるが、彼らは誤って別の定義を持つ新しいクラスを見つける。クラスパス上の内容を確認し、間違ったエントリを削除する必要があります。 Spark、Hive、Hadoop関連のものをすべて削除し、インストールのものだけを使用するか、Apache経由で最新バージョンをダウンロードし、そのAPIに対してコードを作成し、それらのjarファイルのみを使用するようにしてください。余分なものが必要な場合は、それが同じバージョンか、使用しているバージョンと互換性のあるユーティリティであることを確認してください。

関連する問題