|
JMS Queue is created as part of the server configuration, but as per the above, it does not get bound into JNDI until the HornetQ server has started and that happens a good 8 seconds after the persistence unit is initialized and has failed. The difference is most applications leveraging JMS do not try lookup the queue and connection factory during their actual deployment phases. Once an archive is active, HornetQ is ready.
<jms-destinations>
<jms-queue name="IndexingQueue">
<entry name="/queue/indexupdates"/>
<durable>true</durable>
</jms-queue>
</jms-destinations>
In this case org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory() ends up at org.hibernate.search.backend.BackendFactory.createBackend() which calls org.hibernate.search.backend.impl.jms.JmsBackendQueueProcessor.initialize() hence the entire PU fails.
In the case of a MDB, you can configure retries, retry interval, back off multiplier and it will retry until a queue or topic is available, especially in the case its looking at a remote server.
Stepping back, it's possible this does not need retry logic, it could be moved so that the initialization of the queue is not done as part of the PU creation.
Access to the queue is not required until: JmsBackendQueueTask
sender = session.createSender( processor.getJmsQueue() );}}
Which is not called until an actual request is made that makes it to: com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion() so this is not necessarily required when the PU is created. The question is, what is a good time to initialize it.
If this was exclusively run inside an EE container, using resource injection would definitely be the way and get rid of JNDI lookups all together but I do not think that is a luxury we have.
@Resource(mappedName = "java:/JmsXA")
private QueueConnectionFactory queueConnectionFactory;
@Resource(mappedName = "java:/IndexingQueue")
private Queue destination;
|