【问题标题】:Error trying to instantiate a Kotlin class from Java尝试从 Java 实例化 Kotlin 类时出错
【发布时间】:2017-10-05 16:07:24
【问题描述】:

我正在尝试从 Java 实例化 Kotlin 类,但每次尝试使用 Maven 编译时都会收到错误 cannot find symbol:

class ConfigCommand(private val game: Game) : Command("config", "") {

  init {
    addAliases("cfg")
  }

  override fun getRequiredRank(): Rank? {
    return null
  }

  override fun getDescription(): String {
    return "Shows the config for the game"
  }

  @Throws(CommandException::class)
  override fun execute(sender: CommandSender, args: Array<String>): Boolean {

    if (args.isEmpty()) {
        if (sender !is Player)
            throw NoConsoleAccessException()
        sender.openInventory(ConfigGUI(game).build())
        return true
    }

    return false
  }
}

不知道为什么格式不正确,但无论如何在我将它转换为 Kotlin 类之前它可以工作,但我需要在我的主类中注册这个命令,这是一个 Java 类。当我尝试从 Java 类实例化 Kotlin 类时,IDE 中没有错误,但是当我去编译它时,maven 尖叫

cannot find symbol
[ERROR] symbol:   class ConfigCommand

【问题讨论】:

  • 您能否提供更多上下文和要编译的文件代码?也许甚至提供一个最小的失败示例?
  • @ChristianBrüggemann 这有帮助还是您需要更多?
  • 您是否将pom.xml 中的Kotlin Maven 插件配置为described here?如果是,您的pom.xml 是什么样的?顺便说一句,StackOverflow 上的代码格式化是使用 4 个空格缩进完成的。
  • @ChristianBrüggemann 我有,here 是我的 pom.xml
  • 你的 pom 缺少 @ChristianBrüggemann 告诉你的链接中显示的 sourceDirs 声明......再次在这里:kotlinlang.org/docs/reference/…

标签: maven kotlin


【解决方案1】:

我遇到了类似的问题,我尝试这样解决它:

原因是java编译器在kotlin编译器之前运行,java类在编译时找不到kotlin类。

所以在你的 pom.xml(root pom.xml) 中指定 kotlin 编译器插件

    <build>
    <pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>${maven-antrun.version}</version>
            </plugin>
            <plugin>
                <groupId>com.taobao.pandora</groupId>
                <artifactId>pandora-boot-maven-plugin</artifactId>
                <version>${pandora-boot-maven-plugin.version}</version>
            </plugin>
            <plugin>
                <groupId>com.alibaba.citrus.tool</groupId>
                <artifactId>autoconfig-maven-plugin</artifactId>
                <version>${autoconfig-maven-plugin.version}</version>
            </plugin>
        </plugins>
    </pluginManagement>
    <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>
            </execution>
            <execution>
                <id>test-compile</id>
                <phase>test-compile</phase>
                <goals>
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>


    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <executions>
            <execution>
                <id>default-compile</id>
                <phase>none</phase>
            </execution>
            <execution>
                <id>default-testCompile</id>
                <phase>none</phase>
            </execution>
            <execution>
                <id>compile</id>
                <phase>compile</phase>
                <goals>
                    <goal>compile</goal>
                </goals>
            </execution>
            <execution>
                <id>testCompile</id>
                <phase>test-compile</phase>
                <goals>
                    <goal>testCompile</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <target>${maven.compiler.target}</target>
            <source>${maven.compiler.source}</source>
            <encoding>${project.build.sourceEncoding}</encoding>
        </configuration>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>3.0.1</version>
        <executions>
            <execution>
                <id>attatch-sources</id>
                <goals>
                    <goal>jar</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

</plugins>
</build>

它对我有用。

【讨论】:

    【解决方案2】:

    maven-compiler-plugin 添加了在相应阶段首先运行的默认执行 default-compiledefault-testCompile

    为了在 Java 代码中使用 Kotlin 类,您需要在 Java 编译器运行之前运行 Kotlin 编译器。一种方法是将其执行安排到process-sources 阶段。另一种方法是“取消计划”Java 插件的默认执行,并在 Kotlin 插件执行之后安排新的执行。

    使用 pom.xml 的这一部分关闭 Java 插件的默认执行:

        <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>
    
                ...
    
            </executions>
        </plugin>
    

    然后添加新的执行:

                <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>
    

    此处显示完整示例:https://kotlinlang.org/docs/reference/using-maven.html#compiling-kotlin-and-java-sources

    【讨论】:

      【解决方案3】:

      我仍在研究 Kotlin,但我尝试根据您的示例完成一些排列。我很容易根据您的 Hastebin pom 创建您的问题。

      您是对的,将 &lt;phase&gt; 更改为 process-sources 可以让我的测试代码在 Maven 中编译,但我(老实说)不能总是记住所有 Maven 阶段,所以我不会个人对更改为流程源感到满意而无需进行更多研究 - 特别是因为 IntelliJ 工具依赖于compile 阶段。

      在玩弄了我自己的互操作示例之后,似乎关键(并且在工具默认设置中缺少)部分是 &lt;sourceDirectory&gt; 元素作为 &lt;build&gt; 的顶级子元素,如下所示:

      <build>
          <sourceDirectory>src/main/java</sourceDirectory>
              <plugins>
                  <plugin>
                      <groupId>org.jetbrains.kotlin</groupId>
                      <artifactId>kotlin-maven-plugin</artifactId>
                      <version>${kotlin.version}</version>
                      <executions>
                          <execution>
                              <id>compile</id>
      

      当我运行mvn compile 终端命令时,将&lt;sourceDirectory&gt; 添加为&lt;build&gt; 下的顶级元素使我的Java 到Kotlin 互操作代码编译。当我混合“java”目录中的源文件以包含 Java 和 Kotlin 文件时,情况确实如此。

      作为旁注(我不明白我为什么写这篇文章),当我将“Kotlin”作为我的类名的一部分添加到我的 Kotlin 源时,我不需要添加 &lt;sourceDirectory&gt; 元素...

      【讨论】:

        【解决方案4】:

        在多次浏览 this 页面并意识到我没有做错任何事情后,我开始乱搞我的 pom 并最终通过将 Kotlin 编译的阶段更改为 process-sources 来让它工作。

        【讨论】:

          猜你喜欢
          • 2015-12-20
          • 1970-01-01
          • 2016-12-26
          • 1970-01-01
          • 1970-01-01
          • 2017-03-13
          • 2013-10-24
          • 1970-01-01
          • 2012-03-14
          相关资源
          最近更新 更多