Extending io.dropwizard.jackson.Discoverable not strictly necessary?

532 views
Skip to first unread message

Ron Dagostino

unread,
Jul 30, 2015, 12:08:45 PM7/30/15
to dropwizard-user
I just discovered that extending the io.dropwizard.jackson.Discoverable interface is not strictly necessary in order for my custom configuration classes to work.  Is this expected behavior, and is there a reason to extend this interface?  I would prefer to not extend it if it isn't necessary because then my configuration classes can be used without Dropwizard, and that is something we desire in certain cases.
 
Ron

Matt Hurne

unread,
Jul 31, 2015, 1:53:45 PM7/31/15
to dropwiz...@googlegroups.com
I believe extending Discoverable is only useful and necessary when you
need "polymorphic" configuration.
io.dropwizard.logging.AppenderFactory in dropwizard-logging is the
starting point for a good example of this. If polymorphic
configuration is your goal and you don't involve Discoverable, it
won't work (at least, not without extra effort on your part to make it
work in some other way). Also see
io.dropwizard.jackson.DiscoverableSubtypeResolver

https://github.com/dropwizard/dropwizard/blob/master/dropwizard-logging/src/main/java/io/dropwizard/logging/AppenderFactory.java
https://github.com/dropwizard/dropwizard/blob/master/dropwizard-jackson/src/main/java/io/dropwizard/jackson/DiscoverableSubtypeResolver.java


Matt Hurne
> --
> You received this message because you are subscribed to the Google Groups
> "dropwizard-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to dropwizard-us...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Matt Hurne

unread,
Jul 31, 2015, 2:01:31 PM7/31/15
to dropwiz...@googlegroups.com
By the way, if you are implementing polymorphic configuration with
Discoverable, you also need to list your interface that extends
Discoverable in a file:
META-INF/services/io.dropwizard.jackson.Discoverable

And then list the implementations if your interface in a similar file
named after the interface. e.g., if your interface is
com.foo.MyFactory , then: META-INF/services/com.foo.MyFactory with
contents such as:

com.foo.MyFactoryImpl1
com.foo.MyFactoryImpl2

Oh, *and* you need an annotation on your interface that extends
Discoverable: @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property =
"type")

*And* you need to annotate each implementation of your interface, e.g.
@JsonTypeName("foo1")

With property = "type" in the @JsonTypeInfo annotation on the
interface and @JsonTypeName("foo1") on the implementation of that
interface, your YAML config will need a type property referencing foo1
for Dropwizard/Jackson to do its thing:

foo:
type: foo1


Hope this is useful,

Matt Hurne

Tatu Saloranta

unread,
Jul 31, 2015, 6:40:13 PM7/31/15
to dropwiz...@googlegroups.com
I am not sure all of the listed things are needed: my impression was that only a subset was needed. Otherwise it would be much easier to simply annotate interface itself with @JsonTypeInfo and @JsonSubTypes. Discoverable would rather be used to allow auto-discovery, based on limited bit of information.
But it would be great if this was fully documented, otherwise one has to use trial and error to figure out exactly which pieces are necessary.

@JsonTypeName is often used, although not required: if not used, type name defaults to simple name of the class itself.

-+ Tatu +-


Ron Dagostino

unread,
Aug 1, 2015, 7:41:04 AM8/1/15
to dropwiz...@googlegroups.com
Hi folks.  Thanks for the feedback, but I need to clarify something.  I have polymorphic configuration working just fine, and I am not extending the Discoverable interface.

I have the file META-INF/services/io.dropwizard.jackson.Discoverable listing my top-level interfaces.  It contains this text:

com.example.MyInterface1
com.example.MyInterface2

I have files named for each of those top-level interfaces.  The file META-INF/services/com.example.MyInterface1 contains this text:

com.example.PolyClass1A
com.example.PolyClass1B

The file META-INF/services/com.example.MyInterface2 contains this text:

com.example.PolyClass2A
com.example.PolyClass2B

The point I am making is that polymorphic configuration is working just fine whether MyInterface1 and MyInterface2 extend io.dropwizard.jackson.Discoverable or not.


Ron

You received this message because you are subscribed to a topic in the Google Groups "dropwizard-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/dropwizard-user/kSZA35AKq7M/unsubscribe.
To unsubscribe from this group and all its topics, send an email to dropwizard-us...@googlegroups.com.

Matt Hurne

unread,
Aug 1, 2015, 9:02:42 AM8/1/15
to dropwiz...@googlegroups.com
Interesting, Ron - I assumed extending Discoverable was required since
that's how things are done in the polymorphic configuration classes
provided by Dropwizard. Obviously, your findings suggest that my
assumption was incorrect!

Thanks,
Matt Hurne

Ron Dagostino

unread,
Aug 1, 2015, 9:21:49 AM8/1/15
to dropwiz...@googlegroups.com
I find the need to create the file META-INF/services/io.dropwizard.jackson.Discoverable and all of the other files like META-INF/services/com.example.MyInterface1 and META-INF/services/com.example.MyInterface2 (one file per line in META-INF/services/io.dropwizard.jackson.Discoverable) to be cumbersome.  I think it would be much better if most or all of those files could be eliminated via the use of an improved auto-discovery process.  One possibility that would be an improvement over the current implementation while not departing too far from it would be to keep the META-INF/services/io.dropwizard.jackson.Discoverable file and leverage something based on the code at this gist (https://gist.github.com/marcus-nl/8c5c6f8472cced934144) to auto-discover the concrete classes.

Ron

Tatu Saloranta

unread,
Aug 1, 2015, 12:41:47 PM8/1/15
to dropwiz...@googlegroups.com
One alternative is to simply rely on Jackson's Module interface: SimpleModule implementation, for example, has "registerSubtypes()" method, which takes either Classes (assuming either default name, or existence of @JsonTypeName), or `NamedType`s that specify class and its type name (id) to use.

This is not strictly plug-n-play, but quite simple.

-+ Tatu +-

Ron Dagostino

unread,
Aug 2, 2015, 2:31:57 PM8/2/15
to dropwizard-user
See this post on the Dropwizard-dev mailing list for a proposal to move to Jackson modules for bundling and using custom configuration classes instead of the existing io.dropwizard.jackson.Discoverable mechanism.
 
Ron
Reply all
Reply to author
Forward
0 new messages