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?
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'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:
the “Kotlin runtime” is actually just a “Kotlin class library” (and not strictly a separate “runtime” like JRE);
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
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.