Spring AI 2.0

When upgrading to Spring AI 2.0, refer to the Upgrade Notes for newly introduced APIs, deprecated APIs, and breaking changes.

The io.arconia.rewrite.spring.ai2.UpgradeSpringAi_2_0 recipe automates most of the changes introduced in Spring AI 2.0. You can use it to update your project to the latest Spring AI 2.0.x release.

The recipe will:

  • Upgrade all org.springframework.ai dependencies to the 2.0.x release line.

  • Rename Spring AI configuration properties to match the new property names (including flattening the .options. infix on embedding, image, audio, moderation, and OCR keys, and renaming spring.ai.ollama.chat.think-option to spring.ai.ollama.chat.think).

  • Comment out properties removed in 2.0, including each provider’s spring.ai.<provider>.chat.options.internal-tool-execution-enabled, spring.ai.google.genai.chat.options.tool-names, spring.ai.chat.client.tool-calling.stream-tool-call-responses, and spring.ai.chat.client.tool-search-advisor.stream-tool-call-responses.

  • Pass ChatOptions.Builder (rather than a built ChatOptions) to ChatClient.options(…​) and ChatClient.Builder.defaultOptions(…​).

  • Rename the tool-registration methods ChatClient.ChatClientRequestSpec.toolCallbacks(…​) and ChatClient.Builder.defaultToolCallbacks(…​) to tools(…​) and defaultTools(…​), aligning with the new tool-calling API.

  • Rename ChatModel.getDefaultOptions() to getOptions().

  • Rename JsonParser.getObjectMapper() to JsonParser.getJsonMapper().

  • Rename the N(Integer) builder method to n(Integer) on ImageOptionsBuilder, OpenAiChatOptions.Builder, and OpenAiImageOptions.Builder to align with Java naming conventions.

  • Apply the dependency rename from spring-ai-advisors-vector-store to spring-ai-vector-store-advisor.

  • Update type references such as PromptChatMemoryAdvisorMessageChatMemoryAdvisor, OpensearchContainerOpenSearchContainer, and ChatClientCustomizerChatClientBuilderCustomizer.

  • For Anthropic: relocate Anthropic types (AnthropicCacheOptions, AnthropicCacheStrategy, AnthropicCacheTtl, CacheEligibilityResolver, CitationDocumentAnthropicCitationDocument) from org.springframework.ai.anthropic.api to org.springframework.ai.anthropic. Note that constructing AnthropicChatModel from an AnthropicApi no longer applies in 2.0 because the AnthropicApi type and the matching constructor have been removed in favour of the official com.anthropic:anthropic-java SDK; that step requires manual migration.

  • For MCP (Model Context Protocol): adopt the new spring-ai-mcp-annotations artifact in place of org.springaicommunity:mcp-annotations; move the MCP Spring WebFlux and WebMvc artifacts from io.modelcontextprotocol.sdk to org.springframework.ai; relocate the community MCP packages under org.springaicommunity.mcp (annotation, context, method, provider) to the corresponding sub-packages of org.springframework.ai.mcp.annotation; and move MCP transport types from io.modelcontextprotocol to the corresponding org.springframework.ai.mcp.{client,server}.{webflux,webmvc}.transport packages. Replace deprecated McpSchema record constructors (TextContent, ReadResourceResult, GetPromptResult, ProgressNotification) with their builder(…​) factories.

  • For Mistral AI: rename MistralAiEmbeddingOptions.Builder methods withModel(…​) and withEncodingFormat(…​) to model(…​) and encodingFormat(…​), and consolidate deprecated MistralAiApi.ChatModel aliases onto their canonical MISTRAL_*, MINISTRAL_*, and DEVSTRAL names.

  • For OpenAI: rename the spring-ai-openai-sdk and spring-ai-starter-model-openai-sdk artifacts to drop the -sdk suffix, and remove the Azure OpenAI artifacts (spring-ai-azure-openai, spring-ai-starter-model-azure-openai, spring-ai-autoconfigure-model-azure-openai), which have been discontinued in Spring AI 2.0. Migrate OpenAiApi.ChatModel constants to com.openai.models.ChatModel from the openai-java SDK (case-normalising names such as GPT_4_OGPT_4O), OpenAiApi.EmbeddingModel constants to com.openai.models.embeddings.EmbeddingModel, and OpenAiImageApi.ImageModel constants to com.openai.models.images.ImageModel (fixing the upstream GTP_IMAGE_1_MINI typo to GPT_IMAGE_1_MINI in the process). Rename getValue() calls on these enums to asString() to match the openai-java API. Relocate the audio types OpenAiAudioApi.SpeechRequest.Voice and OpenAiAudioApi.SpeechRequest.AudioResponseFormat to OpenAiAudioSpeechOptions, and migrate OpenAiAudioApi.TranscriptResponseFormat to com.openai.models.audio.AudioResponseFormat. Relocate org.springframework.ai.openai.api.ResponseFormat to OpenAiChatModel.ResponseFormat and replace the deprecated new ResponseFormat(type, jsonSchema) constructor with the equivalent ResponseFormat.builder().type(…​).jsonSchema(…​).build() form. Replace string-literal OpenAiEmbeddingOptions.Builder.encodingFormat(String) calls such as .encodingFormat("float") with the matching OpenAiEmbeddingOptions.EncodingFormat enum constant.

  • For Google: relocate GoogleGenAiEmbeddingConnectionDetails to the org.springframework.ai.google.genai.embedding sub-package.

  • Remove the discontinued spring-ai-hanadb-store and spring-ai-spring-cloud-bindings artifacts.

See its entry in the Recipe Catalog for the full list of recipes this upgrade applies, each with its options and a before/after example.

Run the Recipe

You can apply this recipe with any OpenRewrite-compatible tool. The tabs below show three of them: the Arconia CLI, the OpenRewrite Gradle plugin, and the OpenRewrite Maven plugin. See Running Recipes for a comparison of when to pick each one.

  • Arconia CLI

  • Gradle

  • Maven

arconia update spring-ai --to-version 2.0

First, create an init.gradle file in your project root with the following content.

initscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath("org.openrewrite:plugin:latest.release")
    }
}

rootProject {
    plugins.apply(org.openrewrite.gradle.RewritePlugin)
    dependencies {
        rewrite("io.arconia.migrations:rewrite-spring:latest.release")
    }

    // Remove when project repositories are disabled
    afterEvaluate {
        if (repositories.isEmpty()) {
            repositories {
                mavenCentral()
            }
        }
    }

    configurations.named("rewrite") {
        canBeConsumed = false
    }
}

Then, run the following command.

./gradlew rewriteRun \
    --init-script init.gradle \
    --no-parallel \
    -DactiveRecipe=io.arconia.rewrite.spring.ai2.UpgradeSpringAi_2_0

You can remove the init.gradle file afterwards.

./mvnw -U org.openrewrite.maven:rewrite-maven-plugin:run \
  -Drewrite.recipeArtifactCoordinates=io.arconia.migrations:rewrite-spring:LATEST \
  -Drewrite.activeRecipes=io.arconia.rewrite.spring.ai2.UpgradeSpringAi_2_0