Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven verify ClassNotFoundException for class of Spring Boot application

I'm getting a NoClassDefFoundError when I try to run verify lifecycle of Maven for my Java Spring Boot project. It compiles fine using mvn spring-boot:run but when I run mvn clean verify it fails thus:

$mvn clean verify -Dsurefire.skip=true -X
...
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.209 sec <<< FAILURE! - in com.fitforger.FitForgerBackendApplicationTests
    initializationError(com.fitforger.FitForgerBackendApplicationTests)  Time elapsed: 0.005 sec  <<< ERROR!
    java.lang.NoClassDefFoundError: com/fitforger/model/GymRat
    Caused by: java.lang.ClassNotFoundException: com.fitforger.model.GymRat

where com.fitforger.model.GymRat is one of the classes of my application.

Project structure:

+----src
     +----main
     |    +----java
     |    |    +----com
     |    |         +----fitforger
     |    |              +----controller
     |    |              |    +----GymRatController.java
     |    |              |    +----WorkoutNodeController.java
     |    |              +----dao
     |    |              |    +----GymRatDAO.java
     |    |              +----exception
     |    |              |    +----GymRatCreationFailure.java
     |    |              |    +----GymRatExistsException.java
     |    |              |    +----GymRatNotFound.java
     |    |              |    +----GymRatUpdateFailure.java
     |    |              +----FitForgerBackendApplication.java
     |    |              +----model
     |    |              |    +----FitForgerModel.java
     |    |              |    +----GymRat.java
     |    |              |    +----WorkoutAttribute.java
     |    |              |    +----WorkoutNode.java
     |    |              |    +----WorkoutNodeTypes.java
     |    |              +----repository
     |    |                   +----CouchbaseRepository.java
     |    |                   +----FitForgerRepository.java
     |    +----resources
     |         +----application.properties
     +----test
          +----java
          |    +----com
          |         +----fitforger
          |              +----FitForgerBackendApplicationTests.java
          |              +----GymRatSteps.java
          |              +----repository
          |                   +----CouchbaseRepositoryTest.java
          +----resources
               +----com
                    +----fitforger
                         +----GymRat.feature

Relevant bits of my pom.xml:

<build>
    <resources>
        <resource>
            <directory>resources</directory>
            <targetPath>${project.build.outputDirectory}</targetPath>
            <includes>
                <include>application.properties</include>
            </includes>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.19.1</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>1.5.1.RELEASE</version>
        </plugin>
    </plugins>

    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.1.RELEASE</version>
                <executions>
                    <execution>
                        <id>pre-integration-test</id>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <excludes>
                        <exclude>com.fitforger.FitForgerBackendApplicationTests</exclude>
                    </excludes>
                    <skip>${surefire.skip}</skip>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <includes>
                        <include>com.fitforger.FitForgerBackendApplicationTests</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build
like image 680
Ethan Allen Avatar asked Feb 07 '17 05:02

Ethan Allen


3 Answers

OP problem solved by doing below,

This looks to be similar to what you are facing. Could you try with

<plugin>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-maven-plugin</artifactId>
   <configuration>
        <classifier>exec</classifier>
   </configuration>
 </plugin>
like image 68
GauravJ Avatar answered Oct 20 '22 05:10

GauravJ


This problem can also manifest as a failure of integration test cases to find your application.properties resource.

This happens because of the interaction of the Spring Boot repackaging, done by the spring-boot-maven-plugin, and the logic that the maven-failsafe-plugin uses to set up the classpath for integration tests.

The Failsafe plugin puts the packaged JAR on the classpath, rather than the directory holding the unpacked classes and resources (as given by the project.build.outputDirectory property, which is usually ${basedir}/target/classes). However, the repackaging done by spring-boot-maven-plugin places the classes and resources of your application in an unusual location in the JAR, so although Failsafe examines the JAR, it does not find what it is looking for.

You can work around this problem by explicitly telling the Failsafe plugin to put the directory holding the unpacked classes and resources on using classpath, by using additionalClasspathElements in its configuration:

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <configuration>
            <additionalClasspathElements>
                <additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
            </additionalClasspathElements>
            <includes>
                <include>**/*IT.java</include>
            </includes>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
like image 34
Anton Kushch Avatar answered Oct 20 '22 05:10

Anton Kushch


If you are not extending spring-boot-starter-parent, you have to add classesDirectory in your failsafe config (just as spring-boot-starter-parent pom does):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- this one here! -->
        <classesDirectory>${project.build.outputDirectory}</classesDirectory>
    </configuration>
</plugin>

Found in a JIRA comment on a similar issue (failsafe 2.19+ not working with spring boot 1.4).

like image 34
laffuste Avatar answered Oct 20 '22 03:10

laffuste