Search code examples
kotlingradleintellij-idea

Why can I not convert Java file to Kotlin file in IntelliJ?


I want to create a Gradle multi-project which will have no source code. This project will then have one subproject, and it will have a single Java main function that has been generated by the IntelliJ IDE. My intent is to convert a large Java console application to Kotlin, so here, I am creating a simple console application, and attempting (but failing) to convert the simple Java main file to Kotlin.

My computer is running Ubuntu 22.04. I am performing this exercise on IntelliJ IDEA 2022.3.1 (Community Edition). When I type gradle -- version into a CLI window, I get the following response:

------------------------------------------------------------
Gradle 7.2
------------------------------------------------------------

Build time:   2021-08-17 09:59:03 UTC
Revision:     a773786b58bb28710e3dc96c4d1a7063628952ad

Kotlin:       1.5.21
Groovy:       3.0.8
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          16.0.1 (Private Build 16.0.1+9-Ubuntu-120.04)
OS:           Linux 5.15.0-56-generic amd64

To reduce complexity for those who might want to reproduce what I did, I named the root project "untitled" and it's single subproject "untitled1". These values were the defaults presented to me by IntellJ. I start IntelliJ, and, because I didn't start it from a previous session, IntelliJ displays the "Welcome to IntelliJ IDE" window. From this window, I chose New Project.

A second window labelled "New Project" is opened. I select the "New Project" item from the left hand menu items. So I can keep things simple for those who might want to reproduce this problem, I name the project "untitled". The location of this project can be anywhere the reproducer of this problem might like it to be. The language I chose is Java. The build system is Gradle. The JDK is version "java.version 17.0.5". The Gradle DSL is Kotlin. I chose NOT to add sample code for this project because this project will be the root project to a multi-project build. I left the Group and Artifact ID fields with their default values: "org.example" and "untiled" for my IntelliJ installation respectively. Finally, I ask IntelliJ to create this project.

IntelliJ creates this project, and responds with a display that contains, in a left hand view panel, the project files. To the right of this is displayed the project's build file. This window is named "build.gradle.kts(untitled)", and this file contains the following:

 1 plugins {
 2    id("java")
 3 }
 4
 5 group = "org.example"
 6 version = "1.0-SNAPSHOT"
 7
 8 repositories {
 9     mavenCentral()
10 }
11
12 dependencies {
13    testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
14    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
15 }
16
17 tasks.getByName<Test>("test") {
18     useJUnitPlatform()
19 }

Because I told IntelliJ NOT to add sample code to this project, I did not observe a directory named "src" in the project view panel under the project's name "untitled" as one should if one wanted to add sample code.

I now create the subproject. I do this by right-clicking the project name "untitled" in the project view panel. I select New > Module... from the series of menu items that appear. A dialogue box named "New Module" opens, and I select the "New Module" item from the left hand menu items. So I can keep things simple for those who might want to reproduce this problem, I name the project "untitled1". The location of this project under the project that was created before - the location chosen by the reproducer of this problem has the same directory name as the previous New Project window but with the directory "untitled" appended. The language I chose is Java. The build system is Gradle. The JDK is the same as the root project's SDK. The Gradle DSL is Kotlin. The parent project is named "untitled". This time, I DO tick the box that asks me if I want to create sample code because this project is the one in which the sample code I want to convert will be located. I left the Group and Artifact ID fields with their default values: "org.example" and "untiled1" for my IntelliJ installation respectively. Finally, I ask IntelliJ to create this subproject.

Along with the earlier created build file for the root project, IntelliJ creates this subproject, and responds by displaying the project's build file to the right of the project's view panel. This window is named "build.gradle.kts(untitled1)".

I compared each line of the subproject's build file with each from the root project and observed that the subproject's build file is identical to the the root project's.

I find it of passing interest to notice in the project's view panel that "src" directories have now been created for both the root project and its subproject. In both projects, this directory has the following subdirectory structure:

src
    main
        java
        resources
    test

In the subproject, the java directory also contains the sample source code file named "Main" under the package directory "org.example". I can open this file in the IDE, and when I do a window titled "Main.java" appears to the right of the projects view panel, containing the following code:

 1 package org.example;
 2
 3 public class Main {
 4    public static void main(String[] args) {
 5        System.out.println("Hello world!");
 6    }
 7 }

Next, I request that the IDE convert this file into Kotlin. I do this by right-clicking on the tab of the editor's view of the source code. From the drop-down menu that appears, I select the option "Convert Java File to Kotlin File" located at the bottom of this menu. A dialogue box appears which advises me that "Kotlin is not configured in the project, and so therefore I will have to configure Kotlin in the project before performing this conversion. I chose the option labelled "OK, configure Kotlin in the project". Another dialogue box appears. From this one, I accept the the current selection of "All modules" and accept the given value of the Kotlin compiler and runtime version of "1.8.0". Finally, I click the button marked "OK".

I now observed that the build files of both projects have changed by the same amount. They both have the following contents:

 1 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 2
 3 plugins {
 4     id("java")
 5     kotlin("jvm") version "1.8.0"
 6 }
 7
 8 group = "org.example"
 9 version = "1.0-SNAPSHOT"
10
11 repositories {
12     mavenCentral()
13 }
14
15 dependencies {
16     testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
17     testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
18     implementation(kotlin("stdlib-jdk8"))
19 }
20
21 tasks.getByName<Test>("test") {
22     useJUnitPlatform()
23 }
24 val compileKotlin: KotlinCompile by tasks
25 compileKotlin.kotlinOptions {
26     jvmTarget = "1.8"
27 }
28 val compileTestKotlin: KotlinCompile by tasks
29 compileTestKotlin.kotlinOptions {
30     jvmTarget = "1.8"
31 }

I observed that the IDE is complaining about these contents. In addition to the description I provide below, I have also attached a screen shot of the IDE to help assist the reader who may be interested this problem should the screen shot assist them.

At line 1, the package name does not resolve; specifically, the IDE says that it cannot resolve the name "jetbrains". Lines 24 and 28 appear identical: The IDE says that it cannot resolve the name "KotlinCompile" as well as advising that the tasks "Property delegate must have a 'getValue(Build_gradle, KProperty*>)' method."

I switch my editor view to the Java source file. I observed that the file has not changed. My observations about the build files have already led me to conclude that something is wrong, but I forge ahead, and so again, I select the "Convert Java File to Kotlin file" menu option from the drop-down that appears by right-clicking the tab for this editor view. The IDE responds as before; telling me that Kotlin isn't configured in the project, so I click the button that says "OK, configure Kotlin in the project". The IDE responds through a dialogue box that says "Kotlin is not configured in the project" and this is because "There are no configurators available".

So... I don't know what is happening. The only thing I think I can reliably ascertain from this exercise is that IntelliJ's claim that it can easily convert Java to Kotlin is false. How could I have gone wrong in this simple exercise?


Solution

  • Thanks to a comment offered by one Matt Freake, I solved the problem. I now understand the Gradle icon that appears in the top right of the build-file editor window specifies that a library is missing. This icon is actually a manual request to fetch the library from a repository. One has to instruct Gradle to do this explicitly by assenting to the request opened by clicking on the icon.

    Although this process might only be a once-off, I would personally like it if the IntelliJ IDE somehow made this more obvious and removed the necessity of having to run the process twice; I would have had a more productive time on my holidays. Well, alright, I know now.