Java SDK
Use Flagpool feature flags in Java and JVM applications
The official Java SDK for Flagpool. Evaluate feature flags locally with deterministic rollouts, advanced targeting, and automatic polling. Thread-safe with minimal dependencies.
Installation
Maven
<dependency>
<groupId>io.flagpool</groupId>
<artifactId>flagpool-sdk</artifactId>
<version>0.2.0</version>
</dependency>
Gradle
implementation 'io.flagpool:flagpool-sdk:0.2.0'
Requirements: Java 11+
Quick Start
import io.flagpool.sdk.FlagpoolClient;
import io.flagpool.sdk.Types.ClientOptions;
import java.util.Map;
FlagpoolClient client = new FlagpoolClient(
new ClientOptions()
.setProjectId("your-project-uuid")
.setApiKey("your-api-key")
.setDecryptionKey("your-decryption-key")
.setContext(Map.of(
"userId", "user-123",
"email", "alice@example.com",
"plan", "pro"
))
);
client.init();
// Boolean flag
if (client.isEnabled("new-dashboard")) {
showNewDashboard();
}
// String, number, or JSON flag
String buttonColor = (String) client.getValue("cta-button-color");
// Clean up when done
client.close();
Configuration
FlagpoolClient client = new FlagpoolClient(
new ClientOptions()
// Required
.setProjectId("your-project-uuid")
.setApiKey("your-api-key")
.setDecryptionKey("your-decryption-key")
// Optional
.setContext(Map.of(
"userId", "user-123",
"email", "user@example.com",
"plan", "pro"
))
.setPollingInterval(30) // Auto-refresh interval in seconds (default: 30)
.setUrlOverride(null) // Complete URL override (for self-hosted/testing)
);
| Option | Type | Required | Description |
|---|---|---|---|
projectId | String | Yes | Project UUID from the dashboard |
apiKey | String | Yes | Environment-specific API key |
decryptionKey | String | Yes | For CDN URL hashing and target list decryption |
context | Map<String, Object> | No | User context for targeting rules |
pollingInterval | int | No | Polling interval in seconds (default: 30) |
urlOverride | String | No | Complete URL override for self-hosted setups |
analytics | Analytics.Config | No | Analytics configuration (opt-in) |
API Reference
| Method | Description |
|---|---|
init() | Initialize client and fetch flags (required before evaluation) |
isEnabled(key) | Check if a boolean flag is enabled |
getValue(key) | Get flag value (any type, returned as Object) |
getVariation(key) | Alias for getValue |
getAllFlags() | Get all evaluated flag values as a Map |
updateContext(ctx) | Update user context — flags re-evaluate automatically |
onChange(callback) | Subscribe to flag value changes |
close() | Stop polling and clean up resources |
Flag Types
Boolean Flags
if (client.isEnabled("feature-flag")) {
// Feature is enabled for this user
}
String Flags
String variant = (String) client.getValue("button-color");
// "blue" | "green" | "orange"
Number Flags
Number limit = (Number) client.getValue("rate-limit");
// 100 | 1000 | 10000
JSON Flags
@SuppressWarnings("unchecked")
Map<String, Object> config = (Map<String, Object>) client.getValue("checkout-config");
// {"showCoupons": true, "maxItems": 50, ...}
Dynamic Context Updates
Update user context on the fly — flags re-evaluate automatically:
System.out.println(client.getValue("max-upload-size-mb")); // 10
client.updateContext(Map.of("plan", "pro"));
System.out.println(client.getValue("max-upload-size-mb")); // 100
Real-Time Updates
Flags automatically refresh in the background. Listen for changes:
client.onChange((flagKey, newValue) -> {
System.out.println("Flag " + flagKey + " changed to: " + newValue);
});
Thread Safety
The FlagpoolClient is fully thread-safe. You can safely call getValue(), isEnabled(), and other methods from multiple threads.
Framework Examples
Spring Boot
@Configuration
public class FlagpoolConfig {
@Bean
public FlagpoolClient flagpoolClient() throws Exception {
FlagpoolClient client = new FlagpoolClient(
new ClientOptions()
.setProjectId(System.getenv("FLAGPOOL_PROJECT_ID"))
.setApiKey(System.getenv("FLAGPOOL_API_KEY"))
.setDecryptionKey(System.getenv("FLAGPOOL_DECRYPTION_KEY"))
);
client.init();
return client;
}
}
@RestController
public class MyController {
@Autowired
private FlagpoolClient flagpool;
@GetMapping("/dashboard")
public ResponseEntity<?> dashboard(@RequestHeader("X-User-ID") String userId) {
flagpool.updateContext(Map.of("userId", userId));
if (flagpool.isEnabled("new-dashboard")) {
return ResponseEntity.ok(Map.of("version", "v2"));
}
return ResponseEntity.ok(Map.of("version", "v1"));
}
}
Analytics
Track flag evaluation counts. Analytics is opt-in and disabled by default.
import io.flagpool.sdk.Analytics;
Analytics.Config analyticsConfig = new Analytics.Config()
.setEnabled(true)
.setFlushIntervalMs(60000)
.setFlushThreshold(100)
.setSampleRate(1.0);
FlagpoolClient client = new FlagpoolClient(
new ClientOptions()
.setProjectId("your-project-uuid")
.setApiKey("your-api-key")
.setDecryptionKey("your-decryption-key")
.setAnalytics(analyticsConfig)
);
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable/disable analytics |
flushIntervalMs | long | 60000 | Flush interval in ms (minimum: 30000) |
flushThreshold | int | 100 | Flush after N evaluations |
sampleRate | double | 1.0 | Sample rate (0.0–1.0) |
syncFlushOnShutdown | boolean | false | Flush synchronously on JVM shutdown |
Targeting Operators
| Operator | Description | Example |
|---|---|---|
eq | Equals | plan == "enterprise" |
neq | Not equals | plan != "free" |
in | In list | country in ["US", "CA"] |
nin | Not in list | country not in ["CN", "RU"] |
contains | String contains | email contains "@company.com" |
startsWith | String starts with | userId startsWith "admin-" |
inTargetList | In target list | userId in beta-testers |
notInTargetList | Not in target list | userId not in blocked-users |
Next Steps
- Getting Started — full setup guide
- Using Flags in Code — evaluation patterns across all SDKs