I regularly use the Scala REPL for rapid Java iteration and testing, but sometimes I want to trigger some private behavior of a class, and have to recompile the code in order to make the method visible. I'd like to be able to call private Java methods directly in the REPL, without needing to make code changes.
What I've got so far:
// Calls private Java methods
// We currently define an overload for every n-argument method
// there's probably a way to do this in one method?
def callPrivate(obj: AnyRef, methodName: String) = {
val method = obj.getClass().getDeclaredMethod(methodName)
val returnType = method.getReturnType
method.setAccessible(true)
println("Call .asInstanceOf[%s] to cast" format method.getReturnType.getName)
method.getReturnType.cast(method.invoke(obj))
}
def callPrivate(obj: AnyRef, methodName: String, arg: AnyRef) = {
val method = obj.getClass().getDeclaredMethod(methodName, arg.getClass())
method.setAccessible(true)
method.invoke(obj, arg)
}
Which can be used like:
scala> callPrivate(myObj, "privateMethod", arg).asInstanceOf[ReturnedClass]
But this requires defining a near duplicate method for every n-argument method type (and requires an external cast, but I suspect that's unavoidable). Is there any way to refactor this so that one function can handle any number of arguments?
Note: I'm using Scala 2.9.1, so I'm looking for solutions using Java Reflection. Answers using Scala Reflection are welcome, but don't address my problem directly.