I've configured Hibernate Search to cluster using the JMS master/slave config. The slaves work great... I think. The appropriate number of messages are sent to my ActiveMQ queue when an entity is saved or updated. I can't read what the messages are because ActiveMQ complains that the content is serialized and it doesn't have the DeleteLuceneWork class in its classpath. Seems appropriate, though I only have DeleteLuceneWork serialized objects in the JMS message bodies. Is that right?
Anyway, I've created a listener exactly as described in section 10.3.1 in the Hibernate Search in Action book. Though I'm using Spring, so it's an MDPojo instead of an MDBean. The problem is the onMessage method just gets stuck and never returns. So my listener reads the first message from the queue and hangs. Any idea why? Also seems odd that only 1 MDP thread is reading from the queue, I would expect 10 onMessage method invocations:
Code:
public class HibernateSearchListener extends AbstractJMSHibernateSearchController implements MessageListener {
private final Log log = LogFactory.getLog(getClass());
@Autowired
private SessionFactory sessionFactory;
@Override
public void onMessage(Message message) {
log.debug("Received message: " + message);
super.onMessage(message);
log.debug("Done processing message: " + message);
}
@Override
protected Session getSession() {
log.debug("Retrieving session for processing message");
return sessionFactory.getCurrentSession();
}
@Override
protected void cleanSessionIfNeeded(Session session) {
log.debug("Finished with session");
}
}
The output I get is only:
Code:
DEBUG [QueueListener-1] HibernateSearchListener - Received message: ActiveMQObjectMessage {commandId = 5, responseRequired = true, messageId = ID:xxxxx-53941-1271212758168-0:129:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:xxxxx-53941-1271212758168-0:129:1:1, destination = queue://HibernateSearchController, transactionId = null, expiration = 0, timestamp = 1271212877786, arrival = 0, brokerInTime = 1271212877786, brokerOutTime = 1271581732969, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@727a9fa7, marshalledProperties = null, dataStructure = null, redeliveryCounter = 3, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false}
DEBUG [QueueListener-1] HibernateSearchListener - Retrieving session for processing message
DEBUG [QueueListener-1] HibernateSearchListener - Finished with session
That's it, no "Done processing message"s ever...
The relevant portion of my Spring application-context.xml is:
Code:
<amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://${jms.url}:61616?trace=true" userName="${jms.username}" password="${jms.password}"/>
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory"/>
<property name="exceptionListener" ref="jmsExceptionListener"/>
<property name="sessionCacheSize" value="100"/>
</bean>
<bean id="jmsExceptionListener" class="search.JmsExceptionListener"/>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="connectionFactory"/>
</bean>
<bean id="hibernateSearchListener" class="search.HibernateSearchListener" autowire="byType"/>
<jms:listener-container concurrency="10" transaction-manager="transactionManager">
<jms:listener id="QueueListener" destination="HibernateSearchController" ref="hibernateSearchListener"/>
</jms:listener-container>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="eventListeners">
<map>
<entry key="post-update"><bean class="org.hibernate.search.event.FullTextIndexEventListener"/></entry>
<entry key="post-insert"><bean class="org.hibernate.search.event.FullTextIndexEventListener"/></entry>
<entry key="post-delete"><bean class="org.hibernate.search.event.FullTextIndexEventListener"/></entry>
<entry key="post-collection-recreate"><bean class="org.hibernate.search.event.FullTextIndexEventListener"/></entry>
<entry key="post-collection-remove"><bean class="org.hibernate.search.event.FullTextIndexEventListener"/></entry>
<entry key="post-collection-update"><bean class="org.hibernate.search.event.FullTextIndexEventListener"/></entry>
</map>
</property>
<property name="mappingResources">
<list>
<value>repository/my_entitities.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.search.default.indexBase=indexes
hibernate.search.worker.execution=async
hibernate.search.worker.jms.connection_factory=java:comp/env/jms/ConnectionFactory
hibernate.search.worker.jms.queue=java:comp/env/queue/hibernatesearch
hibernate.search.worker.backend=jms
hibernate.search.default.directory_provider=org.hibernate.search.store.FSMasterDirectoryProvider
hibernate.search.default.sourceBase=indexes_source
</value>
</property>
</bean>
When I shut down Tomcat, I have to forcefully kill it with this as its last output line in catalina.out:
Code:
WARN [main] DefaultLifecycleProcessor - Failed to shut down 1 bean with phase value 2147483647 within timeout of 30000: [QueueListener]
Even if I do an indexAll type operation with over 100,000 test entities, nothing happens on the master server. Nothing at all happens, not even the indexing messages going out to ActiveMQ like they do on the slave servers. In any case, the indexes and indexes_source directories are never updated.
Please help :)