Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

What's New In Bootique?

DZone's Guide to

What's New In Bootique?

The Bootique framework just came out with its latest release, including improvements to self-documentation, two new modules, and job hierarchies.

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

More than 3 months have passed since the last Bootique release, as we decided to take it easy and slack through the holidays. Just kidding. Actually, we barely paused the development for Christmas and New Years, though I personally did spend a big part of the last 3.5 months doing other closely related things, namely writing a few interesting and non-trivial Bootique apps (more like multi-module systems than apps). Great experience, very helpful for further framework development. Anyways, Bootique improvements have happened across the board, culminating in 0.21 release featuring 2 new modules and 66 closed tickets.

So let’s go through the release highlights.

Self-Documenting Apps

You probably already know that Bootique apps respond to --help / -h, printing a message with a list of all supported command-line flags. In this release, we took it a step further. Bootique got a new command --help-config / -H that prints two sections of important information, starting with a list of modules present:

MODULES
      BQCoreModule: Bootique core module.
      CayenneModule: Provides integration with Apache Cayenne.
      MyDataModule
      InstrumentedJettyModule
      JdbcModule: Provides configuration for and access to zero or   
              more named JDBC DataSources.
      JettyModule: Integrates Jetty web server in the application.
      LogbackModule: Provides logging based on Logback library.
      MetricsModule


Perhaps more interesting is the second section, CONFIGURATION, that includes a long doc with YAML-style indentation describing the structure and meaning of the configuration tree for a particular module collection. Here is just a small part of a typical CONFIGURATION:

CONFIGURATION
jdbc:
      #
      # Resolved as 
      # 'Map<String, io.bootique.jdbc.TomcatDataSourceFactory>'.
      #
      <string>:
            #
            # Pooling JDBC DataSource configuration.
            # Resolved as 
            # 'io.bootique.jdbc.TomcatDataSourceFactory'.
            #
            commitOnReturn: <true|false>
            defaultAutoCommit: <true|false>
            driverClassName: <string>
            maxActive: <int>
            maxAge: <long>
            maxIdle: <int>
            maxWait: <int>
            minIdle: <int>
            password: <string>
            rollbackOnReturn: <true|false>
            url: <string>
            username: <string>
            ...


This feature alone will make you a hero of your ops group, giving them the ability to figure out configuration format just by looking at the app. Our apologies in advance if you encounter missing or partial configuration info in some of the standard modules. We documented most of them and will need to finish a few more in the following releases.

And of course you can (and should) document your own modules. The trick is to list all your configuration “roots” in BQModuleProvider (those factory classes that are created from configuration data). Usually, there’s just one root factory type per module, but who knows, maybe your module needed more. Here is an example from the bootique-logback module:

public class LogbackModuleProvider implements BQModuleProvider {
    @Override
    public Map<String, Type> configs() {
        return Collections
             .singletonMap("log", LogbackContextFactory.class);
    }
}


Now, go to each root factory class and annotate the class with @BQConfig, and each property setter — with @BQConfigProperty, entering text descriptions inside the annotation. You need to annotate setters, as they accept configuration properties during factory construction; you may not even have a getter for any given property.

@BQConfig
public class LogbackContextFactory {
    @BQConfigProperty("One or more appenders ...")
    public void setAppenders(Collection<AppenderFactory> appenders) {
        this.appenders = appenders;
    }
    @BQConfigProperty("If true, debugging information will be " +
        "printed to console.")
    public void setDebugLogback(boolean debugLogback) {
        this.debugLogback = debugLogback;
    }
}


If any of the configuration properties are not simple values, but rather objects with the properties of their own, annotate the entire object tree recursively. Same applies to collections and maps of such objects. E.g. in the example above, the AppenderFactory class will be annotated with @BQConfig just like LogbackContextFactory.

Job Hierarchies

The bootique-job module is special. It does not integrate any third-party technologies, but actually implements its own job execution framework. This release adds a long-thought feature — job groups, whose purpose is coordination of execution of multiple jobs. A job group is simply a tree of jobs defined in configuration that can be run as a single job:

jobs:
  mygroup:
    type: group
    jobs:
      job1:
        dependsOn:
          - job2
      job2: {}
      job3: {}


When the group is executed, Bootique will automatically figure out which jobs can run in parallel and which have to wait for other jobs to finish. In the example above, it will initially fire up job2 and job3. And once job2 is finished, it will start job1.

New Modules: JCache and Flyway

The list of technologies supported by Bootique out of the box is growing. This release adds two more — bootique-jcache and bootique-flyway. The former supports embedding cache engines that are compatible with JCache specification (EhCache, Hazelcast, etc.). This works kind of like JDBC — bootique-jdbc is driver-agnostic and will work with any driver you place on the classpath. Same story with bootique-jcache — it will work with any JCache provider that you add to your app.

As the name implies, bootique-flyway integrates Flyway, a popular SQL migration framework. We’ve already had bootique-liquibase module serving the same purpose, but some people prefer Flyway, and we don’t want to limit their choices.

Everything Else

A few other modules received their own improvements.

We kept refining test utilities for relational databases. Both bootique-jdbc-test and bootique-cayenne-test received a facelift and lots of bugs got fixed. So now you can easily and reliably manage test DB data.

Bootique-cayenne got upgraded to the latest Cayenne 4.0.M4 that was released in December. It also features integration with bootique-jcache and allows you to import DataMaps in the project without cayenne-project.xml.

Bootique-tapestry has evolved from a very basic adapter into a full-featured Tapestry integration module with support for various contributions, including those of Tapestry’s own DI modules.

Full release notes were posted on the Bootique forum already, so I won’t be reposting them here. Also, make sure you scan through upgrade instructions before updating your apps.

Follow us on Twitter: Bootique project and myself.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
java ,bootique ,documentation

Published at DZone with permission of Andrus Adamchik, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}