Search code examples
javaspringjmsspring-jmsjmstemplate

java.lang.NoClassDefFoundError when sending to oracle aq


I am getting the following exception in my Spring application:

Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.NoClassDefFoundError: javax/transaction/Transaction
    at oracle.jms.AQjmsSession.<init>(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

I have configured an Oracle AQ as follows where I want to push some trade messages to:

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
}

A JmsMessageSender implementation as follows:

@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);
    }

}

The service which receives trade object and uses an executor service to submit tasks:

@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(() -> buffer.executeTask(tradeProcessingTask));

    }

    public void processTrade(Trade trade) {

        Optional<String> xmlTradeMessage = XmlParserUtil.marshall(trade);
        if (xmlTradeMessage.isPresent()) {
            jmsMessageSender.sendMessage(aqname, xmlTradeMessage.get());
            updateTradeStatus(tradeProcessingContext);
        }


    }

}

Solution

  • Looks like one of your libraries is missing a required dependency transaction-api

    If you're using Maven try

    <!-- https://mvnrepository.com/artifact/javax.transaction/javax.transaction-api -->
    <dependency>
        <groupId>javax.transaction</groupId>
        <artifactId>javax.transaction-api</artifactId>
        <version>1.2</version>
    </dependency>
    

    https://mvnrepository.com/artifact/javax.transaction/javax.transaction-api/1.2