FlagZ - modern flag library for Java/Scala

Travis Build MIT License

A modern, annotation-based flags library for Java and Scala that's tailored for large codebases.

Key features

Paint me a code picture

Let's say your project is more than just a simple CLI utility and consists of multiple packages.

You can define parameters that relate to given functionality inside the relevant package.

package com.example.rpc.client
...

public class MyRpcClientFactory {
  @FlagInfo(name="rpc_client_max_threadpool_size", help="Max threadpool size for RPC client callbacks")
  private static final Flag<Integer> maxThreadPool = Flagz.valueOf(10);

  @FlagInfo(name="rpc_client_default_timeout_s", help="Default timeout (seconds) for RPCs.")
  private static final Flag<Double> defaultRpcTimeoutSec = Flagz.valueOf(1.5);
  ...
}

All @FlagInfo-annotated fields on the classpath will automatically be discovered. Let's say that the server's main looks like:

package com.example.superserver
...

public class Main {
  @FlagInfo(name="daemonize", altName="d", help="Whether to fork off the process,")
  private static final Flag<Boolean> daemonize = Flagz.valueOf(false);

  @FlagInfo(name="bind_addr", help="Bind addresses to listen on")
  private static final Flag<List<String>> bindList = Flagz.valueOf(ImmutableList.of("0.0.0.0:80"));

  ...
  public static void main(String[] args) {
    Flagz.parse(args);
    ...
    for (bind in bindList.Get()) {
      server.BindTo(bind);
    }
    if (daemonize.Get()) {
      server.Fork()
    }
    ...
  }

  ...
}

This means you can start the server as:

$ java com.example.superserver.Main --rpc_client_max_threadpool_size=15 -d

This will start the server in daemon mode, and change the the maxThreadPool field in MyRpcClientFactory without the need for punching through massive configuration objects.

Installing

Maven Packages

To use this flag library, include this in your pom.xml:

<repositories>
  ...
  <repository>
    <id>mwitkow-github-repo</id>
    <url>https://raw.github.com/mwitkow/maven-repos/master</url>
  </repository>
  ...
</repositories>
<dependencies>
  ...
  <dependency>
    <groupId>org.flagz</groupId>
    <artifactId>flagz</artifactId>
    <version>2.2</version>
  </dependency>
  ...
</dependencies>

Development

Obviously git-clone this repo. Then install bazel>=0.3.2, which is a fantastic build system that this project uses. Bazel takes care of downloading all other dependencies (Scala, etcd), the only system requirement is JDK>=8.0.

To run all the tests:

bazel test //...

Publishing (internal stuff)

The way that bazel BUILD files are laid out in this project is along the lines of old Maven packages. This means that each target is a maven-deliverable.

To build all of them using:

bazel build //flagz-java/src/main/java/org/flagz
bazel build //flagz-etcd/src/main/java/org/flagz
bazel build //flagz-scala/src/main/scala/org/flagz

The command line will output you the relevant .jar file containing the distributable. TODO(mwitkow) Add a script for Maven publishing.

Sample Apps

The samples/ directory contains two sample JVM apps that show case what's going on.

You can run the JMX example

bazel run -- //samples/src/main/java/org/flagz/samples:jmx

or (with a running etcd instance) the etcd demo:

bazel run -- //samples/src/main/java/org/flagz/samples:etcd --flagz_etcd_directory=/foo

Status

At Improbable we use flagz-etcd and flagz-scala to dynamically reconfigure our simulation runtime environment, allowing our engineers to quickly iterate on tuning parameters and launch new functionality hidden behind flags.

As such, the code is considered production quality.

License and Copyright

flagz is released under the MIT License. See the LICENSE file for details.

The project was completely written by @mwitkow's as a thread-safe and dynamic version of kennyyu/flags, with only the public interfaces remaining from the old project.