Docs/SDKs/

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)
);
OptionTypeRequiredDescription
projectIdStringYesProject UUID from the dashboard
apiKeyStringYesEnvironment-specific API key
decryptionKeyStringYesFor CDN URL hashing and target list decryption
contextMap<String, Object>NoUser context for targeting rules
pollingIntervalintNoPolling interval in seconds (default: 30)
urlOverrideStringNoComplete URL override for self-hosted setups
analyticsAnalytics.ConfigNoAnalytics configuration (opt-in)

API Reference

MethodDescription
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)
);
OptionTypeDefaultDescription
enabledbooleanfalseEnable/disable analytics
flushIntervalMslong60000Flush interval in ms (minimum: 30000)
flushThresholdint100Flush after N evaluations
sampleRatedouble1.0Sample rate (0.0–1.0)
syncFlushOnShutdownbooleanfalseFlush synchronously on JVM shutdown

Targeting Operators

OperatorDescriptionExample
eqEqualsplan == "enterprise"
neqNot equalsplan != "free"
inIn listcountry in ["US", "CA"]
ninNot in listcountry not in ["CN", "RU"]
containsString containsemail contains "@company.com"
startsWithString starts withuserId startsWith "admin-"
inTargetListIn target listuserId in beta-testers
notInTargetListNot in target listuserId not in blocked-users

Next Steps

Start Managing Feature Flags Today

Join teams who trust Flagpool to deliver features safely and efficiently.

No credit card required • Cancel anytime