Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Problem while storing binary data in Workflow MetaDataMap

Avatar

Level 2

Hello Everyone,

I am trying to store a byte array (represents an image or file) in a MetaDataMap. The relevant part of my code is as follows:

  ResourceResolver resourceResolver = writeService.getResolver();

  session = resourceResolver.adaptTo(Session.class);

   //Create a workflow session
   WorkflowSession wfSession = workflowService.getWorkflowSession(session);

   // Get the workflow model
   WorkflowModel wfModel = wfSession.getModel(workflowName);

   WorkflowData wfData = wfSession.newWorkflowData("JCR_PATH", workflowContent);

   Map<String, Object> test = new HashMap<String, Object>();

   // RequestParameter object has image data received via form (post request)

   byte[] bytes =  requestParameter.get();

   test.put("profileImg", bytes);

   Workflow wf =wfSession.startWorkflow(wfModel, wfData, test);

But when it tries to start the workflow, I get following error in the log:

workflow.InvokeWorkflowImpl workflow failed to start

java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object;

  at com.adobe.granite.workflow.core.metadata.MetaDataUtilImpl.setMetaDataProperty(MetaDataUtilImpl.java:118)

  at com.adobe.granite.workflow.core.jcr.WorkflowManager.updateMetadata(WorkflowManager.java:1285)

  at com.adobe.granite.workflow.core.jcr.WorkflowManager.createWorkflowInstance(WorkflowManager.java:310)

  at com.adobe.granite.workflow.core.WorkflowSessionImpl.startWorkflow(WorkflowSessionImpl.java:1337)

  at com.day.cq.workflow.impl.CQWorkflowSessionWrapper.startWorkflow(CQWorkflowSessionWrapper.java:291)

  at edu.umich.lsa.services.osgi.workflow.InvokeWorkflowImpl.StartWorkflow(InvokeWorkflowImpl.java:78)

  at edu.umich.lsa.services.osgi.servlets.PersonUpdateServlet.doPost(PersonUpdateServlet.java:144)

  at org.apache.sling.api.servlets.SlingAllMethodsServlet.mayService(SlingAllMethodsServlet.java:149)

  at org.apache.sling.api.servlets.SlingSafeMethodsServlet.service(SlingSafeMethodsServlet.java:345)

  at org.apache.sling.api.servlets.SlingSafeMethodsServlet.service(SlingSafeMethodsServlet.java:376)

  at org.apache.sling.engine.impl.request.RequestData.service(RequestData.java:547)

  at org.apache.sling.engine.impl.filter.SlingComponentFilterChain.render(SlingComponentFilterChain.java:44)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:77)

  at com.day.cq.wcm.core.impl.WCMDebugFilter.doFilter(WCMDebugFilter.java:151)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.core.impl.WCMComponentFilter.filterRootInclude(WCMComponentFilter.java:371)

  at com.day.cq.wcm.core.impl.WCMComponentFilter.doFilter(WCMComponentFilter.java:171)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.personalization.impl.TargetComponentFilter.doFilter(TargetComponentFilter.java:96)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.engine.impl.SlingRequestProcessorImpl.processComponent(SlingRequestProcessorImpl.java:282)

  at org.apache.sling.engine.impl.filter.RequestSlingFilterChain.render(RequestSlingFilterChain.java:49)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:77)

  at com.day.cq.dam.core.impl.servlet.ActivityRecordHandler.doFilter(ActivityRecordHandler.java:155)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:73)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:73)

  at com.adobe.granite.requests.logging.impl.RequestLoggerImpl.doFilter(RequestLoggerImpl.java:137)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.granite.csrf.impl.CSRFFilter.doFilter(CSRFFilter.java:201)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.security.impl.ContentDispositionFilter.doFilter(ContentDispositionFilter.java:181)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.core.impl.AuthoringUIModeServiceImpl.doFilter(AuthoringUIModeServiceImpl.java:367)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.core.impl.warp.TimeWarpFilter.doFilter(TimeWarpFilter.java:106)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.mobile.core.impl.redirect.RedirectFilter.doFilter(RedirectFilter.java:240)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.cq.social.commons.cors.CORSAuthenticationFilter.doFilter(CORSAuthenticationFilter.java:91)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.cognifide.cq.includefilter.DynamicIncludeFilter.doFilter(DynamicIncludeFilter.java:82)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.analytics.provisioning.impl.UserAuthenticationRequestFilter.doFilter(UserAuthenticationRequestFilter.java:119)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter.doFilter(RequestProgressTrackerLogFilter.java:95)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.foundation.forms.impl.FormsHandlingServlet.doFilter(FormsHandlingServlet.java:269)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.theme.impl.ThemeResolverFilter.doFilter(ThemeResolverFilter.java:76)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.granite.optout.impl.OptOutFilter.doFilter(OptOutFilter.java:74)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.core.impl.WCMRequestFilter.doFilter(WCMRequestFilter.java:90)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.cq.history.impl.HistoryRequestFilter.doFilter(HistoryRequestFilter.java:107)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.day.cq.wcm.designimporter.CanvasPageDeleteRequestFilter.doFilter(CanvasPageDeleteRequestFilter.java:88)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.rewriter.impl.RewriterFilter.doFilter(RewriterFilter.java:83)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.granite.httpcache.impl.InnerCacheFilter.doFilter(InnerCacheFilter.java:77)

  at com.adobe.granite.httpcache.impl.InnerCacheFilter.doFilter(InnerCacheFilter.java:56)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.granite.rest.impl.servlet.ApiResourceFilter.doFilter(ApiResourceFilter.java:68)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.cq.dam.s7imaging.impl.auth.MemoryTokenAuthHandler.doFilter(MemoryTokenAuthHandler.java:156)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.bgservlets.impl.BackgroundServletStarterFilter.doFilter(BackgroundServletStarterFilter.java:135)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.cq.social.ugcbase.security.impl.SaferSlingPostServlet.doFilter(SaferSlingPostServlet.java:132)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at com.adobe.granite.resourceresolverhelper.impl.ResourceResolverHelperImpl.doFilter(ResourceResolverHelperImpl.java:84)

  at org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68)

  at org.apache.sling.engine.impl.SlingRequestProcessorImpl.doProcessRequest(SlingRequestProcessorImpl.java:151)

  at org.apache.sling.engine.impl.SlingMainServlet.service(SlingMainServlet.java:217)

  at org.apache.felix.http.base.internal.handler.ServletHandler.doHandle(ServletHandler.java:336)

  at org.apache.felix.http.base.internal.handler.ServletHandler.handle(ServletHandler.java:297)

  at org.apache.felix.http.base.internal.dispatch.ServletPipeline.handle(ServletPipeline.java:93)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:50)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.felix.http.sslfilter.internal.SslFilter.doFilter(SslFilter.java:96)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:84)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.sling.security.impl.ReferrerFilter.doFilter(ReferrerFilter.java:290)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.sling.junit.impl.servlet.TestLogServlet$TestNameLoggingFilter.doFilter(TestLogServlet.java:252)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at com.adobe.granite.license.impl.LicenseCheckFilter.doFilter(LicenseCheckFilter.java:308)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.sling.i18n.impl.I18NFilter.doFilter(I18NFilter.java:129)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.sling.featureflags.impl.FeatureManager.doFilter(FeatureManager.java:115)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.sling.engine.impl.log.RequestLoggerFilter.doFilter(RequestLoggerFilter.java:75)

  at org.apache.felix.http.base.internal.handler.FilterHandler.doHandle(FilterHandler.java:108)

  at org.apache.felix.http.base.internal.handler.FilterHandler.handle(FilterHandler.java:80)

  at org.apache.felix.http.base.internal.dispatch.InvocationFilterChain.doFilter(InvocationFilterChain.java:46)

  at org.apache.felix.http.base.internal.dispatch.HttpFilterChain.doFilter(HttpFilterChain.java:31)

  at org.apache.felix.http.base.internal.dispatch.FilterPipeline.dispatch(FilterPipeline.java:76)

  at org.apache.felix.http.base.internal.dispatch.Dispatcher.dispatch(Dispatcher.java:49)

  at org.apache.felix.http.base.internal.DispatcherServlet.service(DispatcherServlet.java:67)

  at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)

  at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)

  at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)

  at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)

  at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)

  at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)

  at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)

  at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)

  at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

  at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)

  at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)

  at org.eclipse.jetty.server.Server.handle(Server.java:497)

  at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)

  at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)

  at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)

  at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)

  at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)

  at java.lang.Thread.run(Thread.java:745)

  Could someone please help us in figuring out the issue or provide an example of adding byte array to MetaDataMap?

Thanks,

Ananta

1 Accepted Solution

Avatar

Correct answer by
Level 2

Hi Scott,

Thank you for your response. In the meantime, I was trying few things at my end and I got the byte array thing working as follows:

...

...

Map<String, Object> test = new HashMap<String, Object>();

// RequestParameter object has image data received via form (post request)

byte[] bytes =  requestParameter.get(); // output - [-47, 1, 16, 84, 2, 101, 110....]

String byteArrayString = Arrays.toString(bytes) // output - "[-47, 1, 16, 84, 2, 101, 110....]"

  test.put("profileImg", byteArrayString);

Workflow wf =wfSession.startWorkflow(wfModel, wfData, test);

Once the above workflow is started, in the execute method we will have something as follows :

private MetaDataMap newProps;

public void execute(WorkItem item, WorkflowSession wfsession,MetaDataMap args) throws WorkflowException {

  .....

  .....

  newProps = item.getWorkflowData().getMetaDataMap();

  String byteArrayString = newProps.get("profileImg").toString(); // retrieve value from metaDataMap

  String[] byteValues = requestParameter.substring(1, requestParameter.length() - 1).split(",");

  byte[] bytes = new byte[byteValues.length]; // Convert back to byte array

  for (int i=0, len=bytes.length; i<len; i++) {

    bytes[i] = Byte.parseByte(byteValues[i].trim());

  }

  InputStream bis = new ByteArrayInputStream(bytes); // convert to input stream which can then be used as per requirement

}

Let me know your opinion on this solution.

Thanks,

Ananta

View solution in original post

7 Replies

Avatar

Level 10

I know that we can pass Strings, etc. See: Adobe Experience Manager Help | Passing Values between Adobe Experience Manager Workflow Steps

In this article - it states:

If you need to pass non-primitive data (binary data), you can pass it within a byte[]. However if the byte array is too large, a better approach is to write the data to a JCR node in a given step and retrieve it in a later step. Do not try to store data as an InputStream in the Map.

Avatar

Level 2

Hello Scott,

Thank you for your prompt response. Based on the above comment in the article, it seems it is possible to have byte[] in the map which I am trying to achieve in my initial post. Could you please provide an example of inserting byte[] in the map?

Thanks,

Ananta

Avatar

Level 10

I will look into that. I have tried Strings and numeric values.

Avatar

Level 10

I am seeing that too when trying a byte array. It basically has to do with casting from the map. Each time, the error you specified occurs.

B cannot be cast to [Ljava.lang.Object

I recommend using the workaround that is mentioned in the article.

In the custom workflow step A - write the byte[] to a node prop and then in custom workflow step B - retrieve it.

You can use the JCR API to perform read/write node operations.

Avatar

Correct answer by
Level 2

Hi Scott,

Thank you for your response. In the meantime, I was trying few things at my end and I got the byte array thing working as follows:

...

...

Map<String, Object> test = new HashMap<String, Object>();

// RequestParameter object has image data received via form (post request)

byte[] bytes =  requestParameter.get(); // output - [-47, 1, 16, 84, 2, 101, 110....]

String byteArrayString = Arrays.toString(bytes) // output - "[-47, 1, 16, 84, 2, 101, 110....]"

  test.put("profileImg", byteArrayString);

Workflow wf =wfSession.startWorkflow(wfModel, wfData, test);

Once the above workflow is started, in the execute method we will have something as follows :

private MetaDataMap newProps;

public void execute(WorkItem item, WorkflowSession wfsession,MetaDataMap args) throws WorkflowException {

  .....

  .....

  newProps = item.getWorkflowData().getMetaDataMap();

  String byteArrayString = newProps.get("profileImg").toString(); // retrieve value from metaDataMap

  String[] byteValues = requestParameter.substring(1, requestParameter.length() - 1).split(",");

  byte[] bytes = new byte[byteValues.length]; // Convert back to byte array

  for (int i=0, len=bytes.length; i<len; i++) {

    bytes[i] = Byte.parseByte(byteValues[i].trim());

  }

  InputStream bis = new ByteArrayInputStream(bytes); // convert to input stream which can then be used as per requirement

}

Let me know your opinion on this solution.

Thanks,

Ananta

Avatar

Level 10

Nice - you serialized the byte[] into a string. This would make a good follow up article named Passing Binary data between Workflow steps. I am sure it will help community members in the future.