Initialize SDK
This topic describes how to initialize the Optimizely Java SDK in your application.
Use the builder to initialize the Java SDK and instantiate an instance of the Optimizely client class that exposes API methods like Get Enabled Features.
Version
SDK v3.2.0 and higher
Description
The constructor accepts a configuration object to configure Optimizely.
Some parameters are optional because the SDK provides a default implementation, but you may want to override these for your production environments. For example, you may want override these to set up an error handler and logger to catch issues, an event dispatcher to manage network calls, and a User Profile Service to ensure sticky bucketing.
Parameters
The table below lists the required and optional parameters in Java.
Parameter | Type | Description |
---|---|---|
datafile optional | string | The JSON string representing the project. |
errorHandler optional | ErrorHandler | An error handler object to handle errors. |
access_token optional | string | (Server-side only) Optimizely SDKs can use an access token (in combination with an sdkkey) to fetch the datafile from an authenticated endpoint. Find your datafile access token in the Optimizely app at Settings>Environments. Select your secure environment, and copy the _Datafile access token. |
Returns
Instantiates an instance of the Optimzely class.
Example
Use the builder to initialize the Java SDK and instantiate an instance of the Optimizely client class.
Optimizely optimizely = Optimizely.builder()
.withDatafile(datafile)
.withEventHandler(eventHandler)
.build();
For most advanced implementations, you will want to customize the logger or error handler for your specific requirements.
Exceptions
Exception | Meaning |
---|---|
ConfigParseException | The datafile could not be parsed either because it is malformed or has an incorrect schema. |
Automatic datafile management (ADM)
Optimizely provides out-of-the-box functionality to dynamically manage datafiles (configuration files) on either the client or the server. The Java SDK provides default implementations of an Optimizely EventHandler
and ProjectConfigManager
. The package also includes a factory class, OptimizelyFactory
, which you can use to instantiate the Optimizely SDK with the default configuration of AsyncEventHandler
and HttpProjectConfigManager
.
Whenever the experiment configuration changes, the SDK uses automatic datafile management (ADM) to handle the change for you.
The sections below describe how to use ADM with your implementation.
Basic example
The following code example shows basic Java ADM usage:
import com.optimizely.ab.Optimizely;
import com.optimizely.ab.OptimizelyFactory;
public class App {
public static void main(String[] args) {
String sdkKey = args[0];
Optimizely optimizely = OptimizelyFactory.newDefaultInstance(sdkKey);
}
}
Advanced example
Here is a code example showing advanced configuration for Java ADM. Advanced configuration properties are described in the sections below.
This advanced example shows how to construct the individual components directly to override various configurations. This gives you full control over which implementations to use and how to use them.
Note
When using the Optimizely builder class, you must provide an implementation of the event handler as shown below. Otherwise, the Optimizely instance will default to a no-op event handler.
import com.optimizely.ab.Optimizely;
import com.optimizely.ab.config.HttpProjectConfigManager;
import com.optimizely.ab.event.AsyncEventHandler;
import java.util.concurrent.TimeUnit;
public class App {
public static void main(String[] args) {
String sdkKey = args[0];
EventHandler eventHandler = AsyncEventHandler.builder()
.withQueueCapacity(20000)
.withNumWorkers(5)
.build();
ProjectConfigManager projectConfigManager = HttpProjectConfigManager.builder()
.withSdkKey(sdkKey)
.withPollingInterval(1, TimeUnit.MINUTES)
.build();
Optimizely optimizely = Optimizely.builder()
.withConfigManager(projectConfigManager)
.withEventHandler(eventHandler)
.build();
}
}
AsyncEventHandler
AsyncEventHandler
provides an implementation of EventHandler
backed by a ThreadPoolExecutor
. Events triggered from the Optimizely SDK are queued immediately as discrete tasks to the executor and processed in the order they were submitted.
Each worker is responsible for making outbound HTTP requests to the Optimizely 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.
To use AsyncEventHandler
, you must build an instance with AsyncEventHandler.Builder
and pass the instance to the Optimizely.Builder
.
EventHandler eventHandler = AsyncEventHandler.builder()
.withQueueCapacity(20000)
.withNumWorkers(5)
.build();
Queue capacity
You can set the queue capacity to initialize the backing queue for the executor service. If the queue fills up, events will be dropped and an exception will be logged. Setting a higher queue value will prevent event loss but will use 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
The following builder methods can be used to customize the AsyncEventHandler
configuration.
Method | Default value | Description |
---|---|---|
withQueueCapacity(int) | 1000 | Queue size for pending logEvents |
withNumWorkers(int) | 2 | Number of worker threads |
withMaxTotalConnections(int) | 200 | Maximum number of connections |
withMaxPerRoute(int) | 20 | Maximum number of connections per route |
withValidateAfterInactivity(int) | 5000 | Time to maintain idle connections (in milliseconds) |
Advanced configuration
The following properties can be set to override the default configuration for AsyncEventHandler
.
Property | Default value | Description |
---|---|---|
async.event.handler.queue.capacity | 10000 | Queue size for pending logEvents |
async.event.handler.num.workers | 2 | Number of worker threads |
async.event.handler.max.connections | 200 | Maximum number of connections |
async.event.handler.event.max.per.route | 20 | Maximum number of connections per route |
async.event.handler.validate.after | 5000 | Time to maintain idol connections (in milliseconds) |
HttpProjectConfigManager
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 HttpProjectConfigManager.Builder
, pulling the default values from global properties.
ProjectConfigManager projectConfigManager = HttpProjectConfigManager.builder()
.withSdkKey(sdkKey)
.withPollingInterval(1, TimeUnit.MINUTES)
.build();
SDK key
The SDK key is used to compose the outbound HTTP request to the default datafile location on the Optimizely CDN.
Polling interval
The polling interval is used to specify 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
so that it can be used immediately without blocking execution. The initial datafile also serves as a fallback datafile if HTTP connection cannot be established. This is useful in mobile environments, where internet connectivity is not guaranteed.
The initial datafile will be discarded after the first successful datafile poll.
Builder methods
The following builder methods can be used to customize the HttpProjectConfigManager
con#figuration.
Method | Default value | Description |
---|---|---|
withDatafile(String) | null | Initial datafile, typically sourced from a local cached source |
withUrl(String) | null | URL override location used to specify custom HTTP source for the Optimizely datafile |
withFormat(String) | https://cdn.optimizely.com/datafiles/%s.json | Parameterized datafile URL by SDK key |
withPollingInterval(Long, TimeUnit) | 5 minutes | Fixed delay between fetches for the datafile |
withBlockingTimeout(Long, TimeUnit) | 10 seconds | Maximum time to wait for initial bootstrapping |
withSdkKey(String) | null | Optimizely project SDK key; required unless source URL is overridden |
Advanced configuration
The following properties can be set to override the default configuration for HttpProjectConfigManager
.
Property | Default value | Description |
---|---|---|
http.project.config.manager.polling.duration | 5 | Fixed delay between fetches for the datafile |
http.project.config.manager.polling.unit | MINUTES | Time unit corresponding to polling interval |
http.project.config.manager.blocking.duration | 10 | Maximum time to wait for initial bootstrapping |
http.project.config.manager.blocking.unit | SECONDS | Time unit corresponding to blocking duration |
http.project.config.manager.sdk.key | null | Optimizely project SDK key |
Update Config Notifications
A notification signal will be triggered whenever a *new( datafile is fetched. To subscribe to these notifications, use Optimizely.addUpdateConfigNotificationHandler
:
NotificationHandler<UpdateConfigNotification> handler = message ->
System.out.println("Received new datafile configuration");
optimizely.addUpdateConfigNotificationHandler(handler);
Alternatively, you can add the handler directly to the NotificationCenter
:
notificationCenter.addNotificationHandler(UpdateConfigNotification.class, handler);
optimizely.properties
When an optimizely.properties
file is available within the runtime classpath it can be used to provide default values of a given Optimizely resource. Refer to the resource implementation for available configuration parameters.
Here is an example optimizely.properties
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
OptimizelyFactory
In this package, OptimizelyFactory
provides basic utility to instantiate the Optimizely SDK with a minimal number of configuration options. Configuration properties are sourced from Java system properties, environment variables, or an optimizely.properties
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.
You must provide the SDK key at runtime, either directly via the factory method:
Optimizely optimizely = OptimizelyFactory.newDefaultInstance(<<SDK_KEY>>);
If you provide the SDK key via a global property, use the empty signature:
Optimizely optimizely = OptimizelyFactory.newDefaultInstance();
Provide an event handler for Java
In addition to the datafile, you will 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.
Source files
The language/platform source files containing the implementation for Java are at Optimizely.java.
Updated 12 months ago