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

Getting error in serializing Stream<T> return type from http controller's method #770

Open
porechajp opened this issue Feb 17, 2024 · 2 comments

Comments

@porechajp
Copy link

Expected Behavior

For the following record,

@Introspected
@Serdeable
public record Employee(String firstName, String lastName) {
}

and controller

@Controller("/api/employees")
public class EmployeeController {

    private static final List<Employee> data = List.of(new Employee("First","Last"));

    @Get
    public Stream<Employee> getAll(){
        return data.stream();
    }
}

The getAll method (called on HTTP GET /api/employees) should return a single element array of following,

[
 {"firstName": "First", "lastName":"Last"}
]

Actual Behaviour

Starting 4.3.0, the same method is failing with following exception,

Caused by: io.micronaut.serde.exceptions.SerdeException: Cannot serialize raw stream
	at io.micronaut.serde.support.serializers.StreamSerializer.createSpecific(StreamSerializer.java:37)
	at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue(JacksonJsonMapper.java:174)
	at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue0(JacksonJsonMapper.java:167)
	at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue0(JacksonJsonMapper.java:162)
	at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue(JacksonJsonMapper.java:248)
	at io.micronaut.http.netty.body.NettyJsonHandler.writeTo(NettyJsonHandler.java:161)

and on client side following is received,

{
    "_links": {
        "self": [
            {
                "href": "/api/employees",
                "templated": false
            }
        ]
    },
    "_embedded": {
        "errors": [
            {
                "message": "Internal Server Error: Error encoding object [java.util.stream.ReferencePipeline$Head@70693eaf] to JSON: Cannot serialize raw stream"
            }
        ]
    },
    "message": "Internal Server Error"
}

After some debugging, I concluded that this has probably got introduced due to commit : (Make NettyJsonHandler implement NettyBodyWriter)

Due to this change, the wrap method of RoutingInBoundHandler ,

    <T> NettyBodyWriter<T> wrap(MessageBodyWriter<T> closure) {
        if (closure instanceof NettyBodyWriter<T> nettyClosure) {
            return nettyClosure;
        } else {
            return new CompatNettyWriteClosure<>(closure);
        }
    }

started returning the same instance (as it now inherits from NettyBodyWriter) instead of CompatNettyWriteClosure.

I debugged this flow in 4.2.4 and 4.3.2 and in case of 4.2.4, since it creates CompatNettyWriteClosure, it ultimately results in to correct interpretation of Argument type in StreamSerializer's createSpecific method.

So in case of 4.2.4, Argument instance comes pointing to Stream,
image

whereas in case of 4.3.2, it points to Head,

image

Looks like unintentional effect.

If my understanding is incorrect, please let me know.

Steps To Reproduce

No response

Environment Information

Micronaut version 4.3.2
Oracle JDK 21
Windows 11

Example Application

No response

Version

4.3.2

@altro3
Copy link
Contributor

altro3 commented Feb 18, 2024

looks like a bug in micronaut-serde. Try to use io.micronaut:micronaut-jackson-databind instead io.micronaut.serde:micronaut-serde-jackson. If all will be ok, then bug in micronaut-serialization

@graemerocher graemerocher transferred this issue from micronaut-projects/micronaut-core Feb 18, 2024
@porechajp
Copy link
Author

@altro3 yes, micronaut-jackson-databind is working fine.

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

No branches or pull requests

2 participants