@@ -27,6 +27,7 @@ import org.apache.spark.sql.types._
2727 */
2828object ScalaReflection extends ScalaReflection {
2929 val universe : scala.reflect.runtime.universe.type = scala.reflect.runtime.universe
30+ val mirror : universe.Mirror = universe.runtimeMirror(Thread .currentThread().getContextClassLoader)
3031}
3132
3233/**
@@ -36,6 +37,9 @@ trait ScalaReflection {
3637 /** The universe we work in (runtime or macro) */
3738 val universe : scala.reflect.api.Universe
3839
40+ /** The mirror used to access types in the universe */
41+ val mirror : universe.Mirror
42+
3943 import universe ._
4044
4145 // The Predef.Map is scala.collection.immutable.Map.
@@ -52,7 +56,19 @@ trait ScalaReflection {
5256
5357 /** Returns a catalyst DataType and its nullability for the given Scala Type using reflection. */
5458 def schemaFor [T : TypeTag ]: Schema =
55- ScalaReflectionLock .synchronized { schemaFor(typeOf[T ]) }
59+ ScalaReflectionLock .synchronized { schemaFor(localTypeOf[T ]) }
60+
61+ /**
62+ * Return the Scala Type for `T` in the current classloader mirror.
63+ *
64+ * Use this method instead of the convenience method `universe.typeOf`, which
65+ * assumes that all types can be found in the classloader that loaded scala-reflect classes.
66+ * That's not necessarily the case when running using Eclipse launchers or even
67+ * Sbt console or test (without `fork := true`).
68+ *
69+ * @see SPARK-5281
70+ */
71+ private def localTypeOf [T : TypeTag ]: `Type` = typeTag[T ].in(mirror).tpe
5672
5773 /** Returns a catalyst DataType and its nullability for the given Scala Type using reflection. */
5874 def schemaFor (tpe : `Type`): Schema = ScalaReflectionLock .synchronized {
@@ -67,25 +83,25 @@ trait ScalaReflection {
6783 val udt = Utils .classForName(className)
6884 .getAnnotation(classOf [SQLUserDefinedType ]).udt().newInstance()
6985 Schema (udt, nullable = true )
70- case t if t <:< typeOf [Option [_]] =>
86+ case t if t <:< localTypeOf [Option [_]] =>
7187 val TypeRef (_, _, Seq (optType)) = t
7288 Schema (schemaFor(optType).dataType, nullable = true )
7389 // Need to decide if we actually need a special type here.
74- case t if t <:< typeOf [Array [Byte ]] => Schema (BinaryType , nullable = true )
75- case t if t <:< typeOf [Array [_]] =>
90+ case t if t <:< localTypeOf [Array [Byte ]] => Schema (BinaryType , nullable = true )
91+ case t if t <:< localTypeOf [Array [_]] =>
7692 val TypeRef (_, _, Seq (elementType)) = t
7793 val Schema (dataType, nullable) = schemaFor(elementType)
7894 Schema (ArrayType (dataType, containsNull = nullable), nullable = true )
79- case t if t <:< typeOf [Seq [_]] =>
95+ case t if t <:< localTypeOf [Seq [_]] =>
8096 val TypeRef (_, _, Seq (elementType)) = t
8197 val Schema (dataType, nullable) = schemaFor(elementType)
8298 Schema (ArrayType (dataType, containsNull = nullable), nullable = true )
83- case t if t <:< typeOf [Map [_, _]] =>
99+ case t if t <:< localTypeOf [Map [_, _]] =>
84100 val TypeRef (_, _, Seq (keyType, valueType)) = t
85101 val Schema (valueDataType, valueNullable) = schemaFor(valueType)
86102 Schema (MapType (schemaFor(keyType).dataType,
87103 valueDataType, valueContainsNull = valueNullable), nullable = true )
88- case t if t <:< typeOf [Product ] =>
104+ case t if t <:< localTypeOf [Product ] =>
89105 val formalTypeArgs = t.typeSymbol.asClass.typeParams
90106 val TypeRef (_, _, actualTypeArgs) = t
91107 val constructorSymbol = t.member(nme.CONSTRUCTOR )
@@ -107,19 +123,20 @@ trait ScalaReflection {
107123 schemaFor(p.typeSignature.substituteTypes(formalTypeArgs, actualTypeArgs))
108124 StructField (p.name.toString, dataType, nullable)
109125 }), nullable = true )
110- case t if t <:< typeOf[String ] => Schema (StringType , nullable = true )
111- case t if t <:< typeOf[java.sql.Timestamp ] => Schema (TimestampType , nullable = true )
112- case t if t <:< typeOf[java.sql.Date ] => Schema (DateType , nullable = true )
113- case t if t <:< typeOf[BigDecimal ] => Schema (DecimalType .Unlimited , nullable = true )
114- case t if t <:< typeOf[java.math.BigDecimal ] => Schema (DecimalType .Unlimited , nullable = true )
115- case t if t <:< typeOf[Decimal ] => Schema (DecimalType .Unlimited , nullable = true )
116- case t if t <:< typeOf[java.lang.Integer ] => Schema (IntegerType , nullable = true )
117- case t if t <:< typeOf[java.lang.Long ] => Schema (LongType , nullable = true )
118- case t if t <:< typeOf[java.lang.Double ] => Schema (DoubleType , nullable = true )
119- case t if t <:< typeOf[java.lang.Float ] => Schema (FloatType , nullable = true )
120- case t if t <:< typeOf[java.lang.Short ] => Schema (ShortType , nullable = true )
121- case t if t <:< typeOf[java.lang.Byte ] => Schema (ByteType , nullable = true )
122- case t if t <:< typeOf[java.lang.Boolean ] => Schema (BooleanType , nullable = true )
126+ case t if t <:< localTypeOf[String ] => Schema (StringType , nullable = true )
127+ case t if t <:< localTypeOf[java.sql.Timestamp ] => Schema (TimestampType , nullable = true )
128+ case t if t <:< localTypeOf[java.sql.Date ] => Schema (DateType , nullable = true )
129+ case t if t <:< localTypeOf[BigDecimal ] => Schema (DecimalType .Unlimited , nullable = true )
130+ case t if t <:< localTypeOf[java.math.BigDecimal ] =>
131+ Schema (DecimalType .Unlimited , nullable = true )
132+ case t if t <:< localTypeOf[Decimal ] => Schema (DecimalType .Unlimited , nullable = true )
133+ case t if t <:< localTypeOf[java.lang.Integer ] => Schema (IntegerType , nullable = true )
134+ case t if t <:< localTypeOf[java.lang.Long ] => Schema (LongType , nullable = true )
135+ case t if t <:< localTypeOf[java.lang.Double ] => Schema (DoubleType , nullable = true )
136+ case t if t <:< localTypeOf[java.lang.Float ] => Schema (FloatType , nullable = true )
137+ case t if t <:< localTypeOf[java.lang.Short ] => Schema (ShortType , nullable = true )
138+ case t if t <:< localTypeOf[java.lang.Byte ] => Schema (ByteType , nullable = true )
139+ case t if t <:< localTypeOf[java.lang.Boolean ] => Schema (BooleanType , nullable = true )
123140 case t if t <:< definitions.IntTpe => Schema (IntegerType , nullable = false )
124141 case t if t <:< definitions.LongTpe => Schema (LongType , nullable = false )
125142 case t if t <:< definitions.DoubleTpe => Schema (DoubleType , nullable = false )
0 commit comments