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

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"
}

Related

code generation using sbt

In my scala source files
File.scala
#casejsTraitNative trait Variables extends js.Object {
val first: Int
}
case class Model(in:String)
I want to replace traits with #casejsTraitNative with some boiler plate during compile time
Expected Result : File.scala
trait Variables extends js.Object {
val first: Int
}
object Variables {
#inline def apply(first: Int): Variables = {
val p = FunctionObjectNativeMacro()
p.asInstanceOf[Variables]
}
def copy( source: Variables, first: OptionalParam[Int] = OptDefault): Variables = {
val p = FunctionCopyObjectNativeMacro()
p.asInstanceOf[Variables]
}
}
case class Model(in:String)
I can create expected source string using scalameta,but i don't know which sbt task i need to hook to modify source files before they passed to compiler...
As pointed out by Seth Tisue, the way to fix this is by modifying the sbt source generators keys in your project http://www.scala-sbt.org/1.x/docs/Howto-Generating-Files.html. You can there use Scalameta if you use sbt 1.x. Otherwise, you can't because Scalameta does not cross-compile to 2.10.x, the Scala version sbt 0.13.x uses.
Another way of solving this problem is annotation macros. Have a look at http://docs.scala-lang.org/overviews/macros/annotations.html, but that's more complicated.
All in all, I think the best solution is to use Paiges (https://github.com/typelevel/paiges). It's a little bit more constrained that Scala Meta, but it should allow you to generate that code and more.

Get all the classes that implements a trait in Scala using reflection

I want to list out all the case classes which implements a particular trait. I am currently using Clapper ClassUtil for doing that. I am able to get the case classes that are directly implementing a trait. However, I am not able to get the other classes which are not directly implementing the trait. How can I get all classes which directly or indirectly implements a trait. ?
val finder = ClassFinder()
finder.getClasses().filter(_.isConcrete).filter(_.implements("com.myapp.MyTrait"))
Scala Version : 2.11
Clapper Class Util Version : 1.0.6
Is there any other way I can get these information? Can someone point me to the right direction?
I tried using scala.reflect but could not understand how to get the info.
EDIT:
Sample traits and usages:
trait BaseEntity
trait NamedEntity{ val name:String}
trait MasterDataEntity extends NamedEntity
case class Department(id:Long, override val name:String) extends MasterDataEntity
case class Employee(id:Long, name:String) extends BaseEntity
case class User(id:Long, override val name:String) extends NamedEntity
Now, if I give the trait as NamedEntity, I should be able to get both Department and User since they both are directly or indirectly implementing NamedEntity. With implements method, it will give only User. I also tried by using interfaces method, which will also provide the direct super classes only.
Looking at the source code, the problem seems to be that it doesn't follow the interfaces hierarchy. If you do that, you find all instances:
package foo
import java.io.File
import org.clapper.classutil.{ClassFinder, ClassInfo}
object Main extends App {
val jar = new File("target/scala-2.11/class_test_2.11-0.1.0.jar")
val finder = ClassFinder(jar :: Nil)
val classes = ClassFinder.classInfoMap(finder.getClasses().iterator)
val impl = find("foo.NamedEntity", classes)
impl.foreach(println)
def find(ancestor: String, classes: Map[String, ClassInfo]): List[ClassInfo] =
classes.get(ancestor).fold(List.empty[ClassInfo]) { ancestorInfo =>
val ancestorName = ancestorInfo.name
def compare(info: ClassInfo): Boolean =
info.name == ancestorName ||
(info.superClassName :: info.interfaces).exists {
n => classes.get(n).exists(compare)
}
val it = classes.valuesIterator
it.filter { info => info.isConcrete && compare(info) } .toList
}
}
ClassUtil now contains this functionality (v1.4.0, maybe also in earlier versions):
val finder = ClassFinder()
val impl = ClassFinder.concreteSubclasses("foo.NamedEntity", finder.getClasses())

Scala object that extends Java class

An old trick I used in my previous Java projects was to create e.g. a FileUtils class that offered helper functions for common file operations needed by my project and not covered by e.g. org.apache.commons.io.FileUtils. Therefore my custom FileUtils would extend org.apache.commons.io.FileUtils and offer all their functions as well.
Now I try to do the same in Scala but the apache helper functions are not seen through my FileUtils Scala object, what is wrong here?
import org.apache.commons.io.{ FileUtils => ApacheFileUtils }
object FileUtils extends ApacheFileUtils {
// ... additional helper methods
}
val content = FileUtils.readFileToString(new File("/tmp/whatever.txt"))
here the compiler complains that readFileToString is not a member of my Scala FileUtils but it is of ApacheFileUtils and I extend from it ...
The Scala equivalent of a class with static methods is an object, so in Scala terms, the static components of FileUtils are seen as
object FileUtils {
def readFile(s:String) = ???
...
}
And in Scala, you can't extend an object. This is illegal:
object A
object B extends A // A is not a type
Therefore object FileUtils extends ApacheFileUtils only gives you access to the class-level definitions of ApacheFileUtils (that except for the base Object methods like equals and hashCode, you have none)
You might find that Scala offers more elegant ways of providing extensions. Have a look at the 'pimp up my library' pattern for good starting point.
To apply this pattern to your example:
// definition of your "pimped" methods
import java.io.File
class RichFile(file:File) {
def readToString():String = ???
}
// companion object defines implicit conversion
object RichFile {
implicit def fileToRichFile(f:File):RichFile = new RichFile(f)
}
// Usage
import RichFile._
val content = new File("/tmp/whatever.txt").readToString

Abstract reflection API in Scala 2.10

Scala 2.10 comes with a great reflection API. There are two entry points to it, however: runtime universe and macro context universe.
When using runtime reflection, you should import scala.reflect.runtime.universe. When using reflection inside a macro implementation, you should import universe from the context.
Is it possible to write some code that works in both environments? How should one obtain the universe?
Consider this example:
class MyReflection(val u: scala.reflect.api.Universe) {
import u._
def foo[T: TypeTag] = implicitly[TypeTag[T]].tpe.members // returns MyReflection.u.MemberScope
}
val x = new MyReflection(scala.reflect.runtime.universe)
val members: scala.reflect.runtime.universe.MemberScope = x.foo[String] // BANG! Compiler error
This won't compile because of type mismatch. Same time, it is obvious that both scala.reflect.runtime.universe.MemberScope and MyReflection.u.MemberScope in this example share the same API. Is there a way to abstract over different universes?
Or am I possibly doing something philosophically wrong with trying to export reflection artifacts (MemberScope in this example)?
You can just accept the universe as a parameter:
class MyReflection(val u: scala.reflect.api.Universe) {
import u._
def foo[T : TypeTag] = implicitly[TypeTag[T]].tpe.members
}
val x = new MyReflection(scala.reflect.runtime.universe)
Note that you'll have to refer to the universe via your instance of MyReflection to get the path-dependent types right.
val members: x.u.MemberScope = x.foo[String]
Have a look at this question for more examples and options.

Generating a Scala class automatically from a trait

I want to create a method that generates an implementation of a trait. For example:
trait Foo {
def a
def b(i:Int):String
}
object Processor {
def exec(instance: AnyRef, method: String, params: AnyRef*) = {
//whatever
}
}
class Bar {
def wrap[T] = {
// Here create a new instance of the implementing class, i.e. if T is Foo,
// generate a new FooImpl(this)
}
}
I would like to dynamically generate the FooImpl class like so:
class FooImpl(val wrapped:AnyRef) extends Foo {
def a = Processor.exec(wrapped, "a")
def b(i:Int) = Processor.exec(wrapped, "b", i)
}
Manually implementing each of the traits is not something we would like (lots of boilerplate) so I'd like to be able to generate the Impl classes at compile time. I was thinking of annotating the classes and perhaps writing a compiler plugin, but perhaps there's an easier way? Any pointers will be appreciated.
java.lang.reflect.Proxy could do something quite close to what you want :
import java.lang.reflect.{InvocationHandler, Method, Proxy}
class Bar {
def wrap[T : ClassManifest] : T = {
val theClass = classManifest[T].erasure.asInstanceOf[Class[T]]
theClass.cast(
Proxy.newProxyInstance(
theClass.getClassLoader(),
Array(theClass),
new InvocationHandler {
def invoke(target: AnyRef, method: Method, params: Array[AnyRef])
= Processor.exec(this, method.getName, params: _*)
}))
}
}
With that, you have no need to generate FooImpl.
A limitation is that it will work only for trait where no methods are implemented. More precisely, if a method is implemented in the trait, calling it will still route to the processor, and ignore the implementation.
You can write a macro (macros are officially a part of Scala since 2.10.0-M3), something along the lines of Mixing in a trait dynamically. Unfortunately now I don't have time to compose an example for you, but feel free to ask questions on our mailing list at http://groups.google.com/group/scala-internals.
You can see three different ways to do this in ScalaMock.
ScalaMock 2 (the current release version, which supports Scala 2.8.x and 2.9.x) uses java.lang.reflect.Proxy to support dynamically typed mocks and a compiler plugin to generate statically typed mocks.
ScalaMock 3 (currently available as a preview release for Scala 2.10.x) uses macros to support statically typed mocks.
Assuming that you can use Scala 2.10.x, I would strongly recommend the macro-based approach over a compiler plugin. You can certainly make the compiler plugin work (as ScalaMock demonstrates) but it's not easy and macros are a dramatically superior approach.