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

UnwrappingBeanPropertyWriter incorrectly assumes the found serializer is of type UnwrappingBeanSerializer #2060

Closed
ptahchiev opened this issue Jun 11, 2018 · 8 comments
Milestone

Comments

@ptahchiev
Copy link

Hello,
I want to add a bunch of attributes to the resulting JSON file so I create my own StdSerializerlike this:

    class MarkupAwareStandardSerializer extends StdSerializer<AbstractEntityDefinition> {

        private StdSerializer serializer;

        public MarkupAwareStandardSerializer(StdSerializer src) {
            super(src);
            this.serializer = src;
        }

        @Override
        public void serialize(AbstractEntityDefinition bean, JsonGenerator gen, SerializerProvider provider) throws IOException {
            ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());

            if (servletRequestAttributes != null) {
                String filterId = servletRequestAttributes.getRequest().getParameter("filter");

                if (StringUtils.isNotEmpty(filterId) && filterId.equals("search")) {
                    List<ItemMarkup> itemMarkups = entityFacade.getEntityPropertyMarkups(bean.getClass());
                    gen.writeStartObject(bean);
                    for (ItemMarkup itemMarkup : itemMarkups) {
                        if (itemMarkup != null && itemMarkup.isPartOfSearchResult()) {
                            if (StringUtils.isNotEmpty(itemMarkup.getSearchResultExpression())) {
                                gen.writeStringField(itemMarkup.getName(),
                                                     parseExpression(itemMarkup.getSearchResultExpression(), new ExpressionContext(bean)));
                            } else {
                                try {
                                    provider.defaultSerializeField(itemMarkup.getName(), PropertyUtils.getProperty(bean, itemMarkup.getName()), gen);
                                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException nsmex) {
                                    LOG.warn(nsmex.getMessage());
                                }
                            }
                        }
                    }
                    gen.writeEndObject();
                } else {
                    serializer.unwrappingSerializer(null).serialize(bean, gen, provider);
                }
            } else {
                serializer.unwrappingSerializer(null).serialize(bean, gen, provider);
            }
        }

        @Override
        public boolean isUnwrappingSerializer() {
            return true;
        }
    }

Notice I have overriden the isUnwrappingSerializer() method to return true. But now I get this exception:

java.lang.ClassCastException: com.nemesis.platform.module.restservices.core.jackson.MarkupAwareSerializerModifier$MarkupAwareStandardSerializer cannot be cast to com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanSerializer
	at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter._findAndAddDynamic(UnwrappingBeanPropertyWriter.java:214)
	at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter.serializeAsField(UnwrappingBeanPropertyWriter.java:102)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
	at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1033)
	at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:202)
	at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:150)

And indeed here:
https://github.com/FasterXML/jackson-databind/blob/master/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java#L212

you are trying to cast the serializer to UnwrappingBeanSerializer which I don't think is correct.

@ptahchiev
Copy link
Author

After checking if the serializer is of this type seems to fix it:

        if (serializer.isUnwrappingSerializer() && serializer instanceof UnwrappingBeanSerializer) {
            t = NameTransformer.chainedTransformer(t, ((UnwrappingBeanSerializer) serializer)._nameTransformer);
        }

@cowtowncoder
Copy link
Member

@ptahchiev Thank you for reporting this! I'll have a quick look and hopefully verify your fix. Or, remember why cast was thought to be necessary.

@cowtowncoder cowtowncoder added 2.9 and removed ACTIVE labels Jun 11, 2018
@cowtowncoder cowtowncoder changed the title UnwrappingBeanPropertyWriter incorrectly assumes the found serializer is of type UnwrappingBeanSerializer UnwrappingBeanPropertyWriter incorrectly assumes the found serializer is of type UnwrappingBeanSerializer Jun 12, 2018
cowtowncoder added a commit that referenced this issue Jun 12, 2018
@ptahchiev
Copy link
Author

@cowtowncoder Thank you for your fix. Do you know any estimated ETA for the next release?

@ptahchiev
Copy link
Author

@cowtowncoder Sorry - i just saw you have released a new version 👍

BTW I just noticed that this code in the same class might also need the same if:

https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.9.6/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java#L216

@ptahchiev
Copy link
Author

Oh crap.. I tried the 2.9.6 release and I now I get:

java.lang.ClassCastException: com.nemesis.platform.module.restservices.core.jackson.MarkupAwareSerializerModifier$MarkupAwareStandardSerializer cannot be cast to com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanSerializer
	at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter._findAndAddDynamic(UnwrappingBeanPropertyWriter.java:217)
	at com.fasterxml.jackson.databind.ser.impl.UnwrappingBeanPropertyWriter.serializeAsField(UnwrappingBeanPropertyWriter.java:102)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
	at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1033)
	at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:202)
	at org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer.serialize(PersistentEntityJackson2Module.java:15

@cowtowncoder can you please reopen this issue?

@cowtowncoder cowtowncoder reopened this Jun 19, 2018
@cowtowncoder
Copy link
Member

Sigh. This is the reason why I usually insist on unit tests before fixing.
My bad, I should have noticed the other place (plus line number was indicated originally).

@cowtowncoder cowtowncoder added this to the 2.9.7 milestone Jun 19, 2018
@ptahchiev
Copy link
Author

Hi @cowtowncoder when do you plan the 2.9.7 release?

@cowtowncoder
Copy link
Member

@ptahchiev Since 2.9.6 was just released, probably 2-3 months from now at least.

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