camunda / camunda-spin

Simple API for working with complex data formats such as XML and JSON
30 stars 31 forks source link

Camunda spin doesn't recognise primitives in Javascript mode #18

Open michaelarnauts opened 6 years ago

michaelarnauts commented 6 years ago

According to the docs, camunda-spin should recognize primitives like booleans:

String values that represent JSON primitive values can also be read. For example, JSON("true") returns a SpinJsonNode that represents the boolean value true.

A bit down it states that in Javascript, you don't need to specify that it is a json, but you can just use S() to do this.

JSON can be read from script languages in the same way as from Java. Since script languages use dynamic typing, you do not need to hint the data format but you can use autodetection. The following example demonstrates how to read JSON in Javascript: var customer = S('{"customer": "Kermit"}');

I'm using spin to parse the return value of a REST call in a camunda connector, this works fine if I return an object, but not when I return a primitive like a string or a boolean.

S('true')

I get the following error:

ENGINE-16004 Exception while closing command context: SPIN-01004 No matching data format detected

Stacktrace:

camunda_1         | 21-Mar-2018 16:09:45.896 SEVERE [http-nio-8080-exec-2] org.camunda.commons.logging.BaseLogger.logError ENGINE-16004 Exception while closing command context: SPIN-01004 No matching data format detected
camunda_1         |  org.camunda.spin.spi.SpinDataFormatException: SPIN-01004 No matching data format detected
camunda_1         |     at org.camunda.spin.impl.logging.SpinCoreLogger.unrecognizableDataFormatException(SpinCoreLogger.java:53)
camunda_1         |     at org.camunda.spin.impl.SpinFactoryImpl.createSpinFromReader(SpinFactoryImpl.java:127)
camunda_1         |     at org.camunda.spin.impl.SpinFactoryImpl.createSpin(SpinFactoryImpl.java:50)
camunda_1         |     at org.camunda.spin.impl.SpinFactoryImpl.createSpinFromString(SpinFactoryImpl.java:103)
camunda_1         |     at org.camunda.spin.impl.SpinFactoryImpl.createSpin(SpinFactoryImpl.java:47)
camunda_1         |     at org.camunda.spin.Spin.S(Spin.java:64)
camunda_1         |     at jdk.nashorn.internal.scripts.Script$9$\^eval\_.:program(<eval>:18)
camunda_1         |     at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
camunda_1         |     at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
camunda_1         |     at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
camunda_1         |     at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
camunda_1         |     at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
camunda_1         |     at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
camunda_1         |     at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
camunda_1         |     at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.SourceExecutableScript.evaluateScript(SourceExecutableScript.java:114)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.SourceExecutableScript.evaluate(SourceExecutableScript.java:60)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.ResourceExecutableScript.evaluate(ResourceExecutableScript.java:43)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.ExecutableScript.execute(ExecutableScript.java:56)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.env.ScriptingEnvironment.execute(ScriptingEnvironment.java:97)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.env.ScriptingEnvironment.execute(ScriptingEnvironment.java:83)
camunda_1         |     at org.camunda.bpm.engine.impl.delegate.ScriptInvocation.invoke(ScriptInvocation.java:40)
camunda_1         |     at org.camunda.bpm.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:54)
camunda_1         |     at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocationInContext(DefaultDelegateInterceptor.java:87)
camunda_1         |     at org.camunda.bpm.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:59)
camunda_1         |     at org.camunda.bpm.engine.impl.scripting.ScriptValueProvider.getValue(ScriptValueProvider.java:39)
camunda_1         |     at org.camunda.bpm.engine.impl.core.variable.mapping.OutputParameter.execute(OutputParameter.java:43)
camunda_1         |     at org.camunda.bpm.engine.impl.core.variable.mapping.IoParameter.execute(IoParameter.java:47)
camunda_1         |     at org.camunda.bpm.engine.impl.core.variable.mapping.IoMapping.executeOutputParameters(IoMapping.java:41)
camunda_1         |     at org.camunda.connect.plugin.impl.ServiceTaskConnectorActivityBehavior.applyOutputParameters(ServiceTaskConnectorActivityBehavior.java:84)
camunda_1         |     at org.camunda.connect.plugin.impl.ServiceTaskConnectorActivityBehavior$1.call(ServiceTaskConnectorActivityBehavior.java:58)
camunda_1         |     at org.camunda.connect.plugin.impl.ServiceTaskConnectorActivityBehavior$1.call(ServiceTaskConnectorActivityBehavior.java:51)
camunda_1         |     at org.camunda.bpm.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior.executeWithErrorPropagation(AbstractBpmnActivityBehavior.java:108)
camunda_1         |     at org.camunda.connect.plugin.impl.ServiceTaskConnectorActivityBehavior.execute(ServiceTaskConnectorActivityBehavior.java:51)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute$2.callback(PvmAtomicOperationActivityExecute.java:57)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute$2.callback(PvmAtomicOperationActivityExecute.java:46)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.continueIfExecutionDoesNotAffectNextOperation(PvmExecutionImpl.java:1935)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute.execute(PvmAtomicOperationActivityExecute.java:38)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute.execute(PvmAtomicOperationActivityExecute.java:27)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:89)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:611)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:587)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl$5.callback(PvmExecutionImpl.java:1874)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl$5.callback(PvmExecutionImpl.java:1871)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.continueExecutionIfNotCanceled(PvmExecutionImpl.java:1941)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.dispatchDelayedEventsAndPerformOperation(PvmExecutionImpl.java:1890)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.dispatchDelayedEventsAndPerformOperation(PvmExecutionImpl.java:1871)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(PvmAtomicOperationTransitionNotifyListenerStart.java:57)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(PvmAtomicOperationTransitionNotifyListenerStart.java:27)
camunda_1         |     at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:65)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:89)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:69)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:622)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:597)
camunda_1         |     at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:58)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:89)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:69)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:622)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:597)
camunda_1         |     at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:58)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:89)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:69)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:622)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:597)
camunda_1         |     at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:58)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:89)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:611)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:587)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionCreateScope.scopeCreated(PvmAtomicOperationTransitionCreateScope.java:34)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationCreateScope.execute(PvmAtomicOperationCreateScope.java:50)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationCreateScope.execute(PvmAtomicOperationCreateScope.java:24)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:89)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:112)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext$1.call(CommandInvocationContext.java:95)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext$1.call(CommandInvocationContext.java:93)
camunda_1         |     at org.camunda.bpm.engine.impl.context.ProcessApplicationClassloaderInterceptor.call(ProcessApplicationClassloaderInterceptor.java:44)
camunda_1         |     at org.camunda.bpm.application.AbstractProcessApplication.execute(AbstractProcessApplication.java:114)
camunda_1         |     at org.camunda.bpm.application.AbstractProcessApplication.execute(AbstractProcessApplication.java:125)
camunda_1         |     at org.camunda.bpm.engine.impl.context.Context.executeWithinProcessApplication(Context.java:192)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:93)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:611)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:587)
camunda_1         |     at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.start(PvmExecutionImpl.java:231)
camunda_1         |     at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.start(ExecutionEntity.java:432)
camunda_1         |     at org.camunda.bpm.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:59)
camunda_1         |     at org.camunda.bpm.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:31)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:104)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66)
camunda_1         |     at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
camunda_1         |     at org.camunda.bpm.engine.impl.ProcessInstantiationBuilderImpl.executeWithVariablesInReturn(ProcessInstantiationBuilderImpl.java:162)
camunda_1         |     at org.camunda.bpm.engine.rest.sub.repository.impl.ProcessDefinitionResourceImpl.startProcessInstanceAtActivities(ProcessDefinitionResourceImpl.java:168)
camunda_1         |     at org.camunda.bpm.engine.rest.sub.repository.impl.ProcessDefinitionResourceImpl.startProcessInstance(ProcessDefinitionResourceImpl.java:118)
camunda_1         |     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
camunda_1         |     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
camunda_1         |     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
camunda_1         |     at java.lang.reflect.Method.invoke(Method.java:498)
camunda_1         |     at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
camunda_1         |     at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:257)
camunda_1         |     at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:222)
camunda_1         |     at org.jboss.resteasy.core.ResourceLocator.invokeOnTargetObject(ResourceLocator.java:159)
camunda_1         |     at org.jboss.resteasy.core.ResourceLocator.invoke(ResourceLocator.java:107)
camunda_1         |     at org.jboss.resteasy.core.ResourceLocator.invokeOnTargetObject(ResourceLocator.java:154)
camunda_1         |     at org.jboss.resteasy.core.ResourceLocator.invoke(ResourceLocator.java:92)
camunda_1         |     at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542)
camunda_1         |     at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524)
camunda_1         |     at org.jboss.resteasy.core.SynchronousDispatcher.invokePropagateNotFound(SynchronousDispatcher.java:169)
camunda_1         |     at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:212)
camunda_1         |     at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:59)
camunda_1         |     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
camunda_1         |     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
camunda_1         |     at org.camunda.bpm.engine.rest.filter.CacheControlFilter.doFilter(CacheControlFilter.java:41)
camunda_1         |     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
camunda_1         |     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
camunda_1         |     at org.camunda.bpm.engine.rest.filter.EmptyBodyFilter.doFilter(EmptyBodyFilter.java:95)
camunda_1         |     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
camunda_1         |     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
camunda_1         |     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
camunda_1         |     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
camunda_1         |     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
camunda_1         |     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
camunda_1         |     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
camunda_1         |     at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
camunda_1         |     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
camunda_1         |     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
camunda_1         |     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
camunda_1         |     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
camunda_1         |     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
camunda_1         |     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
camunda_1         |     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
camunda_1         |     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
camunda_1         |     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
camunda_1         |     at java.lang.Thread.run(Thread.java:748)
michaelarnauts commented 6 years ago

Okay, after much debugging, I've found out that you can specify the type as you do with Java, this is just not documented behavior for Javascript. You need application/json as second parameter to S() for this to work.

So, this will not work:

S('true');

And this will work:

S('true', 'application/json');
michaelarnauts commented 6 years ago

There still is something strange going on:

S('"test"', 'application/json');

is still returning "test" (with the quotes). I would expect that camunda-spin removes the quotes since it is part of the definition for json to indicate that it is a string?

mbitencourt commented 4 years ago

It works! Thanks.