Error trying to instantiate a Kotlin class from Java
Asked Answered
H

4

0

I am trying to instantiate a Kotlin class from Java but every time I try to compile with Maven I get the error 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
  }
}

Not sure why that didn't format correctly but anyway before I converted it to a Kotlin class it worked but I need to register this command in my main class which is a Java class. When I try to instantiate a Kotlin class from a Java class there are no errors in the IDE but when I go to compile it maven screams

cannot find symbol
[ERROR] symbol:   class ConfigCommand
Hyperaesthesia answered 7/5, 2017 at 17:11 Comment(6)
Could you please provide some more context and the code that files to compile? Perhaps even provide a minimal failing example?Somersomers
@ChristianBrüggemann Does that help or do you need more?Hyperaesthesia
Did you configure the Kotlin Maven plugin in your pom.xml as described here? If yes, what does your pom.xml look like? By the way, code formatting on StackOverflow is done using 4 space indentation.Somersomers
@ChristianBrüggemann I have and here is my pom.xmlHyperaesthesia
Your pom is missing the sourceDirs declarations shown in the link @ChristianBrüggemann told you about... here again: kotlinlang.org/docs/reference/…Bumble
@Bumble Okay I tried to add that but it still dosen't work here is my pom nowHyperaesthesia
W
0

I'm still figuring out Kotlin, but I tried to work through a few permutations based on your example. I was easily able to create your problem based on your Hastebin pom.

You were right that changing the <phase> to process-sources got my test code to compile in Maven, but I (honestly) can't always remember all the Maven phases off the top of my head so I wouldn't personally be comfortable with changing to process-sources without more research -- especially since the IntelliJ tooling relies on the compile phase.

After playing around with my own interop examples, it seems like the critical (and missing from the tooling defaults) piece is the <sourceDirectory> element as a top-level child of <build> as in:

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

Adding the <sourceDirectory> as a top-level element under <build> made my Java to Kotlin interop code compile when I ran the mvn compile terminal command. That was true when I mixed the source files in the "java" directory to contain both Java and Kotlin files.

As a side note (and I don't I understand why as I write this), when I added "Kotlin" as part of my class name to my Kotlin source I didn't need to add the <sourceDirectory> element...

Winged answered 8/5, 2017 at 6:14 Comment(0)
H
4

After going trough this page multiple times and realizing that I had done nothing wrong I started to just mess around with my pom and eventually got it working by changing the phase of the Kotlin compile to process-sources

Hyperaesthesia answered 8/5, 2017 at 0:0 Comment(0)
C
1

i met similar problem , and i tried to fix it like this:

the reason is that the java compiler runs before kotlin compiler , and the java class can't find the kotlin class when compiling.

so specify the kotlin compiler plugin in your pom.xml(root pom.xml)

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

it works for me.

Crotchety answered 23/1, 2019 at 6:22 Comment(0)
W
0

I'm still figuring out Kotlin, but I tried to work through a few permutations based on your example. I was easily able to create your problem based on your Hastebin pom.

You were right that changing the <phase> to process-sources got my test code to compile in Maven, but I (honestly) can't always remember all the Maven phases off the top of my head so I wouldn't personally be comfortable with changing to process-sources without more research -- especially since the IntelliJ tooling relies on the compile phase.

After playing around with my own interop examples, it seems like the critical (and missing from the tooling defaults) piece is the <sourceDirectory> element as a top-level child of <build> as in:

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

Adding the <sourceDirectory> as a top-level element under <build> made my Java to Kotlin interop code compile when I ran the mvn compile terminal command. That was true when I mixed the source files in the "java" directory to contain both Java and Kotlin files.

As a side note (and I don't I understand why as I write this), when I added "Kotlin" as part of my class name to my Kotlin source I didn't need to add the <sourceDirectory> element...

Winged answered 8/5, 2017 at 6:14 Comment(0)
C
0

The maven-compiler-plugin adds default executions default-compile and default-testCompile that run first in the corresponding phases.

In order to use Kotlin classes in Java code, you need to run Kotlin compiler before Java compiler runs. One way to do it is to schedule its execution to process-sources phase. Another approach is to "unschedule" default executions of Java plugin and schedule new executions instead after the execution of Kotlin plugin.

The default executions of Java plugin are turned off with this section of pom.xml:

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

And then new executions are added:

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

The full example is shown here: https://kotlinlang.org/docs/reference/using-maven.html#compiling-kotlin-and-java-sources

Carnelian answered 8/5, 2017 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.