Skip to content

Commit 74f122b

Browse files
authored
Removed strict rule -dontwarn java.lang.ClassValue (#2123)
The `-dontwarn java.lang.ClassValue` rule embedded in serialization may have a side effect for the target application if it uses `java.lang.ClassValue` too. Instead of this rule, it is enough to disable warnings for ClassValue inheritors in the serialization itself. Resolves #2119
1 parent 67e9259 commit 74f122b

File tree

2 files changed

+29
-26
lines changed

2 files changed

+29
-26
lines changed

core/jvmMain/src/kotlinx/serialization/internal/Caching.kt

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,41 +40,41 @@ internal actual fun <T> createParametrizedCache(factory: (KClass<Any>, List<KTyp
4040
return if (useClassValue) ClassValueParametrizedCache(factory) else ConcurrentHashMapParametrizedCache(factory)
4141
}
4242

43-
@SuppressAnimalSniffer
44-
private class ClassValueCache<T>(private val compute: (KClass<*>) -> KSerializer<T>?) : SerializerCache<T> {
45-
private val classValue = initClassValue()
46-
47-
private fun initClassValue() = object : ClassValue<CacheEntry<T>>() {
48-
/*
49-
* Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable
50-
* serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher
51-
*/
52-
override fun computeValue(type: Class<*>): CacheEntry<T> {
53-
return CacheEntry(compute(type.kotlin))
54-
}
55-
}
43+
private class ClassValueCache<T>(compute: (KClass<*>) -> KSerializer<T>?) : SerializerCache<T> {
44+
private val classValue = ClassValueWrapper(compute)
5645

5746
override fun get(key: KClass<Any>): KSerializer<T>? = classValue[key.java].serializer
5847
}
5948

6049
@SuppressAnimalSniffer
61-
private class ClassValueParametrizedCache<T>(private val compute: (KClass<Any>, List<KType>) -> KSerializer<T>?) : ParametrizedSerializerCache<T> {
62-
private val classValue = initClassValue()
63-
64-
private fun initClassValue() = object : ClassValue<ParametrizedCacheEntry<T>>() {
65-
/*
66-
* Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable
67-
* serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher
68-
*/
69-
override fun computeValue(type: Class<*>): ParametrizedCacheEntry<T> {
70-
return ParametrizedCacheEntry()
71-
}
50+
private class ClassValueWrapper<T>(private val compute: (KClass<*>) -> KSerializer<T>?): ClassValue<CacheEntry<T>>() {
51+
/*
52+
* Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable
53+
* serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher
54+
*/
55+
override fun computeValue(type: Class<*>): CacheEntry<T> {
56+
return CacheEntry(compute(type.kotlin))
7257
}
58+
}
59+
60+
private class ClassValueParametrizedCache<T>(private val compute: (KClass<Any>, List<KType>) -> KSerializer<T>?) : ParametrizedSerializerCache<T> {
61+
private val classValue = ParametrizedClassValueWrapper<T>()
7362

7463
override fun get(key: KClass<Any>, types: List<KType>): Result<KSerializer<T>?> =
7564
classValue[key.java].computeIfAbsent(types) { compute(key, types) }
7665
}
7766

67+
@SuppressAnimalSniffer
68+
private class ParametrizedClassValueWrapper<T> : ClassValue<ParametrizedCacheEntry<T>>() {
69+
/*
70+
* Since during the computing of the value for the `ClassValue` entry, we do not know whether a nullable
71+
* serializer is needed, so we may need to differentiate nullable/non-null caches by a level higher
72+
*/
73+
override fun computeValue(type: Class<*>): ParametrizedCacheEntry<T> {
74+
return ParametrizedCacheEntry()
75+
}
76+
}
77+
7878
/**
7979
* We no longer support Java 6, so the only place we use this cache is Android, where there
8080
* are no classloader leaks issue, thus we can safely use strong references and do not bother

rules/common.pro

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@
2929
# See also https://github.com/Kotlin/kotlinx.serialization/issues/1900
3030
-dontnote kotlinx.serialization.**
3131

32-
# Serialization core uses `Class.forName("java.lang.ClassValue")` for caching in JVM-only, so it is an expected situation that this class is not in Android
33-
-dontwarn java.lang.ClassValue
32+
# Serialization core uses `java.lang.ClassValue` for caching inside these specified classes.
33+
# If there is no `java.lang.ClassValue` (for example, in Android), then R8/ProGuard will print a warning.
34+
# However, since in this case they will not be used, we can disable these warnings
35+
-dontwarn kotlinx.serialization.internal.ClassValueWrapper
36+
-dontwarn kotlinx.serialization.internal.ParametrizedClassValueWrapper

0 commit comments

Comments
 (0)