Completely stuck starting with Kotlin + JIDEA + Gradle


#1

I’ve been trying to get started with Kotlin this weekend. Spent most of yesterady and pretty much got nowhere. I have googled, I have read the docs and getting past Hello World is not happening.

I think the problem is every document assumes the user is well versed with Java and Gradle at least, preferrably also JIDEA. I’m an embedded SW engineer who dabbles with Python occasionally so PyCharm is familiar but everything else is not.

As far as I have been able to figure out I need a build system to add any external libraries. In this case I’d like to start with Klaxon and go on to add TornadoFX. These would allow me write a usable little application.

So what I would really like at this point is a dummy’s user guide on how to create the project and get started:

  1. Do I start the project according to these instructions: https://kotlinlang.org/docs/reference/using-gradle.html ?
  2. Do I need to manually run gradle init in the directory because it seems that the build artifacts are not created automatically, so how else are they generated? If I start a Gradle project instead of Java or Kotlin project they are generated but then JIDEA works all funky (it doesn’t check the code at all etc).
  3. I can get Klaxon into build.gradle but adding org.json seems completely impossible. No matter how many ways I try JIDEA (and the build system) keep telling me org.json is not recognized and Parser is not defined. So what should a correct build.gradle look like?

To put it simply, what steps are missing from https://github.com/cbeust/klaxon to make it work? This page assumes I have an all dancing, all singing system up already.

My last attempt gave me even more confusing errors:

$ gradle build
:compileKotlin
Using Kotlin incremental compilation
Compilation with Kotlin compile daemon was not successful
java.lang.Exception: sun.misc.Unsafe.invokeCleaner(java.nio.ByteBuffer)
	at org.jetbrains.kotlin.daemon.common.CompileService$CallResult$Error.get(CompileService.kt:60)
....
Could not connect to kotlin daemon. Using fallback strategy.
error: no class roots are found in the JDK path: /usr/lib/jvm/java-9-openjdk-amd64

The Java exception was very long so I didn’t copy all of it here. Daemon seems to be running according to ps -ef, though.

I have now created four different projects in JIDEA so far and got nowhere. Yes, Hello World works but that’s it. The code so far looks like

import java.net.URL
import org.json.*

public class HuutoAmpMain {
    companion object {
        @JvmStatic fun main(args: Array<String>) {
            val result = URL("https://api.huuto.net/1.1/categories").readText()
            print(result)
            val parser: Parser = Parser()
        }
    }
}

Running this in JIDEA gives me plenty of errors:

Error:(7, 8) Kotlin: Unresolved reference: java
Error:(8, 12) Kotlin: Unresolved reference: json
Error:(13, 26) Kotlin: Unresolved reference: URL
Error:(15, 25) Kotlin: Unresolved reference: Parser
Error:(15, 34) Kotlin: Unresolved reference: Parser

So it’s obviously not using build.gradle. Running gradle build on the command line gives me error above. Finally, here’s the build.gradle file:

buildscript {
    ext.kotlin_version = '1.1.51'

    repositories {
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

repositories {
    jcenter()
}

apply plugin: "kotlin"

sourceSets {
     main.kotlin.srcDirs += 'src/main/kotlin'
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile 'com.beust:klaxon:0.30'
    compile group: 'org.json', name: 'json', version: '20141113'
    testCompile 'junit:junit:4.12'
}

Any help would be appreciated because I’m just about to give up. Spending a whole weekend to get the tools setup is not a good way to spend my free time. I’d rather learn Kotlin and worry about the rest later. And there is a dozen languages that are easier to start with that interest me as well (I have tried them and gotten past this point much faster, e.g. Clojure).


#2

Let’s try to find out what the problem is step by step.

Are you able to build your project with gradle from command line? To do so just run ./gradlew build from the project directory, assuming you’ve created that project with IDEA’s new project wizard.

I’ve tried to make a project from these build file and source file, and all seems fine except the missing import for Parser: import com.beust.klaxon.Parser.

You might be interested in reading IDEA docs section about its Gradle support: https://www.jetbrains.com/help/idea/gradle.html


#3

Somehow my environment seems to have been corrupted, now I get that compile crash on a different project as well and even if I kill the daemon processes. Have to figure out what that’s all about. gradlew clean didn’t help either.


#4

Ok, for some reason Kotlin daemon is hell bent on using JDK 9 even though I killed the process once & unset JAVA_HOME. The project isn’t using that either (it’s using the SDK version which is 1.8.xxx). I keep getting

error: no class roots are found in the JDK path: /usr/lib/jvm/java-9-openjdk-amd64

And the daemon won’t restart so the build naturally fails.

BTW, when I create the project as suggested at that page Ilya suggested, there is no gradlew wrapper created.

Ok, did I hit a bug in Java? In the daemon log I can find this:

2017-10-29 23:05:38.562 [stderr] INFO: ERROR: sun.misc.Unsafe.invokeCleaner(java.nio.ByteBuffer)

And googling gives me this page: https://bugs.openjdk.java.net/browse/JDK-8171377

I guess I need to somehow manage to change the SDK that daemon uses but how? There is no Kotlin daemon or process running so it seems to start with the wrong every time.

Here’s the debug prints for this issue if anyone’s interested: https://pastebin.com/43gmnh9D


#5

I got rid of the previous problem by removing openjdk-9 from the system. Now it does look like it compiles from the command line, just not correctly (can’t run the jar) but I’ll try to figure this out myself first.

JIDEA still won’t play ball, though. If I select the build.gradle file and select “build” from the RMB menu, I get “Module “Megafooni” is not backed by Gradle”.

Also I don’t think error checking in JIDEA works as it should. Even if I have an obvious error it won’t show it. Like if I have an object that is not defined, or even an obvious typo. If I create a Kotlin project instead of a Gradle project, it works. And it looks like the inspectors are enabled.


#6

Ok, ok. What is the correct way to define the correct main class? Googling gives me about six different variations and none of them work.

This is where I’m currently at: https://github.com/Makistos/Megafooni


#7

I have been adding the main class to pom.xml if developing woith maven.

With gradle one can set it in Project Settings -> artifacts


#8

I can’t select my main function as an artifact. It’s visible in the navigator but the OK button is inactive.


#9

Managed to solve two of the problems finally. First, I can now run the jar both inside JIDEA and with java -jar. The working solution can be found from the repository I linked earlier if someone else has the same problem.

The problem with JIDEA not running Gradle tasks was solved simply by closing and reopening the project.


#10

I think I’ll give Kotlin a pass for now. It seems I spend all my time battling the tools, not coding. It’s pure luck to find any info that actually helps (most is already outdated) and JIDEA is so ridiculously unintuitive and unhelpful that it makes feels like learning Vim was a breeze. Just a few issues I have hit:

  • JIDEA definitely doesn’t automatically detect Kotlin files. I have a project with kt files but File->New still doesn’t offer the chance to create Kotlin files even though I actually tried to add Kotlin to the project when creating it.
  • Thought I’d try to create a TornadoFX project since that’s my goal. Should support Gradle and Kotlin. Guess what? I create the project and am greeted with “Kotlin not configured”. Good luck trying to find how to configure it and JIDEA definitely is not exactly logical either. And guess what part 2? Gradle is also not supported in that project. I can try to compile it online, but guess what part 3? It doesn’t compile, instead gives my a full page of all sorts of errors.
  • Those popups that are supposedly helpful are completely bogus. For instance the one that told me to click here to fix Gradle. Great, I’ll do that. The result was completely ridiculous. I only changed “Use auto-import” and left everything else as-is. Click OK -> “Resolve Error” window opens. “Please, use JDK instead of JRE for Gradle Importer. Open Gradle Settings” Clicking “Open Gradle Settings” gives me, surprise, surprise, an error. “Failed to open “/home/mep/src/Megafooni/#open_external_system_settings”. Error when getting information for file ‘/home/mep/src/Megafooni/#open_external_system_settings’: No such file or directory.”
  • JIDEA logs are packed with all sorts of errors.For the bug above there seems to be an exception in the GradleInstallationManager.java:168.
  • This is more or less the theme, no matter what type of project I create, at least one of the required components is not configured correctly, be it Kotlin, Gradle or something else. And how do you fix that? No idea, I haven’t been able to find any help with Google on how to add a new binding (or whatever it’s called, I thought it could be “module” as per one page, but it wants an artifactid different from the current project so can’t be that). I’ve tried all the possible combinations offered on various pages I googled up and all have these kind of issues with no idea how to fix them.
  • It’s a well-known meme that programmers use Google (and StackOverflow) to solve their problems but that doesn’t seem to work with Kotlin/JIDEA because most of the time instructions are outdated (took me ages to find a Gradle configuration that actually worked because most were just wrong, maybe they worked a year ago?). In many cases there’s just no such option available that the instruction suggest.

Some other exceptions from JIDEA’s log (just the top line for each):

at org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper.execute(GradleExecutionHelper.java:226)
at org.jetbrains.kotlin.psi.KtPsiFactory.createExpression(KtPsiFactory.kt:78)
at com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:65)
at com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration$MyRunnableState.execute(ExternalSystemRunConfiguration.java:167)
at org.jetbrains.plugins.gradle.config.GradleScriptType$1.configureCommandLine(GradleScriptType.java:221)
at org.jetbrains.plugins.gradle.service.GradleInstallationManager.doGetGradleJdk(GradleInstallationManager.java:168)
at com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration$MyRunnableState.execute(ExternalSystemRunConfiguration.java:167)
at org.jetbrains.plugins.gradle.config.GradleScriptType$1.configureCommandLine(GradleScriptType.java:221)
at com.intellij.ide.impl.DataValidator.findInvalidData(DataValidator.java:81)

Many of those multiple times. This is also weird, also multiple times in the log:

2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - IntelliJ IDEA 2017.1.3  Build #IC-171.4424.56 
2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - JDK: 1.8.0_112-release 
2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - VM: OpenJDK 64-Bit Server VM 
2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - Vendor: JetBrains s.r.o 
2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - OS: Linux 
2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - Last Action: ShowProjectStructureSettings 
2017-10-30 23:31:43,547 [14158854]  ERROR - penapi.actionSystem.impl.Utils - update failed for ActionGroup: Firefox (null)[Firefox] 

Finally, am I supposed to update JIDEA by just overwriting the directory with the contents in the zip file because that’s what it looks like? JIDEA keeps nagging me about it but when I click the link provided and download the file that’s what Install-Linux-tar.txt tells me. No mention about updating a previous version.

So I think I’ll wait until Kotlin and JIDEA’s support for it resembles a mature product because I’m really not keen on spending my free time trying to get immature tools to work instead of actually doing something fun LIKE ACTUALLY CODING. I’m definitely not going to suggest we switch to Kotlin in our company any time soon either.


#11

That’s understandable. I have also wasted a lot of time on this kind of issue. Kotlin is a great language, but the tooling is too clumsy.


#12

Did not have any problems with that (maybe because I am on Windows and do not try to do anything manually). The only actual problem in the list is IDE warning about gradle project not being configurated and subsequent “fix”. It works fin for a single module, but for multi-project builds it could actually break gradle build file.

As for the rest, Maybe one should start with actually learning how IDE is called. It is IntelliJ IDEA or simply IDEA. Proper search could produce better results.


#13

Maybe I can’t use Google but what does it help to tell me that? Did I just learn how to do proper searches because you said I’m doing it wrong?

As for the name, funnily enough “jidea” produces just as good search results as “intellij idea” and better than just “idea”. Try it (google disregards the space between j and idea).


#14

@darksnake imagine you are a python user and don’t know gradle/maven. The difficulty in starting a jvm project probably explains why “the java community” has not really grown in recent years, while javascript and python have become increasingly popular.


#15

I’m currently being paid to work on Android firmware/kernel/native, i.e. C with the occasional look into the Java world. But I can do all this with Vim (I build on the command line and do so little Java that I don’t need Android Studio).


#16

I do understand this. But one must understand that build system is one of the best things in Java ecosystem and one can’t an should not start working with java or kotlin without understanding it. For people, who like to work with Vim, it could be hard, but otherwise, it need to be studied first. Besides, how hard could it be? The gradle configuration to use tornadofx is only a few lines of code:

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.1.51"
}

repositories {
    mavenCentral()
}

// Minimum jvmTarget of 1.8 needed since Kotlin 1.1
compileKotlin {
    kotlinOptions.jvmTarget= 1.8
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
    compile 'no.tornado:tornadofx:1.7.12'
}

#17

I think I got over the build system (I managed to build a runnable jar with Klaxon). The issue is with IDEA now. If I’d use Vim, fine, but if I want to IDEA to support Kotlin and Gradle, not so.

That example doesn’t look like it’s even close to a runnable version, though. At least it will complain there’s no main class. Took me a while to figure that out because the answer is a bit Kotlin-centric, no help from Java docs. And there were several different proposed solutions which didn’t work.


#18

For runable jar you will have to add application plugin like this:

plugins{
    id "application"
    id "org.jetbrains.kotlin.jvm" version "1.1.51"
}

mainClassName = <path to your main class>

By default gradle generates jars without entry point.


#19

That wasn’t enough either. I didn’t update my GitHub repo with the latest working version so this is probably wrong but this should be close to what finally worked:

jar {
    manifest {
        attributes 'Main-Class': 'com.sofistes.megafooni.AppKt'
    }
    from { configurations.compile.collect {it.isDirectory() ? it : zipTree(it) } }
}
mainClassName = "com.sofistes.Megafooni.MainKt"

#20

Your problem is definitely not with kotlin, but with gradle application. Manual editing of manifest is not required for such simple scenario. You probably should look into appropriate documentation.