Как скомпилировать проект Java + Kotlin с использованием Maven?

Я пытаюсь скомпилировать проект maven, который имеет классы Kotlin, ссылающиеся на классы Java. Вот часть моего родительского POM:

...

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>${kotlin.version}</version>
</dependency>

...

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

<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>${kotlin.plugin.version}</version>

    <executions>
        <execution>
            <id>compile</id>
            <phase>process-sources</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>

        <execution>
            <id>test-compile</id>
            <phase>process-test-sources</phase>
            <goals>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>

    <configuration>
        <scanForAnnotations>false</scanForAnnotations>
    </configuration>
</plugin>

И связанные части дочернего POM:

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
</dependency>

...

<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <configuration>
        <sourceDirs>
            <source>${project.basedir}/src/main/kotlin</source>
        </sourceDirs>
    </configuration>
</plugin>

И класс Котлина:

Stateless
open class DummyServiceImpl : DummyService {

    PersistenceContext(unitName = Consts.UNIT_NAME)
    private val em: EntityManager? = null

    override fun get(id: Long?): Dummy {
        return em!!.find<Dummy>(javaClass<Dummy>(), id)
    }

    override fun sayHi(): String {
        return "Dummy service says \"Hi!\"."
    }
}
Классы

DummyService и Consts - это классы Java, находящиеся в том же модуле, что и DummyServiceImpl. Поэтому, когда я компилирую модуль, содержащий DummyServiceImpl с Maven, он выглядит примерно так:

[error] C:\somepath\service\DummyServiceImpl.kt: (14, 31) Unresolved reference: DummyService
[error] C:\somepath\service\DummyServiceImpl.kt: (16, 35) Unresolved reference: Consts

Если я переключу исполнение плагина Kotlin phase на compile, то он, как ожидается, провалится, если есть ссылки от Java на классы Kotlin:

[ERROR] /C:/somepath/service/impl/DummyServiceClientImpl.java:[5,27] cannot find symbol
[ERROR] symbol:   class DummyServiceImpl

Итак, что с этим делать? Обратите внимание, что здание с IDEA make отлично подходит.

Ответы

Ответ 1

Убедитесь, что у вас есть это объявление в <build> вашего pom.xml

    <plugins>
        <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <version>${kotlin.version}</version>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <source>src/main/java</source>
                            <source>src/main/kotlin</source>
                            <source>src/main/resources</source>
                        </sourceDirs>
                    </configuration>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>process-test-sources</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <source>src/test/java</source>
                            <source>src/test/kotlin</source>
                            <source>src/test/resources</source>
                        </sourceDirs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>

Убедитесь, что все папки (3x в src/main и 3x в src/test), указанные в конфигурации на самом деле, существуют, даже если они не содержат классов/Ресурсы. Вы все еще можете точно настроить конфигурацию, как только она сработает для вас.

Также обратите внимание на то, чтобы использовать тот же самый порядок, о котором я говорил выше, чтобы компилятор сначала скомпилировал Java-код.

Ответ 2

Я закончил использовать следующую конфигурацию для смешивания исходного кода Java и Kotlin:

<build>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <plugins>
        <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <version>${kotlin.version}</version>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <source>src/main/kotlin</source>
                        </sourceDirs>
                    </configuration>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                    <configuration>
                        <sourceDirs>
                            <source>src/test/kotlin</source>
                        </sourceDirs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>