2010-07-02 23 views
7

Su JBoss 5.1.0 ho Datasource (PostgreSQL 8.3.11) configurato usando * -ds.xml (standard jboss DS). Utilizza XADataSource (PGXADataSource). Ho anche un broker ActiveMQ (in questo momento funziona come in-VM, sotto JBoss, ma sarà su un server separato).Come configurare il connettore JCA ActiveMQ in JBoss per utilizzare le connessioni XA?

Quello che voglio fare è rendere ActiveMQ Connection Factory e Datasource per partecipare alle Transazioni XA. Ad esempio, voglio aggiornare il record DB e inviare un messaggio JMS come UOW. Hai un'idea.

Ho configurato PGXADataSource in my-pg-ds.xml e funziona (posso tracciare l'esecuzione fino a PGXAConnection's start method). Ho provato a configurare ActiveMQXAConnectionFactory direttamente in primavera (sto usando Spring 3.0.2.RELEASE), ma questo non funziona, perché in questo caso il gestore delle transazioni Spring (uso l'annotazione per consentire a Spring di configurare JtaTransactionManager che semplicemente delega tutto il lavoro a JBoss transaction manager) non include XAResource per il dato ActiveMQXAConnection. Ogni volta che provo a inviare un messaggio ottengo un'eccezione JMSException che dice "XAResource della sessione non è stato inserito in una transazione distribuita." generata da ActiveMQXASession.

Dal momento che non ha funzionato, ho passato a configurazione JCA di ActiveMQ ConnectionFactory (sulla base degli this documento) e funziona per regolare , ma non capisco come posso configurarlo per usare XAConnectionFactory. Sembra che Resource Adapter semplicemente non abbia implementazioni adeguate di ManagedConnectionFactory, ManagedConnection, ecc. Per la factory di connessione XA.

Mi manca qualcosa o non ho altra scelta che scrivere i wrapper XA per l'adattatore di risorse?

risposta

6

Ok, ho trovato la soluzione. Jboss include un connettore JCA per qualsiasi fabbrica JMS (supporta entrambi i tipi di transazioni: XA e locale). Si trova in /server//deploy/jms-ra.rar. Ecco come l'ho configurato.

In primo luogo, activemq-jms-ds.xml di file che va nella directory deploy di fianco al jms-ra.rar:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE connection-factories 
    PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN" 
    "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd"> 

<connection-factories> 
    <mbean code="org.jboss.jms.jndi.JMSProviderLoader" 
     name="jboss.messaging:service=JMSProviderLoader,name=ActiveMQJMSProvider"> 
     <attribute name="ProviderName">ActiveMQJMSProvider</attribute> 
     <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute> 
     <attribute name="FactoryRef">java:/activemq/XAConnectionFactory</attribute> 
     <attribute name="QueueFactoryRef">java:/activemq/XAConnectionFactory</attribute> 
     <attribute name="TopicFactoryRef">java:/activemq/XAConnectionFactory</attribute> 
    </mbean> 

    <tx-connection-factory> 
     <jndi-name>JmsXAConnectionFactory</jndi-name> 
     <xa-transaction/> 
     <rar-name>jms-ra.rar</rar-name> 
     <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition> 
     <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/ActiveMQJMSProvider</config-property> 
    </tx-connection-factory> 
</connection-factories> 

Questo dice Jboss di guardare in JMS-ra.rar e trovare l'adattatore in grado di fornire factory di connessione gestita per org.jboss.resource.adapter.jms.JmsConnectionFactory . L'adattatore jms interno dipende da JmsProviderAdapter, che viene utilizzato per memorizzare i nomi JNDI delle factory di connessione (nella mia configurazione tutti i nomi sono uguali).

Uso il tag mbean per configurare JMSProviderLoader (questo viene copiato da una delle configurazioni interne di JBoss). Ora, tutto ciò che devo fare è in qualche modo creare un'istanza del mio factory di connessione XA e collegarlo a java:/activemq/XAConnectionFactory. Ci sono diversi modi per farlo (implementare il wrapper MBean, per esempio).

Da quando sono Jboss 5 ho utilizzato microcontainer (che probabilmente funziona in Jboss 6). Ho aggiunto activemq-jms-jboss-beans.xml file in deployers direcotry:

<?xml version="1.0" encoding="UTF-8"?> 
<deployment xmlns="urn:jboss:bean-deployer:2.0"> 
    <!-- Define a Jndi binding aspect/annotation that exposes beans via jndi 
     when they are registered with the kernel. 
    --> 
    <aop:lifecycle-configure xmlns:aop="urn:jboss:aop-beans:1.0" 
     name="DependencyAdvice" 
     class="org.jboss.aop.microcontainer.aspects.jndi.JndiLifecycleCallback" 
     classes="@org.jboss.aop.microcontainer.aspects.jndi.JndiBinding" 
     manager-bean="AspectManager" 
     manager-property="aspectManager"> 
    </aop:lifecycle-configure> 

    <bean name="ActiveMQXAConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory"> 
     <annotation>@org.jboss.aop.microcontainer.aspects.jndi.JndiBinding(name="activemq/XAConnectionFactory", aliases={"java:/activemq/XAConnectionFactory"})</annotation> 
     <property name="brokerURL">vm://localhost</property> 
    </bean> 
</deployment> 

creo un fagiolo ActiveMQXAConnectionFactory. Per associarlo a JNDI, lo annoto con l'annotazione JndiBinding. Perché questa annotazione funzioni, abbiamo bisogno di JndiLifecycleCallback. Per quanto posso dire, JndiLifecycleCallback viene richiamato su ogni bean creato da microcontainer e controlla l'annotazione JndiBinding su quel bean.

Problemi correlati