James Hamilton
09/03/2020, 3:29 PMkotlinx-metadata-jvm
package published to mvn? The metadata generated by kotlinc 1.4 does not work with the metadata-jvm 0.1.0 versionudalov
James Hamilton
09/03/2020, 3:46 PMKotlinClassMetadata md = KotlinClassMetadata.read(new KotlinClassHeader(k, mv, bv, d1, d2, xs, pn, xi));
If the metadata is generated by 1.3.* it works, but with 1.4 this method returns null
I tried compiling the kotlinx-metadata-jvm library myself and using the jar as a dependency and it seems to fix the problem. I noticed there was some commits recently to the metadata libraryudalov
kotlinx-metadata-jvm
0.1.0 has metadata version JvmMetadataVersion.isCompatible
.
As a workaround, can you try just passing intArrayOf(1, 3, 0)
intArrayOf(1, 1, 0)
] instead of mv
in your code? It should mostly work fine for class metadata. (But if you’re also using KotlinModuleMetadata
, this trick won’t work.)
In any case, I’ll look into it and we’ll probably release the new version built on 1.4 pretty soon.James Hamilton
09/03/2020, 4:17 PMJames Hamilton
09/03/2020, 4:18 PMJames Hamilton
09/03/2020, 4:19 PMudalov
intArrayOf(1, 1, 0)
should work insteadJames Hamilton
09/03/2020, 4:24 PMJames Hamilton
09/03/2020, 4:28 PMudalov
xi
to -1
. To fix the issue, use 0
, or even better, load the actual value of Metadata.xi
from the annotation.
If you’re interested in more detail how it works: Kotlin metadata has a version, and each reader (be it the Kotlin compiler, or the kotlinx-metadata-jvm library) declares what version it supports, which is basically the latest version available when that reader was built. Kotlin metadata is by default fully backwards-compatible (1.4 can read 1.0), and forwards-compatible up to one version (1.4 can read 1.5, but not later). This forward compatibility allows graceful migration to new Kotlin release for complicated projects, but it slows down changes in the metadata format, since we need to support all upcoming changes one release in advance.
However, in case we decide that breaking something in the format is more important than having the forward compatibility, we have a way to turn off this behavior for a specific version. This is possible via a bit in the metadata flags which is called “strict version semantics”. We haven’t used it yet in the compiler, but might use it at some point in the future. For example, metadata of version 1.4 would normally be readable for readers of versions 1.3 and above. However, if strict version semantics is set, it could only be readable for readers of versions 1.4 and above.
By setting xi
to -1, you’re basically enabling all of the flags in the bitfield, including the strict version semantics:
https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/Metadata.kt#L69..L70. Which makes kotlinx-metadata-jvm return null on that metadata, because its version ends up being detected as incompatible.
There are several more confusing details, since we didn’t quite figure out how to support this forward compatibility feature properly from the start. I’ll omit those, but the gist is that kotlinx-metadata-jvm 0.1.0 has metadata version 1.1 but can read Kotlin versions up to, and including, 1.4. So it should be compatible with all Kotlin binaries in existence as of today.James Hamilton
09/24/2020, 7:24 PM