TestTransactionServices.java
package com.github.jonasrutishauser.cdi.test.jta;
import java.util.function.Supplier;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import org.jboss.logging.Logger;
import org.jboss.weld.transaction.spi.TransactionServices;
import com.arjuna.ats.jta.TransactionManager;
import com.arjuna.ats.jta.common.jtaPropertyManager;
import jakarta.transaction.RollbackException;
import jakarta.transaction.Status;
import jakarta.transaction.Synchronization;
import jakarta.transaction.SystemException;
import jakarta.transaction.UserTransaction;
/**
* SPI extension point of the Weld for integrate with transaction manager. If
* the interface is implemented by the deployment the Weld stops to show info
* message:
* <p>
* <code>
* WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available.
* Transactional observers will be invoked synchronously.
* </code>
* </p>
*/
public class TestTransactionServices implements TransactionServices {
private static final Logger LOG = Logger.getLogger(TestTransactionServices.class);
public TestTransactionServices() {
try {
registerInJndi(jtaPropertyManager.getJTAEnvironmentBean().getTransactionManagerJNDIContext(),
TransactionManager::transactionManager);
registerInJndi(
jtaPropertyManager.getJTAEnvironmentBean().getTransactionSynchronizationRegistryJNDIContext(),
jtaPropertyManager.getJTAEnvironmentBean()::getTransactionSynchronizationRegistry);
} catch (NamingException e) {
// ignore
}
}
private void registerInJndi(String jndiName, Supplier<?> supplier) throws NamingException {
int lastSeparator = jndiName.lastIndexOf('/');
Context context = new InitialContext();
try {
context.lookup(jndiName);
} catch (NameNotFoundException e) {
if (lastSeparator > 0) {
((Context) context.lookup(jndiName.substring(0, lastSeparator)))
.bind(jndiName.substring(lastSeparator + 1), supplier.get());
} else {
context.bind(jndiName, supplier.get());
}
} catch (NamingException e) {
context.createSubcontext(jndiName.substring(0, lastSeparator)).bind(jndiName.substring(lastSeparator + 1),
supplier.get());
} finally {
context.close();
}
}
@Override
public void registerSynchronization(Synchronization synchronizedObserver) {
try {
TransactionManager.transactionManager().getTransaction().registerSynchronization(synchronizedObserver);
} catch (SystemException | IllegalStateException | RollbackException e) {
throw new IllegalStateException("Cannot register synchronization observer " + synchronizedObserver
+ " to the available transaction", e);
}
}
@Override
public boolean isTransactionActive() {
try {
int status = TransactionManager.transactionManager().getStatus();
return status == Status.STATUS_ACTIVE || status == Status.STATUS_COMMITTING
|| status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_PREPARED
|| status == Status.STATUS_PREPARING || status == Status.STATUS_ROLLING_BACK
|| status == Status.STATUS_UNKNOWN;
} catch (SystemException se) {
LOG.error("Cannot obtain the status of the transaction", se);
return false;
}
}
@Override
public UserTransaction getUserTransaction() {
return com.arjuna.ats.jta.UserTransaction.userTransaction();
}
@Override
public void cleanup() {
// nothing to clean
}
}