Frage

I have a web application with few spring portlets. Every portlet has an xml with its declared controller, but the services used by the controllers are placed in applicationContext.xml. I know that for every portlet is created one spring application context (from own xml file), and every that context has as root context the spring application context created from applicationContext.xml. That is all beans declared in applicationContext.xml are common for all portlets.

So let's have an example:

xml file for portlet example-portlet.xml: ... ...

controller ExampleController.java:

package example.controller;
@Controller
@RequestMapping(value = "VIEW")
public class NavigareController {

@Autowired
private ExampleService es;
...
}

applicationContext.xml:

...
<context:component-scan base-package="example.service />
...

service ExampleServiceImpl.java:

package example.service;
@Service
public class ExampleServiceImpl implements ExampleService {
...
}

When server starts with the application inside it, the application starts and everything works fine. When the application is redeployed then I have an error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleController'...
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private example.service.ExampleService...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [example.service.ExampleService]...

In result the portlet is not starting.

I have debugged the lifery's sources and I have found the following code:

package org.springframework.web.portlet
...
public abstract class FrameworkPortlet extends GenericPortletBean
implements ApplicationListener<ContextRefreshedEvent> {
...
protected ApplicationContext initPortletApplicationContext() {
ApplicationContext parent = PortletApplicationContextUtils.getWebApplicationContext(getPortletContext());
ApplicationContext pac = createPortletApplicationContext(parent);
...

The code above, in first case (when server starts with application inside) returns not null parent, but in second case (when application is redeployed) it retuns a null parent. Inside PortletApplicationContextUtils.getWebApplicationContext(getPortletContext()) there is the following code:

Object attr = pc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

So in first case this attribute is in portlet context, but in the second case it is not in portlet context. The problem is clear, the exampleService bean is not found in null parent.

The question is: Is there any bug in hot deployment process?. Please help me!!!

War es hilfreich?

Lösung

What is your version of Liferay? If it is 6.1.1 then this is a known issue

http://issues.liferay.com/browse/LPS-29103

If you just need to deploy the portlets once - change order of listeners in web.xml manually as suggested in the ticket.

If you need to redeploy the portlets alot (for development) then the previous solution is very time consuming and the easiest way is to backport the fix from 6.2.0 branch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top