9

Project structure: Pure Kotlin as multi module maven application

kotlinspringboot (root-module)

  • api

  • integration-tests

Problem: When I run

$ cd ./kotlingspringboot/integration-tests/
$ mvn test

or

$ cd ./kotlingspringboot/integration-tests/
$ mvn kotlin:test-compile

I get following compilation error regarding unresolved reference for a class from api module :

[ERROR] Failed to execute goal org.jetbrains.kotlin:kotlin-maven-plugin:1.2.21:test-compile (test-compile) on project hello-integration-tests: Compilation failure: Compilation failure:
[ERROR] C:\workspace\kotlinspringboot\integration-tests\src\test\kotlin\org\ildar\hello\integration\HelloEndpointTests.kt:[6,18] Unresolved reference: SpringKotlinHelloWorldApplication

Note: I've ran previously mvn clean install and verified that .m2 cache contains valid api module jar.

api (sub-module) pom.xml

    ....
    <parent>
        <artifactId>kotlin-spring-boot</artifactId>
        <groupId>org.ildar</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hello-api</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
  ....

integration-tests (sub-module) pom.xml

<parent>
    <artifactId>kotlin-spring-boot</artifactId>
    <groupId>org.ildar</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>hello-integration-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    <plugins>
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <version>${kotlin.version}</version>
            <executions>
                <execution>
                    <id>compile</id>
                    <goals> <goal>compile</goal> </goals>
                </execution>

                <execution>
                    <id>test-compile</id>
                    <goals> <goal>test-compile</goal> </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Link to a project on github : https://github.com/IldarGalikov/kotlinspringboot

Ildar Galikov
  • 431
  • 5
  • 17

2 Answers2

7

Since Spring removed the "MODULE" Layout in Spring Boot 2.0, maven was complaining about a non existent LayoutType ENUM when trying Christophs answer.

Looking at the Docs though helped me resolve the issue: https://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/repackage-classifier.html

Specifically adding this to the spring-boot-maven-plugin:

<executions>
  <execution>
    <id>repackage</id>
    <configuration>
      <classifier>exec</classifier>
    </configuration>
  </execution>
</executions>
Marcel Fraas
  • 86
  • 1
  • 2
5

The problem is caused by Spring Boot's repackaging of the API jar. It moves the class files of your application from the root of the jar into a BOOT-INF/classes folder in the jar. When compiling the integration tests the kotlin compiler only search the root of the jar for class files and does not look into the BOOT-INF folder. As a result it cannot resolve references to the classes in the API jar.

This answer by Damien describes how to make Spring Boot keeping your application classes in the root of the jar. If I add the configuration mentioned there to your api/pom.xml the integration tests in your project compile as expected:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <layout>MODULE</layout>
    </configuration>
</plugin>
Christoph Böhme
  • 3,766
  • 1
  • 19
  • 29