### Complete Callback Integration Example Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md This example demonstrates how to configure GrowthBookClient with various callbacks for tracking experiment assignments, feature evaluations, and handling feature refresh events. It includes methods for initializing the client and retrieving it. ```java class AnalyticsIntegration { private final GrowthBookClient client; private final AnalyticsService analytics; public AnalyticsIntegration(AnalyticsService analytics) { this.analytics = analytics; // Configure callback-enabled options Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .trackingCallBackWithUser((userId, exp, result) -> { onExperimentAssignment(userId, exp, result); }) .featureUsageCallbackWithUser((userId, key, result) -> { onFeatureEvaluated(userId, key, result); }) .featureRefreshCallback(new FeatureRefreshCallback() { @Override public void onRefresh(String featuresJson) { onFeaturesRefreshed(featuresJson); } @Override public void onError(Throwable throwable) { onRefreshError(throwable); } }) .build(); this.client = new GrowthBookClient(options); } private void onExperimentAssignment(String userId, Experiment exp, ExperimentResult result) { if (result.getInExperiment()) { analytics.track("experiment_enrolled", Map.of( "user_id", userId, "experiment_key", exp.getKey(), "variation_id", result.getVariationId(), "variation_name", result.getName() )); } } private void onFeatureEvaluated(String userId, String featureKey, FeatureResult result) { analytics.track("feature_evaluated", Map.of( "user_id", userId, "feature_key", featureKey, "source", result.getSource().toString(), "is_on", result.isOn() )); } private void onFeaturesRefreshed(String featuresJson) { System.out.println("Features refreshed from API"); // Update metrics, cache, etc. } private void onRefreshError(Throwable throwable) { System.err.println("Feature refresh error: " + throwable.getMessage()); // Handle error appropriately } public void initialize() { client.initialize(); } public GrowthBookClient getClient() { return client; } } ``` -------------------------------- ### URL Override Examples Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Examples of URL parameters for enabling specific features or experiments. Use `gb_{feature_key}` for features and `gb_exp_{experiment_key}` for experiments. ```text ?gb_dark_mode=true ``` ```text ?gb_max_retries=5 ``` ```text ?gb_exp_button_color=1 ``` -------------------------------- ### Basic Multi-User Setup and Initialization Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Configure GrowthBook options and initialize a shared client instance for multi-user environments. Use lightweight UserContext for each request. ```java import growthbook.sdk.java.multiusermode.GrowthBookClient; import growthbook.sdk.java.multiusermode.configurations.*; // Configure options once Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123xyz") .cacheMode(CacheMode.FILE) .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) .swrTtlSeconds(120) .build(); // Create singleton client GrowthBookClient client = new GrowthBookClient(options); client.initialize(); // For each user request, create lightweight UserContext UserContext userContext = UserContext.builder() .attributesJson("{\"user_id\": \"user123\", \"plan\": \"premium\"}") .build(); // Evaluate features for this user if (client.isOn("premium_features", userContext)) { // Show premium UI } // Run experiment for this user ExperimentResult result = client.run(experiment, userContext); ``` -------------------------------- ### Example TrackingCallback Implementation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md An example of implementing the TrackingCallback to track experiment enrollments, sending data to an event tracking system. ```java GBContext context = GBContext.builder() .trackingCallback((experiment, result) -> { if (result.getInExperiment()) { // Send to event tracking system eventTracker.trackExperimentEnrollment( experiment.getKey(), result.getVariationId(), result.getHashValue() ); } }) .build(); ``` -------------------------------- ### Configure Production Environment Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Example configuration for a production environment. Utilizes persistent file caching and Server-Sent Events for real-time updates. ```java Options options = Options.builder() .isQaMode(false) .enabled(true) .cacheMode(CacheMode.FILE) // Persistent cache .cacheDirectory("/var/cache/growthbook") .refreshStrategy(FeatureRefreshStrategy.SERVER_SENT_EVENTS) // Real-time .build(); ``` -------------------------------- ### Run a Multi-Variation Experiment Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Example of setting up an experiment with multiple variations (three price points in this case) and custom weights. The experiment key is 'pricing_test'. ```java Experiment experiment = Experiment.builder() .key("pricing_test") .variations(Arrays.asList(99, 149, 199)) // Three price points .weights(Arrays.asList(0.33f, 0.33f, 0.34f)) .build(); ExperimentResult result = growthBook.run(experiment); Integer price = result.getValue(); ``` -------------------------------- ### Configure Development Environment Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Example configuration for a development environment. Uses in-memory caching and Stale-While-Revalidate refresh strategy with a shorter TTL. ```java Options options = Options.builder() .isQaMode(false) .enabled(true) .cacheMode(CacheMode.MEMORY) // No persistence .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) .swrTtlSeconds(30) // More frequent updates .build(); ``` -------------------------------- ### GrowthBook SDK Initialization Example Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/configuration.md Demonstrates how to create a GBContext object using the builder pattern and initialize the GrowthBook SDK with the configured context. User attributes and feature data are provided. ```java GBContext context = GBContext.builder() .attributesJson("{\"user_id\": \"user123\", \"country\": \"US\", \"plan\": \"premium\"}") .featuresJson(featuresJsonString) .encryptionKey(null) .enabled(true) .isQaMode(false) .url("https://app.example.com/dashboard") .build(); GrowthBook growthBook = new GrowthBook(context); ``` -------------------------------- ### Example FeatureUsageCallback Implementation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md An example of how to implement the FeatureUsageCallback to log feature evaluations and send data to an analytics system. ```java GBContext context = GBContext.builder() .featureUsageCallback((key, result) -> { // Track feature evaluation System.out.println("Feature evaluated: " + key); System.out.println("Source: " + result.getSource()); System.out.println("Value: " + result.getValue()); // Send to analytics analytics.track("feature_evaluated", "feature_key", key, "source", result.getSource(), "value", result.getValue()); }) .build(); ``` -------------------------------- ### Build UserContext with Attributes and URL Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/configuration.md Example of creating a UserContext instance using the builder pattern, setting user attributes and the current URL. ```java UserContext userContext = UserContext.builder() .attributesJson("{\"user_id\": \"user123\", \"email\": \"user@example.com\", \"plan\": \"premium\"}") .url("https://app.example.com/settings") .build(); ``` -------------------------------- ### Example ExperimentRunCallback Implementation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md An example implementation of the ExperimentRunCallback interface. This snippet demonstrates how to subscribe to experiment assignment changes and track user assignments in analytics. ```java growthBook.subscribe((experiment, result) -> { if (result.getInExperiment()) { // User is in experiment System.out.println("Experiment: " + experiment.getKey()); System.out.println("Variation: " + result.getVariationId()); System.out.println("Value: " + result.getValue()); // Track in analytics analytics.track("experiment_assignment", experiment.getKey(), result.getVariationId()); } else { // User not qualified System.out.println("User not in experiment pool"); } }); ``` -------------------------------- ### Basic GrowthBook SDK Setup and Usage Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Initialize the GrowthBook SDK with user attributes and features, then evaluate feature flags and run experiments. This is suitable for per-user or per-request SDK instances. ```java import growthbook.sdk.java.GrowthBook; import growthbook.sdk.java.model.*; // Create context with user attributes and features GBContext context = GBContext.builder() .attributesJson("{\"user_id\": \"user123\", \"country\": \"US\"}") .featuresJson(featuresJsonFromAPI) .build(); // Create SDK instance GrowthBook growthBook = new GrowthBook(context); // Check if feature is on if (growthBook.isOn("new_dashboard")) { // Show new dashboard } // Get typed feature value String theme = growthBook.getFeatureValue("theme_color", "light"); // Run an experiment Experiment exp = Experiment.builder() .key("button_color_test") .variations(Arrays.asList("blue", "red", "green")) .weights(Arrays.asList(0.33f, 0.33f, 0.34f)) .build(); ExperimentResult result = growthBook.run(exp); if (result.getInExperiment()) { String buttonColor = result.getValue(); } ``` -------------------------------- ### Migrate from GBContext to UserContext Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Example demonstrating the migration from the older single-user GBContext API to the new multi-user UserContext API with GrowthBookClient. Shows initialization and usage with UserContext. ```java // Old (single-user) GBContext context = GBContext.builder() .attributesJson("{\"user_id\": \"123\"}") .featuresJson(features) .build(); GrowthBook gb = new GrowthBook(context); // New (multi-user) Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .build(); GrowthBookClient client = new GrowthBookClient(options); client.initialize(); UserContext userContext = UserContext.builder() .attributesJson("{\"user_id\": \"123\"}") .build(); // Same evaluation methods client.isOn("feature", userContext); client.run(experiment, userContext); ``` -------------------------------- ### Create GrowthBookClient with Default Options Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-client.md Use this constructor to create a GrowthBookClient instance with default configuration settings. No specific setup is required beyond calling the constructor. ```java public GrowthBookClient() ``` -------------------------------- ### Complete UserContext Example Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/user-context.md Demonstrates how to build a comprehensive UserContext object with various settings like attributes, URL, and forced variations, and then use it with a GrowthBookClient to evaluate features and run experiments. ```java // Build comprehensive user context UserContext userContext = UserContext.builder() .attributesJson("{\"user_id\": \"user123\", \"email\": \"user@example.com\", \"plan\": \"premium\", \"country\": \"US\", \"company_id\": \"acme-corp\", \"created_at\": \"2023-01-15\", \"ltv\": 5000.00}") .url("https://app.example.com/settings") .forcedVariationsMap(Map.of( "checkout_redesign", 1, "feature_beta", 0 )) .forcedFeatureValues(Map.of( "new_dashboard", true, "discount_percent", 0.10 )) .build(); // Use with GrowthBookClient GrowthBookClient client = new GrowthBookClient(options); client.initialize(); // Evaluate features for this user FeatureResult dashboard = client.evalFeature("dashboard_style", String.class, userContext); // Run experiments for this user ExperimentResult checkoutResult = client.run(checkoutExperiment, userContext); ``` -------------------------------- ### Initialize GrowthBookClient with Options Builder Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/configuration.md Example of initializing the GrowthBookClient using the Options builder. This demonstrates setting essential parameters like API host, client key, and enabling specific features and caching modes. ```java Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123xyz") .enabled(true) .isQaMode(false) .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) .swrTtlSeconds(120) .cacheMode(CacheMode.FILE) .globalAttributes(JsonObject.parseJson("{\"app_version\": \"2.1.0\"}")) .build(); GrowthBookClient client = new GrowthBookClient(options); client.initialize(); ``` -------------------------------- ### GrowthBookClient() Constructor Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-client.md Creates a GrowthBookClient instance with default configuration options. This constructor is suitable for basic setups where default settings are sufficient. ```APIDOC ## GrowthBookClient() ### Description Creates a GrowthBookClient with default options. ### Returns GrowthBookClient instance with default configuration ``` -------------------------------- ### Maven Installation for GrowthBook SDK Java Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/README.md Configure your Maven project to use the jitpack.io repository and add the GrowthBook SDK for Java as a dependency. ```xml jitpack.io https://jitpack.io com.github.growthbook growthbook-sdk-java 0.5.0 ``` -------------------------------- ### SSE Endpoint URL Format Example Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Shows the URL format for the GrowthBook Server-Sent Events (SSE) endpoint, which includes a query parameter to enable SSE. ```text {apiHost}/api/features/{clientKey}?sse=true ``` -------------------------------- ### Example: Handling Feature Refresh Errors Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md Provides an example of implementing the FeatureRefreshCallback to handle errors during feature refresh. It shows how to check for specific exceptions like FeatureFetchException and log relevant error details. ```java repository.onFeaturesRefresh(new FeatureRefreshCallback() { @Override public void onRefresh(String featuresJson) { System.out.println("Refresh successful"); } @Override public void onError(Throwable throwable) { if (throwable instanceof FeatureFetchException) { FeatureFetchException e = (FeatureFetchException) throwable; System.err.println("Error code: " + e.getErrorCode()); } System.err.println("Refresh failed: " + throwable.getMessage()); } }); ``` -------------------------------- ### Custom DatabaseStickyBucketService Implementation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Example of a custom sticky bucket service that integrates with a database for persistence. It includes error handling for database operations. ```java public class DatabaseStickyBucketService implements StickyBucketService { private final Database db; public DatabaseStickyBucketService(Database db) { this.db = db; } @Override public StickyAssignmentsDocument getAssignments(String attributeName, String attributeValue) { try { return db.queryDocument(attributeName, attributeValue); } catch (Exception e) { logger.error("Failed to get sticky assignment", e); return null; // Fallback to regular hashing } } @Override public void saveAssignments(StickyAssignmentsDocument doc) { try { db.saveOrUpdate(doc); } catch (Exception e) { logger.error("Failed to save sticky assignment", e); // SDK still returns variation to user } } @Override public Map getAllAssignments(Map attributes) { Map result = new HashMap<>(); for (Map.Entry entry : attributes.entrySet()) { StickyAssignmentsDocument doc = getAssignments(entry.getKey(), entry.getValue()); if (doc != null) { String key = entry.getKey() + "||" + entry.getValue(); result.put(key, doc); } } return result; } } // Usage growthBook.setOwnStickyBucketService(new DatabaseStickyBucketService(db)); ``` -------------------------------- ### Run an A/B Test with Targeting Conditions Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md This example demonstrates running an experiment with specific targeting conditions, ensuring only users from the US with 'pro' or 'enterprise' plans are included. The experiment key is 'us_premium_test'. ```java JsonObject condition = JsonObject.parseJson( "{\"country\": {\"$eq\": \"US\"}, \"plan\": {\"$in\": [\"pro\", \"enterprise\"]}}" ); Experiment experiment = Experiment.builder() .key("us_premium_test") .variations(Arrays.asList("control", "variant")) .conditionJson(condition) .build(); ExperimentResult result = growthBook.run(experiment); ``` -------------------------------- ### Configure Namespace for Experiment Collision Avoidance Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Set up a namespace to ensure users are consistently bucketed and to prevent experiments from interfering with each other. Only the first 50% of users are included in this example namespace. ```java Namespace namespace = new Namespace(); namespace.setNamespace("pricing_tests"); namespace.setStart(0.0f); namespace.setEnd(0.5f); // Only first 50% of users Experiment exp = Experiment.builder() .key("pricing_test_v2") .variations(Arrays.asList("old_pricing", "new_pricing")) .namespace(namespace) .build(); ``` -------------------------------- ### DatabaseStickyBucketService (Custom Implementation) Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md An example of a custom implementation of StickyBucketService that persists assignments to a database. This allows for persistent sticky bucketing across application restarts. ```APIDOC ## DatabaseStickyBucketService (Custom Implementation) An example custom implementation of `StickyBucketService` using a database for persistence. ### Usage ```java // Assuming 'db' is an instance of your Database class growthBook.setOwnStickyBucketService(new DatabaseStickyBucketService(db)); ``` ### Class Definition ```java public class DatabaseStickyBucketService implements StickyBucketService { private final Database db; public DatabaseStickyBucketService(Database db) { this.db = db; } @Override public StickyAssignmentsDocument getAssignments(String attributeName, String attributeValue) { try { return db.queryDocument(attributeName, attributeValue); } catch (Exception e) { logger.error("Failed to get sticky assignment", e); return null; // Fallback to regular hashing } } @Override public void saveAssignments(StickyAssignmentsDocument doc) { try { db.saveOrUpdate(doc); } catch (Exception e) { logger.error("Failed to save sticky assignment", e); // SDK still returns variation to user } } @Override public Map getAllAssignments(Map attributes) { Map result = new HashMap<>(); for (Map.Entry entry : attributes.entrySet()) { StickyAssignmentsDocument doc = getAssignments(entry.getKey(), entry.getValue()); if (doc != null) { String key = entry.getKey() + "||" + entry.getValue(); result.put(key, doc); } } return result; } } ``` ``` -------------------------------- ### Subscribe to Experiment Changes Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/configuration.md Example of subscribing to experiment changes using GrowthBook's subscribe method. This is useful for tracking experiment enrollments. ```java growthBook.subscribe((experiment, result) -> { if (result.getInExperiment()) { analyticsService.track("experiment_enrolled", experiment.getKey(), result.getVariationId()); } }); ``` -------------------------------- ### Run an Experiment in Java Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Use the `run()` method to execute an experiment and get the result. Ensure the `Experiment` object is properly configured with key, variations, weights, and hash attributes. ```java public ExperimentResult run( Experiment experiment ) ``` ```java Experiment exp = Experiment.builder() .key("button_color_test") .variations(Arrays.asList("blue", "red", "green")) .weights(Arrays.asList(0.33f, 0.33f, 0.34f)) .hashAttribute("user_id") .build(); ExperimentResult result = growthBook.run(exp); if (result.getInExperiment()) { String buttonColor = result.getValue(); // "blue", "red", or "green" } ``` -------------------------------- ### GrowthBook SDK Setup with Callbacks Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Configure the GrowthBook SDK with custom tracking and feature usage callbacks. The tracking callback is invoked when an experiment result is recorded, and the feature usage callback is called whenever a feature is evaluated. ```java GBContext context = GBContext.builder() .attributesJson("{\"user_id\": \"123\"}") .featuresJson(featuresJson) .trackingCallback((exp, result) -> { if (result.getInExperiment()) { analytics.track("experiment_enrolled", exp.getKey()); } }) .featureUsageCallback((key, result) -> { System.out.println("Feature " + key + " evaluated"); }) .build(); GrowthBook gb = new GrowthBook(context); ``` -------------------------------- ### Features Endpoint URL Format Example Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Illustrates the standard URL format for the GrowthBook Features API endpoint, including placeholders for the API host and client key. ```text {apiHost}/api/features/{clientKey} ``` ```text https://cdn.growthbook.io/api/features/sdk-abc123xyz ``` -------------------------------- ### Example: Handling Successful Feature Refresh Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md Demonstrates how to use the onRefresh callback to log feature refresh events and count the number of updated features. This is useful for monitoring and debugging. ```java repository.onFeaturesRefresh((featuresJson) -> { System.out.println("Features refreshed"); logger.info("New feature count: " + JsonParser.parseString(featuresJson).getAsJsonObject().size()); }); ``` -------------------------------- ### Monitor Callback Performance Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md Log callback execution times in production to monitor performance. This example measures the time taken for an analytics tracking call within a callback. ```java growthBook.subscribe((exp, result) -> { long start = System.nanoTime(); try { analytics.track("experiment_enrolled", exp.getKey()); } finally { long elapsed = System.nanoTime() - start; metrics.recordCallbackTime(elapsed); } }); ``` -------------------------------- ### Configure Identifier Attributes for Sticky Bucketing Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Sets the attributes to be used for identifying users in sticky bucketing. This example uses 'user_id' as the primary identifier and 'session_id' as a fallback. ```java Options options = Options.builder() .stickyBucketIdentifierAttributes(Arrays.asList( "user_id", // Primary identifier "session_id" // Fallback for anonymous users )) .build(); ``` -------------------------------- ### Redis Sticky Bucket Service Implementation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Implements the StickyBucketService interface using Redis for storing and retrieving sticky assignments. Includes methods for getting, saving, and retrieving all assignments. ```java public class RedisStickyBucketService implements StickyBucketService { private final RedisClient redis; @Override public StickyAssignmentsDocument getAssignments(String attributeName, String attributeValue) { String key = "sticky:" + attributeName + ":" + attributeValue; String json = redis.get(key); if (json != null) { return gson.fromJson(json, StickyAssignmentsDocument.class); } return null; } @Override public void saveAssignments(StickyAssignmentsDocument doc) { String key = "sticky:" + doc.getAttributeName() + ":" + doc.getAttributeValue(); String json = gson.toJson(doc); redis.setex(key, 86400, json); // Expire after 24 hours } @Override public Map getAllAssignments(Map attributes) { Map result = new HashMap<>(); for (Map.Entry entry : attributes.entrySet()) { StickyAssignmentsDocument doc = getAssignments(entry.getKey(), entry.getValue()); if (doc != null) { result.put(entry.getKey() + "||" + entry.getValue(), doc); } } return result; } } ``` -------------------------------- ### Feature Evaluation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/README.md Methods for evaluating feature flags and retrieving their values. These methods allow you to check if a feature is on/off, get its specific value, or get a detailed feature result object. ```APIDOC ## Feature Evaluation ### Description Methods for evaluating feature flags and retrieving their values. These methods allow you to check if a feature is on/off, get its specific value, or get a detailed feature result object. ### Methods #### `GrowthBook.evalFeature(key, type)` - **Description**: Evaluates a feature flag by its key and returns a `FeatureResult` object. - **Returns**: `FeatureResult` #### `GrowthBook.isOn(key)` - **Description**: Checks if a feature flag is enabled. - **Returns**: `Boolean` #### `GrowthBook.isOff(key)` - **Description**: Checks if a feature flag is disabled. - **Returns**: `Boolean` #### `GrowthBook.getFeatureValue(key, default)` - **Description**: Retrieves the value of a feature flag, returning a default value if the feature is not found or disabled. - **Returns**: Type-specific #### `GrowthBookClient.evalFeature(key, type, context)` - **Description**: Evaluates a feature flag with a specific user context. - **Returns**: `FeatureResult` #### `GrowthBookClient.isOn(key, context)` - **Description**: Checks if a feature flag is enabled for a specific user context. - **Returns**: `Boolean` #### `GrowthBookClient.getFeatureValue(key, default, type, context)` - **Description**: Retrieves the value of a feature flag for a specific user context. - **Returns**: Type-specific ``` -------------------------------- ### getAttributes() Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/user-context.md Gets user attributes as a JsonObject. ```APIDOC ## getAttributes() ### Description Gets user attributes as JsonObject. ### Method ```java public JsonObject getAttributes() ``` ### Response #### Success Response - **JsonObject of attributes** ``` -------------------------------- ### Manually Initialize GBContext, Repository, and Growthbook Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/README.md Manually create a features repository with optional refresh strategy and callbacks. Initialize the repository, then create a GBContext and GrowthBook instance. ```java GBFeaturesRepository featuresRepository = GBFeaturesRepository .builder() .apiHost("https://cdn.growthbook.io") .clientKey("") // replace with your client key .encryptionKey("") // optional, nullable .refreshStrategy(FeatureRefreshStrategy.SERVER_SENT_EVENTS) // optional; options: STALE_WHILE_REVALIDATE, SERVER_SENT_EVENTS (default: STALE_WHILE_REVALIDATE) .build(); // Optional callback for getting updates when features are refreshed featuresRepository.onFeaturesRefresh(new FeatureRefreshCallback() { @Override public void onRefresh(String featuresJson) { System.out.println("Features have been refreshed"); System.out.println(featuresJson); } @Override public void onError(Throwable throwable) { System.out.println("Features refreshed with error"); } }); try { featuresRepository.initialize(); } catch (FeatureFetchException e) { // TODO: handle the exception e.printStackTrace(); } // Initialize the GrowthBook SDK with the GBContext and features GBContext context = GBContext .builder() .featuresJson(featuresRepository.getFeaturesJson()) .attributesJson(userAttributesJson) .build(); GrowthBook growthBook = new GrowthBook(context); growthBook.isOn("featureKey"); ``` -------------------------------- ### Get UserContext Attributes Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/user-context.md Retrieves the user attributes currently set in the UserContext as a JsonObject. ```java public JsonObject getAttributes() ``` -------------------------------- ### getRefreshStrategy() Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Gets the configured feature refresh strategy. This determines how the SDK fetches updated feature data. ```APIDOC ## getRefreshStrategy() ### Description Gets the configured feature refresh strategy. This determines how the SDK fetches updated feature data. ### Method ```java public FeatureRefreshStrategy getRefreshStrategy() ``` ### Returns - FeatureRefreshStrategy enum value: The configured refresh strategy. ``` -------------------------------- ### Complete GrowthBook Client Options Configuration Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/user-context.md This snippet shows how to build and initialize the GrowthBook client with a wide range of options, including API host, client key, refresh strategies, experiment settings, sticky bucketing, tracking and feature usage callbacks, global attributes, and caching. ```java Options options = Options.builder() // API configuration .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123xyz") // Feature refresh configuration .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) .swrTtlSeconds(120) // Experiment configuration .enabled(true) .isQaMode(false) .allowUrlOverrides(false) .url("https://app.example.com") // Security .decryptionKey(null) // Sticky bucketing .stickyBucketIdentifierAttributes(Arrays.asList("user_id")) .stickyBucketService(new InMemoryStickyBucketServiceImpl(new HashMap<>())) // Callbacks .trackingCallBackWithUser((userId, exp, result) -> { analytics.track("experiment_enrolled", userId, exp.getKey()); }) .featureUsageCallbackWithUser((userId, key, result) -> { analytics.track("feature_evaluated", userId, key); }) .featureRefreshCallback(new FeatureRefreshCallback() { @Override public void onRefresh(String json) { System.out.println("Features refreshed"); } @Override public void onError(Throwable t) { System.err.println("Refresh failed: " + t.getMessage()); } }) // Global overrides .globalAttributes(JsonObject.parseJson("{\"app_version\": \"2.1.0\"}")) .globalForcedFeatureValues(Map.of("beta_ui", true)) .globalForcedVariationsMap(Map.of("test_exp", 1)) // Caching .cacheMode(CacheMode.FILE) .cacheDirectory("/var/cache/myapp") .build(); // Initialize client GrowthBookClient client = new GrowthBookClient(options); client.initialize(); ``` -------------------------------- ### Get Decryption Key Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Retrieves the decryption key if it has been configured. This key is used to decrypt feature data if encryption is enabled. ```java public String getDecryptionKey() ``` -------------------------------- ### Keep Callbacks Lightweight: Blocking Operation Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/callbacks-and-utilities.md Avoid heavy operations in callbacks. This example shows a blocking I/O operation which is discouraged. ```java // ❌ BAD: Blocks evaluation growthBook.subscribe((exp, result) -> { databaseService.saveExperimentAssignment(exp, result); // Blocking I/O }); ``` -------------------------------- ### Initialize GrowthBook Client Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Shows the basic initialization of a `GrowthBookClient` and checks if the initialization was successful. Use defaults or retry if it fails. ```java GrowthBookClient client = new GrowthBookClient(options); if (!client.initialize()) { System.err.println("Failed to initialize GrowthBookClient"); // Use defaults or retry } ``` -------------------------------- ### Initialize GrowthBookClient with Options Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/README.md Initialize a shared GrowthBookClient instance with API host and client key. Call initialize() to load features, then use isOn() with user attributes. ```java // build options to configure your Growthbook instance Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .build(); // Create growthbook instance using the options you need GrowthBookClient gb = new GrowthBookClient(options); // call the init method to load features gb.initialize(); gb.isOn("featureKey", UserContext.builder() .attributesJson("{\"id\" : \"123\"}").build() ); ``` -------------------------------- ### Options Builder Configuration Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/user-context.md Demonstrates how to construct an Options object using the builder pattern, setting essential configuration parameters like apiHost and clientKey. ```APIDOC ## Options Class Global configuration for `GrowthBookClient`. ### Constructor (via Builder) ```java Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .build(); ``` ### Builder Methods #### apiHost() ```java public OptionsBuilder apiHost(String apiHost) ``` Sets the GrowthBook API host URL. **Required:** Yes **Example:** ```java .apiHost("https://cdn.growthbook.io") ``` #### clientKey() ```java public OptionsBuilder clientKey(String clientKey) ``` Sets the SDK connection key from GrowthBook. **Required:** Yes **Example:** ```java .clientKey("sdk-abc123xyz") ``` #### enabled() ```java public OptionsBuilder enabled(Boolean enabled) ``` Globally enables or disables all experiments. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | enabled | Boolean | true | Whether experiments are active | **Example:** ```java .enabled(true) // Enable experiments ``` #### isQaMode() ```java public OptionsBuilder isQaMode(Boolean isQaMode) ``` Enables QA mode (disables random assignment, uses forced variations only). | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | isQaMode | Boolean | false | Whether to enable QA mode | **Example:** ```java .isQaMode(true) // For testing ``` #### isCacheDisabled() ```java public OptionsBuilder isCacheDisabled(Boolean isCacheDisabled) ``` Disables feature caching entirely. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | isCacheDisabled | Boolean | false | Whether to disable caching | #### allowUrlOverrides() ```java public OptionsBuilder allowUrlOverrides(Boolean allowUrlOverrides) ``` Allows URL-based feature flag overrides for testing. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | allowUrlOverrides | Boolean | false | Whether to allow URL overrides | #### url() ```java public OptionsBuilder url(String url) ``` Sets the current page URL for URL-based experiment targeting (global). | Parameter | Type | Description | |-----------|------|-------------| | url | String | Default page URL | **Example:** ```java .url("https://app.example.com/home") ``` #### decryptionKey() ```java public OptionsBuilder decryptionKey(String decryptionKey) ``` Sets the key for decrypting encrypted feature payloads. | Parameter | Type | Description | |-----------|------|-------------| | decryptionKey | String | Decryption key from GrowthBook | #### refreshStrategy() ```java public OptionsBuilder refreshStrategy(FeatureRefreshStrategy strategy) ``` Sets how features are refreshed from the API. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | strategy | FeatureRefreshStrategy | STALE_WHILE_REVALIDATE | Refresh strategy enum | **Options:** - `STALE_WHILE_REVALIDATE`: Poll API at regular intervals - `SERVER_SENT_EVENTS`: Real-time SSE connection - `REMOTE_EVAL_STRATEGY`: Evaluate on remote server **Example:** ```java .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) ``` #### swrTtlSeconds() ```java public OptionsBuilder swrTtlSeconds(Integer swrTtlSeconds) ``` Sets polling interval for STALE_WHILE_REVALIDATE strategy. | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | swrTtlSeconds | Integer | 60 | Seconds between polls | **Example:** ```java .swrTtlSeconds(120) // Poll every 2 minutes ``` #### stickyBucketIdentifierAttributes() ```java public OptionsBuilder stickyBucketIdentifierAttributes( List attributes ) ``` Sets which user attributes to use for sticky bucketing. | Parameter | Type | Description | |-----------|------|-------------| | attributes | List | List of attribute names (e.g., ["user_id", "session_id"]) | **Example:** ```java .stickyBucketIdentifierAttributes(Arrays.asList("user_id", "session_id")) ``` ``` -------------------------------- ### getSwrTtlSeconds() Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Gets the stale-while-revalidate (SWR) Time-To-Live (TTL) in seconds. This setting influences how long cached feature data is considered fresh. ```APIDOC ## getSwrTtlSeconds() ### Description Gets the stale-while-revalidate (SWR) Time-To-Live (TTL) in seconds. This setting influences how long cached feature data is considered fresh. ### Method ```java public Integer getSwrTtlSeconds() ``` ### Returns - Integer seconds: The duration in seconds before feature data is considered stale. ``` -------------------------------- ### Get Feature Refresh Strategy Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Retrieves the configured strategy for refreshing feature data. This determines how the SDK updates its feature flags. ```java public FeatureRefreshStrategy getRefreshStrategy() ``` -------------------------------- ### Create GrowthBook Instance with GBContext Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Initializes GrowthBook with a pre-configured GBContext object. The context should include attributes, features, and other relevant configuration. ```java public GrowthBook(GBContext context) ``` -------------------------------- ### Get SSE Endpoint URL Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Retrieves the full URL for the Server-Sent Events (SSE) endpoint. This endpoint is used for real-time updates. ```java public String getEventsEndpoint() ``` -------------------------------- ### GBContext Builder Pattern Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/types.md Demonstrates how to create a GBContext instance using the builder pattern, setting user attributes and features. ```java GBContext context = GBContext.builder() .attributesJson("{\"user_id\": \"123\"}") .featuresJson(featuresJsonString) .enabled(true) .build(); ``` -------------------------------- ### GrowthBook Constructor Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Initializes the GrowthBook SDK. You can create an instance with default context or provide a pre-configured GBContext object. ```APIDOC ## GrowthBook Constructor ### Description Initializes the GrowthBook SDK. You can create an instance with default context or provide a pre-configured GBContext object. ### Method Signatures ```java public GrowthBook() public GrowthBook(GBContext context) ``` ### Parameters #### `GrowthBook(GBContext context)` - **context** (GBContext) - Required - Context containing features, attributes, and configuration ### Returns - GrowthBook instance ### Example ```java GBContext context = GBContext.builder() .attributesJson("{\"id\": \"user123\", \"country\": \"US\"}") .featuresJson(featuresJsonString) .build(); GrowthBook growthBook = new GrowthBook(context); ``` ``` -------------------------------- ### Run Performance Harness Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/docs/perf/pr-196-followup-results.md Command to execute the performance harness with specified warmup and iteration counts. Ensure JAVA_HOME is set correctly. ```bash JAVA_HOME=/opt/homebrew/Cellar/openjdk@17/17.0.18/libexec/openjdk.jdk/Contents/Home \ ./gradlew :lib:runPerfHarness -PperfWarmupIterations=20000 -PperfIterations=100000 ``` -------------------------------- ### StickyBucketService Interface Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md The StickyBucketService interface defines the contract for managing sticky assignments. It includes methods to retrieve, save, and get all assignments for a user. ```APIDOC ## StickyBucketService Interface This interface provides methods for managing sticky experiment assignments. ### Methods - **getAssignments(String attributeName, String attributeValue)**: Retrieves persisted assignments for a user based on a given attribute. - **saveAssignments(StickyAssignmentsDocument doc)**: Persists or updates user assignments. - **getAllAssignments(Map attributes)**: Retrieves all assignments for multiple user attributes. ``` -------------------------------- ### Get Features Endpoint URL Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Retrieves the full URL for the features API endpoint. This is the endpoint used to fetch feature flag data. ```java public String getFeaturesEndpoint() ``` ```java String endpoint = repository.getFeaturesEndpoint(); // Returns: "https://cdn.growthbook.io/api/features/sdk-abc123" ``` -------------------------------- ### Initialize InMemoryStickyBucketService (Multi-User Mode) Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Set up the in-memory sticky bucket service with a custom HashMap for multi-user testing. This implementation does not persist data across restarts. ```java // Multi-user mode Options options = Options.builder() .stickyBucketService(new InMemoryStickyBucketServiceImpl(new HashMap<>())) .build(); ``` -------------------------------- ### Initialize InMemoryStickyBucketService (Single-User Mode) Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/advanced-features.md Configure the SDK to use the in-memory sticky bucket service for development or testing. This mode is suitable for single-user scenarios. ```java // Single-user mode growthBook.setInMemoryStickyBucketService(); ``` -------------------------------- ### Handle Feature Refresh Callback Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/configuration.md Example implementation of the FeatureRefreshCallback to process updated features and handle refresh errors. This is used to update local caches. ```java repository.onFeaturesRefresh(new FeatureRefreshCallback() { @Override public void onRefresh(String featuresJson) { System.out.println("Features updated"); cacheService.updateCache(featuresJson); } @Override public void onError(Throwable throwable) { logger.error("Feature refresh failed", throwable); } }); ``` -------------------------------- ### GrowthBookClient Initialization Failure Handling Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/errors.md Shows how to check the boolean return value of GrowthBookClient.initialize() to detect and handle initialization failures. This is crucial as features will not be loaded if initialization fails. ```java GrowthBookClient client = new GrowthBookClient(options); boolean success = client.initialize(); if (!success) { // Handle initialization failure logger.error("Failed to initialize GrowthBookClient"); // Features will not be loaded } ``` -------------------------------- ### Get Parsed Features Map Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Obtain the parsed feature definitions as a Map> using getParsedFeatures(). This allows iterating through feature keys. ```java Map> features = repository.getParsedFeatures(); features.keySet().forEach(key -> System.out.println("Feature: " + key)); ``` -------------------------------- ### GrowthBookClient(Options options) Constructor Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-client.md Creates a GrowthBookClient instance with custom configuration options provided via an Options object. This allows for fine-grained control over API host, client key, caching, and refresh strategies. ```APIDOC ## GrowthBookClient(Options options) ### Description Creates a GrowthBookClient with custom configuration options. ### Parameters #### Path Parameters - **opts** (Options) - Optional - Configuration options for the client ### Returns GrowthBookClient instance ### Example ```java Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .cacheMode(CacheMode.FILE) .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) .build(); GrowthBookClient client = new GrowthBookClient(options); ``` ``` -------------------------------- ### Get Custom Object Feature Value Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Retrieve a feature's value as a custom object. Ensure the class has a default constructor and public fields or getters/setters. ```java class PricingConfig { String currency; Double basePrice; List features; } PricingConfig pricing = growthBook.getFeatureValue( "pricing_config", new PricingConfig(), PricingConfig.class ); ``` -------------------------------- ### Get Feature Value as Double Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Retrieves a feature flag's value as a Double. Provide a default value to be returned if the feature is not found or its value is null. ```java public Double getFeatureValue(String featureKey, Double defaultValue) ``` ```java Double sampleRate = growthBook.getFeatureValue("sample_rate", 1.0); ``` -------------------------------- ### Create GrowthBookClient with Custom Options Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-client.md Instantiate a GrowthBookClient with specific configuration options such as API host, client key, cache mode, and refresh strategy. Ensure all necessary options are provided for your environment. ```java Options options = Options.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .cacheMode(CacheMode.FILE) .refreshStrategy(FeatureRefreshStrategy.STALE_WHILE_REVALIDATE) .build(); GrowthBookClient client = new GrowthBookClient(options); ``` -------------------------------- ### Get Feature Value as Float Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Retrieves a feature flag's value as a Float. Provide a default value to be returned if the feature is not found or its value is null. ```java public Float getFeatureValue(String featureKey, Float defaultValue) ``` ```java Float discountPercent = growthBook.getFeatureValue("discount_percent", 0.0f); ``` -------------------------------- ### Run a Basic A/B Test Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/quick-start-reference.md Use this to set up a simple A/B test with two variations and a 50% coverage. The experiment key is 'button_color'. ```java Experiment experiment = Experiment.builder() .key("button_color") .variations(Arrays.asList("blue", "red")) .weights(Arrays.asList(0.5f, 0.5f)) .coverage(0.5f) // Only 50% of users .build(); ExperimentResult result = growthBook.run(experiment); if (result.getInExperiment()) { String color = result.getValue(); System.out.println("Button color: " + color); } else { System.out.println("User not in experiment"); } ``` -------------------------------- ### Get Feature Value as Integer Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Retrieves a feature flag's value as an Integer. Provide a default value to be returned if the feature is not found or its value is null. ```java public Integer getFeatureValue(String featureKey, Integer defaultValue) ``` ```java Integer maxRetries = growthBook.getFeatureValue("max_retries", 3); ``` -------------------------------- ### Get Feature Value as String Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Retrieves a feature flag's value as a String. Provide a default value to be returned if the feature is not found or its value is null. ```java public String getFeatureValue(String featureKey, String defaultValue) ``` ```java String theme = growthBook.getFeatureValue("theme_color", "#000000"); ``` -------------------------------- ### Initialize GBFeaturesRepository via Builder Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Instantiate the GBFeaturesRepository using its builder pattern. Configure the API host and client key to connect to the GrowthBook API. ```java GBFeaturesRepository repository = GBFeaturesRepository.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .build(); ``` -------------------------------- ### Get Feature Value as Boolean Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/growthbook-core.md Retrieves a feature flag's value as a Boolean. Provide a default value to be returned if the feature is not found or its value is null. ```java public Boolean getFeatureValue(String featureKey, Boolean defaultValue) ``` ```java Boolean darkMode = growthBook.getFeatureValue("dark_mode", false); ``` -------------------------------- ### Configuring Repository with Decryption Key Source: https://github.com/growthbook/growthbook-sdk-java/blob/main/_autodocs/repository.md Illustrates how to build a `GBFeaturesRepository` instance with API host, client key, and a decryption key for encrypted feature payloads. Initialization will automatically decrypt features. ```java GBFeaturesRepository repository = GBFeaturesRepository.builder() .apiHost("https://cdn.growthbook.io") .clientKey("sdk-abc123") .decryptionKey("your-decryption-key") .build(); repository.initialize(); // Features auto-decrypted ```