45

I'm just trying to understand the underlying architecture, which I think I am getting wrong.

Taking the tutorial here as the example.

When I do:

kotlinc-jvm hello.kt -include-runtime -d hello.jar

Why it's needed to bundle the Kotlin runtime into the jar if the compiler already converted the code to Java bytecode?

kaneda
  • 5,981
  • 8
  • 48
  • 73

6 Answers6

45

When you write an application in Java, you get to rely on all of the standard class libraries. The java. classes (e.g. java.lang.*, java.util.* ...) are included with every JRE, so you don't need to package them yourself.

Kotlin includes its own standard class library (the Kotlin runtime), separate to the Java class library. To distribute a jar file that can be run by anyone with a plain old JRE, you need to bundle the Kotlin runtime as well.

If you didn't bundle the Kotlin runtime, then your user would have to ensure the Kotlin runtime was on the classpath when executing your application. The page you linked gives an example of this scenario:

Compiling a library

If you’re developing a library to be used by other Kotlin applications, you can produce the .jar file without including the Kotlin runtime into it.

$ kotlinc-jvm hello.kt -d hello.jar

If you're targeting other Kotlin users, then its reasonable to assume they'll already have the Kotlin runtime available to them. However, if you're trying to deploy an application for an end-user, then you want to include the Kotlin runtime so that your application is self-contained.

Greg Kopff
  • 15,945
  • 12
  • 55
  • 78
39

Greg Kopff's accepted answer explains the general case for needing to bundle something, but I feel that the main point of the question was missed: why should something that compiles to Java byte-code (and is therefore no longer Kotlin) require a Kotlin “runtime”?

My expectation (and that of the questioner, I suspect) is that once compiled, there's no trace of Kotlin anymore, and so there should be no need for a Kotlin runtime.

My expectation is also that a “runtime” is some sort of native binary, like JRE, directly responsible for executing the byte-code.

From the Kotlin language reference on packages, though:

A number of packages are imported into every Kotlin file by default:

  • kotlin.*
  • kotlin.annotation.*
  • kotlin.collections.*
  • kotlin.comparisons.* (since 1.1)
  • kotlin.io.*
  • kotlin.ranges.*
  • kotlin.sequences.*
  • kotlin.text.*

Therefore, it seems that:

  1. the “Kotlin runtime” is actually just a “Kotlin class library” (and not strictly a separate “runtime” like JRE);

  2. when Kotlin code is compiled into Java byte-code, the Kotlin is gone, but the byte-code that replaces it needs access to the Kotlin class library; and so

  3. the Kotlin runtime must be available to any Java byte-code which was originally Kotlin code, which can be done by bundling the Kotlin runtime with such code.

For me, the Kotlin team's use of the word “runtime” is what triggered so much confusion. I would prefer that they call it “the Kotlin support classes” rather than use a Java term with a very different connotation.

This doesn't explain why so many things under the kotlin package namespace are needed, or whether Kotlin files can be written that don't actually rely on the Kotlin runtime at all, but perhaps these are issues for another question.

Alex Peters
  • 2,601
  • 1
  • 22
  • 29
  • 2
    I still don't get it. JRE (compiled native code) + Kotlin JAR (java bytecode) = runnable app? Or does it also require Kotlin Runtime (native code)? Or in other words, "can I hand a Java 7 environment my jar file + a kotlin jar file and expect it to work without having to worry about the underlying OS?" – Benjamin H Jul 17 '17 at 23:34
  • @BenjaminH it's libraries. Just like some javax.* packages have to be included compile and runtime, kotlin has libraries. So far as I understand it. It's probably closer to something like glassfish. If the JAR (EAR/WAR) is being run *inside* glassfish et. al. then you don't need to include a bunch of libraries which glassfish already provides. HOWEVER, if you're not deploying to glassfish then you *need* to include the glassfish jar's at runtime somehow someway. – Thufir Nov 05 '17 at 05:22
  • 1
    Kotlin “runtime,” in my opinion, is a misnomer. It's not like a Java runtime, which is a native executable that runs Java bytecode. The Kotlin “runtime” is just a plain old Java library which only does anything if a Java runtime is around to do something with it. Kotlin code relies on the Kotlin “runtime” library. Therefore, JRE + Kotlin JAR = running Kotlin code. No other native binaries needed. – Alex Peters Nov 05 '17 at 09:26
  • 1
    So it's like a Java program that comes with its own set of libraries – Florian Walther May 20 '19 at 18:25
  • Java Collections Framework like `ArrayList`, `HashMap` built-in with JRE but Kotlin isn't. So It need to `-include-runtime` to use Kotlin Collections Interfaces like `MutableList`, `MutableMap` etc. – Sang-Kil Park Nov 24 '22 at 07:33
2

Kotlin runtime is nothing but a set of libraries ( bundled in a jar) which is referred during runtime, just like any other jar in classpath.

NeeK
  • 662
  • 1
  • 8
  • 21
2

JRE is not only native binary, JRE consist of JVM, java standard library (Java SE API) and other tools like Rmiregisty (Java 8 and lower). enter image description here

JVM is native application and it directly responsible for executing byte-code. If you write java application that depends only Java SE API, it does't need to add any library to classpath, because Bootstrap classloader and delegate model are doing their job. If you write Kotlin application, kotlinc compiler adds some "runtime code" and your application became to depends from Kotlin library (it seems like your source code does't depends kotlin library, but binary code depends). Because of that, I think, guys from JetBrains call it runtime-library. BTW, according to Central Maven repository, runtime-library was rename to kotlin-stdlib (Kotlin Runtime (deprecated, use kotlin-stdlib artifact instead).

-1

maybe .jar is compatible for java.
kotlin can run .class by itself.
This is work too

kotlinc hello.kt
kotlin HelloKt
grey
  • 1
  • 1
-1

Using kotlin command line allows easily resolving all kotlin-specific dependencies. AFAIK all the other params are similar to java

foo
  • 574
  • 8
  • 13