On Tue, Jan 29, 2019 at 10:27 AM pscl <petercs...@gmail.com> wrote: > > Thanks for the feedback. Just to loop back - I ended up bypassing Mixins and > customizing my ObjectMapper to seek out the inner Builder class via > reflection. > > @Slf4j > public class CustomObjectMapper extends ObjectMapper{ > private static final long serialVersionUID = 1L; > > public CustomObjectMapper() { > this.setAnnotationIntrospector(new JacksonAnnotationIntrospector() { > private static final long serialVersionUID = 1L; > > @Override > public Class<?> findPOJOBuilder(AnnotatedClass ac) { > > //log.info(Class.forName(ac.getName()+"$"+ac.getRawType().getSimpleName()+"Builder"); > Class<?> innerBuilder; > try { > innerBuilder = > Class.forName(ac.getName()+"$"+ac.getRawType().getSimpleName()+"Builder"); > log.info("Builder found: {}", ac.getName()); > return innerBuilder; > } catch( ClassNotFoundException e ) { > return super.findPOJOBuilder(ac); > } > } > > @Override > public Value findPOJOBuilderConfig(AnnotatedClass ac) { > if (ac.hasAnnotation(JsonPOJOBuilder.class)) { > return super.findPOJOBuilderConfig(ac); > } > return new JsonPOJOBuilder.Value("build", ""); > } > }); > } > }
Excellent! Thank you for sharing this. -+ Tatu +- > > > > On Thursday, January 24, 2019 at 8:45:02 PM UTC-8, Tatu Saloranta wrote: >> >> On Thu, Jan 24, 2019 at 8:39 PM pscl <peter...@gmail.com> wrote: >> > >> > Hi, >> > >> > Here's a question I've posted on SO - crossposting here in hope of getting >> > some domain-expertise. >> > >> > >> > I have a 3rd party Lombok builder POJO, one that I cannot modify, that I >> > want to serialize using jackson. Notably it does not have a >> > NoArgsConstructor. >> > >> > @Data >> > @Builder >> > public class ExternalClass { >> > private String name; >> > private String data; >> > // etc. >> > } >> > >> > >> > On the surface this would appear to be simple, but it is incredibly >> > frustrating in practice as each possible option seems to be counteracted >> > by a different complication. In essence, I'm having trouble getting an >> > external Lombok builder to work with a jackson mixin. >> > >> > >> > Lombok produces fluent setters of the style .name(String name) while >> > Jackson's built-in builder deserializer expects .withName(String name). >> > Lombok documentation, and recipes elsewhere such as here suggest using >> > @JsonDeserialize(builder=ExternalClass.ExternalClassBuilder.class) in >> > conjunction with @JsonPOJOBuilder(withPrefix="") on a predeclared inner >> > stub builder. But this is not possible because the Lombok class is in an >> > external library. >> > >> > Applying these annotations to a mixin has no effect. >> >> As explained, that approach should work, I think, as long as mixins >> are bound to targets properly (that is, value class mixin has >> annotation pointing to target class; builder class mixin has overrides >> for prefix name). >> So I may be missing something here, but what? Is builder class not >> available from sources and only materialized as part Lombok >> processing? >> >> > @JsonDeserialize(ExternalClass.ExternalClassBuilder.class) >> > public abstract class ExternalClassMixin { >> > @JsonPOJOBuilder(withPrefix="") >> > public static ExternalClassBuilder { >> > } >> > } >> > >> > >> > The only approach I've found that works is to leverage the package-access >> > AllArgsConstructor created by @Builder and populate the mixin with the >> > following constructor >> >> Note that as long as annotation exists, AllArgsConstructor can even be >> private, if that matters; Jackson can access it via reflection (unless >> Java 11+ start blocking that or something). >> >> > >> > public abstract class ExternalClassMixin { >> > @JsonCreator public ExternalClassMixin( >> > @JsonProperty("name") String name, >> > @JsonProperty("data") String data, >> > // etc. >> > ) {} >> > } >> > >> > >> > This is obviously not desirable as it requires iterating and hard-coding >> > every class property explicitly, making the mixin fragile to any change in >> > the external POJO. >> > >> > My question is - is there a robust, maintainable way to serialize this >> > external builder class using Jackson without modifying it, using either a >> > mixin or maybe a full blown deserializer? >> >> If mixin-for-builder approach does not, maybe others have ideas. >> >> One interesting thing to note is that Jackson can actually override >> settings on final properties too. >> So as long as there are public accessors, these would be found. >> >> -+ Tatu +- > > -- > You received this message because you are subscribed to the Google Groups > "jackson-user" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to jackson-user+unsubscr...@googlegroups.com. > To post to this group, send email to jackson-user@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "jackson-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to jackson-user+unsubscr...@googlegroups.com. To post to this group, send email to jackson-user@googlegroups.com. For more options, visit https://groups.google.com/d/optout.