Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeToken interprets Kotlin type variance wrongly #420

Open
NichtStudioCode opened this issue Jul 21, 2023 · 0 comments
Open

TypeToken interprets Kotlin type variance wrongly #420

NichtStudioCode opened this issue Jul 21, 2023 · 0 comments

Comments

@NichtStudioCode
Copy link

NichtStudioCode commented Jul 21, 2023

Since Kotlin's type variance works different, there are some issues when using io.leangen.geantyref.TypeToken:

In Java, this works as expected:

System.out.println(new TypeToken<Set<String>>() {}.getType()); // java.util.Set<java.lang.String>

In Kotlin, this interpreted wrongly:

println(object : TypeToken<Set<String>>() {}.type) // java.util.Set<? extends java.lang.String>

This can then lead to unexpected exceptions, as Configurate won't find serializes for type ? extends String:

// import org.spongepowered.configurate.kotlin.extensions.get
println(root.node("list").get<Set<String>>())
Exception in thread "main" org.spongepowered.configurate.serialize.SerializationException: [list] of type ? extends java.lang.String: No applicable type serializer for type
	at org.spongepowered.configurate.serialize.AbstractListChildSerializer.deserialize(AbstractListChildSerializer.java:50)
	at org.spongepowered.configurate.AbstractConfigurationNode.get(AbstractConfigurationNode.java:151)
	at org.spongepowered.configurate.ConfigurationNode.get(ConfigurationNode.java:458)
	at org.example.ConfigurateTestKt.main(ConfigurateTest.kt:70)
	at org.example.ConfigurateTestKt.main(ConfigurateTest.kt)

The reason for this is that Kotlin has declaration-site variance and the immutable kotlin.collections.Set is covariant (public interface Set<out E> : Collection<E>), which translates to java.util.Set<? extends java.lang.String> at runtime.
The easiest way to fix this would be to use Kotlin's built-in typeOf in Configurate's Kotlin extension functions. As an additional benefit, this also removes the overhead of tons of anonymous classes.

println(typeOf<Set<String>>().javaType) // java.util.Set<java.lang.String>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant