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 ?

jopasserat
  • 5,721
  • 4
  • 31
  • 50
Mathieu
  • 313
  • 1
  • 8
  • 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 interfaces – Mathieu May 14 '13 at 13:47

2 Answers2

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.

Community
  • 1
  • 1
Malte Schwerhoff
  • 12,684
  • 4
  • 41
  • 71
  • Maybe you are missing the _scala-reflect_ dependency (`libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.10.0"`), which is granted in the REPL. – neutropolis May 27 '13 at 18:17
  • 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. – Malte Schwerhoff May 28 '13 at 07:06
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
Mathieu
  • 313
  • 1
  • 8