Aloha,
as Java developer there is sometimes the need for a feature flags when you are following the trunk based development strategy. The project Togglz is a great example to make feature flags viable and easy to use. I found it configuring though sometimes really hard. The documentation is out of date and there are too many ways to configure the plugin for my liking. Let's have a look at the basic configuration for a simple SpringBoot application. For that i used the SpringBoot generator which can be found here. There is also great websites like JHipster which help you configuring SpringBoot applications with web dependencies.
I used gradle for this example but you could also use maven:
// build.gradle
plugins {
id 'org.springframework.boot' version '2.4.3'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation("org.assertj:assertj-core:3.19.0")
// Togglz
implementation("org.togglz:togglz-spring-boot-starter:2.9.6")
}
test {
useJUnitPlatform()
}
What you definitly need is an enum in which you can define the feature flags:
// TogglzFeatures.java
import org.togglz.core.Feature;
import org.togglz.core.annotation.Label;
public enum TogglzFeatures implements Feature {
@Label("Toggle Description")
MY_TOGGLE;
}
These flags are set to false by default and to enable them you need to configure togglz in your application.yaml or application.properties.
//application.properties
togglz.enabled=true
togglz.features.MY_TOGGLE.enabled=true
This configuration should all you would need but in my case this was not enough.
I currently don't know the reason but the something prevented the Togglz libary to supply a bean of UserProvider.class which caused the application to fail on startup. The error message was intiutive as always for java errors: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.togglz.core.user.UserProvider' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
The solution to this problem was to create a configuration class for Togglz and supply the NoOpsUserProvider bean myself.
@Configuration
public class TogglzConfiguration {
@Bean
public FeatureProvider featureProvider() {
return new EnumBasedFeatureProvider(TogglzFeatures.class);
}
@Bean
public UserProvider getUserProvider() {
return new NoOpUserProvider();
}
}
If you had this problem and solved it differently, please let me know in the comments.