Search code examples
mavenjunitspring-bootjakarta-mail

ClassNotFoundException on Spring JavaMailSenderImpl in JUnit test with Spring Boot


I've only just started a new project with Spring Boot, which I'm trying to get to grips with. I'm using Spring Tool Suite which has created a Spring Boot project for me and loaded some dependencies which I know I'll need further down the line (specifically Spring Batch and Spring Data)

This is my pom.xml:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- JDBC driver -->
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <version>6.1.0.jre8</version>
    </dependency>
</dependencies>

I've been reading the reference documentation and know that I'll need mail at some point down the line, so I added this to my application.properties file:

spring.mail.host=my.mail.host

I then tried to build the application with mvn package but it threw an error in the tests. The test consists of the following:

package its.idcard.batch;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class IdCardBatchApplicationTests {

    @Test
    public void contextLoads() {
    }

}

So all it's doing is trying to load the application context, but it fails with a ClassNotFoundException on org.springframework.mail.javamail.JavaMailSenderImpl.

I know this is a problem purely with the test, as after adding a bit of Spring Data stuff, and skipping tests in maven, my stub application runs as expected (and looking in the generated jar, I can see that spring-context-support-4.3.4-RELEASE.jar is present, containing the offending class), so it appears to be a classpath issue on the tests but I'm stumped. If I comment out the spring.mail.host line in the properties file, the test runs without problems.

Any ideas would be gratefully appreciated.


Solution

  • I think that the problem that I was just having appeared to be corrupt jar files in my maven repository. I decided to manually create the MailSender bean in my configuration class to see if that helped, but Eclipse was flagging up the class as not found, even though the jar containing it was in the maven dependencies. I then tried mvn compile from the command line, which gave me a more useful error, indicating corrupt jars, so I deleted the offending jars from my local repository and had maven re-download them and now I'm no longer getting the error in the configuration above.

    Hope this helps others.