[ 
https://issues.apache.org/jira/browse/GROOVY-4843?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul King closed GROOVY-4843.
-----------------------------

> Mocking a method with byte[] parameter type throws a ClassCastException: 
> ArrayList cannot be cast to Number
> -----------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-4843
>                 URL: https://issues.apache.org/jira/browse/GROOVY-4843
>             Project: Groovy
>          Issue Type: Bug
>          Components: mocks and stubs
>    Affects Versions: 1.7.10, 1.8.0
>            Reporter: Sébastien Launay
>            Assignee: Eric Milles
>            Priority: Major
>             Fix For: 5.0.0-beta-1, 3.0.25, 4.0.27
>
>         Attachments: GROOVY-fix-mock-byte-array-method-2011-05-25.patch
>
>
> If I want to mock a class with a method having a single byte[] paremeter like 
> this one:
> {code:java}
> def baisContext = new MockFor(FileInputStream)
> baisContext.demand.read(1..1) {byte[] b ->
>   ...
> }
> def bais = baisContext.proxyDelegateInstance("/dev/null")
> bais.read(new byte[2]) // will throws ClassCastException
> {code}
> it will fail with the following exception:
> {noformat}
> java.lang.ClassCastException: java.util.ArrayList cannot be cast to 
> java.lang.Number
>   at 
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.convertToByteArray(DefaultTypeTransformation.java:701)
>   at 
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.convertToPrimitiveArray(DefaultTypeTransformation.java:802)
>   at 
> org.codehaus.groovy.reflection.stdclasses.ArrayCachedClass.coerceArgument(ArrayCachedClass.java:38)
>   at 
> org.codehaus.groovy.reflection.ParameterTypes.coerceArgumentsToClasses(ParameterTypes.java:138)
>   at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:231)
>   at 
> org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
>   at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:884)
>   at 
> org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
>   at 
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
>   at 
> org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54)
>   at 
> groovy.mock.interceptor.MockInterceptor.beforeInvoke(MockInterceptor.groovy:33)
>   at 
> groovy.mock.interceptor.MockProxyMetaClass.invokeMethod(MockProxyMetaClass.java:78)
>   at 
> org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
>   at 
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
>   at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
>   at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
> {noformat}
> This is because {{MockInterceptor}} invoke the target closure by expanding 
> the arguments array like this:
> {code:java}
> return result(*arguments)
> {code}
> resulting in the following type coercion from 
> {{ParameterTypes#coerceArgumentsToClasses(Object[])}} (closure with 1 
> argument of array type is considered as a variable argument method call):
> {noformat}
> Object[] {byte[]} => Object[] {Object[] {ArrayList<Byte>}} => byte[]
> {noformat}
> instead of the excepted coercion:
> {noformat}
> Object[] {byte[]} => Object[] {Byte[]} => byte[]
> {noformat}
> I think this issue does not only affects byte[] arguments but most certainly 
> all the kind of arrays.
> Current workaround is to use the type {{List<Byte>}} instead of {{byte[]}} in 
> the closure intercepting the call.
> I attached a test case to reproduce the bug plus a proposed fix by using 
> {{InvokerHelper.invokeClosure()}} instead of expanding the arguments array.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to