Applying workflow on any assets in Liferay 6

Liferay 6 integrates workflow engines like jBPM or Kaleo on any assets finally. This feature has been expected for a while.  By this feature, users are able to manage the content creation process with a workflow. Especially, this feature helps content creators collaborate and go through the necessary steps in order to produce better and more accurate content like assets. Within a workflow, any type of assets like Document Library document, wiki entry or web content can go through review-approval processes.

In this article, I am going to show this feature with examples. Asset here refers to Liferay core content types: like Document Library document, Image Gallery image, Message Boards message, Web Content, Wiki page, comments, Blogs entry. Logically, workflow should be available for any assets like Image Gallery image, Calendar event, layout page, Bookmarks entry, user, organization, etc. (Abstracted from the book: Liferay Portal 6 Enterprise Intranets)


Install Workflow engine

First prepare Liferay portal. Here I use Liferay 6.0.3 GA (revision 55391). Liferay 6.0.2 RC 2 would be OK, too.  Install the portal and you would have a folder $PORTAL_HOME and deploy-folder $PORTAL_HOME/deploy.  Then start the portal. 

When the portal is running, deploy the workflow engine – that is, drop the WAR ${workflow-web-6.0.2.1}.war to the folder $PORTAL_HOME/deploy. You can use either jbpm-web or kaleo-web. Kaleo is Liferay custom Workflow plugin.  Here I use kaleo-web. 

You can download kaleo-web from 

kaleo-web-6.0.2.1.war.

Note that you can find example workflow single-approver-definition.xml at 

/kaleo-web/WEB-INF/classes/META-INF/definitions.

Of course, you can download example at 

/palm_tree/book/0387/chapter09/definitions.

Configure workflow on any assets

Now you can configure workflow now. I use asset Blog Entry as an example.

Create two users: David Berger – a content creator; Lotti Stein – a content reviewer. And assign them as members of community Guest.

Login as admin and go to Control panel | Liferay.com| Workflow Configuration

Locate Blogs Entry and select “Single Approver” workflow and save it.

Go to Control panel | Portal| Communities and assign user roles of community guest; note that you can apply  workflow on any assets of any groups (communities and organizations). Here I  use the group Guest as an example.

Assign roles (community or organization content reviewer – Auto-generated role from workflow definition) to users (David Berger and Lotti Stein).

 

Go through workflow

Assign proper permissions to users David Berger and Lotti Stein that they can manage pages and create blogs entries in community Guest;

Login as David Berger and create a blog called “Liferay Portal 6 Enterprise Intranets”; you would see that the asset Blog entry goes workflow and it states as “Pending Approval”;

 

Login as Lotti Stein and go to Control Panel | Lotti Stein | My Workflow Tasks; you would see tabs: Assigned to Me, Assigned to My Roles, My Completed Tasks. Under the tab Assigned to My Roles, you would see the workflow task “Liferay Portal 6 Enterprise Intranets”.

 
Click on the workflow task and assign this to yourself “Lotti Stein”; and add comment “Please review”; as you can see, the workflow task is moved to the tab “Assigned to Me”;
 

 

Click on the workflow task under the tab “Assigned to Me”; and you can either reject it or approve it; you can click on “Approve Asset” and add comment “looks good” as well; 

 

As you can see, the workflow task is move to the tab “My Completed Tasks”;

 

After approved, the blog entry “Liferay Portal 6 Enterprise Intranets” would be visible for end users.

Summary

As you can see, Liferay 6 integrates workflow engine either jBPM or Kaleo smoothly. Thus you can manage easily workflow definitions, instances and tasks in one place, that is, Control Panel. In brief, this integration has following beauties

  • ability to integrate many workflow engines like jBPM | Kaleo; 

  • ability to have configurable workflow definitions;

  • ability to apply workflow on any assets like Blogs Entry, Bookmarks Entry, Calendar Event, Document Library Document, Image Gallery Image, Web Content, Wiki Page, etc.

Last but not least, I'd like to send a ton of thanks to Brian Chan, Jorge Ferrer, Julio Camarero, Raymond Auge, Bruno Farache, Shuyang Zhou, Michael Han, Marcellus Tavares, etc. who did an amazing job to make Asset Workflow a reality. This is big and long-time expected feature.

What’s next?

What’s next? You should be able to apply workflow on any custom assets in Liferay 6 like Knowledge Base articles. Right? I will address details in next blogs post. 

 

Blogs
Great work. With kaleo-web I had no problem but if I install jbpm-web (compiled from svn) I can't upload the sample workflow. Only activating DEBUG log level for some packages I managed to see the error:

Begin Code----------------------------------------
22:40:38,298 DEBUG [ProxyMessageListener:58] com.liferay.portal.kernel.workflow.WorkflowDefinitionFileException: org.jbpm.jpdl.JpdlException: [[ERROR] no proces
sdefinition.xml inside process archive]
com.liferay.portal.kernel.workflow.WorkflowDefinitionFileException: org.jbpm.jpdl.JpdlException: [[ERROR] no processdefinition.xml inside process archive]
at com.liferay.portal.workflow.jbpm.WorkflowDefinitionManagerImpl.deployWorkflowDefinition(WorkflowDefinitionManagerImpl.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.liferay.portal.kernel.util.MethodInvoker.invoke(MethodInvoker.java:94)
at com.liferay.portal.kernel.messaging.proxy.ProxyRequest.execute(ProxyRequest.java:69)
at com.liferay.portal.kernel.messaging.proxy.ProxyMessageListener.receive(ProxyMessageListener.java:51)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:65)
at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:63)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.jbpm.jpdl.JpdlException: [[ERROR] no processdefinition.xml inside process archive]
at org.jbpm.jpdl.par.JpdlArchiveParser.readFromArchive(JpdlArchiveParser.java:43)
at org.jbpm.jpdl.par.ProcessArchive.parseProcessDefinition(ProcessArchive.java:87)
at com.liferay.portal.workflow.jbpm.WorkflowDefinitionManagerImpl.deployWorkflowDefinition(WorkflowDefinitionManagerImpl.java:64)
... 12 more
22:40:38,300 DEBUG [InvokerPortletImpl:370] processAction for 151 takes 22 ms

End Code----------------------------------------

I'm not sure how to proceed, is it a bug or I missed something?
1.- installed from zip (on win and linux)
2.- compiled jbpm-web and dropped the war to deploy dir
3.- after installation is completed, I try to upload the sample file in jbpm-web/docroot/WEB-INF/classes/META-INF/definitions and it throws the error.

Is there something I've missed?
Thanks Jonas for the article.

Have faced few issues though -

I created 2 users, Gaurish and Ashu and assigned them content reviewer for the guest community. When I logged in as Gaurish and assigned a document for review to Ashu, the 'activity' section shows 'Gaurish assigned the task to himself' whereas it should have shown 'Gaurish assigned the task to Ashu'. And when I log in as Ashu, it shows the document in 'Assigned to Me' section (as expectedd). But in the 'activity' section it shows 'Ashu assigned the task to himself' whereas it should have shown 'Gaurish assigned the task to Ashu'. Isn't it?

Also, even if I change the due date from 'never' to a date, it never shows the selected due date and always shows 'never' in the due date section.
Jonas,

Very nice posting!

I followed the instruction and was able to make everything working except one. When I click "My workflow task", I got

"Unable find model com.liferay.portal.workflow.kaleo.model.impl.KaleoTaskInstanceTokenImpl
java.lang.ClassNotFoundException: com.liferay.portal.workflow.kaleo.model.impl.KaleoTaskInstanceTokenImpl. I found that KaleoTaskInstanceTokenImpl class is in kaleo-web.war and not available as a library. Here is the stack trace. I used 6.0.2 rc version. Did I miss something? Thank you.

Brian Ko

2010-06-15 17:56:53,987 ERROR [com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl] (liferay/workflow_task) Unable find model com.liferay.portal.workflow.kaleo.model.impl.KaleoTaskInstanceTokenImpl
java.lang.ClassNotFoundException: com.liferay.portal.workflow.kaleo.model.impl.KaleoTaskInstanceTokenImpl
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl.getImplClass(DynamicQueryFactoryImpl.java:80)
at com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl.forClass(DynamicQueryFactoryImpl.java:41)
at com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil.forClass(DynamicQueryFactoryUtil.java:31)
at com.liferay.portal.workflow.kaleo.service.impl.KaleoTaskInstanceTokenLocalServiceImpl.buildDynamicQuery(KaleoTaskInstanceTokenLocalServiceImpl.java:559)
at com.liferay.portal.workflow.kaleo.service.impl.KaleoTaskInstanceTokenLocalServiceImpl.search(KaleoTaskInstanceTokenLocalServiceImpl.java:347)
at com.liferay.portal.workflow.kaleo.service.impl.KaleoTaskInstanceTokenLocalServiceImpl.search(KaleoTaskInstanceTokenLocalServiceImpl.java:335)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at com.liferay.portal.dao.jdbc.aop.DynamicDataSourceTransactionInterceptor.invoke(DynamicDataSourceTransactionInterceptor.java:47)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at com.liferay.portal.dao.jdbc.aop.DynamicDataSourceTransactionInterceptor.invoke(DynamicDataSourceTransactionInterceptor.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy358.search(Unknown Source)
at com.liferay.portal.workflow.kaleo.service.KaleoTaskInstanceTokenLocalServiceUtil.search(KaleoTaskInstanceTokenLocalServiceUtil.java:293)
at com.liferay.portal.workflow.kaleo.WorkflowTaskManagerImpl.search(WorkflowTaskManagerImpl.java:460)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at com.liferay.portal.dao.jdbc.aop.DynamicDataSourceTransactionInterceptor.invoke(DynamicDataSourceTransactionInterceptor.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy362.search(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.liferay.portal.kernel.util.MethodInvoker.invoke(MethodInvoker.java:94)
at com.liferay.portal.kernel.messaging.proxy.ProxyRequest.execute(ProxyRequest.java:69)
at com.liferay.portal.kernel.messaging.proxy.ProxyMessageListener.receive(ProxyMessageListener.java:51)
at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:65)
at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:63)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:619)
@Brian @Gaurish @Marcelo @ts

Complete workflow functions would be available in Liferay 6 GA version. This article will be updated after GA version. By the way, 6.0 GA version would be ready in weeks.
Hi Everyone,

Please note, that this article is based on unfinished code. Some things have changed since it was written.

Jonas, I think it would be less confusing for people if you wait for new frameworks to be finalized before writing tutorials about them.

For this one, please add a warning note and update it when 6.0 GA comes out.
Thanks, Jorge. As you can see, Workflow is big feature. Yes, this article will be updated when 6.0 GA is ready.
Hi Jorge

Any idea when the GA will be released?
Hi Hennie,

We are working on it, trying to fix bugs so that it's a very stable release.

All help both testing and reporting bugs (creating a JIRA ticket + posting about it in the Beta Testing forum category)
and fixing the open tickets that relate to 6.0 is welcome.
Jorge,
I got it. However, I want to point that it is still very helpful tutorial. Everything step up to the error worked fine. I just thought that I missed some step. Thank you.
Hi Brian,

Great to know. Actually, we would really appreciate the feedback of all of you trying out the workflow system.

You can use the Beta Testing category for that.
Sir, Thanks for writing about this big feature. Very Informative emoticon
Very powerful! Liferay needs something like that to make it more versatility.
Great job!
Is there any estimate on when the blog about applying workflows to custom assets will be ready? I want to use the workflow engine to define workflows for some custom services I am generating.
Thanks, Nicholas. Applying workflows to custom assets will be ready soon.
I'm not sure what you mean by custom assets in this context.

I am looking for the ability to configure workflow (simple approval would be fine bit more complex as well) to just specific content types, so anyone can publish basic web articles but for say Pres Releases or white paper content types they have to be put through workflow.

Will this be possible soon?
Hi Dave, Out-of-the-box, liferay 6 provides the ability to enable workflow for core assets:
* Blogs Entry
* Comments
* Document Library Document
* Message Boards Message
* Web Content
* Wiki Page
custom assets are generated by Service-Builder) through plugins. Knowledge base articles are examples.

Notice that workflow is based on assets, not the type of assets. For example, you can apply workflow on the asset Web Content articles, not the type of Web Content.

Hope that it helps,

Thanks
Hi Nicholas,

Applying workflows to custom assets is ready at

http://www.liferay.com/c/blogs/find_entry?entryId=5624351
Hi,I don't know whther Jonas Yuan can help me,but I'm in a confusion about the using of jbpm3 in liferay
1-is the plugin jbpm3 or kaleo with liferay does'nt support swimlane?
2-To assign task to some user,should i follow the example of Single Approver (Assign task to some roles).
Hi Bradai, Thanks.

It would be better to use Kaleo web. two new features: 1) swim-lane and 2) role-based workflow.

1) is good feature. It would get supported shortly.

2) got supported in the back-end. UI support would come out soon.
Thanks Jonas for your reply,
But are there any examples of process definition using swimlane?
Hi Bradai, you may refer to the new feature:

Ability to specify workflow process definition using swimlane
http://issues.liferay.com/browse/LPS-16014
Hi Jonas,Thanks for reply
I want to know if workflow process definition in jbpm3 with Liferay 6.0.5 support sending mail notification in his xml file,
in fact according to your answer,I will decide whether i will use jbpm or kaleo
Hi Jonas,
I have configured Liferay 6.0.5 with jbpm3
but my goal now is to use 2 or more reviewer,I have followed The Single Approver example but,i have failed,so please can u help me,
I have posted a new thread:
http://www.liferay.com/community/forums/-/message_boards/message/7941822?_19_preview=false
Brilliant, works great. Loving your book, a most excellent read. In the image http://liferay.cignex.com/palm_tree/0387/workflow/workflow-04.png of My workflow tasks note that each line item are links, when I click it I get a blank space, what is it supposed to be? Is there any way to review the actual item there?
But I can set up an automatic change of status after a time, e.g. with a timer, if an user in workflow don't approve?
Hi Corrado, thanks. It would be better to set time (due time, expired time) in workflow definition. Do you agree?
Hi,

Do you known how to enable workflow for user, organization.

Or any schedule from Liferay this feature will available.
Hi ARA, role based approach would be better .... right?
Hi Jonas, thanks your reply,

I really want to have workflow for user, role and organization as when create new user, role or org need review and accept or reject by an approver.

Without this workflow my project cannot to go production.
Hi ERA, Thank you. Got you, you are going to apply workflow on core assets: user, role, and organization. right?

These are not supported OOB, but you can add these by using Ext Plugin, and/or hooks, or Liferay Portal Core. Logically, you can apply workflow on any assets, either portal core assets or custom assets.

Please let me know if you need more helps.
Thanks you very much Jonas,

You right! Im going to apply workflow on user, role and organization. Could you guild me how to? such as you write a article "applying workflow on user management in liferay 6" on your blog. I will flow your guild and apply for role, org.

Thanks you in advanced!
Hi ERA, is it urgent - applying workflow on user management in liferay 6? This can be done in portlet custom registration ...
Hi Jonas, we are using Liferay CE 6.0.5 with JBoss bundle and we are getting below error:

Kindly let me know how we can resolve this issue as we want to use the workflow engine for the web contents.

2010-11-22 12:54:21,664 ERROR [org.springframework.web.context.ContextLoader] (HDScanner) Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.liferay.portal.dao.shard.ShardUtil' defined in ServletContext resource [/WEB-INF/classes/META-INF/shard-data-source-spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'shardAdvice' of bean class [com.liferay.portal.dao.shard.ShardUtil]: Bean property 'shardAdvice' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1353)
Hi Jonas, it seems there was some issue with the kaleo war file which i was using. I downloaded "kaleo-web-6.0.5.1.war" and did a clean deployment. it was successful and i have to start using it emoticon
Thanks, Abdul! You are right that a lot of bugs got fixed in latest kaleo-web. In Liferay 6.1, you would see more features related to kaleo-web workflow ... :-)
Hi Era,
I know it's an old topic.
Did you manage to solve this problem? I would need to define workflow for organizations in Liferay 6.2 CE: https://www.liferay.com/community/forums/-/message_boards/view_message/41120923

Could you help me with some hints?

Thanks!
Are there known issues with this process on Liferay 6.0.10 (Enterprise)? The kaleo war deploys as expected, but at no point do I get the "Workflow Configuration" menu item in control panel. Is there an alternate workflow configuration process for Liferay EE?
Hi Barry, Thanks. The answer is NO. In EE, many known bugs got fixed. With CE, you may have to fixed these bugs.
Where can I find a version of the kaleo-web.war that works with Liferay EE 6.0.10? I am currently working with the EE version of Liferay, and would like to get started setting up workflows.
Hi Barry, Thanks. As EE user, you should be able to access the WAR of Kaleo web at

http://www.liferay.com/group/customer/downloads?p_p_id=3_WAR_osbportlet&p_p_lifecycle=1&p_p_state=maximized&_3_WAR_osbportlet_fileName=/plugins/6.0.10/kaleo-web-6.0.10.1.war

Please let me know if you have any questions,

Thanks again,

Jonas