My trait:
@remote trait Computer {
def execute(task: Task[Any]): Any
}
Snippet of main class in a companion object of a class ComputerImpl
that implements Computer
simply by defining execute
to be = task.execute()
.
val name = "Computer"
val engine: Computer = new ComputerImpl()
val stub = UnicastRemoteObject.exportObject(engine, 0).asInstanceOf[Computer]
I get this error:
system/ComputerImpl.scala:19: error: type mismatch;
found : api.Computer
required: java.rmi.Remote
val stub = UnicastRemoteObject.exportObject(engine, 0).asInstanceOf[Computer]
It goes away if I do the more explicit trait Computer extends Remote
but in "Scala for Impatient" it says "Scala uses annotations @cloneable
and @remote
instead of the Cloneable
and java.rmi.Remote
interfaces for cloneable and remote object."
What is going wrong?
This looks as if it should work, but this is a compilation phase problem. The compiler is applying the @remote
, that is adding in the interface to the trait definition, after it's done the type checking for the compilation. However, the following works:
val stub = UnicastRemoteObject.exportObject(engine.asInstanceOf[java.rmi.Remote], 0).asInstanceOf[Computer]
but it's a bit ugly.
EDIT: It's failing in the typer
compilation phase, whereas it looks like the @remote
substitution is being done in the jvm
phase, which is after the typer
phase.
And in fact, this is a known issue, type inference fails with @remote annotation. From there, Martin Odersky says:
That's completely as speced. @remote is not the same as `extends Remote' for the type checker.
There is no further explanation, but I wouldn't hold your breath for a compiler solution :-)