Search code examples
springliferay-6liferay-hook

Liferay 6.2 + Spring @Autowired not working in a hook


I am using Spring 4.0.6 with Liferay 6.2. Spring isn't able to inject autowired components in to the hook, object comes as null. I have also tried with spring version 3.1 that comes with liferay. Same code works in portlets but not in hooks.

private ApplicationEventPublisher publisher in ActivityEventPublisher.java is null.

web.xml

<?xml version="1.0"?>

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-         app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
<listener-class>com.liferay.portal.kernel.servlet.SecurePluginContextListener</listener-  class>
</listener>
<listener>
<listener-class>com.liferay.portal.kernel.servlet.PortletContextListener</listener-class>
</listener>

<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
</web-app>

ActivityEventPublisher.java

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

import connect.activity.solr.document.ActivityData;

@Component
public class ActivityEventPublisher implements ApplicationEventPublisherAware {

private ApplicationEventPublisher publisher;

@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}

public ApplicationEventPublisher getPublisher() {
return publisher;
}

public void setPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}

public void publish(ActivityData data) {
ActivityEvent event = new ActivityEvent(this);
event.setActivityData(data);
this.publisher.publishEvent(event);
}
}

Any help will be much appreciated.

Thanks


Solution

  • Unfortunately, autowired mechanisms are not allowed in hooks, wrappers or startup actions at Liferay.

    You can implement an ApplicationContextProvider, it's so easy and useful:

    @Component("applicationContextProvider")
    public class ApplicationContextProvider implements ApplicationContextAware {
        private static ApplicationContext ctx = null;
    
        public static ApplicationContext getApplicationContext() {
            return ctx;
        }
    
        @Override
        public void setApplicationContext(ApplicationContext ac) throws BeansException {
            ctx = ac;
        }
    }
    

    An example of use in a Hook will be the following:

    public class PostLoginActionHook extends Action {
    
    // That code "replaces" @Autowired annotation
    private final UserProxyService userProxyService = (UserProxyService) ApplicationContextProvider.
            getApplicationContext().getBean(UserProxyService.class);
    
    
    @Override
    public void run(HttpServletRequest request, HttpServletResponse response) throws ActionException {
            UserVO myCustomUser = userProxyService.getCustomUserByLiferayUser(user.getUserId());
            {...}
    }
    

    Hope it helps!