Uploaded image for project: 'Geode'
  1. Geode
  2. GEODE-2899

Unexpected array lifting in function argument passing

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: functions, rest (dev)
    • Labels:
      None

      Description

      When passing an array with one argument to a function call, the array is flattened and:

      FunctionContext.getArguments()

      returns the value itself. (This is the same behavior within the function context as if the caller had passed just the argument object instead of boxed in an array.)

      For example, given this function:

      public class EchoFunction extends Object implements Function {
          public void execute(FunctionContext fc) {
              RegionFunctionContext context = (RegionFunctionContext)fc;
      	Object[] arguments = (Object[])context.getArguments(); // <-----
              ResultSender<String> resultSender = fc.getResultSender();
      	for (int i = 0; i < arguments.length - 1; i++) {
                  resultSender.sendResult(arguments[i].toString());
              }
              resultSender.lastResult(arguments[arguments.length - 1].toString());
          }
          // ...
      }
      

      This curl command with 2 arguments works:

       2017-05-09 09:50:10 ☆  EUROPA-WIN10 in ~
      ○ → curl -H "Content-Type: application/json" -d '[{"@type":"Long", "@value":210}, {"@type":"Long", "@value":211}]' http:
      //35.165.170.9:8080/gemfire-api/v1/functions/EchoFunction?onRegion=orders
      [ "210", "211" ]
      

      This curl command with 1 argument fails in an expected manner:

       2017-05-09 09:51:23 ☆  EUROPA-WIN10 in ~
      ○ → curl -H "Content-Type: application/json" -d '{"@type":"Long", "@value":210}' http://35.165.170.9:8080/gemfire-api/v1
      /functions/EchoFunction?onRegion=orders
      {"message" : "Server has encountered an error while processing function execution!", "stackTrace" : "org.apache.geode.rest.internal.web.exception.GemfireRestException: Server has encountered an error while processing function execution!
              at org.apache.geode.rest.internal.web.controllers.FunctionAccessController.execute(FunctionAccessController.java:249)
              at org.apache.geode.rest.internal.web.controllers.FunctionAccessController$$FastClassBySpringCGLIB$$b1783d32.invoke(<generated>)
              at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
              at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
              at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
              at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
              at org.apache.geode.rest.internal.web.controllers.FunctionAccessController$$EnhancerBySpringCGLIB$$c708a3cd.execute(<generated>)
              at sun.reflect.GeneratedMethodAccessor342.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:498)
              at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
              at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
              at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
              at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
              at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
              at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
              at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
              at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
              at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
              at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
              at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
              at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:821)
              at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1685)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
              at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
              at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
              at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
              at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
              at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
              at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
              at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
              at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)
              at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
              at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
              at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
              at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
              at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1158)
              at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
              at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
              at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1090)
              at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
              at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
              at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119)
              at org.eclipse.jetty.server.Server.handle(Server.java:517)
              at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308)
              at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242)
              at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:261)
              at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
              at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75)
              at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213)
              at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147)
              at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)
              at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
              at java.lang.Thread.run(Thread.java:745)
      Caused by: org.apache.geode.cache.execute.FunctionException: java.lang.ClassCastException: java.lang.Long cannot be cast to [Ljava.lang.Object;
              at org.apache.geode.internal.cache.execute.LocalResultCollectorImpl.setException(LocalResultCollectorImpl.java:187)
              at org.apache.geode.internal.cache.execute.PartitionedRegionFunctionResultSender.setException(PartitionedRegionFunctionResultSender.java:379)
              at org.apache.geode.internal.cache.execute.AbstractExecution.handleException(AbstractExecution.java:587)
              at org.apache.geode.internal.cache.execute.AbstractExecution.executeFunctionLocally(AbstractExecution.java:358)
              at org.apache.geode.internal.cache.execute.AbstractExecution$1.run(AbstractExecution.java:275)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
              at org.apache.geode.distributed.internal.DistributionManager.runUntilShutdown(DistributionManager.java:621)
              at org.apache.geode.distributed.internal.DistributionManager$9$1.run(DistributionManager.java:1067)
              ... 1 more
      Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to [Ljava.lang.Object;
              at cheezypizza.EchoFunction.execute(EchoFunction.java:19)
              at org.apache.geode.internal.cache.execute.AbstractExecution.executeFunctionLocally(AbstractExecution.java:333)
              ... 6 more
      "}
      

      This curl command with 1 argument in an array fails unexpectedly:

       2017-05-09 09:51:36 ☆  EUROPA-WIN10 in ~
      ○ → curl -H "Content-Type: application/json" -d '[{"@type":"Long", "@value":210}]' http://35.165.170.9:8080/gemfire-api/
      v1/functions/EchoFunction?onRegion=orders
      {"message" : "Server has encountered an error while processing function execution!", "stackTrace" : "org.apache.geode.rest.internal.web.exception.GemfireRestException: Server has encountered an error while processing function execution!
              at org.apache.geode.rest.internal.web.controllers.FunctionAccessController.execute(FunctionAccessController.java:249)
              at org.apache.geode.rest.internal.web.controllers.FunctionAccessController$$FastClassBySpringCGLIB$$b1783d32.invoke(<generated>)
              at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
              at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
              at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
              at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
              at org.apache.geode.rest.internal.web.controllers.FunctionAccessController$$EnhancerBySpringCGLIB$$c708a3cd.execute(<generated>)
              at sun.reflect.GeneratedMethodAccessor342.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:498)
              at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
              at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
              at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
              at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
              at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
              at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
              at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
              at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
              at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
              at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
              at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
              at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:821)
              at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1685)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)
              at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
              at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
              at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
              at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
              at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
              at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
              at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
              at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
              at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
              at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)
              at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)
              at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
              at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
              at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
              at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1158)
              at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
              at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
              at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1090)
              at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
              at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
              at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119)
              at org.eclipse.jetty.server.Server.handle(Server.java:517)
              at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:308)
              at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242)
              at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:261)
              at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
              at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75)
              at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213)
              at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147)
              at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)
              at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
              at java.lang.Thread.run(Thread.java:745)
      Caused by: org.apache.geode.cache.execute.FunctionException: java.lang.ClassCastException: java.lang.Long cannot be cast to [Ljava.lang.Object;
              at org.apache.geode.internal.cache.execute.LocalResultCollectorImpl.setException(LocalResultCollectorImpl.java:187)
              at org.apache.geode.internal.cache.execute.PartitionedRegionFunctionResultSender.setException(PartitionedRegionFunctionResultSender.java:379)
              at org.apache.geode.internal.cache.execute.AbstractExecution.handleException(AbstractExecution.java:587)
              at org.apache.geode.internal.cache.execute.AbstractExecution.executeFunctionLocally(AbstractExecution.java:358)
              at org.apache.geode.internal.cache.execute.AbstractExecution$1.run(AbstractExecution.java:275)
              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
              at org.apache.geode.distributed.internal.DistributionManager.runUntilShutdown(DistributionManager.java:621)
              at org.apache.geode.distributed.internal.DistributionManager$9$1.run(DistributionManager.java:1067)
              ... 1 more
      Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to [Ljava.lang.Object;
              at cheezypizza.EchoFunction.execute(EchoFunction.java:19)
              at org.apache.geode.internal.cache.execute.AbstractExecution.executeFunctionLocally(AbstractExecution.java:333)
              ... 6 more
      "}
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              alidaka Augustus Lidaka
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: