Bump project to Java 17#779
Merged
Merged
Conversation
The springai sample modules require Java 17 (Spring AI 1.1 needs Spring Boot 3.x, which needs Java 17). Running spotlessCheck on Java 11 made google-java-format choke on text blocks in those sources with "unclosed string literal" errors. Bump the format job's setup-java to 17 so it can parse the springai sources. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Spring AI requires Java 17, but parts of the build (CI Docker image, root Java target, format-job JDK) were still pinned to Java 11. The follow-on for the spring-ai work was a partial bump that only fixed the format job. This finishes the bump everywhere: - docker/github/Dockerfile: eclipse-temurin:11-focal -> :17-jammy. This is the image the unittest CI job runs ./gradlew test inside. - build.gradle: drop the Spring-Boot-version-conditional Java target (Spring Boot 2.7 runs fine on Java 17, so there's no reason to pin source/target compatibility to 11). - springboot-basic/build.gradle: drop a dead isJava11Compatible() branch (both arms were identical). - ci.yml: keep Java 17 for the format job; clean up the inline comment that framed it as a springai-only exception. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
maciejdudko
approved these changes
May 1, 2026
donald-pinckney
added a commit
that referenced
this pull request
May 1, 2026
Adds Spring AI to the module list at the top, describes the four nested samples (basic, mcp, multimodel, rag) under a new "Running Spring AI Samples" section, and consolidates the per-sample Java version notes into a single "Java 17+ for all samples" line now that #779 bumped the project-wide target. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
donald-pinckney
added a commit
that referenced
this pull request
May 1, 2026
* Spring AI samples * Fix sample configs and remove runtimeOnly workarounds - Remove runtimeOnly spring-ai-rag and spring-ai-mcp from shared config (no longer needed after T6 plugin split in sdk-java) - Fix workflow class package references (old prototype packages) - Add web-application-type: none to RAG and multimodel configs - Exclude conflicting chat auto-configs in multimodel sample All 5 samples now boot successfully against a Temporal dev server. MCP sample requires Node.js/npx for the MCP server. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * Update samples for T15: remove @DeterministicTool and sandboxing sample - StringTools: remove @DeterministicTool (plain tools run in workflow context by default now) - Delete springai-sandboxing sample (SandboxingAdvisor removed from SDK) - Update comments referencing @DeterministicTool Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * Clean up Spring AI samples PR for merge - Remove committed build/ directories and add them to .gitignore. - Gate includeBuild('../sdk-java') on sibling checkout existence so the build works out-of-the-box when the springai samples are not being touched (and will resolve cleanly once temporal-spring-ai publishes). - core: pin io.grpc:grpc-util version explicitly and switch the SSL sample to AdvancedTlsX509KeyManager.updateIdentityCredentials (non-deprecated API) to fix compilation under -Werror with the composite-build grpc. - springai-multimodel: fix doc mismatch on model names, route unprefixed input to the "default" model, drop hard-coded model-version hints from system prompts. - springai-rag: correct Javadoc to match actual code (no EmbeddingModelActivity), accept bare "ask" as a usage-prompt trigger, normalize text block indentation. - springai-mcp: fix advisor name comment, normalize text block indentation. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Use mavenLocal for temporal-spring-ai instead of composite build Replace the includeBuild('../sdk-java') dependency-substitution block with a plain mavenLocal() repository and a pinned 1.35.0-SNAPSHOT coordinate for the springai* samples. Build temporal-spring-ai locally with `./gradlew publishToMavenLocal` in an sdk-java checkout and the samples pick it up via mavenLocal — no composite build, no SDK-wide substitution. A nice side-effect: the core module no longer has a newer grpc forced onto its classpath, so the SSL sample's gRPC workarounds (explicit grpc-util dep + updateIdentityCredentials switch) are no longer needed. Revert them. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Add TASK_QUEUE.json tracking remaining PR work Tracks the mavenLocal workaround unwind (blocked on temporal-spring-ai publishing) and unaddressed reviewer threads. Delete before merge. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Updated after changes to Spring AI * Add snipsync markers to Spring AI samples Wraps natural snippet boundaries in the spring-ai samples so the docs/spring-ai-integration page can pull canonical code via snipsync instead of carrying inline copies. Six markers added: - samples-java-spring-ai-chat-workflow-init: ChatWorkflowImpl @WorkflowInit - samples-java-spring-ai-activity-tool: WeatherActivity interface - samples-java-spring-ai-side-effect-tool: TimestampTools class - samples-java-spring-ai-plain-tool: StringTools class - samples-java-spring-ai-per-model-options: ChatModelConfig per-model bean - samples-java-spring-ai-provider-options: MultiModelWorkflowImpl think route Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * spring-ai samples: pin to released temporal-spring-ai 1.35.0 temporal-spring-ai is now on Maven Central. Drop the mavenLocal() repository and the SNAPSHOT pin that were bridging the gap; the springai* samples now resolve from mavenCentral like everything else. springAiSdkVersion stays separate from javaSDKVersion because the spring-ai module requires a newer SDK than the rest of the samples currently pin. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Group spring-ai samples under a single springai/ directory Moves the four spring-ai sample modules from top-level peers into nested subprojects of springai/, so the repo root has one springai/ instead of four (springai, springai-mcp, springai-multimodel, springai-rag). Each module keeps its own build.gradle and Spring Boot entry point — only the directory layout and Gradle project paths change. Invocations become :springai:basic, :springai:mcp, etc. Also folds in the earlier simplification: now that javaSDKVersion is 1.35.0 globally, gradle/springai.gradle drops the separate springAiSdkVersion variable and references the global one directly. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai/mcp: await initialization in chat signal handler Replaces the early-return-with-placeholder pattern in McpWorkflowImpl.chat() with Workflow.await(() -> initialized). Signals can yield, so awaiting is the idiomatic Temporal way to handle "operation arrived before init finished" — the client's signal RPC has already returned, and the workflow-side handling just resumes once run() completes MCP tool discovery and finishes building the chat client. listTools() stays placeholder-based because it's a @QueryMethod and queries cannot yield. Addresses brianstrauch review comment on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai/multimodel: drop redundant default: CLI prefix The CLI exposed both `default:` and `openai:` prefixes, which both ended up calling OpenAI — ChatModelConfig declares @primary on openAiChatModel, so ActivityChatModel.forDefault() resolves to it. Reviewers reasonably found this confusing. Drop the explicit `default:` prefix; route no-prefix input to the "default" workflow client instead. The chatClients entry stays so the sample still demonstrates both forDefault() (@primary resolution) and forModel(name) (explicit lookup) — added a comment block at the registration site explaining that the dual entry is intentional. Addresses brianstrauch review comment on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai/rag: show usage when add/search are typed without args Reviewer noted that bare `ask` falls through to printing usage but bare `add` or `search` did not — the startsWith check required a trailing space. Apply the same equals|startsWith pattern that the ask branch already uses, with a length guard around the substring. Addresses brianstrauch review comment on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Add ai-sdk to CODEOWNERS for springai * springai/multimodel: include "think" in chat() javadoc model names The javadoc listed "openai", "anthropic", "default" but the workflow also accepts "think" (Anthropic with extended thinking enabled). Add it to the @param doc so users don't send a name and wonder why it falls through to the unknown-model branch. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai/basic: explain why run()'s systemPrompt parameter is unused @WorkflowInit requires the constructor and the @WorkflowMethod to share a parameter list, so run(String) must take systemPrompt even though only the constructor uses it. Add a comment so readers don't trip over the apparent unused parameter (and so static analyzers that flagged it have an explanation in-source). Addresses Copilot review on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * gradle/springai: document the Spring Boot plugin/BOM version skew The root build.gradle pins the Spring Boot Gradle plugin at springBootPluginVersion (2.7.13) for the legacy springboot/ samples, while Spring AI 1.1.0 needs Spring Boot 3.5.x via BOM import. The plugin and BOM are independent enough that this works in practice, but a future reader (or static analyzer) reasonably gets confused. Add a comment block explaining the trade-off and naming the two follow-up paths that would actually fix it (move plugin out of root plugins block, or migrate legacy springboot/ to 3.x). Addresses Copilot review on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * .gitignore: collapse per-module build/out entries into globs Replaces twelve explicit per-module entries (/build, /core/build, /springai/basic/build, ...) with two globs (**/build/, **/out/) so new sample modules don't need a .gitignore edit. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * README: document Spring AI samples and Java 17 requirement Adds Spring AI to the module list at the top, describes the four nested samples (basic, mcp, multimodel, rag) under a new "Running Spring AI Samples" section, and consolidates the per-sample Java version notes into a single "Java 17+ for all samples" line now that #779 bumped the project-wide target. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai samples: address Copilot review nits Five small fixes flagged in PR #775 review: - Rename springai/basic/src/main/resources/application.yml to .yaml to match the convention used by every other sample in the repo. - Fix the @code ./gradlew :example-* paths in McpApplication, RagApplication, and MultiModelApplication javadocs to the actual module paths (:springai:mcp, :springai:rag, :springai:multimodel). - Add spring.main.web-application-type: none to springai/mcp's application.yaml. The module pulls in spring-boot-starter-webflux which would otherwise spin up a reactive web server we don't want. Matches the other three springai samples. - Drop stale references to EmbeddingModelActivity from the RagApplication javadoc and startup banner. The sample uses VectorStoreActivity exclusively; embeddings are produced inside the configured Spring AI VectorStore, not via a separate activity. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Untrack .vscode/ IDE settings Slipped into the previous commit via git add -A. .vscode/ is per-developer IDE config — add to .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * undo gitignore change * springai/multimodel: use LinkedHashMap for chatClients The unknown-model error message renders chatClients.keySet() into lastResponse, which is workflow state. HashMap iteration order isn't guaranteed across JVMs, so a replay on a different worker could produce a different rendered string and surface as a non-determinism error. LinkedHashMap iterates in insertion order, which is deterministic regardless of JVM. Addresses Copilot review on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai/rag: capture lastResponse before signaling, not after waitForResponse() previously read getLastResponse() *after* the signal had been sent. If the workflow processed the signal between the signal call and the first poll, the captured baseline was already the new response and the loop waited for a second change that never came, then timed out. Fix matches the pattern McpApplication uses: capture previousResponse before the signal, pass it into waitForResponse, and poll for a value different from that pre-signal baseline. Addresses Copilot review on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * springai/multimodel: capture previous response before signaling Same bug pattern that RagApplication had: the polling loop compared against an empty-string baseline, so the very first poll could return the stale prior response and print it as if it were the new one. Capture previousResponse before sending the chat signal and wait until getLastResponse() differs from that pre-signal baseline. Also drop the redundant initial Thread.sleep(100) — the loop's own sleep handles backoff, and reading immediately is fine when we're comparing against the pre-signal baseline. Addresses Copilot review on PR #775. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Remove TASK_QUEUE.json Internal tracking file scoped to PR #775. All listed tasks and review threads have been resolved or replied to; the file's job is done. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]> * Update README.md Co-authored-by: Maciej Dudkowski <[email protected]> --------- Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Maciej Dudkowski <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Spring AI work surfaced that the project's CI and build settings still pinned Java 11 in several places. This PR moves to Java 17 everywhere:
docker/github/Dockerfile:eclipse-temurin:11-focal→:17-jammy(image used by the unittest CI job)build.gradle: drop the Spring-Boot-version-conditional Java target (Spring Boot 2.7 runs on Java 17 fine)springboot-basic/build.gradle: drop a deadisJava11Compatible()branch with identical armsci.yml: keep Java 17 on the Code format job (cherry-picked from the in-flight Spring AI samples PR), clean up the inline comment that framed it as a springai-only exceptionSplit out from #775 so the Java-version bump can be reviewed independently.
Test plan
./gradlew clean spotlessCheck compileJavapasses locally