Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pre-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
if: github.event.inputs.sdkJavaVersion != ''
with:
distribution: "temurin"
java-version: "21"
java-version: "25"
- name: Setup Gradle
if: github.event.inputs.sdkJavaVersion != ''
uses: gradle/actions/setup-gradle@v3
Expand Down
24 changes: 0 additions & 24 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ jobs:

java-hello-world-gradle.zip
java-hello-world-maven.zip
java-hello-world-new-api-gradle.zip
java-hello-world-new-api-maven.zip
java-hello-world-maven-spring-boot.zip
java-hello-world-new-api-maven-spring-boot.zip
java-hello-world-maven-quarkus.zip
java-hello-world-lambda-cdk.zip
java-tour-of-orchestration.zip
Expand Down Expand Up @@ -145,27 +142,6 @@ jobs:
with:
source-directory: java/templates/java-maven-spring-boot
destination-repo: java-spring-boot-template
copy-java-new-api-maven-template:
name: Copy Java New API Maven template to java-new-api-maven-template repo
uses: ./.github/workflows/copy-to-repo.yml
secrets: inherit
with:
source-directory: java/templates/java-new-api-maven
destination-repo: java-new-api-maven-template
copy-java-new-api-gradle-template:
name: Copy Java New API Gradle template to java-new-api-gradle-template repo
uses: ./.github/workflows/copy-to-repo.yml
secrets: inherit
with:
source-directory: java/templates/java-new-api-gradle
destination-repo: java-new-api-gradle-template
copy-java-new-api-spring-boot-template:
name: Copy Java New API Spring boot template to java-new-api-spring-boot-template repo
uses: ./.github/workflows/copy-to-repo.yml
secrets: inherit
with:
source-directory: java/templates/java-new-api-maven-spring-boot
destination-repo: java-new-api-spring-boot-template
copy-kotlin-template:
name: Copy Kotlin template to kotlin-template repo
uses: ./.github/workflows/copy-to-repo.yml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
RESTATE_DISABLE_TELEMETRY: "true"
strategy:
matrix:
jvm-version: [ 21 ]
jvm-version: [ 25 ]

steps:
- uses: actions/checkout@v3
Expand Down
3 changes: 0 additions & 3 deletions .tools/prepare_release_zip.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ create_release_zip java/integrations/java-gradle-lambda-cdk java-hello-world-lam
create_release_zip java/patterns-use-cases java-patterns-use-cases
create_release_zip java/templates/java-gradle java-hello-world-gradle
create_release_zip java/templates/java-maven java-hello-world-maven
create_release_zip java/templates/java-new-api-gradle java-hello-world-new-api-gradle
create_release_zip java/templates/java-new-api-maven java-hello-world-new-api-maven
create_release_zip java/templates/java-maven-spring-boot java-hello-world-maven-spring-boot
create_release_zip java/templates/java-new-api-maven-spring-boot java-hello-world-new-api-maven-spring-boot
create_release_zip java/templates/java-maven-quarkus java-hello-world-maven-quarkus
create_release_zip java/tutorials/tour-of-orchestration-java java-tour-of-orchestration
create_release_zip java/tutorials/tour-of-workflows-java java-tour-of-workflows
Expand Down
3 changes: 0 additions & 3 deletions .tools/run_jvm_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ PROJECT_ROOT="$(dirname "$SELF_PATH")/.."

pushd $PROJECT_ROOT/java/templates/java-gradle && ./gradlew --console=plain check && popd
pushd $PROJECT_ROOT/java/templates/java-maven && mvn -B verify && popd
pushd $PROJECT_ROOT/java/templates/java-new-api-gradle && ./gradlew --console=plain check && popd
pushd $PROJECT_ROOT/java/templates/java-new-api-maven && mvn -B verify && popd
pushd $PROJECT_ROOT/java/templates/java-maven-quarkus && mvn -B verify && popd
pushd $PROJECT_ROOT/java/templates/java-maven-spring-boot && mvn -B verify && popd
pushd $PROJECT_ROOT/java/templates/java-new-api-maven-spring-boot && mvn -B verify && popd
pushd $PROJECT_ROOT/kotlin/templates/kotlin-gradle && ./gradlew --console=plain check && popd
pushd $PROJECT_ROOT/kotlin/templates/kotlin-gradle-spring-boot && ./gradlew --console=plain check && popd

Expand Down
3 changes: 0 additions & 3 deletions .tools/update_jvm_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ function search_and_replace_version_maven() {

search_and_replace_version_gradle $PROJECT_ROOT/java/templates/java-gradle
search_and_replace_version_maven $PROJECT_ROOT/java/templates/java-maven
search_and_replace_version_gradle $PROJECT_ROOT/java/templates/java-new-api-gradle
search_and_replace_version_maven $PROJECT_ROOT/java/templates/java-new-api-maven
search_and_replace_version_maven $PROJECT_ROOT/java/templates/java-maven-quarkus
search_and_replace_version_maven $PROJECT_ROOT/java/templates/java-maven-spring-boot
search_and_replace_version_maven $PROJECT_ROOT/java/templates/java-new-api-maven-spring-boot
search_and_replace_version_gradle $PROJECT_ROOT/kotlin/templates/kotlin-gradle
search_and_replace_version_gradle $PROJECT_ROOT/kotlin/templates/kotlin-gradle-spring-boot

Expand Down
14 changes: 10 additions & 4 deletions java/basics/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ repositories {
mavenCentral()
}

val restateVersion = "2.7.0"
val restateVersion = "2.9.0"

dependencies {
annotationProcessor("dev.restate:sdk-api-gen:$restateVersion")

// Restate SDK
implementation("dev.restate:sdk-java-http:$restateVersion")

Expand All @@ -27,7 +25,7 @@ dependencies {

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(25))
}
}

Expand All @@ -38,10 +36,18 @@ application {
} else {
mainClass.set("durable_execution.RoleUpdateService")
}
// Java 25 warnings: --enable-native-access for the Restate SDK state machine, --sun-misc-unsafe-memory-access for netty.
applicationDefaultJvmArgs = listOf("--enable-native-access=ALL-UNNAMED", "--sun-misc-unsafe-memory-access=allow")
}

tasks.withType<JavaCompile> {
// Using -parameters allows to use Jackson ParameterName feature
// https://github.com/FasterXML/jackson-modules-java8/tree/2.14/parameter-names
options.compilerArgs.add("-parameters")
}

tasks.named<Test>("test") {
useJUnitPlatform()
// Java 25 warnings: --enable-native-access for the Restate SDK state machine, --sun-misc-unsafe-memory-access for netty.
jvmArgs("--enable-native-access=ALL-UNNAMED", "--sun-misc-unsafe-memory-access=allow")
}
Binary file modified java/basics/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 3 additions & 1 deletion java/basics/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
13 changes: 5 additions & 8 deletions java/basics/gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 12 additions & 24 deletions java/basics/gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions java/basics/src/main/java/building_blocks/MyService.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package building_blocks;

import dev.restate.sdk.Context;
import dev.restate.sdk.Restate;
import dev.restate.sdk.annotation.Handler;
import dev.restate.sdk.annotation.Service;
import dev.restate.sdk.endpoint.Endpoint;
import dev.restate.sdk.http.vertx.RestateHttpServer;
import virtual_objects.GreeterObjectClient;
import virtual_objects.GreeterObject;

import java.time.Duration;
import java.util.UUID;
Expand All @@ -31,43 +31,43 @@ public class MyService {
// This handler can be called over HTTP at http://restate:8080/MyService/handlerName
// Use the context to access Restate's durable building blocks
@Handler
public void run(Context ctx) throws Exception {
public void run() throws Exception {
// 1. IDEMPOTENCY: Add an idempotency key to the header of your requests
// Restate deduplicates calls automatically. Nothing to do here.

// 2. DURABLE RPC: Call other services without manual retry and deduplication logic
// Restate persists all requests and ensures execution till completion
String result = GreeterObjectClient.fromContext(ctx, "my-obj-key").greet("hello").await();
String result = Restate.virtualObject(GreeterObject.class, "my-obj-key").greet("hello");

// 3. DURABLE MESSAGING: send (delayed) messages to other services without deploying a message broker
// Restate persists the timers and triggers execution
GreeterObjectClient.fromContext(ctx, "my-obj-key").send().greet("hello");
Restate.virtualObjectHandle(GreeterObject.class, "my-obj-key").send(GreeterObject::greet, "hello");

// 4. DURABLE PROMISES: tracked by Restate, can be moved between processes and survive failures
// Awakeables: block the workflow until notified by another handler
var awakeable = ctx.awakeable(String.class);
var awakeable = Restate.awakeable(String.class);
// Wait on the promise
// If the process crashes while waiting, Restate will recover the promise somewhere else
String greeting = awakeable.await();
// Another process can resolve the awakeable via its ID
ctx.awakeableHandle(awakeable.id()).resolve(String.class, "hello");
Restate.awakeableHandle(awakeable.id()).resolve(String.class, "hello");

// 5. DURABLE TIMERS: sleep or wait for a timeout, tracked by Restate and recoverable
// When this runs on FaaS, the handler suspends and the timer is tracked by Restate
// Example of durable recoverable sleep
// If the service crashes two seconds later, Restate will invoke it after another 3 seconds
ctx.sleep(Duration.ofSeconds(5));
Restate.sleep(Duration.ofSeconds(5));
// Example of waiting on a promise (call/awakeable/...) or a timeout
awakeable.await(Duration.ofSeconds(5000));
// Example of scheduling a handler for later on
GreeterObjectClient.fromContext(ctx, "my-obj-key").send().ungreet(Duration.ofDays(1));
Restate.virtualObjectHandle(GreeterObject.class, "my-obj-key").send(GreeterObject::ungreet, Duration.ofDays(1));

// 7. PERSIST RESULTS: avoid re-execution of actions on retries
// Use this for non-deterministic actions or interaction with APIs, DBs, ...
// For example, generate idempotency keys that are stable across retries
// Then use these to call other APIs and let them deduplicate
String paymentDeduplicationID = UUID.randomUUID().toString();
ctx.run(() -> chargeBankAccount(paymentDeduplicationID, 100));
Restate.run("charge-bank-account", () -> chargeBankAccount(paymentDeduplicationID, 100));
}

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package durable_execution;

import dev.restate.sdk.Context;
import dev.restate.sdk.Restate;
import dev.restate.sdk.annotation.Handler;
import dev.restate.sdk.annotation.Service;
import dev.restate.sdk.endpoint.Endpoint;
Expand Down Expand Up @@ -33,18 +33,18 @@
public class SubscriptionService {

@Handler
public void add(Context ctx, SubscriptionRequest req) {
// Restate persists the result of all `ctx` actions and recovers them after failures
public void add(SubscriptionRequest req) {
// Restate persists the result of all `Restate` actions and recovers them after failures
// For example, generate a stable idempotency key:
var paymentId = ctx.random().nextUUID().toString();
var paymentId = Restate.random().nextUUID().toString();

// ctx.run persists results of successful actions and skips execution on retries
// Restate.run persists results of successful actions and skips execution on retries
// Failed actions (timeouts, API downtime, etc.) get retried
var payRef = ctx.run(String.class, () ->
var payRef = Restate.run("createRecurringPayment", String.class, () ->
createRecurringPayment(req.creditCard(), paymentId));

for (String subscription : req.subscriptions()) {
ctx.run(() -> createSubscription(req.userId(), subscription, payRef));
Restate.run("createSubscription", () -> createSubscription(req.userId(), subscription, payRef));
}
}

Expand Down
Loading
Loading