ClassCast Exception org.camunda.spin.plugin.variable.value.impl.JsonValueImpl

Hi Community,

I’m stuck at an exception that I can’t resolve and don’t know why it occurs.

My Case:

I have two classes and want to store their objects as a Variable in ProcessInstance.

I create the first Object through a Delegate Expression from a JSON File and then write to Camunda.

@Component
public class OptionsTask implements JavaDelegate {
    @Autowired
    private ResourceLoader resourceLoader;
    private Expression optionsFile;

    public void execute(DelegateExecution execution) throws Exception {
        String jsonFileNameForOptions = (String) optionsFile.getValue(execution);
        Resource fileResource = resourceLoader.getResource("classpath:json/"+jsonFileNameForOptions);
        ObjectMapper objectMapper = new ObjectMapper();
        Options optionsObject = objectMapper.readValue(fileResource.getInputStream(), Options.class);
        execution.setVariable(ProcessConstants.OPTIONS, Spin.JSON(optionsObject));
    }
}

When I read the variable, I get the Object back in SpringBoot.

private Options buildOptions(ProcessInstance processInstance) throws InterruptedException {
		Options options = (Options) camundaService.getTaskVariable(processInstance, ProcessConstants.OPTIONS);
		return (options);
	}

The second Object is also created and instantiated by a Delegate Expression.

 @Component
public class NavigationTask implements JavaDelegate {
    private static final Logger logger = LoggerFactory.getLogger(NavigationTask.class);

    @Autowired private CamundaService camundaService;

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        Map<String,String> nav = (Map<String,String>) execution.getVariable(ProcessConstants.NAVIGATION_RAW);
        Navigation navigation = new Navigation();
        navigation.setNav(new ArrayList<NavigationEntry>());

        if(nav != null){
            BackendHelper.printMap(nav);

            for(Map.Entry<String, String> entry:nav.entrySet()) {
           
               
            }
        }
        execution.setVariable(ProcessConstants.NAVIGATION, Spin.JSON(navigation));
    }
}
public Navigation buildNavigation(ProcessInstance processInstance) throws InterruptedException {
		Navigation navigation  =  (Navigation)camundaService.getTaskVariable(processInstance, ProcessConstants.NAVIGATION);
		return (navigation);
	}

However, when I read the Variable and Cast it back to Navigation, I got the ClassCastException below.

java.lang.ClassCastException: class org.camunda.spin.plugin.variable.value.impl.JsonValueImpl cannot be cast to class ch.galliard.framework.Navigation (org.camunda.spin.plugin.variable.value.impl.JsonValueImpl and ch.galliard.framework.Navigation are in unnamed module of loader org.springframework.boot.loader.LaunchedURLClassLoader @7daf6ecc)

I saw in Cockpit that Spin created the variables correctly in Camunda.

Any help is much appreciated.

Turns out neither Variables were correctly deserialised.

However, I think I fixed it using the following. Any guidance on whether this is the correct way of doing it?

private Options buildOptions(ProcessInstance processInstance) throws InterruptedException, JsonProcessingException {
		Object object = camundaService.getTaskVariable(processInstance, ProcessConstants.OPTIONS);
		logger.info("CLASS NAME: " + object.getClass().getTypeName());
		JsonValueImpl jsonValue = (JsonValueImpl)object;
		SpinJsonNode spinJsonNode = jsonValue.getValue();
		Options options = spinJsonNode.mapTo(Options.class);

		if (options == null) {
			return (new Options());
		}
		else {
			return (options);
		}
	
	}