> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upgrade the Java API client to version 3

> Keep your Java API client up to date to benefit from improvements and bug fixes.

export const Legacy = ({title, href}) => {
  return <Note>

    This page documents an earlier version of the API client.
    For the latest version, see <a href={href}>{title}</a>.

    </Note>;
};

<Legacy title="Upgrade" href="/doc/libraries/sdk/upgrade/java" />

The Java API client follows [semantic versioning](http://semver.org).

## Upgrade to version 3

The client and index class [have been renamed](#client-instantiation) `SearchClient` and `SearchIndex`. The method names remain the same.
To have all the asynchronous and synchronous methods in the same place, the asynchronous client is now part of the `SearchClient`.
The `Analytics` and `Insights` clients use the same API design.

This version is **compatible with Java 8 and later**.

<Info>
  This version removes all deprecated methods and features from version 2.
</Info>

## Upgrade the library

The library now comes in two parts.

* `algoliasearch-core` which holds all the methods, the plain old Java object (POJO), the transport layer and the retry strategy. This JAR is agnostic of any HTTP client implementation.
* `algoliasearch-apache` which is the default HTTP client implementation for the core library.

### Upgrade with maven

Add the following code in your `pom.xml`:

```xml pom.xml icon=code-xml theme={"system"}
<dependency>
  <groupId>com.algolia</groupId>
  <artifactId>algoliasearch-core</artifactId>
  <version>3.6.1</version>
</dependency>

<dependency>
  <groupId>com.algolia</groupId>
  <artifactId>algoliasearch-apache</artifactId>
  <version>3.6.1</version>
</dependency>
```

### Upgrade with Gradle

Add the following code in your `build.gradle`:

```groovy build.gradle icon=braces theme={"system"}
compile 'com.algolia:algoliasearch-core:3.+'
compile 'com.algolia:algoliasearch-apache:3.+'
```

## Client instantiation

Replace the instantiation of the client as shown below.

```java Java icon=code theme={"system"}
// Before
APIClient client = 
new ApacheAPIClientBuilder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
.build();

Index<Contact> index = client.initIndex("INDEX_NAME", Contact.class);

AsyncAPIClient client =
new AsyncHttpAPIClientBuilder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
.build();

AsyncIndex<Contact> index = client.initIndex("INDEX_NAME", Contact.class);

// After
// It's the same class for async and sync methods!
SearchClient client =
DefaultSearchClient.create("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");

SearchIndex<Contact> index = client.initIndex("INDEX_NAME", Contact.class);
```

### Instantiate with configuration

You can instantiate all clients with a configuration builder.
This is useful to affect the way a client behaves.

You can configure :

* **DefaultHeaders**: to set HTTP headers for every request
* **BatchSize**: to customize the chunk size of batches for save methods
* **Hosts**: to set custom hosts to target
* **Timeouts** : to set timeout such as the read timeout, the write timeout, and the connect timeout
* **ExecutorService**: to set your own `ExecutorService`

Example:

```java Java icon=code theme={"system"}
SearchConfig config =
  new SearchConfig.Builder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
      .setHosts(...)
      .setReadTimeOut(...)
      .setWriteTimeOut(...)
      .setConnectTimeOut(...)
      .setBatchSize(...)
      .setExecutorService(...)
      .build();

SearchClient client = DefaultSearchClient.create(config);
```

## Analytics instantiation

Similarly, you need to update the way you initialize the Analytics client.

```java Java icon=code theme={"system"}
// Before
APIClient client =
new ApacheAPIClientBuilder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
.build();

Analytics analytics = client.initAnalytics();

AsyncAPIClient client =
new AsyncHttpAPIClientBuilder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
.build();

AsyncAnalytics analytics = client.initAnalytics();

// After
// It's the same class for async and sync methods!
AnalyticsClient analytics =
DefaultAnalyticsClient.create("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");
```

## Insights instantiation

You need to update the way you initialize the Insights client:

```java Java icon=code theme={"system"}
// Before
APIClient client =
new ApacheAPIClientBuilder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
.build();

SyncInsightsClient insights =
new SyncInsightsClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", client)

AsyncAPIClient client =
new AsyncHttpAPIClientBuilder("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY")
.build();

AsyncInsightsClient insights =
new AsyncInsightsClient("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", client)

// After
// It's the same class for async and sync methods!
InsightsClient insights =
DefaultInsightsClient.create("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");
```

## Review breaking changes

To ease the update, most of the plain old java objects (POJO) didn't change.
You can find *some* breaking changes in the following table.

All methods marked as `@Depracted` are removed.

### Clients

| Methods/Features in version 2 | Breaking Change                                                             | Methods/Features in version 3                                                                           |
| ----------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `APIClient`                   | **Removed**. Use `SearchClient` `AnalyticsClient` `InsightsClient` instead. | `DefaultSearchClient.create(..)` `DefaultAnalyticsClient.create(..)` `DefaultInsightsClient.create(..)` |
| `AsyncAPIClient`              | **Removed**. Use `SearchClient` `AnalyticsClient` `InsightsClient` instead. | `DefaultSearchClient.create(..)` `DefaultAnalyticsClient.create(..)` `DefaultInsightsClient.create(..)` |

### `SearchClient`

| Methods/Features in version 2 | Breaking Change                           | Methods/Features in version 3 |
| ----------------------------- | ----------------------------------------- | ----------------------------- |
| `listKeys()`                  | **Removed**. Use `listApiKeys()` instead. | `listApiKeys()`               |

### `Index/SearchIndex`

| Methods/Features in version 2                     | Breaking Change                                               | Methods/Features in version 3                 |
| ------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------- |
| `deleteByQuery(query)`                            | **Removed**. Use `deleteBy()` instead.                        | `deleteBy(query)`                             |
| `searchInFacetValues(facetName,facetQuery,query)` | **Removed**. Use `searchForFacetValues()` instead.            | `searchForFacetValues(String, String, Query)` |
| `index.browse(Query)`                             | **Breaking**                                                  | `index.browseObjects(BrowseIndexQuery)`       |
| `BrowseResult<T>`                                 | **Breaking**                                                  | `BrowseIndexResponse<T>`                      |
| `IndexSetting.getAttributesToIndex()`             | **Removed**. Use `searchableAttributes` instead.              | `IndexSetting.getSearchableAttributes()`      |
| `IndexSetting.setAttributesToIndex()`             | **Removed**. Use `searchableAttributes` instead.              | `IndexSetting.setSearchableAttributes()`      |
| `Query.setFacetFilters(List<String>)`             | **Breaking**                                                  | `Query.setFacetFilters(List)`                 |
| `Query.setNumericFilters(List<String>)`           | **Breaking**                                                  | `Query.setNumericFilters(List)`               |
| `Query.setTagFilters(List<String>)`               | **Breaking**                                                  | `Query.setTagFilters(List)`                   |
| `Query.setOptionalFilters(List<String>)`          | **Breaking**                                                  | `Query.setOptionalFilters(List)`              |
| `AbstractSynonym`                                 | **Removed**. Use `Synonym` instead.                           | `Synonym`                                     |
| `ConsequenceQueryObject`                          | **Removed**. Use `ConsequenceQuery` instead.                  | `ConsequenceQuery`                            |
| `ConsequenceQueryObject.setRemove(List<String>)`  | **Removed**. Use `ConsequenceQuery.setEdits()` instead.       | `ConsequenceQuery.setEdits(List<Edits>>)`     |
| `Index<T>.addObject(T object)`                    | **Removed**. Use `SearchIndex<T>.saveObject(T data)` instead. | `SearchIndex<T>.saveObject(T data)`           |

### `AnalyticsClient`

| Methods/Features in version 2         | Breaking Change | Methods/Features in version 3                |
| ------------------------------------- | --------------- | -------------------------------------------- |
| `TaskABTest addABTest(ABTest abtest)` | **Breaking**    | `AddABTestResponse addABTest(ABTest abTest)` |
| `TaskABTest stopABTest(long id)`      | **Breaking**    | `StopAbTestResponse stopABTest(long id)`     |
| `TaskABTest deleteABTest(long id)`    | **Breaking**    | `DeleteAbTestResponse deleteABTest(long id)` |
| `ABTest getABTest(long id)`           | **Breaking**    | `ABTestResponse getABTest(long id)`          |
