blog/source/_posts/kotlin-unresolve-reference.md

68 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Kotlin中“Unresolved reference”的解决经验
date: 2021-04-10 17:56:04
tags: [JVM, Kotlin, Unresolved reference, Exception, Error]
categories:
- [JVM, Kotlin]
---
在Kotlin的使用过程中常常会出现“Unresolved reference: XXX”的错误这个错误的出现归根结底是Kotlin编译器没有找到代码中所使用的库、类或者方法。<!--more-->出现这个错误的时候请不要慌张也不要尝试去寻找编译器所给出的具体提示在多次解决这个问题的过程中已经有很多经验表明Kotlin编译器甚至是Gradle等构建工具所给出的错误提示和栈跟踪信息都没什么卵用。
Kotlin是一门JVM语言可以自由的调用Java中的所有库功能这虽然为Kotlin的使用提供了极大的便利但是也增加了Kotlin在使用的时候配置功能的复杂性。
从网上的许多博客和帖子中搜到的解决方案基本上都是针对Android开发过程中遇到的这个问题而且这个问题的确也是在使用Gradle构建时常常发生的而且在使用IntelliJ IDEA开发的时候出现的可能会更加频繁一些。但是出现“Unresolved Reference”问题在大部分情况下与IDE无关但是有可能与IDE中的设置有关。
> 不代表使用Maven就可以偷着乐了Maven一样会出现这个问题。
## 配置,一切都是配置的错
当运行`./gradlew run`或者在IntelliJ IDEA中点击Run看到“Unresolved reference”以后你的第一反应一定是“我X我代码里少写啥了。”但是这个错误真不是你代码里少写什么了而是你的项目配置和项目构建文件里少写啥了或者写错啥了。
### JDK版本配置错误
在使用Gradle构建Kotlin JVM项目的时候你所面临的JDK设置实际上有两个一个是系统中的`JAVA_HOME`,一个是`build.grade`中的`kotlinOptions.jvmTarget`而如果在IntelliJ IDEA中使用GradleIDE针对Gradle运行环境的配置也会产生影响但是这个影响基本上与在系统中设置`JAVA_HOME`的效果差不多。
先来看一个编译示例。
{% oss_image kotlin-unresolve-reference/error-prompt.png 编译示例 450 %}
一个项目在使用`./gradlew run`构建运行的时候报出了`Unresovled reference: readString`错误。这个`readString`是调用的`java.nio.file.Files.readString()`方法。可是为什么会报这个方法没有找到呢?先来看一下这个方法的文档信息。
{% oss_image kotlin-unresolve-reference/file-docs.png 文档信息 450 %}
好吧有点儿长但是似乎看不出什么端倪来。这里要注意了这个方法是在Java 11引入的那我们来看看项目的构建配置。
{% oss_image kotlin-unresolve-reference/gradle-file.png Gradle构建配置 300 %}
Kotlin的编译目标看起来也没有什么问题同样是面向Java 11编译的理论上使用这个新引入的方法完全没有问题。那么再来看看IDE中的项目配置。
{% oss_image kotlin-unresolve-reference/ide-setting.png IDE项目配置 450 %}
项目配置这里依旧没有问题。那么Gradle构建Kotlin项目所所涉及到的两个JDK版本问题就已经确认了一个了。那么我们来看另一个JDK配置。
{% oss_image kotlin-unresolve-reference/system-setting.png 系统JDK 450 %}
好吧我机器上的Java是通过SDKMan安装的这里安利一下真的很好用Windows用户就暂时不要想了。不过`JAVA_HOME`也是Java 11这就尴尬了好不。不过不用急能够影响Gradle所使用的JVM的还有一处位置那就是用户家目录下的`.gradle`目录这是Gradle保存全局配置的目录这个目录里有一个用于配置Gradle的`gradle.properties`文件。
{% oss_image kotlin-unresolve-reference/gradle-setting.png 'Gradle JDK' 500 %}
看起来我们似乎找到了问题的源头Gradle没有在使用环境变量中配置的`JAVA_HOME`,而是使用了`.gradle/grade.properties`中另行指定的JDK目录。那么修改它一下试试。
{% oss_image kotlin-unresolve-reference/gradle-setting-modified.png 'Gradle JDK 修改后' 500 %}
现在我们再来试一下吧。
{% oss_image kotlin-unresolve-reference/second-test-run.png 第二次实验运行 350 %}
看起来依旧好尴尬问题依旧。那么能够配置Gradle所使用的JVM的位置还有没有呢这个位置还真的还有一个那就是IDE中的配置。
{% oss_image kotlin-unresolve-reference/ide-gradle-setting.png 修改IDE中的Gradle配置 450 %}
IDE中配置Gradle使用的是Java 8那么把这里也修改成Java 11试试看。
{% oss_image kotlin-unresolve-reference/third-test-run.png 成功运行 350 %}
至此由于Gradle所使用的JVM配置错误而导致Kotlin发生“Unresolved reference”的问题已经全部解决。这个问题是由于Gradle使用的JVM是Java 8其中并不带有项目中所使用的Java 11的内容而Gradle所使用的JVM又是项目编译所要使用的JVM这就导致了Kotlin报出“Unresolved reference”错误。
> 如果使用高版本的JVM来编译使用低版本JDK的项目也同样可能会出现这个问题此时就要注意项目中是否使用了已经被高版本JVM废弃的内容。编译项目所使用的JVM版本尽量要与项目所依赖的JDK版本相同。