Java SDK

The Java SDK provides a code-first approach to developing Kalix applications. This SDK offers a way to develop applications which should be familiar to someone who has worked with Spring applications by making use of annotations to assemble Kalix and its components.

When using the Kalix Java SDK, your services are exposed using traditional Spring REST annotations and serialization is backed by the ubiquitous Jackson library.

If you’re new to Kalix and the different types of entities that exist in a Kalix app, consider reading this section before continuing.

Prerequisites

The following are required to develop services in Java:

Java

Kalix requires Java 17 or later.

Apache Maven

Kalix relies on Apache Maven new tab as build tool.

Docker

Kalix requires Docker new tab 20.10.14 for building your service images. Most popular build tools have plugins that assist in building Docker images.

Getting Started

You can start a new Kalix service using our Getting started guide.

On the other hand, if you would rather spend some time exploring our documentation, here are some main features you will find in this section:

Spring Boot Integration

The Kalix Java SDK provides a familiar developer experience for Java developers that are used to Spring. Its Main class is annotated with @SpringBootApplication and starts exactly the same way as a common Spring Boot application, namely by calling SpringApplication.run(Main.class, args).

For all matters, it’s a Spring Boot application that runs and connects with the Kalix Runtime. As such, your application can benefit of most features available to Spring applications. However, some features are not available or are not recommended when building a Kalix application based on the Java SDK. Those are explained in the sections below.

Dependency Injection

Actions, Entities and Views are all Kalix components, and they get special treatment.

When your application starts, it will scan the classpath for any class extending one of the Kalix components. Each time such a component is found, it’s analysed in order to generate the necessary metadata that Kalix requires to be able to interact with them. The component is then registered to Kalix and made available to the Runtime through Kalix internal protocol.

It’s important to understand that interacting directly with a Kalix component is NOT possible. All interactions must happen through the Runtime since that’s how Kalix manages state and distribution. Therefore, it’s not possible to use dependency injection to inject Kalix components inside other components and doing so will raise a runtime error.

On the other hand, it is possible to inject non-Kalix classes into Kalix components. Any Spring bean defined in your application can be injected into a Kalix component. However, you must keep in mind that Kalix components can only receive other dependencies through constructor injection.

For more details on how Kalix manage state and distribution, consult the Programming model page.

@Transactional

Kalix is a stateful serverless solution and as such it takes care of all the aspects of persisting data in a distributed environment. Using @Transactional annotations on methods have no effect because the database access and transactional management won’t happen at the level of the Spring container. All database operations take place within the Kalix Runtime side.

Moreover, and also related with the subject of transactions, each entity in Kalix lives in its own transactional boundary. Therefore, it’s not possible to send two commands to two different entities and have them be applied in the same transaction.

Kalix is a distributed runtime and two different entities may be located on different JVMs, on different nodes, running on different hardware, making it, if not impossible, extremely expensive and inefficient to mutate two different entities on the same transaction.

Spring Repositories

Spring developers are used to build Spring Data Repositories to store and retrieve data. However, in Kalix these tasks are fulfilled by the Runtime, not by the Spring container. As stateful serverless solution, Kalix takes care of all data persistence for you. Configuring your own Spring Data Repositories means that you will need to manage the database yourself and that defeats the purpose of using Kalix. Therefore, the usage of Spring Data Repositories is not recommended.

In Kalix, data storage and retrieval follows the Command Query Responsibility Segregation (CQRS) pattern. In CQRS, we work with two models. One that is designed for writes, often called the command-model, and one that is optimized for reads, also known as the query-model.

The persistent Kalix entities (Event Sourced Entity and Value Entity) represent the command-model in the CQRS pattern. They receive Commands and mutate data in their own transaction.

Data produced by entities can be propagated to Views in order to generate query-models, also known as view-models. Views are indexed representations of your model. You can query your data using different fields, while Entities are only accessible by their entity id.

In both cases, Kalix manages all persistence aspects and your code only need to specify the business logic.