How do you configure Kotlin JVM target/source comp...
# gradle
e
How do you configure Kotlin JVM target/source compatability when using the multiplatform plugin?
I'm aware of configuring the Kotlin extension with:
Copy code
jvm {
      compilations.all {
         kotlinOptions {
            jvmTarget = "1.8"
         }
      }
   }
but it doesn't seem to set the java target of the outgoing variant (at least not when it's used in a composite build)
Initially I had issues with resolution failing to choose between
apiElements
and
jvmApiElements
due to:
Copy code
> The consumer was configured to find an API of a library compatible with Java 17, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'. However we cannot choose between the following variants of project :kotest:kotest-framework:kotest-framework-api:
          - apiElements
          - jvmApiElements
        All of them match the consumer attributes:
          - Variant 'apiElements' capability io.kotest:kotest-framework-api:5.4.0-LOCAL declares an API of a library compatible with Java 17, packaged as a jar, and its dependencies declared externally:
              - Unmatched attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'jvm')
          - Variant 'jvmApiElements' capability io.kotest:kotest-framework-api:5.4.0-LOCAL declares an API of a library, packaged as a jar, preferably optimized for standard JVMs, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm':
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java version (required compatibility with Java 17)
If I add the following, the issue is instead moved to
runtimeElements
vs
jvmRuntimeElements
Copy code
java {
   sourceCompatibility = JavaVersion.VERSION_1_8
   targetCompatibility = JavaVersion.VERSION_1_8
}
Copy code
> The consumer was configured to find a runtime of a library compatible with Java 8, packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'. However we cannot choose between the following variants of project :kotest:kotest-runner:kotest-runner-junit5:
          - jvmRuntimeElements
          - runtimeElements
        All of them match the consumer attributes:
          - Variant 'jvmRuntimeElements' capability io.kotest:kotest-runner-junit5:5.4.0-LOCAL declares a runtime of a library, packaged as a jar, preferably optimized for standard JVMs, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm':
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java version (required compatibility with Java 8)
          - Variant 'runtimeElements' capability io.kotest:kotest-runner-junit5:5.4.0-LOCAL declares a runtime of a library compatible with Java 8, packaged as a jar, and its dependencies declared externally:
              - Unmatched attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'jvm')
t
use jvm toolchain - works with MPP as well
e
Tried that this morning as well πŸ™‚
Copy code
kotlin {
   jvmToolchain {
      (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(11))
   }
}
Copy code
Could not determine the dependencies of task ':kotest-extensions-spring:compileJava'.
> Could not resolve all task dependencies for configuration ':kotest-extensions-spring:compileClasspath'.
   > Could not resolve io.kotest:kotest-framework-api:5.3.1.
     Required by:
         project :kotest-extensions-spring
      > The consumer was configured to find an API of a library compatible with Java 11, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'. However we cannot choose between the following variants of project :kotest:kotest-framework:kotest-framework-api:
          - apiElements
          - jvmApiElements
        All of them match the consumer attributes:
          - Variant 'apiElements' capability io.kotest:kotest-framework-api:5.4.0-LOCAL declares an API of a library compatible with Java 11, packaged as a jar, and its dependencies declared externally:
              - Unmatched attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'jvm')
          - Variant 'jvmApiElements' capability io.kotest:kotest-framework-api:5.4.0-LOCAL declares an API of a library, packaged as a jar, preferably optimized for standard JVMs, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm':
              - Unmatched attributes:
                  - Doesn't say anything about how its dependencies are found (required its dependencies declared externally)
                  - Doesn't say anything about its target Java version (required compatibility with Java 11)
I think this only occurs when using gradle's included builds. I'm trying build
kotest-examples-spring-webflux
which include
kotest-extensions-spring
and
kotest
.
kotest-extensions-spring
depends on
kotest
as well, and this happens on the outgoing variants from
kotest
when
kotest-extensions-spring
tries to resolve them
t
could paste here outgoingVariants for kotest-framework-api?
e
It's quite a lot. See snippet
t
interestingly I don't see
apiElements
variant in
kotest-framework-api
published version. And JVM one is named
jvmApiElements-published
e
Same task, when executed in kotest directory itself, exact same source:
t
anyway I think it is a Kotlin Gradle plugin bug.
apiElements
should not be present in MPP case and
jvmApiElements
should also contain
org.gradle.jvm.version  = 11
. To workaround it - in
kotest-framework-api
you need to add bundling and jvm version attributes to
jvmApiElements
configuration:
Copy code
configurations["jvmApiElements"].attributes {
    attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling, Bundling.EXTERNAL)
    attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 11)
}
e
I tried that as well, but then modules with
kotest
fails to resolves one another
t
You need to do the same for
kotest-assertions-shared:jvmApiElements
configuration. Probably you could just add this attributes into all kotest projects
jvmApiElements
configurations
e
sorry, this is when adding the attributes to all
jvmApiElements
. Perhaps I should just do it to do framework-api
it's all open source, I can provide branches and reproduction if you'd like πŸ™‚
t
please provide, our MPP developer will take a look into it
πŸ™ 1
πŸ™ 1
e
a
Hey Emil, I'm the MPP developer who Yahor mentioned 😎 So, I was curios why would you need a
java-library
plugin applied? Is it only for
javadoc
generation? But I don't see any java code in kotest πŸ€” Basically applying
java-library
or any java-related plugins with Kotlin Gradle Plugin is not recommended. Due to such reasons that you are experiencing right now πŸ™‚ If you really need java alongside kotlin and javadoc generation then you can use following:
Copy code
kotlin {
   jvm {
      withJava() // <-- this will enabled Java compilation and other tooling around it. such as javadoc.
   }
}
e
Hi @Anton Lakotka [JB] ! I'm not sure tbh, probably used for javadoc generation only. I'll try your suggestion
(Can Dokka generate that?)
a
What I'm trying to say that
javadoc
tasks are always executed with NO-SOURCE status.
Copy code
> Task :kotest-framework:kotest-framework-api:javadoc NO-SOURCE
Even without applying
withJava()
. So I was wondering why would you need that?
e
Ah, gotcha. So Javadoc won't be generated for Kotlin sources. Im kinda new to the Kotest project so not sure why it was added originally:)
a
Yes. Dokka is the way to generate docs for kotlin sources. So then it is safe just to remove
java-library
application. Together with
javadoc
publication. since it is always empty.
πŸ‘ 1