Provides comprehensive Jackson JSON processing support for Dropwizard applications with pre-configured ObjectMapper instances and essential modules.
—
Dropwizard Jackson provides a service-based discovery mechanism for polymorphic configurations, allowing runtime loading of Jackson subtypes through META-INF/services files.
A Jackson subtype resolver that discovers subtypes via META-INF/services configuration files.
public class DiscoverableSubtypeResolver extends StdSubtypeResolver {
public DiscoverableSubtypeResolver()
public DiscoverableSubtypeResolver(Class<?> rootKlass)
public List<Class<?>> getDiscoveredSubtypes()
protected ClassLoader getClassLoader()
protected List<Class<?>> discoverServices(Class<?> klass)
}Default Constructor:
public DiscoverableSubtypeResolver()Constructs a resolver that scans for subtypes of the Discoverable interface.
Custom Root Class Constructor:
public DiscoverableSubtypeResolver(Class<?> rootKlass)Constructs a resolver that scans for subtypes of the provided root class.
Parameters:
rootKlass (Class<?>): The class to use for selecting the correct META-INF/services filegetDiscoveredSubtypes():
public List<Class<?>> getDiscoveredSubtypes()Returns the list of subtypes discovered from META-INF configuration files.
Returns: List<Class<?>> of discovered subtype classes
getClassLoader():
protected ClassLoader getClassLoader()Returns the ClassLoader from the current class for resource loading.
Returns: Current ClassLoader instance
discoverServices():
protected List<Class<?>> discoverServices(Class<?> klass)Discovers services in META-INF/services folder for the provided class.
Parameters:
klass (Class<?>): The class to lookup services forReturns: List<Class<?>> of discovered service classes
A tag interface that allows Dropwizard to load Jackson subtypes at runtime for polymorphic configurations.
public interface Discoverable {
}Purpose: Marker interface for classes that should be automatically discovered as Jackson subtypes.
// Base configuration class
public abstract class DatabaseConfig implements Discoverable {
public abstract String getType();
}
// PostgreSQL implementation
public class PostgreSQLConfig extends DatabaseConfig {
private String host;
private int port;
private String database;
@Override
public String getType() {
return "postgresql";
}
// constructors, getters, setters...
}
// MySQL implementation
public class MySQLConfig extends DatabaseConfig {
private String connectionUrl;
private String driver;
@Override
public String getType() {
return "mysql";
}
// constructors, getters, setters...
}Create a file at META-INF/services/io.dropwizard.jackson.Discoverable:
com.example.config.PostgreSQLConfig
com.example.config.MySQLConfigObjectMapper mapper = Jackson.newObjectMapper();
// DiscoverableSubtypeResolver is automatically configured
// JSON with type information
String json = """
{
"type": "postgresql",
"host": "localhost",
"port": 5432,
"database": "myapp"
}
""";
DatabaseConfig config = mapper.readValue(json, DatabaseConfig.class);
// Automatically deserializes to PostgreSQLConfig instance// Custom base class for plugin discovery
public abstract class Plugin {
public abstract String getName();
}
// Plugin implementation
public class LoggingPlugin extends Plugin {
private String logLevel;
@Override
public String getName() {
return "logging";
}
// implementation...
}
// Custom resolver for Plugin subtypes
DiscoverableSubtypeResolver pluginResolver = new DiscoverableSubtypeResolver(Plugin.class);
List<Class<?>> pluginTypes = pluginResolver.getDiscoveredSubtypes();
// Register with ObjectMapper
ObjectMapper mapper = new ObjectMapper();
mapper.setSubtypeResolver(pluginResolver);Create META-INF/services/com.example.Plugin:
com.example.plugins.LoggingPlugin
com.example.plugins.SecurityPlugin
com.example.plugins.CachePluginThe resolver handles common issues gracefully:
The resolver is automatically configured with Jackson factory methods:
ObjectMapper mapper = Jackson.newObjectMapper();
// DiscoverableSubtypeResolver is automatically set
ObjectMapper minimal = Jackson.newMinimalObjectMapper();
// Also includes DiscoverableSubtypeResolver for polymorphic support// Discover subtypes at runtime
DiscoverableSubtypeResolver resolver = new DiscoverableSubtypeResolver();
List<Class<?>> subtypes = resolver.getDiscoveredSubtypes();
// Filter subtypes based on runtime conditions
List<Class<?>> enabledSubtypes = subtypes.stream()
.filter(clazz -> isFeatureEnabled(clazz))
.collect(Collectors.toList());
// Create custom resolver with filtered types
ObjectMapper mapper = new ObjectMapper();
mapper.setSubtypeResolver(resolver);Note: The discovery process occurs during resolver construction and scans the entire classpath for applicable service files.
Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard--dropwizard-jackson