Scala : get mixin interfaces at runtime
Asked Answered
L

2

5

I need to get all the interfaces at runtime from a given Class (all loaded in a ClassLoader).

For instance, if a class has been declared this way :

trait B
trait C
trait D    
class A extends B with C with D

I want to get this information at runtime : A depends on B and C and D. The java getInterfaces() (or the interfaces() from the clapper library) methods gives only the first dependency, namely: A depends on B.

Is there a way to achieve that ?

I guess by reflection but I don't know how ?

Lichenin answered 13/5, 2013 at 10:38 Comment(1)
The problem is that I don't know the class a priori. So I can not call typeOf[A] What I get is a list of classes built by reading the target/classes and intancitating them with Class.forName, so that I get a list of unknown classes at runtime. val classes: List[Class[_] = ... // my list of read classes classes.map{c=> c-> ???} // Map with its interfacesLichenin
E
2

This question gives the answer:

import scala.reflect.runtime.universe._

trait B
trait C
class A extends B with C

val tpe = typeOf[A]
tpe.baseClasses foreach {s => println(s.fullName)}
  // A, C, B, java.lang.Object, scala.Any   


It works in the REPL, but when I put the code into a Scala script file and executed it, it didn't any longer:

typeOf[A]
  // Compiler error: No TypeTag available for this.A

Using weakTypeTag instead didn't help either

weakTypeTag[A]
  // Runtime error: scala.reflect.internal.FatalError:
  // ThisType(free type $anon) for sym which is not a class

I got the same behaviour with Scala 2.10.0, 2.10.1 and 2.11.0-M2.

Estren answered 13/5, 2013 at 12:32 Comment(2)
Maybe you are missing the scala-reflect dependency (libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0"), which is granted in the REPL.Gallicanism
Thanks for the suggestion. I explicitly added it to the classpath - which scala.bat automatically does anyway, if I am not mistaken - but nothing changed. Moreover, I assume that import scala.reflect.runtime.universe._ (the import had previously been omitted from my answer) would have failed if the library hadn't been present already.Estren
L
2

The solution I found with reflection :

import scala.reflect.runtime.{universe => ru}
val mirror = ru.rootMirror
val t = m.staticClass(classString).typeSignature
t.baseClasses
Lichenin answered 13/5, 2013 at 15:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.