title: java.lang.NoClassDefFoundError when sending to oracle aq
body: <p>I am getting the following exception in my Spring application:</p>
  
  <pre><code>Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.NoClassDefFoundError: javax/transaction/Transaction
      at oracle.jms.AQjmsSession.&lt;init&gt;(AQjmsSession.java:364)
      at oracle.jms.AQjmsConnection.createSession(AQjmsConnection.java:1130)
      at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:192)
      at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:475)
      at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:570)
      at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:658)
      at com.company.service.JmsMessageSender.sendMessage(JmsMessageSender.java:19)
      at com.company.service.TradeService.processTrade(TradeService.java:72)
      at com.company.task.TradeProcessingTask.run(TradeProcessingTask.java:28)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: java.lang.ClassNotFoundException: javax.transaction.Transaction
      at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
      at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
      ... 12 more
  </code></pre>
  
  <p>I have configured an <code>Oracle AQ</code> as follows where I want to push some trade messages to:</p>
  
  <pre><code>import static oracle.jms.AQjmsFactory.getQueueConnectionFactory;
  
  @Configuration
  @ConfigurationProperties("oracle")
  public class OracleAQConfiguration {
  
      @NotNull
      private String url;
  
      @NotNull
      private String aqname;
  
      @NotNull
      private String aquser;
  
      @NotNull
      private String aqpassword;
  
      @NotNull
      private String driver;
  
  
      @Bean
      public ConnectionFactory connectionFactory() throws Exception {
          Properties info = new Properties();
  
          info.put("driver-name", driver);
          info.put("user", aquser);
          info.put("password", aqpassword);
          return getQueueConnectionFactory(url, info);
      }
  
  
          //setter and getters
  }
  </code></pre>
  
  <p>A <code>JmsMessageSender</code> implementation as follows:</p>
  
  <pre><code>@Component
  @EnableJms
  public class JmsMessageSender implements MessageSender {
  
      @Autowired
      private JmsTemplate jmsTemplate;
  
      @Override
      public void sendMessage(String queueName, String message) {
          jmsTemplate.convertAndSend(queueName, message);
          log.info("Message sent: {}", message);
      }
  
  }
  </code></pre>
  
  <p>The service which receives trade object and uses an executor service to submit tasks:</p>
  
  <pre><code>@Service
  public class TradeService {
  
      private final ExecutorService executorService = Executors.newSingleThreadExecutor();
  
      @Autowired
      private TradeRequestBuffer buffer;
  
      @Autowired
      private JmsMessageSender jmsMessageSender;
  
  
      @Value("${oracle.aqname}")
      private String aqname;
  
  
      public void submitTradeForProcessing(Trade trade) {
  
          final TradeProcessingTask tradeProcessingTask = new TradeProcessingTask(this, trade);
          executorService.execute(() -&gt; buffer.executeTask(tradeProcessingTask));
  
      }
  
      public void processTrade(Trade trade) {
  
          Optional&lt;String&gt; xmlTradeMessage = XmlParserUtil.marshall(trade);
          if (xmlTradeMessage.isPresent()) {
              jmsMessageSender.sendMessage(aqname, xmlTradeMessage.get());
              updateTradeStatus(tradeProcessingContext);
          }
  
  
      }
  
  }
  </code></pre>