Dev guideAPI Reference
Dev guideAPI ReferenceUser GuideGitHubNuGetDev CommunityDoc feedbackLog In
GitHubNuGetDev CommunityDoc feedback

Initialize the Java SDK

How to initialize the Optimizely Feature Experimentation Java SDK in your application.

Use the Optimizely Builder to initialize the Java SDK and instantiate an instance of the Optimizely client class that exposes API methods like the Decide methods.


SDK v3.2.0 and higher


The SDK provides a default implementation, but you may want to override the optional parameters for your production environments. For example, you can override the defaults to:


The table below lists the optional builder methods.

ProjectConfigManager object to manage project configuration. You should provide an instance of HttpProjectConfigManager or your own custom object.

If this is not set, the parameter uses static ProjectConfig without polling datafile periodically.
EventProcessor object to process events. You should provide an instance of BatchEventProcessor with AsyncEventHandler or your own custom object.

If this is not set, the parameter uses ForwardingEventProcessor with NoopEventHandler() by default.
UserProfileService object to support persistent variation assignments.

If this is not set, persistent decisions are not supported.
withErrorHandler(ErrorHandler)ErrorHandler object to handle errors.
withDatafile(String)The JSON string representing the project.

If an instance of ProjectConfigManager is not provided, you must use this datafile.
An array of OptimizelyDecideOption enums.

When the Optimizely client is constructed with this parameter, it sets default decide options which are applied to all the Decide calls made during the lifetime of the Optimizely client. Additionally, you can pass options to individual Decide methods (does not overrides defaults).

For example code, see OptimizelyDecideOption.


An instantiated instance of the Optimizely class.


The example below shows how to initialize the Optimizely Feature Experimentation Java SDK using the builder options.

Optimizely Feature Experimentation provides default implementations of HttpProjectConfigManager, BatchEventProcessor and AsyncEventHandler.

ProjectConfigManager configManager = HttpProjectConfigManager.builder()

EventHandler eventHandler = AsyncEventHandler.builder()

EventProcessor batchProcessor = BatchEventProcessor.builder()

Optimizely optimizely = Optimizely.builder()


ConfigParseException – The SDK could not parse the datafile, either because it is malformed or has an incorrect schema.


Whenever the experiment configuration changes, the SDK uses automatic datafile management (ADM) to handle the change for you.

HttpProjectConfigManager is an implementation of the abstract PollingProjectConfigManager. The poll method is extended and makes an HTTP GET request to the configured URL to asynchronously download the project datafile and initialize an instance of the ProjectConfig.

By default, HttpProjectConfigManager will block until the first successful datafile retrieval, up to a configurable timeout.

Set the frequency of the polling method and the blocking timeout with withPollingInterval() and withBlockingTimeout(), pulling the default values from global properties.

The example below shows how to initialize the HttpProjectConfigManager with builder options.

ProjectConfigManager projectConfigManager = HttpProjectConfigManager.builder()
    .withPollingInterval(1, TimeUnit.MINUTES)
    .withBlockingTimeout(10, TimeUnit.SECONDS)

SDK key

The SDK key composes the outbound HTTP request to the default datafile location on the Optimizely CDN.

Polling interval

The polling interval specifies a fixed delay between consecutive HTTP requests for the datafile.

Initial datafile

You can provide an initial datafile via the builder to bootstrap the ProjectConfigManager to use it immediately without blocking execution. The initial datafile also serves as a fallback datafile if an HTTP connection cannot be established. This is useful in mobile environments where internet connectivity is not guaranteed.

The preceding datafile is discarded after the first successful datafile poll.

Builder methods

You can use the following builder methods to customize the HttpProjectConfigManager configuration.

MethodDefault valueDescription
withDatafile(String)nullInitial datafile, typically sourced from a local cached source
withUrl(String)nullURL override location used to specify custom HTTP source for the Optimizely Feature Experimentation datafile
withFormat(String) datafile URL by SDK key
withPollingInterval(Long, TimeUnit)5 minutesFixed delay between fetches for the datafile
withBlockingTimeout(Long, TimeUnit)10 secondsMaximum time to wait for initial bootstrapping
withSdkKey(String)nullOptimizely Feature Experimentation project SDK key; required unless source URL is overridden

Advanced configuration

The following properties can be set to override the default configuration for HttpProjectConfigManager.

PropertyDefault valueDescription
http.project.config.manager.polling.duration5The fixed delay between fetches for the datafile
http.project.config.manager.polling.unitMINUTESTime unit corresponding to the polling interval
http.project.config.manager.blocking.duration10Maximum time to wait for initial bootstrapping
http.project.config.manager.blocking.unitSECONDSTime unit corresponding to blocking duration
http.project.config.manager.sdk.keynullOptimizely Feature Experimentation project SDK key

Update Config Notifications

The SDK triggers a notification signal after fetching a new datafile. To subscribe to these notifications, use Optimizely.addUpdateConfigNotificationHandler:

NotificationHandler<UpdateConfigNotification> handler = message ->
    System.out.println("Received new datafile configuration");

Alternatively, you can add the handler directly to the NotificationCenter:

notificationCenter.addNotificationHandler(UpdateConfigNotification.class, handler);


AsyncEventHandler provides an implementation of EventHandler backed by a ThreadPoolExecutor. The event handler queues the triggered events from the SDK immediately as discrete tasks to the executor and processes them in submission order.

Each worker must make outbound HTTP requests to the Optimizely Feature Experimentation log endpoint for metrics tracking. Configure the default queue size and number of workers via global properties. Use AsyncEventHandler.Builder to override the default queue size and number of workers.



When using the Optimizely builder class, you must provide an implementation of the event handler as shown below. Otherwise, the Optimizely Feature Experimentation instance will default to a no-op event handler.

To use AsyncEventHandler, you must build an instance with AsyncEventHandler.Builder and pass the instance to the Optimizely.Builder.

You can also initialize the SDK with the OptimizelyFactory methods if you want to use the default AsyncEventHandler implementation.

EventHandler eventHandler = AsyncEventHandler.builder()

Queue capacity

You can set the queue capacity to initialize the backing queue for the executor service. This drops an event if the queue fills up and logs an exception. Setting a higher queue value prevents event loss but uses more memory if the workers cannot keep up with the production rate.

Number of workers

The number of workers determines the number of threads the thread pool uses.

Builder methods

You can use the following builder methods to customize the AsyncEventHandler configuration.

MethodDefault valueDescription
withQueueCapacity(int)1000Queue size for pending logEvents
withNumWorkers(int)2Number of worker threads
withMaxTotalConnections(int)200Maximum number of connections
withMaxPerRoute(int)20Maximum number of connections per route
withValidateAfterInactivity(int)5000Time to maintain idol connections (in milliseconds)

Advanced configuration

You can set the following properties to override the default configuration for AsyncEventHandler.

PropertyDefault valueDescription
async.event.handler.queue.capacity10000Queue size for pending logEvents
async.event.handler.num.workers2Number of worker threads
async.event.handler.max.connections200Maximum number of connections
async.event.handler.event.max.per.route20Maximum number of connections per route
async.event.handler.validate.after5000Time to maintain idle connections (in milliseconds)


The Optimizely Feature Experimentation Java SDK provides BatchEventProcessor, the default implementation of the EventProcessor interface and batches events.

For more details and configuration options, refer to the article on event batching in Java.

EventHandler eventHandler = AsyncEventHandler.builder()

EventProcessor batchProcessor = BatchEventProcessor.builder()

Optimizely Properties

You can use an available file within the runtime classpath to provide default values of a given Optimizely Feature Experimentation resource. Refer to the resource implementation for available configuration parameters.

An example file:

http.project.config.manager.polling.duration = 1
http.project.config.manager.polling.unit = MINUTES

async.event.handler.queue.capacity = 20000
async.event.handler.num.workers = 5


In this package, OptimizelyFactory provides a basic utility to instantiate the Optimizely Feature Experimentation Java SDK with a minimal number of configuration options.The package sources configuration properties from Java system properties, environment variables, or an file, in that order.

OptimizelyFactory does not capture all configuration and initialization options. For more use cases, build the resources via their respective builder classes.

When instantiated with the OptimizelyFactory methods, the Java SDK uses the default configuration of HttpProjectConfigManager, BatchEventProcessor, and AsyncEventHandler.

The example below shows how to initialize the Java SDK using the OptimizelyFactory methods.

Optimizely optimizelyClient = OptimizelyFactory.newDefaultInstance(sdkKey);

// If you provide the SDK key via a global property, use the empty signature:
Optimizely optimizely = OptimizelyFactory.newDefaultInstance();

// with fallback datafile
Optimizely optimizelyClient = OptimizelyFactory.newDefaultInstance(sdkKey, datafile);

In addition to the datafile, you need to provide an event dispatcher (also called event handler) object as an argument to the Optimizely.builder function. Use our default event dispatcher implementation, or provide your own implementation as described in Configure the event dispatcher.

Use authenticated datafile in a secure environment

You can fetch the Optimizely datafile from an authenticated endpoint using a server-side (only) Optimizely Feature Experimentation SDK, for example, the Java SDK.

To use an authenticated datafile, download your Optimizely environment's access token from the Optimizely app at Settings > Environments. Select your secure environment, and copy the Datafile access token. The example below shows how to initialize the Optimizely client using an access token and sdkKey, enabling the client to fetch the authenticated datafile and complete initialization.

// fetch the datafile from an authenticated endpoint
String accessToken = "<YOUR_DATAFILE_ACCESS_TOKEN>";
String sdkKey = "<YOUR_SDK_KEY>";
Optimizely optimizelyClient = OptimizelyFactory.newDefaultInstance(sdkKey, null, accessToken);

Source files

The language and platform source files containing the implementation for Java are available on GitHub.