Error while closing command context: NullPointerException

Hi. I have a TaskListener which needs to use the ContentEngine, the task’s form has an upload fieldType and when the task is completed the TaskListener is invoked:

<userTask id="fileUploadTask" name="File Upload Task" flowable:formKey="file_upload">
    <extensionElements>
        <flowable:taskListener
                event="complete"
                class="FileUploadToContentTaskListener" />
    </extensionElements>
</userTask>

The TaskListener gets a handle on the ContentEngine:

    ContentService contentService = ContentEngines.getDefaultContentEngine().getContentService();

and subsequently:

                InputStream inputStream = contentService.getContentItemData(value.toString());

When the TaskListener is done, then I get this exception:

ERROR org.flowable.engine.common.impl.interceptor.CommandContext - Error while closing command context
java.lang.NullPointerException
at org.flowable.content.engine.impl.util.CommandContextUtil.getContentItemEntityManager(CommandContextUtil.java:57)
at org.flowable.content.engine.impl.util.CommandContextUtil.getContentItemEntityManager(CommandContextUtil.java:53)
at org.flowable.content.engine.impl.cmd.CreateContentItemCmd.execute(CreateContentItemCmd.java:31)
at org.flowable.content.engine.impl.cmd.CreateContentItemCmd.execute(CreateContentItemCmd.java:25)
at org.flowable.engine.common.impl.interceptor.DefaultCommandInvoker.execute(DefaultCommandInvoker.java:10)
at org.flowable.engine.common.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
at org.flowable.engine.common.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:72)
at org.flowable.engine.common.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.flowable.engine.common.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.engine.common.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.content.engine.impl.ContentServiceImpl.newContentItem(ContentServiceImpl.java:33)
at FileUploadToContentTaskListener.notify(FileUploadToContentTaskListener.java:25)
at org.flowable.engine.impl.delegate.invocation.TaskListenerInvocation.invoke(TaskListenerInvocation.java:35)
at org.flowable.engine.impl.delegate.invocation.DelegateInvocation.proceed(DelegateInvocation.java:35)
at org.flowable.engine.impl.delegate.invocation.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:26)
at org.flowable.engine.impl.bpmn.helper.ClassDelegate.notify(ClassDelegate.java:122)
at org.flowable.engine.impl.delegate.invocation.TaskListenerInvocation.invoke(TaskListenerInvocation.java:35)
at org.flowable.engine.impl.delegate.invocation.DelegateInvocation.proceed(DelegateInvocation.java:35)
at org.flowable.engine.impl.delegate.invocation.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:26)
at org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper.executeTaskListeners(ListenerNotificationHelper.java:125)
at org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper.executeTaskListeners(ListenerNotificationHelper.java:106)
at org.flowable.engine.impl.util.TaskHelper.completeTask(TaskHelper.java:77)
at org.flowable.engine.impl.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:64)
at org.flowable.engine.impl.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:26)
at org.flowable.engine.impl.cmd.NeedsActiveTaskCmd.execute(NeedsActiveTaskCmd.java:58)
at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:51)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:93)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:72)
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:56)
at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:25)
at org.flowable.engine.common.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
at org.flowable.engine.common.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:72)
at org.flowable.engine.common.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.flowable.engine.common.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.engine.common.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.engine.impl.TaskServiceImpl.complete(TaskServiceImpl.java:215)
at FileUploadToContentTaskListenerTest.test(FileUploadToContentTaskListenerTest.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.flowable.engine.test.FlowableRule$1.evaluate(FlowableRule.java:116)
at org.flowable.content.engine.test.FlowableContentRule$1.evaluate(FlowableContentRule.java:97)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

I’m running from a JUnit test using FlowableContentRule.

Not sure what’s wrong. Any advice please? Using Flowable 6.2.1

Thanks.

Hi. Any response please?

It would help if you provided the source code of the Junit test that you are using as it is hard to tell what is going on in FileUploadToContentTaskListener.

Hi. I’m restricted on posting code from my org, but let me try and provide the essentials:

@Rule
public FlowableRule flowableRule = new FlowableRule();

@Rule
public FlowableContentRule rule = new FlowableContentRule();

private static ContentEngine cachedContentEngine;
private ContentService contentService;

@Before
public void initFormEngine() {
    if (cachedContentEngine == null) {
        cachedContentEngine = rule.getContentEngine();
    }
    this.contentService = cachedContentEngine.getContentService();
}

@Test
@Deployment(resources = {
        "file-upload.bpmn20.xml"
})
public void test() {
    ProcessInstance processInstance = flowableRule.getRuntimeService().startProcessInstanceByKey("fileUpload");
    Task task = flowableRule.getTaskService().createTaskQuery().singleResult();

    ContentItem contentItem = contentService.newContentItem();
    contentItem.setName("announcement.msg");
    contentItem.setMimeType("application/octet-stream");
    contentItem.setProcessInstanceId(processInstance.getId());
    contentItem.setTaskId(task.getId());
    contentService.saveContentItem(contentItem, FileUploadToContentTaskListener.class.getResourceAsStream("content/announcement.msg"));

    flowableRule.getTaskService().complete(task.getId());
}

And it works in deployment… just can’t get the unit test working without this error.

Hi,

The problem is that the content engine should be started together with the process engine. An example on how this can be done can be found here:

This is using Spring XML configuration, but the idea is the same for a Spring Java config. The CMMN engine is booted together with the process engine by adding a CmmnEngineConfigurator to the configurators of the process engine configuration.

You can do a similar thing with the SpringContentEngineConfigurator:

Best regards,

Tijs

1 Like

Ok, thanks. That makes sense. But how do I get around this error:

org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [flowable.content.cfg.xml]; nested exception is java.io.FileNotFoundException: class path resource [flowable.content.cfg.xml] cannot be opened because it does not exist

Caused at the last line:

@Before
public void initFormEngine() {
    if (cachedContentEngine == null) {
        cachedContentEngine = rule.getContentEngine();
    }
    this.contentService = cachedContentEngine.getContentService();
}

flowable.cfg.xml:

<bean id="processEngineConfiguration"
      class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration" depends-on="flowableHelper">

    <property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000;MVCC=TRUE"/>
    <property name="jdbcDriver" value="org.h2.Driver"/>
    <property name="jdbcUsername" value="sa"/>
    <property name="jdbcPassword" value=""/>

    <property name="databaseSchemaUpdate" value="true"/>

    <property name="configurators">
        <list>
            <ref bean="formEngineConfigurator"/>
            <ref bean="contentEngineConfigurator"/>
        </list>
    </property>

</bean>

<bean id="formEngineConfigurator" class="org.flowable.form.engine.configurator.FormEngineConfigurator">
    <property name="formEngineConfiguration" ref="formEngineConfiguration"/>
</bean>
<bean id="formEngineConfiguration" class="org.flowable.form.engine.impl.cfg.StandaloneFormEngineConfiguration">
</bean>

<bean id="contentEngineConfigurator" class="org.flowable.content.engine.configurator.ContentEngineConfigurator">
    <property name="contentEngineConfiguration" ref="contentEngineConfiguration"/>
</bean>
<bean id="contentEngineConfiguration" class="org.flowable.content.engine.impl.cfg.StandaloneContentEngineConfiguration">
    <property name="jdbcUrl" value="jdbc:h2:mem:flowablecontent;DB_CLOSE_DELAY=1000" />
    <property name="jdbcDriver" value="org.h2.Driver" />
    <property name="jdbcUsername" value="sa" />
    <property name="jdbcPassword" value="" />
</bean>

Hi. Could you please advise on a sample config xml that would get this working? Thanks.

Any help please? Still stuck on this.