代码之家  ›  专栏  ›  技术社区  ›  Mir-Ismaili

拼图:找不到Kotlin符号

  •  3
  • Mir-Ismaili  · 技术社区  · 6 年前

    我有一个Java/Kotlin项目,有多个子项目(模块)。这是 module-info.java 对于基本模块:

    module ir.openuniverse {
        requires java.desktop;
        requires kotlin.stdlib;
        requires transitive org.apache.logging.log4j;
        requires org.apache.logging.log4j.core;
    
        exports ir.openuniverse;  // Base module has exported here.
    }
    

    对于消费者模块,我有:

    module ir.openuniverse.watchservice {
        requires kotlin.stdlib;
        requires gson;
        requires ir.openuniverse; // Base module has imported here
    
        exports ir.openuniverse.watchservice;
    }
    

    现在,我在consumer module中插入一个测试文件:

    package ir.openuniverse.watchservice;
    
    import ir.openuniverse.UtilKt;
    import ir.openuniverse.JUtil;
    import ir.openuniverse.Entry; 
    
    public class Test {}
    

    然后试着编译它:

    > Task :watch-service:compileJava FAILED
    [...]\watch-service\src\main\ir\openuniverse\watchservice\Test.java:3: error: cannot find symbol
    import ir.openuniverse.UtilKt;
                          ^
      symbol:   class UtilKt
      location: package ir.openuniverse
    [...]\watch-service\src\main\ir\openuniverse\watchservice\Test.java:5: error: cannot find symbol
    import ir.openuniverse.Entry;
                          ^
      symbol:   class Entry
      location: package ir.openuniverse
    2 errors
    
    FAILURE: Build failed with an exception.
    

    三门课( UtilKt , JUtil , Entry )在基本模块中。但是 朱蒂尔 在爪哇( JUtil.java )科特林还有另外两人( Util.kt Entry.kt ).

    正如您所见,导入没有问题 朱蒂尔 ,但无法解析其在Kotlin中来源的类。(无需导入两个Kotlin类,我就可以成功编译该模块)。

    此外,如果我不完全使用Java9模块系统,也没有问题。


    我使用Gradle并使用以下两个插件进行了测试:

    gradle.plugin.org.gradle.java:experimental-jigsaw:0.1.1
    

    异或:

    gradle.plugin.rgoldberg:experimental-jigsaw:0.4.1-SNAPSHOT
    

    更新1:

    由于@nullpointer的评论,我试图检查 classpath s、 这是执行任务的一部分 --debug 显示的选项 -classpath 空荡荡的 --module-path 具有正确的值(尤其是以下两个: D:\Devel\IdeaProjects\Tinifier\base\build\classes\java\main;D:\Devel\IdeaProjects\Tinifier\base\build\classes\kotlin\main; ):

    05:40:29.575 [DEBUG] [org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler] Compiler arguments: -source 11 -target 11 -d D:\Devel\IdeaProjects\Tinifier\watch-service\build\classes\java\main -g -sourcepath  -proc:none -XDuseUnsharedTable=true -classpath  --module-path D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk8\1.3.10\71d0fa967493eb76648b575edf1762cb2d0c7f10\kotlin-stdlib-jdk8-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\com.google.code.gson\gson\2.8.5\f645ed69d595b24d4cf8b3fbb64cc505bede8829\gson-2.8.5.jar;D:\Devel\IdeaProjects\Tinifier\base\build\classes\java\main;D:\Devel\IdeaProjects\Tinifier\base\build\classes\kotlin\main;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk7\1.3.10\4d147bf43060dc43d61b096e24da1e67dfe0c032\kotlin-stdlib-jdk7-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.3.10\b178c1501609c6e4ee8be635513cb023a466457d\kotlin-stdlib-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.11.1\268f0fe4df3eefe052b57c87ec48517d64fb2a10\log4j-api-2.11.1.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-common\1.3.10\1b19d99229dcedad7caf50534dce38fe82845269\kotlin-stdlib-common-1.3.10.jar;D:\Devel\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\13.0\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\annotations-13.0.jar;D:\Devel\IdeaProjects\Tinifier\watch-service\build\classes\kotlin\main D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\ir\openuniverse\watchservice\T.java D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\module-info.java
    05:40:29.576 [INFO] [org.gradle.api.internal.tasks.compile.JdkJavaCompiler] Compiling with JDK Java compiler API.
    05:40:30.138 [ERROR] [system.err] D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\ir\openuniverse\watchservice\T.java:3: error: cannot find symbol
    05:40:30.139 [ERROR] [system.err] import ir.openuniverse.UtilKt;
    05:40:30.139 [ERROR] [system.err]                       ^
    05:40:30.139 [ERROR] [system.err]   symbol:   class UtilKt
    05:40:30.139 [ERROR] [system.err]   location: package ir.openuniverse
    05:40:30.142 [ERROR] [system.err] D:\Devel\IdeaProjects\Tinifier\watch-service\src\main\ir\openuniverse\watchservice\T.java:5: error: cannot find symbol
    05:40:30.142 [ERROR] [system.err] import ir.openuniverse.Entry;
    05:40:30.143 [ERROR] [system.err]                       ^
    05:40:30.143 [ERROR] [system.err]   symbol:   class Entry
    05:40:30.143 [ERROR] [system.err]   location: package ir.openuniverse
    05:40:30.164 [ERROR] [system.err] 2 errors
    

    不幸的是,尽管我知道 Compiler arguments 从上面的日志中,我不知道如何手动编译源代码。只是跑步 javac <compiler-arguments> 没用。


    更新2:

    复制Kotlin .class 指向Java路径的文件 文件解决了这个问题。看看我的答案,一个简单的Gradle的配置来做到这一点。但我知道这不是一个根本的解决方案。


    更新3:

    我发现了一个更根本的问题!如果我从一个模块中删除了所有Java源代码(即使它不依赖于另一个模块,比如我的基本模块),并且只保留Kotlin源代码,那么该模块的编译将抛出该包的位置(只包括Kotlin源代码) 出口 (在 模块信息。JAVA )然后说 包裹是空的 !!:

    > Task :base:compileJava FAILED
    D:\Devel\IdeaProjects\Tinifier\base\src\main\module-info.java:9: error: package is empty or does not exist: ir.openuniverse
        exports ir.openuniverse;
                  ^
    1 error
    
    FAILURE: Build failed with an exception.
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Mir-Ismaili    6 年前

    复制Kotlin .class 指向Java路径的文件 文件解决了这个问题。但我知道这不是一个根本性的解决方案(示例见问题的更新3)。您可以更改Kotlin编译的目标路径。在格拉德尔:

    sourceSets {
        main {
            // Optional: Removing `java` directory from output path that usually is `build/classes/java/main/`:  
            java.outputDir = file(java.outputDir.toString().replaceAll("\\${File.separatorChar}java", ""))
    
            // Mandatory:
            kotlin.outputDir = java.outputDir 
        }
    }
    
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    
        // Unfortunately setting `main.kotlin.outputDir` isn't enough. See: https://stackoverflow.com/questions/49638136/kotlin-gradle-plugin-how-to-use-custom-output-directory#comment95108749_49638136 and https://youtrack.jetbrains.com/issue/KT-23807
        destinationDir = sourceSets.main.kotlin.outputDir
    }
    
    compileTestKotlin {
        // ...
    }
    
    推荐文章