1
0
Files
spring-ai-2-migration/run.txt
Ankur cb777068a7 Spring AI 1.x to 2.0 migration: breaking-change reference and offline verification suite
Companion code for the ankurm.com guide. Verified on Spring AI 2.0.0, Spring Boot 4.1.0,
JDK 25.0.3. run.txt is unedited mvn test output: 5 tests, 0 failures.

Runs with NO API key, no network and no provider account. A canned ChatModel returns fixed
responses; ChatClient, advisors and chat memory all sit above the model, so everything that
changed is still exercised faithfully. TestChatModel records each Prompt it receives, which
lets the tests assert what Spring AI SENT rather than what a model replied.

docs/01  complete breaking-change reference: platform (Boot 4 mandatory, Jackson 2 to 3),
         artifact renames (spring-ai-advisors-vector-store -> spring-ai-vector-store-advisor,
         spring-ai-core split, OCI and Minimax removals, MCP transports moved into Spring AI),
         options builders replacing setters, the dropped .options property prefix, tool
         calling (internalToolExecutionEnabled and toolNames removed outright, not renamed),
         chat memory, structured output schema changes, and a migration order that works.

Tested here
  - Chat memory becomes stricter: 2.0 removes the remaining default-ID and builder-based
    configuration paths (ChatMemory.DEFAULT_CONVERSATION_ID and .conversationId() are both
    gone). Explicit per-request conversation ids - introduced during the 1.x line and already
    the recommended approach - become the only migration target.
  - CONVERSATION_ID survives as the metadata KEY. It and the removed DEFAULT_CONVERSATION_ID
    look interchangeable and are opposites; swapping them to clear a compile error restores
    exactly the shared-conversation behaviour that removing it was meant to take away.
  - PromptChatMemoryAdvisor is gone; MessageChatMemoryAdvisor replaces it, and the difference
    is not cosmetic (system-prompt text vs real Message objects, so token counts change).
  - A test asserts two conversation ids cannot see each other.
2026-08-01 10:51:02 +05:30

121 lines
13 KiB
Plaintext

mvn.cmd : WARNING: A restricted method in java.lang.System has been called
At line:5 char:1
+ & $mvn -B test *> run.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (WARNING: A rest...has been called:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
WARNING: java.lang.System::load has been called by org.fusesource.jansi.internal.JansiLoader in an unnamed module
(file:/C:/Users/Ankur/ankurm-blog-tools/apache-maven-3.9.9/lib/jansi-2.4.1.jar)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by
com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper
(file:/C:/Users/Ankur/ankurm-blog-tools/apache-maven-3.9.9/lib/guava-33.2.1-jre.jar)
WARNING: Please consider reporting this to the maintainers of class
com.google.common.util.concurrent.AbstractFuture$UnsafeAtomicHelper
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.ankurm.ai:spring-ai-2-migration >-----------------
[INFO] Building Spring AI 1.x to 2.0 migration 1.0.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.5.0:resources (default-resources) @ spring-ai-2-migration ---
[INFO] skip non existing resourceDirectory C:\Users\Ankur\ankurm-blog-tools\projects\spring-ai-2-migration\src\main\resources
[INFO] skip non existing resourceDirectory C:\Users\Ankur\ankurm-blog-tools\projects\spring-ai-2-migration\src\main\resources
[INFO]
[INFO] --- compiler:3.15.0:compile (default-compile) @ spring-ai-2-migration ---
[INFO] Nothing to compile - all classes are up to date.
[INFO]
[INFO] --- resources:3.5.0:testResources (default-testResources) @ spring-ai-2-migration ---
[INFO] skip non existing resourceDirectory C:\Users\Ankur\ankurm-blog-tools\projects\spring-ai-2-migration\src\test\resources
[INFO]
[INFO] --- compiler:3.15.0:testCompile (default-testCompile) @ spring-ai-2-migration ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 1 source file with javac [debug parameters release 25] to target\test-classes
[INFO]
[INFO] --- surefire:3.5.6:test (default-test) @ spring-ai-2-migration ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.ankurm.ai.ChatMemoryMigrationTest
==============================================================================
4. Proving isolation, now that explicit ids are the only path
==============================================================================
bob's prompt: USER what did you hear?
>> Passing distinct ids keeps the conversations separate -- and in 2.0
>> there is no longer a way NOT to pass one. Under 1.x the same code
>> with the ids omitted would have compiled, put alice and bob in the
>> shared 'default' conversation, and failed this assertion silently.
==============================================================================
1. ChatMemory.DEFAULT_CONVERSATION_ID has been removed
==============================================================================
public constants on ChatMemory : [CONVERSATION_ID]
Note the survivor is CONVERSATION_ID, the metadata key you use to PASS an id.
The removed one was DEFAULT_CONVERSATION_ID, the value 'default' used when you
passed nothing. Same prefix, opposite meaning -- so 'fixing' the compile error by
swapping one for the other restores exactly the shared-conversation behaviour
that removing it was meant to take away.
==============================================================================
2. PromptChatMemoryAdvisor has been removed
==============================================================================
PromptChatMemoryAdvisor : ClassNotFoundException (as expected in 2.0)
MessageChatMemoryAdvisor: org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor
Replacement is MessageChatMemoryAdvisor. The difference is not cosmetic: the
removed one injected history into the SYSTEM PROMPT as text, the replacement
adds it as real Message objects. Providers treat those differently, so expect
your prompts -- and your token counts -- to change on migration.
==============================================================================
5. Direct ChatMemory use, for the storage-layer migration
==============================================================================
stored: first
stored: second
after clear: 0 messages
>> If you use a JDBC/Cassandra/Mongo/Neo4j ChatMemoryRepository, note a
>> separate 2.0 change: retrieved messages now carry a creation
>> timestamp in metadata, so a message read back is NOT equals() to an
>> identical one built in code. Any test or cache keyed on Message
>> equality, or storing Messages in a Set, will change behaviour.
==============================================================================
3. The conversation ID is now required, per request
==============================================================================
turn 1 -- conversation 'user-42'
turn 2 -- same conversation
messages the model received on turn 2 : 3
USER my name is Ankur
ASSISTANT hello back
USER what is my name?
>> The id travels as an advisor PARAM per request, not as builder state.
>> This form already existed in 1.x; 2.0 removes the alternatives, so it
>> is now the only option. That suits how the id is actually scoped: in a
>> web app it is per user or per session, and therefore cannot sensibly
>> be baked into a singleton ChatClient.
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.336 s -- in com.ankurm.ai.ChatMemoryMigrationTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.939 s
[INFO] Finished at: 2026-08-01T10:50:45+05:30
[INFO] ------------------------------------------------------------------------