Problem invoking Java vargargs with argument array

204 views
Skip to first unread message

Ichthyostega

unread,
Dec 6, 2013, 11:58:43 PM12/6/13
to scala...@googlegroups.com

Please excuse if this is a FAQ --
Google turned up mostly old stuff and nothing beyond what I figured out myself..


I am having problems when trying to invoke a Java varargs method not with
varargs syntax, but with an array of arguments. Is this even supposed to work?


In my concrete example, I am receiving JMX calls and forwarding them as messages
to some actor, which embodies the implementation of the MBean.

This means, I got a java.lang.reflection.Method object and I got an
Object[] with the arguments. And now I need to call Method.invoke(target, args)

Now it turns out that this call, when done from Scala, seems to be interpreted
on the Java side as invoking an 1-argument Method with an Array,
which leads to an IllegalArgumentException "argument type mismatch"



For example, in the following code I'm invoking: def func3(i:Int) = i+1



val mj3 = ..... // get the java.lang.reflect.Method

val javaInteger = new java.lang.Integer(222)
var res = mj3.invoke(instance, javaInteger) // note this works
res should be (223)



val args = Array[AnyRef](javaInteger)

evaluating {
mj3.invoke(instance, args)
} should produce [IllegalArgumentException]


// building a java Object[] doesn't help either
val arrayList = new java.util.ArrayList[java.lang.Object](1)
arrayList.add(javaInteger)
val javaObjectArray = arrayList.toArray()

evaluating {
mj3.invoke(instance, javaObjectArray)
} should produce [IllegalArgumentException]


// to work around this problem, invoke the "invoke" method
// through Java reflection
val invokeMethod = classOf[Method].getMethods
.find{_.getName() == "invoke"}
.get

res = invokeMethod.invoke(mj3, instance, args)
res should be (223)


Thus, in the end, the only workaround I could come up with was to invoke
the Method.invoke *itself* through Java-reflection. Is this a known problem?
Is there any better workaround or solution?


Thanks
Hermann Vosseler




Jan Vanek

unread,
Dec 7, 2013, 4:43:18 AM12/7/13
to Ichthyostega, scala...@googlegroups.com
On 07.12.2013 05:58, Ichthyostega wrote:
>
> For example, in the following code I'm invoking: def func3(i:Int) = i+1
>
>
>
> val mj3 = ..... // get the java.lang.reflect.Method
>
> val javaInteger = new java.lang.Integer(222)
> var res = mj3.invoke(instance, javaInteger) // note this works
> res should be (223)
>
>
>
> val args = Array[AnyRef](javaInteger)
>
> evaluating {
> mj3.invoke(instance, args)
> } should produce [IllegalArgumentException]
>

Hi Hermann, try:

mj3.invoke(instance, args:_*)


With regards,
Jan

Ichthyostega

unread,
Dec 7, 2013, 7:48:49 PM12/7/13
to scala...@googlegroups.com
> On 07.12.2013 05:58, Ichthyostega wrote:
>>
>> val mj3 = ..... // get the java.lang.reflect.Method
>>
>> val javaInteger = new java.lang.Integer(222)
>> var res = mj3.invoke(instance, javaInteger) // note this works
>> res should be (223)
>>
>>
>>
>> val args = Array[AnyRef](javaInteger)
>>
>> evaluating {
>> mj3.invoke(instance, args)
>> } should produce [IllegalArgumentException]


Am 07.12.2013 10:43, schrieb Jan Vanek:

> mj3.invoke(instance, args:_*)


To confirm: this solved the problem.
Thanks for the quick help!




Reply all
Reply to author
Forward
0 new messages