Skip to content

Passing of a custom MetadataKey leads to an exception #70

@yevhenii-nadtochii

Description

@yevhenii-nadtochii

There is a method io.spine.logging.ScopedLoggingContext.Builder.withMetadata(key: MetadataKey<T>, value: T) for attaching context metadata. It accepts a metadata key, which is an interface: interface MetadataKey<T: Any>. An attempt to create an object that implements this interface and pass it to the builder leads to an exception on JVM.

A failing code snippet:

import io.spine.logging.LoggingFactory
import io.spine.logging.MetadataKey
import io.spine.logging.WithLogging
import io.spine.logging.context.ScopedLoggingContext

typealias User = String

object UserKey : MetadataKey<User> {
    override val canRepeat: Boolean = false
    override val label: String = "user"
    override fun cast(value: Any): User =
        if (value is User) value else error("The passed `$value` can't be cast to `User`.")
}

object Example : WithLogging {
    fun doAct() {
        val user: User = "Bill"
        val logger = LoggingFactory.forEnclosingClass()
        ScopedLoggingContext.newContext()
            .withMetadata(UserKey, user)
            .execute {
                logger.atInfo().log { "..." }
            }
    }
}

fun main() = Example.doAct()

It fails with the following exception:

Exception in thread "main" java.lang.ClassCastException: class logging.test.UserKey cannot be cast to class io.spine.logging.JvmMetadataKey (logging.test.UserKey and io.spine.logging.JvmMetadataKey are in unnamed module of loader 'app')
        at io.spine.logging.context.DelegatingContextBuilder.withMetadata(LoggingContextFactory.kt:180)
        at logging.test.AppKt.main(App.kt:38)
        at logging.test.AppKt.main(App.kt)

However, it works fine if a key is created by LoggingFactory:

val userKey = LoggingFactory.singleMetadataKey("user", User::class)

We should either document somewhere that keys can be created only by the factory, or allow passing of custom ones.


Additionally, align naming of method arguments in overloads of singleMetadataKey(...) and repeatedMetadataKey(...). KClass for values is named different. We should go with valueClass name. It relates to LoggingFactory for JVM.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions