title: How to configure Oracle XA Datasource on spring boot app that communicating with an EJB in JBoss EAP
body: <p>I'm trying to use an EJB on a Spring boot application. This application runs in 'undertow' and it can call an EJB on a JBoss EAP (Jboss EAP 7.0). </p>
  
  <p>I tried to configure the application to use Oracle XA transactions without success. </p>
  
  <p>What I need is that when the Spring boot app calls the EJB and, after the call, some failure occurs on this app that EJB does a rollback the previous work.</p>
  
  <p>Follows some configurations of the spring boot app: </p>
  
  <p>pom</p>
  
  <pre><code>&lt;dependencies&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
              &lt;exclusions&gt;
                  &lt;exclusion&gt;
                      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                      &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
                  &lt;/exclusion&gt;
              &lt;/exclusions&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-undertow&lt;/artifactId&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.wildfly&lt;/groupId&gt;
              &lt;artifactId&gt;wildfly-ejb-client-bom&lt;/artifactId&gt;
              &lt;version&gt;17.0.0.Final&lt;/version&gt;
              &lt;type&gt;pom&lt;/type&gt;
          &lt;/dependency&gt;
  
      &lt;/dependencies&gt;
  
  </code></pre>
  
  <p>properties</p>
  
  <pre><code>spring.datasource.url=jdbc:oracle:thin:@&lt;host&gt;:&lt;port&gt;:&lt;data&gt;
  spring.datasource.username=user
  spring.datasource.password=pass
  spring.datasource.xa.data-source-class-name=bitronix.tm.resource.jdbc.lrc.LrcXADataSource
  spring.datasource.xa.properties.driver-class-name=oracle.jdbc.driver.OracleDriver
  
  
  spring.jpa.properties.hibernate.hbm2ddl.schema_filter_provider=&lt;class&gt;
  spring.jpa.hibernate.ddl-auto=update
  spring.jpa.properties.hibernate.format_sql=true
  spring.jpa.properties.hibernate.show_sql=true
  
  spring.jpa.properties.hibernate.integration.envers.enabled=false
  </code></pre>
  
  <p>App Class</p>
  
  <pre><code>Configuration
  @SpringBootApplication
  @EnableTransactionManagement
  @ComponentScan(basePackages={...,...})
  @EntityScan(basePackages={...,...,...})
  public class SpringBootApplication {
  
      public static void main(String[] args) {
          SpringApplication.run(SpringBootApplication .class, args);
      }
  
  </code></pre>
  
  <p>EJB 'producer' </p>
  
  <pre><code>
  @Configuration
  public class EJBConfiguration {
  
      @Bean
      public Context context() throws NamingException {
          Properties jndiProps = new Properties();
          jndiProps.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
          jndiProps.put("jboss.naming.client.ejb.context", true);
          jndiProps.put("java.naming.provider.url", "http-remoting://localhost:8081");
          return new InitialContext(jndiProps);
      }
  
  
  @Bean
      public EJBRemote(Context c) throws NamingException {
  
          return (EJBRemote) c.lookup("full EJB remote name")
  }
  
  }
  
  </code></pre>
  
  <p>the call of EJB is made as follows: 
  stuff </p>
  
  <p>Spring boot App controller </p>
  
  <pre><code>class AppControler {
  
      @AutoWired
      Service service
  
      @PostMapping("/")
      @Transactional
      public ResponseEntity controllerMethod() {
          return new ResponseEntity&lt;&gt;(this.service.doStuff(), HttpStatus.OK);
      }
  }
  
  </code></pre>
  
  <p>Spring boot app service </p>
  
  <pre><code>class Service {
  
          @Autowired
      private EJBRemote EJBRemote;
  
          @Autowired
      private DAOObject dao;
  
      @TransactionAttribute(TransactionAttributeType.MANDATORY)
          Public Object doStuff() {
               dao.save();
               EJBRemote.saveSomeThing(); // OK operation, needs to rolback if oerros occurs after
               dao.saveOtherThing();// errors occurs
          }
  }
  
  </code></pre>
  
  <p>the EJB implementation class on JBoss EAP is like </p>
  
  <pre><code>
  class EJBRemoteImpl implements EJBRemote {
  
      @Override
      public void saveSomeThing() {
            someDao.save();
      }
  }
  </code></pre>
  
  <p>So when a error occurs in 'dao.saveOtherThing();' the operation made in 'EJBRemove.saveSomeThing();' needs to rolback.</p>
  
  <p>If I'm put '@TransactionAttribute(TransactionAttributeType.MANDATORY)' on EJB this error occurs: </p>
  
  <pre><code>javax.ejb.EJBTransactionRequiredException: WFLYEJB0062: A transaction is required to call org.jboss.invocation.InterceptorContext@493c9dbb  
  at org.jboss.as.ejb3.tx.CMTTxInterceptor.mandatory(CMTTxInterceptor.java:289) ~[na:na]
      at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:233) ~[na:na]
      at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
      at org.jboss.as.ejb3.remote.EJBRemoteTransactionPropagatingInterceptor.processInvocation(EJBRemoteTransactionPropagatingInterceptor.java:79) ~[na:na]
      at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
      at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) ~[na:na]
      at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
      at org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:43) ~[na:na]
      at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:340) ~[na:na]
  .
  .
  .
  </code></pre>
  
  <p>If the annotation (@TransactionAttribute(TransactionAttributeType.MANDATORY)) is not present the calls to EJB occurs normally but the rollback not occurs. </p>