Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
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.