在Java中使用Kotlin类:找不到符号。

72

我发现了一个与Android相关的类似问题(链接),但是我使用的是纯Java和Maven构建工具。因此我认为最好还是新开一个问题。

我创建了一个Kotlin类,想要从Java类中引用它,使用MyKotlinClass.class语法。但Maven构建失败,而在IntelliJ Idea编译正常。我已经将Kotlin插件添加到了Maven中:

        <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>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

然而,这并没有帮助到问题的解决:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project app: Compilation failure
[ERROR] MyClassLinkingKotlin.java:[100,40] error: cannot find symbol

行/列指的确切是符号MyKotlinClass.class。即使像这样使用也会失败:

System.err.println(MyKotlinClass.class)

1
请展示 MyClassLinkingKotlin.java 文件中第 100 行的代码(我认为是[line,col])。 - ThrowingSpoon
添加到问题中。 - Vojtěch
4个回答

110

你的Maven配置添加了Kotlin编译器插件,但没有调整Java编译器插件执行顺序,以便在Kotlin编译器之后运行Java编译器。因此,Java编译器在Kotlin之前运行,并且无法看到由Kotlin编译的类。

下面是一个示例片段,显示了混合语言项目的正确配置(摘自文档):

<build>
    <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>
                    <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>
    </plugins>
</build>

4
谢谢。很遗憾,当Java和Kotlin同时存在时,Intellij似乎无法正确设置POM文件。我不得不按照文档手动设置它。 - Ferran Maylinch

27
如果你正在使用Android Studio并已经通过“设置”->“插件”->“Kotlin”添加了Kotlin插件,那么可能是因为您还没有设置Gradle的其余部分以使用Kotlin。以下是来自https://medium.com/@elye.project/setup-kotlin-for-android -studio-1bffdf1362e8中的片段:
步骤1:在Android Studio中设置Kotlin插件

Android Studio → 首选项... → 插件 → 浏览存储库 → 在搜索框中键入“Kotlin” → 安装

步骤2:将Kotlin类路径添加到项目Build.Gradle
buildscript {
    ext.kotlin_version = "1.1.1"
    ext.supportLibVersion = "25.3.0"
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

步骤3:在您的模块Build.gradle中添加Kotlin库并应用Kotlin插件

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    // ... various gradle setup
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile "com.android.support:appcompat-v7:$supportLibVersion"
    compile "com.android.support:recyclerview-v7:$supportLibVersion"
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

请注意,'kotlin-android-extensions'插件已被弃用。 - doctorram

5
如果有人正在使用纯Java项目,而不是Maven,而是使用Gradle,则需要将模块gradle文件更改为以下内容:
假设您的模块中有以下插件:
apply plugin: 'java-library'

如果你想使用Kotlin插件,则需要在Java插件之前添加Kotlin插件:

apply plugin: 'kotlin'
apply plugin: 'java-library'

原因是:

您的配置添加了Kotlin编译器插件,但没有调整Java编译器插件执行顺序,使得Java编译器在Kotlin编译器之前运行,因此Java编译器在 Kotlin 编译后运行,无法识别 Kotlin 编译出的类。

正如@yole在回答中所解释的那样。


5
我遇到了相同的错误,但我已经正确设置了pom。我的问题是我刚刚使用Intellij将一个Java类转换为Kotlin类,这将那个Kotlin文件留在了 src/main/java
对我来说,解决方案是创建一个 src/main/kotlin 并将我的Kotlin类移到那里,让我的Java文件保留在 src/main/java 中。但是你确实需要像@yole的答案展示的那样进行maven设置。

1
只是好奇:为什么这样做的原因是 Kotlin 文件被移动到 src/main/kotlin 后会在 Java 文件之前编译?这就是它的工作方式? - Michal Vician

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接