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

Vert.x 4 Serialization error (Native mode) #16555

Closed
pjgg opened this issue Apr 15, 2021 · 3 comments · Fixed by #16941
Closed

Vert.x 4 Serialization error (Native mode) #16555

pjgg opened this issue Apr 15, 2021 · 3 comments · Fixed by #16941
Labels
kind/bug Something isn't working
Milestone

Comments

@pjgg
Copy link
Contributor

pjgg commented Apr 15, 2021

Describe the bug

Quarkus: 2.X Native mode.

I am working in a Vert.x application over Quarkus 2.x and I am getting the following error when I am trying to encode a io.vertx.ext.auth.User into a Json String through this method Json.encode(user) (Note that the user is empty).

Error:

Failed to encode as JSON: No serializer found for class io.vertx.ext.auth.impl.UserImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)"

I have tried to register an auth "user", for reflection through a reflection-config.json file or by a @RegisterForReflection(targets = {User.class, UserImpl.class}) annotation without success.

For example:

package io.quarkus.qe.vertx.web.auth;

import io.quarkus.runtime.annotations.RegisterForReflection;
import io.vertx.ext.auth.User;
import io.vertx.ext.auth.impl.UserImpl;

@RegisterForReflection(targets = {User.class, UserImpl.class})
public class MyReflectionConfiguration {
}

In the end following the error recommendation we have created a custom object mapper used by Vertx Json.encode library.

@Singleton
public class VertxAuthObjectMapperCustomizer implements ObjectMapperCustomizer {

    @Override
    public void customize(ObjectMapper objectMapper) {
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }
}

You have a reproducer in this project over this module. You could clone the project, remove the class io.quarkus.qe.vertx.web.config.VertxAuthObjectMapperCustomizer and run the following command: mvn clean install -pl 302-quarkus-vertx-jwt -P native

Another way to reproduce the issue is just to create a simple Vertx app for example with Reactive-routes:

Dependencies:

 <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-vertx-web</artifactId>
        </dependency>

        <dependency>
            <groupId>io.vertx</groupId>
            <artifactId>vertx-auth-jwt</artifactId>
        </dependency>

And then create the following endpoint:

@RouteBase(path = "/test")
public class TestRouteHandler {
   
    @Route(methods = HttpMethod.GET, path = "/hello")
    Uni<String> hello() {
        User user = new UserImpl();
        System.out.println(Json.encode(user));
        return Uni.createFrom().item("hello");
    }
}

Make a native compilation and then make a request to http://localhost:8080/test/hello/

Or even forget about io.vertx:vertx-auth-jwt

IF you have a "RandomObject" like

@RegisterForReflection
public class RandomObject {
}

And then you try to serialize as a Json, is going to fail (native mode):

@RouteBase(path = "/test")
public class TestRouteHandler {

    @Route(methods = HttpMethod.GET, path = "/hello")
    Uni<String> hello() {
        RandomObject random = new RandomObject();
        System.out.println(Json.encode(random));
        return Uni.createFrom().item("hello");
    }
}

Query: curl -v http://localhost:8080/test/hello/
Result:

 io.vertx.core.json.EncodeException: Failed to encode as JSON: No serializer found for class io.quarkus.qe.RandomObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
@pjgg pjgg added the kind/bug Something isn't working label Apr 15, 2021
@cescoffier
Copy link
Member

Yes, this case cannot be easily tracked.
Note that it should work if you return a Uni<RandomObject> directly.

@cescoffier
Copy link
Member

BTW, was it working with the 1.x version?

@NinjaTycoon
Copy link

NinjaTycoon commented May 1, 2021

I had an issue with a 3rd party library I created that uses gson. To my surprise, gson itself basically works without a problem in the native, barring the fact that the objects were incorrectly empty. but, it was only when I saw this syntax above that I discovered how to annotate 3rd party library classes inside the main project:

@RegisterForReflection(targets = {User.class, UserImpl.class})

Where User and UserImpl could be in a utility jar.

Sort of off topic, but just wanted a quick way to suggest that the documentation have this added in various locations as I read a ton of documentation yet never saw this usage. Only here in this Issue did I discover it. Saved the day!!! Thanks!

cescoffier added a commit to cescoffier/quarkus that referenced this issue May 3, 2021
- add an example with multiple classes registered
- add a canonical example
- link the section in the various guides mentioning the @RegisterForReflection annotation

Fix quarkusio#16555.
@quarkus-bot quarkus-bot bot added this to the 2.0 - main milestone May 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants