For our purpose we wanted to provide a more fault tolerant solution than web services alone and so looked to expose this functionality via JMS and employ JMS bridging (part of JBoss JMS) to move the messages from disparate applications to the Liferay instance for processing.
Luckily Liferay also provides a rich set of static instance utility classes and to gain access to these we can tear a page from the portal-web.war. Within portal-web.war Liferay exposes a RemotingServlet within the WEB-INF/web.xml and a corresponding WEB-INF/remoting-servlet.xml which then uses Spring provided proxies for the WS interfaces.
In our case we can slim down the remoting-servlet.xml considerably as we are looking to allow our MDB access to Liferay not to extend or change any of the functionality.
To accomplish this we create a war that provides a hook int liferay with a web.xml like this:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- Provides access to locally deployed LifeRay -->
<servlet>
<servlet-name>Spring Servlet</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortalClassLoaderServlet</servlet-class>
<init-param>
<param-name>servlet-class</param-name>
<param-value>com.liferay.portal.spring.servlet.RemotingServlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
And a remoting-servlet.xml such as this:
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
</beans>
Once that is complete the next step is to create an MDB. In our case we create this as an EJB jar
@MessageDriven(name = "UserConsumerBean", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/LR_USER_QUEUE")
})
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class UserConsumer implements MessageListener {
private static final Log LOG = LogFactory.getLog(UserConsumer.class);
@Resource
private MessageDrivenContext context;
protected void setContext(MessageDrivenContext context) {
this.context = context;
}
public void onMessage(Message message) {
String name = null;
TextMessage om = (TextMessage) message;
try {
if (LOG.isInfoEnabled()) {
LOG.info("Message Text : " + om.getText());
}
User user = UserLocalServiceUtil.getUserById(1L); //some user that exists
System.out.println("User Name :"+user.getScreenName());
} catch (Exception e) {
LOG.error(e);
throw new EJBException(e); //rollback
}
}
}
Once this is all bundled as an ear and deployed you should be able to send a message to the queue and see your output.