Skip to main content

Java

Java client version

The current Java client version is v5.0.0.

Breaking changes introduced in v4

The package and import paths have been updated from technology.semi.weaviate to io.weaviate.

See the Migration Guide for more info.

Installation and setup

To get the latest stable version of the Java client library, add this dependency to your project:

<dependency>
<groupId>io.weaviate</groupId>
<artifactId>client</artifactId>
<version>4.7.0</version> <!-- Check latest version -->
</dependency>

This API client is compatible with Java 8 and beyond.

You can use the client in your project as follows:

package io.weaviate;

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateClient;
import io.weaviate.client.base.Result;
import io.weaviate.client.v1.misc.model.Meta;

public class App {
public static void main(String[] args) {
Config config = new Config("http", "localhost:8080");
WeaviateClient client = new WeaviateClient(config);
Result<Meta> meta = client.misc().metaGetter().run();
if (meta.getError() == null) {
System.out.printf("meta.hostname: %s\n", meta.getResult().getHostname());
System.out.printf("meta.version: %s\n", meta.getResult().getVersion());
System.out.printf("meta.modules: %s\n", meta.getResult().getModules());
} else {
System.out.printf("Error: %s\n", meta.getError().getMessages());
}
}
}

Authentication

For more comprehensive information on configuring authentication with Weaviate, refer to the authentication page.

The Java client offers multiple options for authenticating against Weaviate, including multiple OIDC authentication flows.

The suitable authentication options and methods for the client largely depend on the specific configuration of the Weaviate instance.

WCD authentication

WCD + Weaviate client

Each Weaviate instance in Weaviate Cloud (WCD) is pre-configured to act as a token issuer for OIDC authentication.

See our WCD authentication documentation for instructions on how to authenticate against WCD with your preferred Weaviate client.

API key authentication

Added in Weaviate Java client version 4.0.2.

If you use an API key to authenticate, instantiate the client like this:

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;

Config config = new Config("https", "WEAVIATE_INSTANCE_URL");
WeaviateClient client = WeaviateAuthClient.apiKey(config, "YOUR-WEAVIATE-API-KEY"); // Replace with your Weaviate instance API key

OIDC authentication

To authenticate against Weaviate with OIDC, you must select a flow made available by the identity provider and create the flow-specific authentication configuration.

This configuration will then be used by the Weaviate client to authenticate. The configuration includes secrets that help the client obtain an access token and, if configured, a refresh token.

The access token is added to the HTTP header of each request and is utilized for authentication with Weaviate. Typically, this token has a limited lifespan, and the refresh token can be employed to obtain a new set of tokens when necessary.

Resource Owner Password Flow

This OIDC flow uses the username and password to obtain required tokens for authentication.

Note that not every provider automatically includes a refresh token and an appropriate scope might be required that depends on your identity provider. The client uses offline_access as the default scope. This works with some providers, but as it depends on the configuration of the identity providers, we ask you to refer to the identity provider's documentation.

Without a refresh token, there is no possibility to acquire a new access token and the client becomes unauthenticated after expiration.

note

The Weaviate client does not save the username or password used.

They are only used to obtain the first tokens, after which existing tokens will be used to obtain subsequent tokens if possible.

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;

Config config = new Config("http", "weaviate.example.com:8080");
WeaviateAuthClient.clientPassword(
config,
"Your user",
"Your password",
Arrays.asList("scope1", "scope2") // optional, depends on the configuration of your identity provider (not required with WCD)
);

Client Credentials flow

This OIDC flow uses a client secret to obtain required tokens for authentication.

This flow is recommended for server-to-server communication without end-users and authenticates an application to Weaviate. This authentication flow is typically regarded as more secure than the resource owner password flow: a compromised client secret can be simply revoked, whereas a compromised password may have larger implications beyond the scope of breached authentication.

To authenticate a client secret most identity providers require a scope to be specified. This scope depends on the configuration of the identity providers, so we ask you to refer to the identity provider's documentation.

Most providers do not include a refresh token in their response so client secret is saved in the client to obtain a new access token on expiration of the existing one.

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;

Config config = new Config("http", "weaviate.example.com:8080");
WeaviateAuthClient.clientCredentials(
config,
"your_client_secret",
Arrays.asList("scope1" ,"scope2") // optional, depends on the configuration of your identity provider
);

Refresh Token flow

Any other OIDC authentication method can be used to obtain tokens directly from your identity provider, for example by using this step-by-step guide of the hybrid flow.

If no refresh token is provided, there is no possibility to obtain a new access token and the client becomes unauthenticated after expiration.

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateAuthClient;

Config config = new Config("http", "weaviate.example.com:8080");
WeaviateAuthClient.bearerToken(
config,
"Your_access_token",
500, // lifetime in seconds
"Your_refresh_token",
);

Custom headers

You can pass custom headers to the client, which are added at initialization:

import io.weaviate.client.Config;
import io.weaviate.client.WeaviateClient;

public class App {
public static void main(String[] args) {
Map<String, String> headers = new HashMap<String, String>() { {
put("header_key", "value");
} };
Config config = new Config("http", "localhost:8080", headers);
WeaviateClient client = new WeaviateClient(config);
}
}

References

All RESTful endpoints and GraphQL functions references covered by the Java client, and explained on those reference pages in the code blocks.

Design

Builder pattern

The Java client functions are designed with a 'Builder pattern'. A pattern is used to build complex query objects. This means that a function (for example to retrieve data from Weaviate with a request similar to a RESTful GET request, or a more complex GraphQL query) is built with single objects to reduce complexity. Some builder objects are optional, others are required to perform specific functions. All is documented on the RESTful API reference pages and the GraphQL reference pages.

The code snippet above shows a simple query similar to RESTful GET /v1/meta. The client is initiated by requiring the package and connecting to the running instance. Then, a query is constructed by using the .metaGetter() on .misc(). The query will be sent with the .run() function, this object is thus required for every function you want to build and execute.

Migration Guides

From 3.x.x to 4.0.0

Moved from technology.semi.weaviate to io.weaviate package

Before:

package technology.semi.weaviate;
import technology.semi.weaviate.client.*;

After:

package io.weaviate;
import io.weaviate.client.*;

From 2.4.0 to 3.0.0

Removed @Deprecated method Aggregate::withFields(Fields fields)

Before:

// import io.weaviate.client.v1.graphql.query.fields.Field;
// import io.weaviate.client.v1.graphql.query.fields.Fields;

Fields fields = Fields.builder().fields(new Field[]{name, description}).build();
client.graphQL().aggregate().withFields(fields)...

After:

client.graphQL().aggregate().withFields(name, description)...

Removed @Deprecated method Get::withFields(Fields fields)

Before:

// import io.weaviate.client.v1.graphql.query.fields.Field;
// import io.weaviate.client.v1.graphql.query.fields.Fields;

Fields fields = Fields.builder().fields(new Field[]{name, description}).build();
client.graphQL().get().withFields(fields)...

After:

client.graphQL().get().withFields(name, description)...

Removed @Deprecated method Get::withNearVector(Float[] vector)

Before:

client.graphQL().get().withNearVector(new Float[]{ 0f, 1f, 0.8f })...

After:

// import io.weaviate.client.v1.graphql.query.argument.NearVectorArgument;

NearVectorArgument nearVector = NearVectorArgument.builder().vector(new Float[]{ 0f, 1f, 0.8f }).certainty(0.8f).build();
client.graphQL().get().withNearVector(nearVector)...

All where filters use the same implementation

With batch delete feature, unified filters.WhereFilter implementation is introduced, which replaces classifications.WhereFilter, graphql.query.argument.WhereArgument and graphql.query.argument.WhereFilter.

GraphQL

Before:

// import io.weaviate.client.v1.graphql.query.argument.GeoCoordinatesParameter;
// import io.weaviate.client.v1.graphql.query.argument.WhereArgument;
// import io.weaviate.client.v1.graphql.query.argument.WhereOperator;

GeoCoordinatesParameter geo = GeoCoordinatesParameter.builder()
.latitude(50.51f)
.longitude(0.11f)
.maxDistance(3000f)
.build();
WhereArgument where = WhereArgument.builder()
.valueGeoRange(geo)
.operator(WhereOperator.WithinGeoRange)
.path(new String[]{ "add "})
.build();

client.graphQL().aggregate().withWhere(where)...

After:

// import io.weaviate.client.v1.filters.Operator;
// import io.weaviate.client.v1.filters.WhereFilter;

WhereFilter where = WhereFilter.builder()
.valueGeoRange(WhereFilter.GeoRange.builder()
.geoCoordinates(WhereFilter.GeoCoordinates.builder()
.latitude(50.51f)
.longitude(0.11f)
.build()
)
.distance(WhereFilter.GeoDistance.builder()
.max(3000f)
.build()
)
.build()
)
.operator(Operator.WithinGeoRange)
.path(new String[]{ "add" })
.build();

client.graphQL().aggregate().withWhere(where)...

Before:

// import io.weaviate.client.v1.graphql.query.argument.WhereArgument;
// import io.weaviate.client.v1.graphql.query.argument.WhereOperator;

WhereArgument where = WhereArgument.builder()
.valueText("txt")
.operator(WhereOperator.Equal)
.path(new String[]{ "add" })
.build();

client.graphQL().aggregate().withWhere(where)...

After:

// import io.weaviate.client.v1.filters.Operator;
// import io.weaviate.client.v1.filters.WhereFilter;

WhereFilter where = WhereFilter.builder()
.valueText("txt")
.operator(Operator.Equal)
.path(new String[]{ "add" })
.build();

client.graphQL().aggregate().withWhere(where)...

Before:

// import io.weaviate.client.v1.graphql.query.argument.WhereArgument;
// import io.weaviate.client.v1.graphql.query.argument.WhereFilter;
// import io.weaviate.client.v1.graphql.query.argument.WhereOperator;

WhereArgument where = WhereArgument.builder()
.operands(new WhereFilter[]{
WhereFilter.builder()
.valueInt(10)
.path(new String[]{ "wordCount" })
.operator(WhereOperator.LessThanEqual)
.build(),
WhereFilter.builder()
.valueText("word")
.path(new String[]{ "word" })
.operator(WhereOperator.LessThan)
.build()
})
.operator(WhereOperator.And)
.build();

client.graphQL().aggregate().withWhere(where)...

After:

// import io.weaviate.client.v1.filters.Operator;
// import io.weaviate.client.v1.filters.WhereFilter;

WhereFilter where = WhereFilter.builder()
.operands(new WhereFilter[]{
WhereFilter.builder()
.valueInt(10)
.path(new String[]{ "wordCount" })
.operator(Operator.LessThanEqual)
.build(),
WhereFilter.builder()
.valueText("word")
.path(new String[]{ "word" })
.operator(Operator.LessThan)
.build(),
})
.operator(Operator.And)
.build();

client.graphQL().aggregate().withWhere(where)...
Classification

Before:

// import io.weaviate.client.v1.classifications.model.GeoCoordinates;
// import io.weaviate.client.v1.classifications.model.Operator;
// import io.weaviate.client.v1.classifications.model.WhereFilter;
// import io.weaviate.client.v1.classifications.model.WhereFilterGeoRange;
// import io.weaviate.client.v1.classifications.model.WhereFilterGeoRangeDistance;

WhereFilter where = WhereFilter.builder()
.valueGeoRange(WhereFilterGeoRange.builder()
.geoCoordinates(GeoCoordinates.builder()
.latitude(50.51f)
.longitude(0.11f)
.build())
.distance(WhereFilterGeoRangeDistance.builder()
.max(3000d)
.build())
.build())
.operator(Operator.WithinGeoRange)
.path(new String[]{ "geo" })
.build();

client.classifications().scheduler().withTrainingSetWhereFilter(where)...

After:

// import io.weaviate.client.v1.filters.Operator;
// import io.weaviate.client.v1.filters.WhereFilter;

WhereFilter where = WhereFilter.builder()
.valueGeoRange(WhereFilter.GeoRange.builder()
.geoCoordinates(WhereFilter.GeoCoordinates.builder()
.latitude(50.51f)
.longitude(0.11f)
.build())
.distance(WhereFilter.GeoDistance.builder()
.max(3000f)
.build())
.build())
.operator(Operator.WithinGeoRange)
.path(new String[]{ "geo" })
.build();

client.classifications().scheduler().withTrainingSetWhereFilter(where)...

Releases

Go to the GitHub releases page to see the history of the Java client library releases.

Click here for a table of Weaviate and corresponding client versions

This table lists the Weaviate core versions and corresponding client library versions.

Weaviate
(GitHub)
First
release date
Python
(GitHub)
TypeScript/
JavaScript
(GitHub)
Go
(GitHub)
Java
(GitHub)
1.27.x2024-10-164.9.x3.2.x4.16.x5.0.x
4.9.x
1.26.x2024-07-224.7.x3.1.x4.15.x4.8.x
1.25.x2024-05-104.6.x2.1.x4.13.x4.6.x
1.24.x2024-02-274.5.x2.0.x4.10.x4.4.x
1.23.x2023-12-183.26.x1.5.x4.10.x4.4.x
1.22.x2023-10-273.25.x1.5.x4.10.x4.3.x
1.21.x2023-08-173.22.x1.4.x4.9.x4.2.x
1.20.x2023-07-063.22.x1.1.x4.7.x4.2.x
1.19.x2023-05-043.17.x1.1.x14.7.x4.0.x
1.18.x2023-03-073.13.x2.14.x4.6.x3.6.x
1.17.x2022-12-203.9.x2.14.x4.5.x3.5.x
1.16.x2022-10-313.8.x2.13.x4.4.x3.4.x
1.15.x2022-09-073.6.x2.12.x4.3.x3.3.x
1.14.x2022-07-073.6.x2.11.x4.2.x3.2.x
1.13.x2022-05-033.4.x2.9.x4.0.x2.4.x
1.12.x2022-04-053.4.x2.8.x3.0.x2.3.x
1.11.x2022-03-143.2.x2.7.x2.6.x2.3.x
1.10.x2022-01-273.1.x2.5.x2.4.x2.1.x
1.9.x2021-12-103.1.x2.4.x2.4.x2.1.x
1.8.x2021-11-303.1.x2.4.x2.3.x1.1.x
1.7.x2021-09-013.1.x2.4.x2.3.x1.1.x
1.6.x2021-08-112.4.x2.3.x2.2.x1.0.x
1.5.x2021-07-132.2.x2.1.x2.1.x1.0.x
1.4.x2021-06-092.2.x2.1.x2.1.x1.0.x
1.3.x2021-04-232.2.x2.1.x2.1.x1.0.x
1.2.x2021-03-152.2.x2.0.x1.1.x-
1.1.x2021-02-102.1.x---
1.0.x2021-01-142.0.x---

TypeScript client change

The TypeScript client replaced the JavaScript client on 2023-03-17.

Questions and feedback

If you have any questions or feedback, let us know in the user forum.