Why Scala Enumeration does not work in Apache Zeppelin but it works in maven - scala

Enumeration works as expected when I use it in a maven project(with the same Scala version).
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
def main(args: Array[String]) = f(DashStyle.Solid)
}
But when it runs in Apache Zeppelin(Zeppelin 0.6, Spark 1.6, Scala 2.10, Java 1.8)
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
f(DashStyle.Solid)
It reports the following error even it says found and required type is exactly the same
<console>:130: error: type mismatch;
found : DashStyle.Value
required: DashStyle.Value
f(DashStyle.Solid)
Why and how should I use it?

I figured out the trick to solve this issue.
In Apache Zeppelin (or Scala REPL). In order to use Enumeration or sealed&object, it should be wrapped in object but not directly define on the root scope.
The reason why it works in maven is that I already put it into an object.
Define enumeration in an object in a Zeppelin paragraph
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
}
Then use it in a Zeppelin paragraph
import t._
f(DashStyle.Solid)

Related

scala 2.13: type IndexedSeq takes type parameters

I have the following snippet which works fine on Scala 2.12 but does not compile on Scala 2.13.
import scala.util.Random
object Hello {
def main(args: Array[String]) = {
val random = new Random()
random.shuffle[Int, IndexedSeq](2 to 100).toArray
}
}
The error is:
trait IndexedSeq takes type parameters
I have no idea on how to fix it. Thank you!
You can add required type parameter:
random.shuffle[Int, IndexedSeq[Int]](2 to 100).toArray

Why is the Scala compiler giving me an error when passing a Kotlin sealed class into a constructor?

I have a sealed class, written in Kotlin:
sealed class Schema {
class RecordSchema(val fields: List<Field>): Schema()
class ArraySchema(val elementSchema: Schema): Schema()
...
}
And another class that takes RecordSchema as a parameter:
class Enrichment(config: Config, val schema: RecordSchema) { ... }
In Scala I have a class that, among other things, get an instance of the RecordSchema and then create an instance of the Enrichment.
object Job {
def main(args: Array[String]): Unit = {
/// some initializing of resources... and then...
val recordSchema = schemas.getSchema(id) // type is Schema.RecordSchema
val enrichment = Enrichment(config, recordSchema) // this is where scalac errors out
}
}
The scala compiler ends up printing this error message:
Error:(52, 62) type mismatch;
found : com.companyname.enricher.schemas.com.companyname.enricher.schemas.com.companyname.enricher.schemas.
required: com.companyname.enricher.schemas.(some other)com.companyname.enricher.schemas.com.companyname.enricher.schemas.
val enrichment = new Enrichment(config, recordSchema)
If I cast recordSchema using asInstanceOf I get another, not so useful, error:
Error:(52, 62) type mismatch;
found : com.companyname.enricher.schemas.Schema.RecordSchema
required: com.companyname.enricher.schemas.com.companyname.enricher.schemas.
val enrichment = new Enrichment(config, recordSchema.asInstanceOf[RecordSchema])
Overall, I have no idea why this is happening. If I make the constructor take the parent class as a parameter rather than nested class, it compiles just fine (which is my workaround for now). If I do the same type of thing, except having written the sourcecode in Java rather than Kotlin, this error does not happen. I am using Java 1.8, Kotlin 1.0.4, Scala 2.11.8.
UPDATE:
demonstrated bug here:
https://github.com/mjburghoffer/scala-kotlin-innerclass-bug/tree/master
Looks like Kotlin generates different number of classes for this case. I compiled Java and Kotlin sources and found that Java has additional file ParentSealedJava$1.class. Bytecode of Parent and Sealed classes in Java and Kotlin pretty the same (i inspect bytecode using javap -c), so i think Scala compiler relies somehow on this missing file in Kotlin.

Spray route inside IDEA complains about false error

I'm using spray and I have the following code:
import spray.json.DefaultJsonProtocol
import spray.routing.Directives
import spray.httpx.SprayJsonSupport.sprayJsonMarshaller
import spray.httpx.SprayJsonSupport.sprayJsonUnmarshaller
case class SomeResult(id: String, color: String)
trait Protocols extends DefaultJsonProtocol {
implicit val someResultFormat = jsonFormat2(SomeResult)
}
trait Api extends Directives with Protocols {
val route =
path("order" / IntNumber) { id =>
get {
complete {
val result: List[SomeResult] = List(SomeResult("foo", "green"+id), SomeResult("bar", "red"+id))
result
} // ERROR HERE
}
}
}
This compiles and runs fine, however, inside IntelliJ IDEA editor it complains about an error. Namely, it says that Expression of type List[SomeResult] doesn't conform to expected type ToResponseMarshallable. How can I avoid the IDE complaining about such things? is there any fix for this? is it a well-known error? I already invalidated cache files and restarted but the error persist.
FWIW, I'm using:
Scala 2.11.1
Spray 1.3.1
IDEA 14.0.3
Scala plugin 1.3.2
JDK 1.7.0_71

private field in object doesn't compile

I tried to run one example from Programming in Scala but compiler gives me error:
Description Resource Path Location Type
illegal start of statement (no modifiers allowed here) ChecksumAcc.sc /HelloWorld/src line 3 Scala Problem
basically complains about private
import scala.collection.mutable.Map
object ChecksumAcc {
private val cache = Map[String, Int]()
}
I'm using Eclipse for Scala worksheet. Same after updating. I believe it uses 2.9.3 scala compiler. Why doesn't it compile?
Not sure what your actual question is, but the Scala worksheet has some special rules (as indicated by the very clear error message...). One thing you can do if you have to use the worksheet, is to put all your code inside a Worksheet object like this:
object Worksheet {
import scala.collection.mutable.Map
object ChecksumAcc {
private val cache = Map[String, Int]()
}
}
Or alternatively, use Eclipse's "New Scala object..." and use that instead of the worksheet.
To avoid the error message you are seeing, when you are working in a Eclipse Scala work sheet
wrap the Class definition and Companion class (Singleton object) in the same object
object worksheet {
class CheckSumAccumulator {
...
}
object CheckSumAccumulator {
...
}
CheckSumAccumulator.calculate("foobar")
}

Is there anyway to create a new Scala object from a Java Class

I have a number of use cases for this, all around the idea of interop between existing Java libraries and new Scala Code. The use case I've selected is the easiest I think.
Use Case:
I working on providing a JUnit Runner for some scala tests (so that I can get my lovely red / green bar in Eclipse)
The runner needs to have a constructor with a java class as a parameter. So in Scala I can do the following:
class MyRunner(val clazz: Class[Any]) extends Runner {
def getDescription(): Description
def run(notifier: RunNotifier)
}
When I use either
#RunWith(MyRunner)
object MyTestObject
or
#RunWith(MyRunner)
class MyTestClass
then the runner is indeed instantiated correctly, and is passed a suitable class object
Unfortunately what i want to do now is to "get hold of" the object MyTestObject, or create a MyTestClass, which are both Scala entities. I would prefer to use Scala Reflection, but I also want to use the standard Junit jar.
What I have done
The following Stackover flow questions were educational, but not the same problem. There were the nearest questions I could find
How to create a TypeTag manually?
Any way to obtain a Java class from a Scala (2.10) type tag or symbol?
Using Scala reflection with Java reflection
The discussion on Environments, Universes and Mirrors in http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html was good, and the similar documents on other scala reflection also helped. Mostly through it is about the Scala reflection.
I browsed the Scaladocs, but my knowledge of Scala reflection wasn't enough (yet) to let me get what I wanted out of them.
Edit:
As asked here is the code of the class that is being created by reflection
#RunWith(classOf[MyRunner])
object Hello2 extends App {
println("starting")
val x= "xxx"
}
So the interesting thing is that the solution proposed below using the field called MODULE$ doesn't print anything and the value of x is null
This solution works fine if you want to use plan old java reflection. Not sure if you can use scala reflection given all you will have is a Class[_] to work with:
object ReflectTest {
import collection.JavaConversions._
def main(args: Array[String]) {
val fooObj = instantiate(MyTestObject.getClass())
println(fooObj.foo)
val fooClass = instantiate(classOf[MyTestClass])
println(fooClass.foo)
}
def instantiate(clazz:Class[_]):Foo = {
val rm = ru.runtimeMirror(clazz.getClassLoader())
val declaredFields = clazz.getDeclaredFields().toList
val obj = declaredFields.find(field => field.getName() == "MODULE$") match{
case Some(modField) => modField.get(clazz)
case None => clazz.newInstance()
}
obj.asInstanceOf[Foo]
}
}
trait Foo{
def foo:String
}
object MyTestObject extends Foo{
def foo = "bar"
}
class MyTestClass extends Foo{
def foo = "baz"
}