This uses the ObjectWeb ASM library. This extracts all the methods of a given class instance. There is also code for getting method name inside this.
import org.objectweb.asm.Type
import org.objectweb.asm.Type
import org.objectweb.asm.tree._
import org.objectweb.asm.util._
import java.lang.reflect.Method
case class ScalaMethod(name:String, returnType:Type, params:List[Param], parentClassName:String)
case class Param(paraName:String, paraType:Type)
object MethodReader {
/*
* stackoverflow.com/questions/7640617/how-to-get-parameter-names-and-types-via-reflection-in-scala-java-methods
*/
def getMethods(c:AnyRef, is:java.io.InputStream) = {
val cn = new ClassNode();
val cr = new ClassReader(is);
cr.accept(cn, 0);
is.close();
val methods = cn.methods.asInstanceOf[java.util.List[MethodNode]];
var mList:List[ScalaMethod] = Nil
if (methods.size > 0) for (i <- 1 to methods.size) {
try {
val m:MethodNode = methods.get(i-1)
val argTypes:Array[Type] = Type.getArgumentTypes(m.desc);
val vars = m.localVariables.asInstanceOf[java.util.List[LocalVariableNode]];
var pList:List[Param] = Nil
if (argTypes.length > 0 && vars.length > 0) for (i <- 1 to argTypes.length) {
// The first local variable actually represents the "this" object in some cases
val difference = if (vars.get(0).name == "this") 0 else 1
pList = Param(vars.get(i-difference).name, argTypes(i-1)) :: pList
}
mList = ScalaMethod(m.name, Type.getReturnType(m.desc), pList.reverse, c.getClass.getCanonicalName):: mList
} catch {
case e:Throwable =>
}
}
mList.reverse
}
def getMethods(c, is):List[ScalaMethod] = {
val t = Type.getType(c);
val url = t.getInternalName() + ".class";
val is = try {
val cl = c.getClassLoader();
val is = cl.getResourceAsStream(url);
if (is == null) throw new IllegalArgumentException("Cannot find class: " + url);
else is
} catch {
case e:IllegalArgumentException =>
new java.io.FileInputStream(url)
}
}
}