0
votes

I am trying to use portlets based on MVCPortlet on Liferay 6.1.1, and it does not behave as I was expecting. My portlets are supposed to be independent, but are not...

My need:

  • I have a first portlet A with a form.
  • I have several instances of a portlet B, based on MVCPortlet.

When the form is submitted, the portlet A launches an event, and all portlet B receive this event. When a portlet B receive the event, it must build an URL, connect to it and read data from it, and display the result.

My B portlet is based on MVCPortlet, is instanceable, ajaxable and with a render-weight of 0, for having a parallel processing and displaying of all instances of portlet B.

But it does not work well:

1) I could not do the processing of the URL in the event processing, as all events reception (one per instance of my portlet B ) are processed in the same thread. So in the event I just set a renderRequest parameter, so the jsp page automatically use an ActionURL to call the action processing in my portlet.

This action builds the URL, use it, process the data, and redirect to the result display page (response.setRenderParameter("jspPage", "/html/display/results.jsp")).

2) I was expecting each portlet to be independent from the other, but they are not. There is only one instance of the MVCPortlet, shared by all portlets, that greatly surprised me. The portlet session is also shared by all my instances of portlet. The action method is executed by different thread, that is good, but the rendering of portlets can be blocked by actions processing of other portlets. One portlet can provoke the whole page refresh. All things that I wanted to avoid by having instanceable, ajaxable and render-weight with 0...

I wonder if there is something wrong, if it is normal to have only one instance of the class extending MVCPortlet, etc. Or if there is a best way to have the desired behavior.

1

1 Answers

0
votes

1) I'm not completely sure what you're doing here: Event handling is AFAIK undefined in terms of parallelism, so it's normal behaviour that all events are handled sequentially in the same thread. However, I don't understand what you mean by the ActionURL part of your description. You're able to change state of your portlet in the eventhandler, but not during the render phase. Typically every request handles only one action, multiple (as necessary) events, then renders all portlets. Do you imply that this is followed by an action on every single B-portlet? That's unexpected and I'd rather recommend you do either the processing in your event handler or trigger it to asynchronously run in the back while continuing through the event processing (especially when it takes time)

2) The portlets are independent of each other, however, not every portlet maps to a single Java object. In fact, the implementation is just like in the servlet world: There's only one object that's not supposed to have any state. Almost all instances of member variables in a portlet (or a servlet) are a sign of misunderstanding the API: The whole state of the portlet is coming in through the various PortletRequest and PortletResponse objects, nothing shall be kept within portlet member variables.

Based on your intent to asynchronously render all B portlets, I assume that rendering might take a while - eventhandling should continue as quickly as possible. Otherwise there's no point in rendering asynchronously if the whole result is already there.