A Guide to Getting Started Quickly with the Feature Toggle in Java

Oct 31, 2018

This is the first post I wrote for the Rollout blog. The original is here. I’ve had a lot of fun playing with the feature flag posts, and it’s something I plan on adding the enviornment at the day job soon.


Feature toggles (also known as feature flags) are simple. You want to introduce new behavior in a Java application, but you’re not ready to turn it on right away, or you only want to make it available for a subset of users. Maybe another application needs to be ready for the new feature; perhaps the business isn’t prepared to support it yet.

So you add a feature toggle to your configuration file or the command line, default it to “off,” and move on.

I don’t blame you if you think there’s something more to it. Sometimes changing configuration is as difficult as pushing new code, and slapping booleans into your code feels superficial.

You’re right. There is more. There’s feature flag management. Instead of using conditionals that will inevitably turn into technical debt, you can include feature flags as part of a strategy for improving your code and your ability to support it.

This post will tackle feature flag management in Java. We’ll start with a simple flag to control a new feature, and then we’ll integrate it into Rollout’s secure feature management system.

Basic Feature Toggles for Java

For this tutorial, I’m using a small application called SimpleXKCDClient. You can grab a local copy from here. It uses OkHttp to download JSON information about XKCD comics from the XKCD REST service. As the name implies, it’s simple and gives us a way to focus on feature toggles. We’ll use JUnit tests to illustrate how the toggles change the application behavior.

Here’s a Java representation of an XKCD comic:

public class XKCDComic {
    private String month;
    private int num;
    private String year;
    private String news;
    private String safe_title;
    private String transcript;
    private String alt;
    private String img;
    private String title;
    private String day;
    private String link;

Initially, the client retrieves my favorite comic from XKCD:

private String REST_URI = "https://xkcd.com/386/info.0.json";

public XKCDComic getComic() {

    Request request = new Request.Builder().url(REST_URI).build();

    try (Response response = httpClient.newCall(request).execute()) {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(response.body().bytes(), XKCDComic.class);
    } catch(IOException ioe) {
        return null;


We can verify that we retrieved the correct comic with this unit test:

public void givenRequest_ComicIsDutyCalls() {
    XKCDComic XKCDComic = simpleXKCDClient.getComic();
    assertEquals("Duty Calls", XKCDComic.getTitle());

So let’s add a new feature. We want to load a different comic during the holidays.

boolean holidaySeason = true;

public XKCDComic getComic() {

    if (holidaySeason) {
        REST_URI = "https://xkcd.com/521/info.0.json";

    Request request = new Request.Builder().url(REST_URI).build();

    try (Response response = httpClient.newCall(request).execute()) {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(response.body().bytes(), XKCDComic.class);
    } catch(IOException ioe) {
        return null;

Then we’ll add a new test that checks for a different title:

public void givenHolidays_ComicsIsXMasSpecial() {
    XKCDComic XKCDComic = simpleXKCDClient.getComic();
    assertEquals("2008 Christmas Special", XKCDComic.getTitle());

We’ve added our first feature flag. If holidaySeason is true, we retrieve a different comic.

An Introduction to Feature Flag Management

Of course, to activate the different behavior, we have to change the code, build, and deploy. That’s not a feature flag. We want to turn features on and off without touching any code.

Before fully delving into the management features that Rollout gives us, let’s make another small but still significant change to SimpleXKCDClient.

Getting the Configuration Out of Code

Getting the feature toggle out of code is the first step in managing it. Opening code and changing it is not only unmaintainable; it’s not toggling features. It’s deploying new releases.

Let’s create a configuration file:


We’ll call it application.properties.

Then let’s override the default constructor to load the configuration file:

public SimpleXKCDClient() throws Exception {
    InputStream props = new FileInputStream(“src/test/resources/application.properties”);
    holidaySeason = Boolean.parseBoolean(Optional.of(System.getProperty(“holidaySeason”)).orElse(“false”));

Now we can edit the properties file to set holidaySeason to true or false and watch the results of our tests change.

Managing Feature Flags Centrally

We’ve done a limited version of feature flag management that requires distributing and modifying configuration files to toggle features  Let’s look at a better way.

Getting Started With Rollout

First, you’ll need to create a free Rollout account.

Sign in with your account and create a new app:

Create New App dialog on Rollout.io
Be sure to select Java and Java Server, as shown.

Next, you’ll see instructions for adding Rollout to your application:

Java Installation instructions on Rollout.io

Add the Rollout library to your dependencies. At the time of this writing, the current version of the library is 2.0.1. Here’s my Gradle.build:

dependencies {
    compile group: ‘com.squareup.okhttp3’, name: ‘okhttp’, version: ‘3.10.0’
    compile group: ‘io.rollout.rox’, name: ‘rox-java-server’, version: ‘2.0.1’
    compile group: ‘com.fasterxml.jackson.core’, name:’jackson-databind‘, version:’2.9.4’
    compileonly group: ‘org.projectlombok’, name: ‘lombok’, version: ‘1.16.20’
    testCompile group: ‘junit’, name: ‘junit’, version: ‘4.12’

Next, add the call to Rox.setup() to initialize the SDK, using your application key.

SimpleXKCDClient() throws Exception {
    // Initialize ROllout
    Rox.setup(“replace with your application key”);

Back on the Rollout website, click Next for the prompt to build and run your application.

Build and Run DialogBuild and run it, and you’re rewarded after a few moments.Success Dialog

Implementing a Feature Flag

Now, let’s turn holidaySeason into a managed feature flag. Managed flags are RoxFlags:

public class Flags implements RoxContainer {
    public RoxFlag holidaySeason = new RoxFlag();

They’re public members of a RoxContainerIn this example, holidaySeason is created with its default value disabled. RoxFlag will also accept a boolean value as an argument to its constructor as a default value.

Next, we can modify our constructor to create the container and register it.

SimpleXKCDClient() throws Exception {

    // Create Rollout container
    flags = new Flags();

    // Register container with Rollout
    Rox.register("Flags", flags);

    // Initialize Rollout
    Rox.setup("your app key");

Run the application again, and then look for your feature toggle in the Rollout dashboard:

Feature Toggle Dashboard on Rollout.io

It’s there!

In our application, we’re downloading a document via REST and exiting. Since the feature toggle determines which document we request, we want to update the value of our flag from Rollout before we make the REST request.

Rollout’s API is asynchronous, so we need to do a little bit of extra work to ensure that we have the correct flag setting before the REST request is initiated. Rollout has more information on how flags are updated here.

We can install a configuration fetched handler that Rollout will call after the configuration is received. By using this callback to set a CountdownLatch, we can block until we’re ready.

Let’s move the Rollout initialization to a private method and install the callback. Then we’ll call this new method from our constructor:

private void initializeRox() {
    CountDownLatch roxFirstFetch = new CountDownLatch(1);
    try {
        flags = new Flags();
        Rox.register("Flags", flags);

        RoxOptions options = new RoxOptions.Builder()
            new ConfigurationFetchedHandler() {
                public void onConfigurationFetched(FetcherResults arg0) {
                    if (roxFirstFetch.getCount() > 0) {
                        System.err.println("Got Rollout configuration");

        Rox.setup("your key", options);
        roxFirstFetch.await(10, TimeUnit.SECONDS);
    } catch (InterruptedException ie) {
        System.err.println("Interrupted waiting for rollout data.");

We’re ready to start setting our flag from the management console.

Managing a Feature Flag

We manage flags by adding them to experiments. An experiment is a scheme for controlling flags (and other variables) in production.

Click on Production in the left-hand side menu, and then click Experiments. This will bring up a screen with a Create Experiment button.  Click that, and then fill the new experiment window out appropriately.

New Experiment Dialog on Rollout.io
Select Set Audience.

Experiment Dashboard

And we see a console for setting flags to true, false, or split.

If we run our tests now, we see that holidaySeason is false.

Let’s change it to true.

When we run our tests again, the results are reversed!

We can change the behavior of our application without touching code or configuration files.

Before we wrap up, let’s take a look at the experiment on the console again. Flip the flag from true to split.

Split Settings for a Feature Toggle

We don’t just have the ability to change the application behavior from the console; we can also experiment (hence the name) with how often the application loads the different comic.

This is the power of feature flags

This Is Just the Beginning

This guide is intended to show you how to get started with Rollout in a Java project. Rollout’s documentation has details on how you can do a great deal more with flags, experiments, groupings, and the management console.

You now have an understanding of feature flag management and how it can improve your Java code and help you manage your projects. Get to it!


Photo credit: Nolan Isaac.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.