Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Kotlin class in Java: Cannot find symbol

I have found this similar question regarding Android, but I am using plain Java with Maven as build tool. I think it is better to post a new question.

I have created a Kotlin class to which I am trying to refer from Java class as MyKotlinClass.class. The Maven build fails, whereas compilation in IntelliJ Idea works fine. I have already added Kotlin plugin to 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>

However that does not help:

[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

The line/column exactly refers to symbol MyKotlinClass.class. It will fail even when using like this:

System.err.println(MyKotlinClass.class)
like image 982
Vojtěch Avatar asked May 15 '17 12:05

Vojtěch


People also ask

Can we use Kotlin class in Java?

You can use Kotlin in a Java project: In any project you have already started, you can decide to start writing the new code in Kotlin. You can then call it from Java code.

How do you call Kotlin class method from Java class?

If we want to call the Kotlin code from Java class both present inside the different packages, this requires to import the package name with Kotlin file name inside Java class and calling the Kotlin code from Java class. Another way is to give full path as packageName. KotlinFileKt. methodName().

Is Java code valid Kotlin code?

Yes. Kotlin is 100% interoperable with the Java programming language and major emphasis has been placed on making sure that your existing codebase can interact properly with Kotlin. You can easily call Kotlin code from Java and Java code from Kotlin. This makes adoption much easier and lower-risk.

Can I call Kotlin method in Java?

Kotlin has been designed from the beginning to fully interoperate with Java, and both JetBrains and Google have pushed in that direction. For instance, IntelliJ and Android Studio allow users to convert files from Java to Kotlin. The conversion is not always problem-free, but it generally does a good job.


4 Answers

Your Maven configuration adds the Kotlin compiler plugin, but doesn't adjust the Java compiler plugin execution so that the Java compiler runs after the Kotlin compiler. Therefore, the Java compiler runs before Kotlin, and doesn't see Kotlin-compiled classes.

Here's a snippet showing the correct configuration for a mixed-language project (taken from the documentation):

<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>
like image 61
yole Avatar answered Oct 17 '22 18:10

yole


If you are using Android Studio and have already added the Kotlin plugins via Settings -> Plugins -> Kotlin, then it could be that you haven't setup the rest of Gradle to use Kotlin. Here's a snippet from https://medium.com/@elye.project/setup-kotlin-for-android-studio-1bffdf1362e8:

Step 1: Setup the Kotlin Plugin in Android Studio

Android Studio → Preferences… →Plugins → Browse Repository → type “Kotlin” in search box → install

Step 2: Add Kotlin classpath to project 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
    }
}

Step 3: Add Kotlin library and apply Kotlin Plugins in your module Build.gradle

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"
}
like image 24
Chris Sprague Avatar answered Oct 17 '22 18:10

Chris Sprague


I ran into this same error, but had the correct pom setup. My issue was that I had just converted a Java class to a Kotlin class with Intellij, which left that Kotlin file in src/main/java.

The solution for me was to create a src/main/kotlin and move my Kotlin class there, and leave my Java files in src/main/java. But you do definitely need the maven setup that @yole's answer shows.

like image 5
Sean Avatar answered Oct 17 '22 18:10

Sean


If anyone is using Plain Java project with Gradle instead of Maven then change your module gradle file as follows:

Say you have following plugin in your module:

apply plugin: 'java-library'

If you wanna have kotlin plugin then add kotlin plugin before java plugin:

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

Reasson is

Your configuration adds the Kotlin compiler plugin, but doesn't adjust the Java compiler plugin execution so that the Java compiler runs after the Kotlin compiler. Therefore, the Java compiler runs before Kotlin, and doesn't see Kotlin-compiled classes.

as explained by @yole in answers

like image 4
Farid Avatar answered Oct 17 '22 18:10

Farid