混合 Kotlin + Java 与 Maven,未解决的参考
Mixed Kotlin + Java with Maven, unresolved reference
我有一个带有 Kotlin 代码 hello.kt
的 Maven 项目,它调用 Java 代码 JavaFoo.java
,它调用 Kotlin 代码 KotlinFoo.kt
。 hello.kt
也直接调用 KotlinFoo.kt
。我正在尝试使用 mvn clean install
完全使用 kotlinlang's Maven docs.
中描述的 Maven 设置来构建它
如果 hello.kt
不调用 JavaFoo
(但我将 JavaFoo
留在项目中),那么构建就很好了。
文档说应该在 Java 编译器之前调用 Kotlin 编译器,这对我来说意味着所有 Kotlin 代码都需要在任何 Java 代码之前编译,即使用此设置您可以从 Java 调用 Kotlin,但反之则不行。但是,文档将此设置描述为 "mixed code applications",而不是 "calling Kotlin from Java"。
换句话说,这个失败似乎与文档似乎暗示的内容一致,但与他们直接说的不一致——或者我只是误解了什么。
我想从另一种语言中调用每种语言。有没有可以执行此操作的 Maven 配置?
(我查看了关于混合代码设置的各种 StackExchange 问题,none 的解决方案对我有用。)
按要求添加代码:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.kotlindemo</groupId>
<artifactId>kotlin-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>kotlin-demo</name>
<properties>
<kotlin.version>1.1.2-2</kotlin.version>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<main.class>com.example.kotlindemo.HelloKt</main.class>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals> <goal>test-compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals> <goal>testCompile</goal> </goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals> <goal>single</goal> </goals>
<configuration>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/kotlin/hello.kt
:
package com.example.kotlindemo
fun main(args : Array<String>) {
println("Hello, world!")
var kfoo = KotlinFoo()
kfoo.printFooString()
kfoo.fooString = "init2"
kfoo.printFooString()
var foo2 = JavaFoo("abcd")
foo2.printString()
}
src/main/kotlin/KotlinFoo.kt
:
package com.example.kotlindemo
class KotlinFoo {
var fooString = "init"
fun printFooString() {
println(this.fooString)
}
}
src/main/java/JavaFoo.java
:
package com.example.kotlindemo;
class JavaFoo {
private KotlinFoo k;
JavaFoo(String initializer) {
k = new KotlinFoo();
k.setFooString(initializer);
}
void printString() {
this.k.printFooString();
}
}
错误:
[ERROR] .../src/main/kotlin/hello.kt: (12, 14) Unresolved reference: JavaFoo
编译失败,因为您的 Java class 不在与其包语句匹配的目录中。虽然 Kotlin 允许您将 classes 放在任何目录中,而不管它们位于哪个包中,但 Java 要求您将每个文件放在与其目录相对应的包中。此要求也适用于混合语言项目。
要修复错误,请将 JavaFoo.java
移动到 src/main/java/com/example/kotlindemo
。
如果你使用的是maven,你需要添加目标:<goal>addSources</goal>
像这样:
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>testGenerateStubs</goal>
<goal>testCompile</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
我有一个带有 Kotlin 代码 hello.kt
的 Maven 项目,它调用 Java 代码 JavaFoo.java
,它调用 Kotlin 代码 KotlinFoo.kt
。 hello.kt
也直接调用 KotlinFoo.kt
。我正在尝试使用 mvn clean install
完全使用 kotlinlang's Maven docs.
如果 hello.kt
不调用 JavaFoo
(但我将 JavaFoo
留在项目中),那么构建就很好了。
文档说应该在 Java 编译器之前调用 Kotlin 编译器,这对我来说意味着所有 Kotlin 代码都需要在任何 Java 代码之前编译,即使用此设置您可以从 Java 调用 Kotlin,但反之则不行。但是,文档将此设置描述为 "mixed code applications",而不是 "calling Kotlin from Java"。
换句话说,这个失败似乎与文档似乎暗示的内容一致,但与他们直接说的不一致——或者我只是误解了什么。
我想从另一种语言中调用每种语言。有没有可以执行此操作的 Maven 配置?
(我查看了关于混合代码设置的各种 StackExchange 问题,none 的解决方案对我有用。)
按要求添加代码: pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.kotlindemo</groupId>
<artifactId>kotlin-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>kotlin-demo</name>
<properties>
<kotlin.version>1.1.2-2</kotlin.version>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<main.class>com.example.kotlindemo.HelloKt</main.class>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals> <goal>test-compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals> <goal>testCompile</goal> </goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals> <goal>single</goal> </goals>
<configuration>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/kotlin/hello.kt
:
package com.example.kotlindemo
fun main(args : Array<String>) {
println("Hello, world!")
var kfoo = KotlinFoo()
kfoo.printFooString()
kfoo.fooString = "init2"
kfoo.printFooString()
var foo2 = JavaFoo("abcd")
foo2.printString()
}
src/main/kotlin/KotlinFoo.kt
:
package com.example.kotlindemo
class KotlinFoo {
var fooString = "init"
fun printFooString() {
println(this.fooString)
}
}
src/main/java/JavaFoo.java
:
package com.example.kotlindemo;
class JavaFoo {
private KotlinFoo k;
JavaFoo(String initializer) {
k = new KotlinFoo();
k.setFooString(initializer);
}
void printString() {
this.k.printFooString();
}
}
错误:
[ERROR] .../src/main/kotlin/hello.kt: (12, 14) Unresolved reference: JavaFoo
编译失败,因为您的 Java class 不在与其包语句匹配的目录中。虽然 Kotlin 允许您将 classes 放在任何目录中,而不管它们位于哪个包中,但 Java 要求您将每个文件放在与其目录相对应的包中。此要求也适用于混合语言项目。
要修复错误,请将 JavaFoo.java
移动到 src/main/java/com/example/kotlindemo
。
如果你使用的是maven,你需要添加目标:<goal>addSources</goal>
像这样:
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>testGenerateStubs</goal>
<goal>testCompile</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>