stupid question, if I define `targetCompatiblity` ...
# announcements
r
stupid question, if I define
targetCompatiblity
in my build.gradle to be 8 but do not define
kotlinOptions.jvmTarget
to be 1.8, so it should be 1.6 per default, what is the compiler supposed to generate? I am asking because I came across
java.util.function.Consumer
in the resulting byte code and this one was introduced in 1.8
i
Kotlin compiler generates bytecode taking into account solely
jvmTarget
option value, so if it's 1.6, then the resulting bytecode will be compatible with JVM 1.6. You can meet
j.u.function.Consumer
type in the compiled code, however, if you use JDK 1.8 or greater in the compile classpath and use API either from that JDK or other java dependencies that takes it as a parameter. The path to JDK can be overridden with
jdkHome
option.
s
where do
sourceCompatibility
and
targetCompatibility
come into play then? I’ve seen them in various
build.gradle[.kts]
files, but if
kotlinc
only cares about
jvmTarget
then how did we get these extraneous properties?
i
They affect java code compilation. Perhaps, they are generated by a wizard or are copy-pasted from somewhere.
r
@ilya.gorbunov So I should file a bug right? I am not using
j.u.function.Consumer
directly and I can see it in my jar not in the jdk8 jar
i
Where do you see it? Is it some Java API call?
r
sorry, false alarm. I just dug deeper and saw that it's not in the resulting byte code kotlin generates
ok, false alarm of the false alarm 😄 I could not see it in the kotlin byte code viewer but it is there in the jar file
and no, no java call is made.
and the resulting class file
and this one contains: java/util/function/Consumer<TT;>
but maybe don't spend time yet. Since you mention it should not be the case it could also be that there is a problem in the project setup and
jvmTarget
is set somewhere to 1.8
Copy code
afterEvaluate {
    println("kotlin jvmTarget: " + compileKotlin.kotlinOptions.jvmTarget)
}
kotlin jvmTarget: 1.6
Shall I file a bug?
i
It looks like JDK's
forEachRemaining
iterator member function is used instead of the imported extension
ch.tutteli.kbox.forEachRemaining
.
Note that
jvmTarget
option affects what bytecode version is produced by the compiler, not what subset of API is visible in the JDK. If you need your code being actually runnable on JVM 6, it makes sense to specify the path to JDK 6 to Kotlin compiler with the
jdkHome
compiler option.
r
I see, shall I file a bug for not using the extension method?
i
Why is that a bug? Member wins over extension when both are applicable.
r
well, there is a discrepancy between generated byte code and Kotlin byte code viewer. Also intellij does not show that jdk's method takes precedence. There is definitely a bug somewhere
i
This may be if IDEA uses different JDK than compiler. Could be some problem in project import then. That's sure worth reporting.