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

Serializing ZoneId throws error #1023

Open
distinctdan opened this issue Jan 17, 2025 · 3 comments
Open

Serializing ZoneId throws error #1023

distinctdan opened this issue Jan 17, 2025 · 3 comments
Labels
info: good first issue Good for newcomers

Comments

@distinctdan
Copy link

Expected Behavior

It looks like Serde isn't compatible with ZoneId, it's throwing errors.

Actual Behaviour

It should work.

Steps To Reproduce

Serializing my model DTO produces the following error:

@Serdeable
data class Location(
    val timeZoneId: ZoneId,
)
Caused by: io.micronaut.serde.exceptions.SerdeException: No serializable introspection present for type ZoneRegion. Consider adding Serdeable. Serializable annotate to type ZoneRegion. Alternatively if you are not in control of the project's source code, you can use @SerdeImport(ZoneRegion.class) to enable serialization of this type.

After this, I tried to use @SerdeImport to import the affected classes. ZoneRegion wasn't available for import, maybe because it's internal, but after adding the following imports, I got farther, but I eventually hit a new error:

@SerdeImport(ZoneId::class)
@SerdeImport(ZoneRules::class)
@SerdeImport(ZoneOffsetTransition::class)

Final error:

18:14:30.726 [default-nioEventLoopGroup-1-3] ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: class com.cfa.ots.fsd.$java_time_zone_ZoneOffsetTransition$Introspection tried to access method 'java.util.List java.time.zone.ZoneOffsetTransition.getValidOffsets()' (com.cfa.ots.fsd.$java_time_zone_ZoneOffsetTransition$Introspection is in unnamed module of loader 'app'; java.time.zone.ZoneOffsetTransition is in module java.base of loader 'bootstrap')
java.lang.IllegalAccessError: class com.cfa.ots.fsd.$java_time_zone_ZoneOffsetTransition$Introspection tried to access method 'java.util.List java.time.zone.ZoneOffsetTransition.getValidOffsets()' (com.cfa.ots.fsd.$java_time_zone_ZoneOffsetTransition$Introspection is in unnamed module of loader 'app'; java.time.zone.ZoneOffsetTransition is in module java.base of loader 'bootstrap')
	at com.cfa.ots.fsd.$java_time_zone_ZoneOffsetTransition$Introspection.dispatchOne(Unknown Source)
	at io.micronaut.inject.beans.AbstractInitializableBeanIntrospection$BeanReadPropertyImpl.getUnsafe(AbstractInitializableBeanIntrospection.java:1170)
	at io.micronaut.serde.support.serializers.SerBean$PropSerProperty.get(SerBean.java:511)
	at io.micronaut.serde.support.serializers.CustomizedObjectSerializer.serializeInto(CustomizedObjectSerializer.java:63)

Is there anything else I can try here? I'm considering writing custom serializers, but I wanted to check if there's a better way because this is surely a common problem.

Environment Information

OSX Sequioa 15.2
JDK 17.0.10

Example Application

No response

Version

4.7.4

@graemerocher
Copy link
Contributor

likely you need to write a custom Serializer<ZoneId>

@distinctdan
Copy link
Author

Yup, that's what I ended up doing, the docs were good on how to do that. However, I opened this issue because I was expecting Serde to be able to automatically handle the built in java classes. Is this something you guys have in scope?

Here's my implementation:

@Singleton
class ZoneIdSerde : Serde<ZoneId> {
    override fun serialize(
        encoder: Encoder,
        context: Serializer.EncoderContext,
        type: Argument<out ZoneId?>,
        value: ZoneId?,
    ) {
        if (value != null) {
            encoder.encodeString(value.id)
        } else {
            encoder.encodeNull()
        }
    }

    override fun deserialize(
        decoder: Decoder,
        context: Deserializer.DecoderContext,
        type: Argument<in ZoneId>,
    ): ZoneId? {
        val zoneIdString = decoder.decodeStringNullable()
        if (zoneIdString != null) {
            return ZoneId.of(zoneIdString)
        }
        return null
    }
}

@graemerocher
Copy link
Contributor

seems like something simple to add yes, contributions welcome

@graemerocher graemerocher added the info: good first issue Good for newcomers label Jan 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info: good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants