> 
> Hi,
> 
> 
> 
> I’m trying to build the stratio spark-mongodb connector and got error 
> "java.lang.IncompatibleClassChangeError: class 
> com.stratio.deep.mongodb.MongodbRelation has interface 
> org.apache.spark.sql.sources.PrunedFilteredScan as super class” when trying 
> to create a table using the driver:
> 
> 
> 
> scala> import org.apache.spark.sql.SQLContext
> 
> val sqlContext = new SQLContext(sc)import org.apache.spark.sql.SQLContext
> 
> 
> 
> import org.apache.spark.sql.SQLContext
> 
> 
> 
> scala> val sqlContext = new SQLContext(sc)
> 
> sqlContext: org.apache.spark.sql.SQLContext = 
> org.apache.spark.sql.SQLContext@37050c15
> 
> 
> 
> scala> import com.stratio.deep.mongodb
> 
> import com.stratio.deep.mongodb
> 
> import com.stratio.deep.mongodb
> 
> 
> 
> scala> sqlContext.sql("CREATE TEMPORARY TABLE students_table USING 
> com.stratio.deep.mongodb OPTIONS (host 'host:port', database 'highschool', 
> collection 'students')")
> 
> sqlContext.sql("CREATE TEMPORARY TABLE students_table USING com.stratio.d 
> 
> eep.mongodb OPTIONS (host 'host:port', database 'highschool', collection 
> 'studen 
> 
> ts')")
> 
> java.lang.IncompatibleClassChangeError: class 
> com.stratio.deep.mongodb.MongodbRelation has interface 
> org.apache.spark.sql.sources.PrunedFilteredScan as super class
> 
> at java.lang.ClassLoader.defineClass1(Native Method)
> 
> at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
> 
> at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
> 
> at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
> 
> at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
> 
> at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
> 
> at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
> 
> at java.security.AccessController.doPrivileged(Native Method)
> 
> at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
> 
> at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
> 
> at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
> 
> at java.lang.Class.getDeclaredConstructors0(Native Method)
> 
> at java.lang.Class.privateGetDeclaredConstructors(Class.java:2585)
> 
> at java.lang.Class.getConstructor0(Class.java:2885)
> 
> at java.lang.Class.newInstance(Class.java:350)
> 
> at org.apache.spark.sql.sources.ResolvedDataSource$.apply(ddl.scala:288)
> 
> at org.apache.spark.sql.sources.CreateTempTableUsing.run(ddl.scala:376)
> 
> at 
> org.apache.spark.sql.execution.ExecutedCommand.sideEffectResult$lzycompute(commands.scala:55)
> 
> at 
> org.apache.spark.sql.execution.ExecutedCommand.sideEffectResult(commands.scala:55)
> 
> 
> 
> The code failed at line 288 in ddl.scala:
> 
>   def apply(
> 
>       sqlContext: SQLContext,
> 
>       userSpecifiedSchema: Option[StructType],
> 
>       provider: String,
> 
>       options: Map[String, String]): ResolvedDataSource = {
> 
>     val clazz: Class[_] = lookupDataSource(provider)
> 
>     val relation = userSpecifiedSchema match {
> 
>       case Some(schema: StructType) => clazz.newInstance() match {
> 
>         case dataSource: SchemaRelationProvider =>
> 
>           dataSource.createRelation(sqlContext, new 
> CaseInsensitiveMap(options), schema)
> 
>         case dataSource: org.apache.spark.sql.sources.RelationProvider =>
> 
>           sys.error(s"${clazz.getCanonicalName} does not allow user-specified 
> schemas.")
> 
>       }
> 
> 
> 
>       case None => clazz.newInstance() match {  <——— failed here
> 
>         case dataSource: RelationProvider =>
> 
>           dataSource.createRelation(sqlContext, new 
> CaseInsensitiveMap(options))
> 
>         case dataSource: org.apache.spark.sql.sources.SchemaRelationProvider 
> =>
> 
>           sys.error(s"A schema needs to be specified when using 
> ${clazz.getCanonicalName}.")
> 
>       }
> 
>     }
> 
>     new ResolvedDataSource(clazz, relation)
> 
>   }
> 
> 
> 
> The “clazz” here is com.stratio.deep.mongodb.DefaultSource, which extends 
> RelationProvider:
> 
> class DefaultSource extends RelationProvider {
> 
> 
> 
>   override def createRelation(
> 
>     sqlContext: SQLContext,
> 
>     parameters: Map[String, String]): BaseRelation = {
> 
> 
> 
>     /** We will assume hosts are provided like 'host:port,host2:port2,...'*/
> 
>     val host = parameters
> 
>       .getOrElse(Host, notFound[String](Host))
> 
>       .split(",").toList
> 
> 
> 
>     val database = parameters.getOrElse(Database, notFound(Database))
> 
> 
> 
>     val collection = parameters.getOrElse(Collection, notFound(Collection))
> 
> 
> 
>     val samplingRatio = parameters
> 
>       .get(SamplingRatio)
> 
>       .map(_.toDouble).getOrElse(DefaultSamplingRatio)
> 
> 
> 
>     MongodbRelation(
> 
>       MongodbConfigBuilder()
> 
>         .set(Host,host)
> 
>         .set(Database,database)
> 
>         .set(Collection,collection)
> 
>         .set(SamplingRatio,samplingRatio).build())(sqlContext)
> 
> 
> 
>   }
> 
> 
> 
> }
> 
> 
> 
> In createRelation function it returns MongodbRelation, which is extended from 
> PrunedFilteredScan
> 
> case class MongodbRelation(
> 
>   config: DeepConfig,
> 
>   schemaProvided: Option[StructType] = None)(
> 
>   @transient val sqlContext: SQLContext) extends PrunedFilteredScan {
> 
> 
> 
> Since both TableScan and PrunedFilteredScan are based on BaseRelation, I’m 
> not sure why clazz.newInstance() call failed by 
> java.lang.IncompatibleClassChangeError.
> 
> Is there any special way to deal with if I need to use PrunedFilteredScan?
> 
> 
> 
> I’m using scala 2.10 and JDK 1.7
> 
> 
> 
> Thanks
> 
> TW
> 

Reply via email to