Migrating to Dropwizard version 0.7.0 was anything but straightforward so I thought I would share some of the migration changes need for upgrading to the latest release of from version 0.6.x. The Release notes are a good place to start, but beyond that any hints or guides for upgrading are pretty sparse. This will not be a complete guide and will only cover the specific issues I had to deal with. A working example is availbale at our GitHub project called XDropWizard. XDropWizard is a jump-start web application integrating and demonstrating several useful open source projects such as Yank, Sundial (a Quartz fork), Flot, Bootstrap, AngularJS, HSQLDB, XChart, JUnit, etc., and demonstrates how to serve static content, dynamic content loaded into Freemarker templates, using AJAX and more. The README file has clear instructions on how to build and deploy the app using Maven as well as explanations for how to integrate a plethora of capabilities into a Dropwizard-based web application and web service.
Dropwizard Namespace and Jars
Dropwizard’s namespace changed from com.yammer.dropwizard
to io.dropwizard
, so all your import statements and Maven pom
dependencies need to be updated. Several Dropwizard modules were broken up into smaller modules, and it was required that extra dependencies were added to pom.xml
. Following is an excerpt from the upgraded pom
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-core</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-configuration</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-assets</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-views</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>io.dropwizard</groupId> <artifactId>dropwizard-views-freemarker</artifactId> <version>0.7.0</version> </dependency> |
I originally only had the first two dependencies. One thing I struggled with for a while was an error relating to the FreeMarker
views in the application. The error was:
1 |
io.dropwizard.views.ViewRenderException: Unable to find a renderer for /com/xeiam/xdropwizard/views/ftl/book.ftl |
Once I added the dropwizard-views-freemarker
dependency, the error went away.
Dropwizard Configuration (YML) File
Converting the configuration file took the most amount of effort. Apparently the preferred way to access the admin features of Dropwizard is now via the same port as the application, but at a different root URL path. I also wasn’t sure if I should choose the simple
server type of the default
. I ended up using the simple
option. Setting up logging was a pain as well as the official example Dropwizard app’s configuration file is very minimal. Getting my preferred console
and file
logging configured was a pain. I noticed that the yml
file has to be perfectly formatted otherwise starting of the app will fail. Indenting and spacing must be perfect. Below are the before and after versions of the configurations file in XDropWizard.
Before (Version 0.6.x)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
http: port: 9090 adminPort: 9091 rootPath: /service/* # Default is /* logging: level: INFO console: enabled: true threshold: ALL file: enabled: true threshold: ALL currentLogFilename: ./log/xdropwizard.log archivedFileCount: 5 timeZone: UTC sundial: thread-pool-size: 5 shutdown-on-unload: true wait-on-shutdown: false start-delay-seconds: 0 start-scheduler-on-load: true global-lock-on-load: false yank: dbPropsFileName: DB.properties sqlPropsFileName: SQL.properties template: Hello, %s! defaultName: Stranger |
After (Version 0.7.0)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
server: type: simple applicationContextPath: / adminContextPath: /admin connector: type: http port: 9090 logging: level: INFO appenders: - type: console threshold: ALL timeZone: UTC target: stdout - type: file threshold: ALL currentLogFilename: ./log/xdropwizard.log archivedLogFilenamePattern: ./log/xdropwizard-%d.log.gz, archivedFileCount: 5 timeZone: UTC sundial: thread-pool-size: 5 shutdown-on-unload: true wait-on-shutdown: false start-delay-seconds: 0 start-scheduler-on-load: true global-lock-on-load: false yank: dbPropsFileName: DB.properties sqlPropsFileName: SQL.properties template: Hello, %s! defaultName: Stranger |
Service to Application
The Service
class was renamed to Application
, so you’ll need to change that right away. In the initialize
method, I removed the bootstrap.setName("xdropwizard-service");
method as the setName
method seems to have been removed from the API.
Since the XDropWizard webservice root URL was service
, and the option to configure that was no longer available via the configuration file, I added the following line in the run
method:
1 |
environment.jersey().setUrlPattern("/service/*"); |
Resources
Adding resources to the application used to be done like this: environment.addResource(new YankBookResource());
. The new way to do it looks like this: environment.jersey().register(new YankBookResource());
.
Tasks
Adding tasks to the application used to be done like this: environment.addTask(new LockSundialSchedulerTask());
. The new way to do it looks like this: environment.admin().addTask(new LockSundialSchedulerTask());
.
Managed Objects
Adding tasks to the application used to be done like this: environment.manage(sm);
. The new way to do it looks like this: environment.lifecycle().manage(sm);
.
For a completeness, the Application
class is pasted below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
import io.dropwizard.Application; import io.dropwizard.assets.AssetsBundle; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import io.dropwizard.views.ViewBundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.xeiam.xdropwizard.health.TemplateHealthCheck; import com.xeiam.xdropwizard.manager.SundialManager; import com.xeiam.xdropwizard.manager.YankManager; import com.xeiam.xdropwizard.resources.HelloWorldResource; import com.xeiam.xdropwizard.resources.RandomNumberResource; import com.xeiam.xdropwizard.resources.ViewBookResource; import com.xeiam.xdropwizard.resources.ViewMarkdownResource; import com.xeiam.xdropwizard.resources.XChartResource; import com.xeiam.xdropwizard.resources.YankBookResource; import com.xeiam.xdropwizard.task.LockSundialSchedulerTask; import com.xeiam.xdropwizard.task.MyJobTask; import com.xeiam.xdropwizard.task.SampleJob3Task; import com.xeiam.xdropwizard.task.UnlockSundialSchedulerTask; public class XDropWizardService extends Application<XDropWizardServiceConfiguration> { private final Logger logger = LoggerFactory.getLogger(XDropWizardService.class); public static void main(String[] args) throws Exception { new XDropWizardService().run(args); } @Override public void initialize(Bootstrap<XDropWizardServiceConfiguration> bootstrap) { bootstrap.addBundle(new AssetsBundle("/assets/", "/")); bootstrap.addBundle(new ViewBundle()); } @Override public void run(XDropWizardServiceConfiguration configuration, Environment environment) throws Exception { logger.info("running DropWizard!"); environment.jersey().setUrlPattern("/service/*"); final String template = configuration.getTemplate(); final String defaultName = configuration.getDefaultName(); environment.jersey().register(new HelloWorldResource(template, defaultName)); environment.healthChecks().register("TemplateHealth", new TemplateHealthCheck(template)); // MANAGERS ///////////////////////// // Sundial SundialManager sm = new SundialManager(configuration.getSundialProperties()); // A DropWizard Managed Object environment.lifecycle().manage(sm); // Assign the management of the object to the Service // Yank YankManager ym = new YankManager(configuration.getYankConfiguration()); // A DropWizard Managed Object environment.lifecycle().manage(ym); // Assign the management of the object to the Service environment.jersey().register(new YankBookResource()); // TASKS //////////////////////////// // tasks are things that should run triggered by a POST, but don't need to respond environment.admin().addTask(new MyJobTask()); environment.admin().addTask(new SampleJob3Task()); environment.admin().addTask(new LockSundialSchedulerTask()); environment.admin().addTask(new UnlockSundialSchedulerTask()); // RESOURCES //////////////////////////// environment.jersey().register(new XChartResource()); environment.jersey().register(new ViewBookResource()); environment.jersey().register(new ViewMarkdownResource()); environment.jersey().register(new RandomNumberResource()); } } |
Wrap Up
Migrating from DropWizard 0.6.x to 0.7.0 can be a bit tricky due to lack of an official migration guide. I hope some of the above examples are helpful to others.
Subscribe To Our Newsletter
Join our low volume mailing list to receive the latest news and updates from our team.