Kotlin and Spring:

The Modern Server Side Stack

Rod Johnson, Embabel
Creator of Spring

Why This Talk?

  • The JVM is not just legacy—it's the future
  • Kotlin and Spring are the power duo for modern backend
  • Server-side development is evolving
  • This deck was built by an agent—written in Kotlin, powered by Spring

My Language Adventures Over The Last Decade

Language Verdict
Scala Elegant, but too clever for mortals
TypeScript Love the language, but Node is messy
Python Getting better, but still thumbs its nose at CS
Modern Java Improved a lot—Spring is a relief after Node/Python
Kotlin The best of both worlds

JVM: The Unsung Hero

  • Robust performance
  • Mature ecosystem
  • Cross-platform
  • Security and GC
  • JVM languages: Kotlin, Scala, Java—interoperable and future-proof

Spring: The Backbone of Enterprise

spring

  • Comprehensive, modular, flexible
  • Spring Boot: Rapid development
  • Spring Security: Robust auth
  • Spring Cloud: Microservices
  • Scales from startup to enterprise
  • How much of the world's most valuable code is written

Kotlin: The Pragmatic Modern Language

kotlin

Why Kotlin?

  • Concise, expressive, safe

  • Null safety built-in

  • Extension functions

  • Great for DSLs

  • Highly readable

  • Interoperable with Java

  • Plays nice with Java ecosystem, unlike Scala

  • Kotlin just feels right...created by practitioners

Kotlin + Spring: Perfect Together

  • Spring's annotations work naturally in Kotlin
  • Kotlin data classes + @ConfigurationProperties = type-safe config
  • Null safety + Spring: fewer runtime errors
  • Close cooperation between teams:
    • Kotlin compiler plugin for Spring
    • Spring extension functions, @NonNull annotations etc.
    • More on the way!

Real-World Example: @Service in Kotlin

@Service
class NewsService(val repository: NewsRepository) {
    fun latestHeadlines(): List<News> = repository.findLatest()
}
  • No need for 'open' keyword thanks to kotlin-spring plugin
  • Clean, idiomatic Kotlin

Data Classes + @ConfigurationProperties

@ConfigurationProperties("app.news")
data class NewsConfig(
    val feedUrl: String,
    val refreshInterval: Duration = Duration.ofMinutes(10)
)
  • Immutable, concise, type-safe configuration
  • Sensible defaults & nullability

Kotlin Reification: Type-Safe Generics

inline fun <reified O> AgentProcess.resultOfType(): O = resultOfType(O::class.java)
  • Reification and extension functions work great to extend Java APIs
  • No more ugly class references
  • Type checks/casts at runtime
  • Always ensure you have a form Java can call with Class<O>

Java Consuming Kotlin: Natural Interop

@Autowired
private NewsService newsService;

public List<News> findStarNews() {
    return newsService.latestHeadlines()
        .stream()
        .filter(news -> news.isStarred())
        .collect(Collectors.toList());
}
  • Java calls Kotlin as if it were Java
  • Seamless integration
  • If you're writing a framework, always consider Java users. But the work to support them in an idiomatic way is modest

Under the Hood: Kotlin 'open' in pom.xml

<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <configuration>
        <compilerPlugins>
            <plugin>spring</plugin>
        </compilerPlugins>
    </configuration>
</plugin>
  • Automatically opens Spring-annotated classes
  • Prevents proxy errors

This Deck: Built by an Agent

  • Generated by Embabel: agent framework written in Kotlin using Spring
    • Manual changes relatively minor (mainly deleting some slides)
  • Input was YAML file describing narrative
  • All code examples were taken from the source code by the agent
  • Not just a demo—this is agentic software in action
  • The code that built this deck is available

Why Do We Need Agents?

embabel

The Following are Necessary but not Sufficient

  • Better models--and improvement may be slowing
  • MCP - essential integration resource, but doesn't solve discoverability or control flow
  • Spring AI/LangChain level frameworks
    • Low level, analogous to servlet API
    • Wrong level for sophisticated applications
  • Orchestration is vital
    • Naive approaches like state machines are not enough
    • Need predictability, understandability, extensibility, safety, and ability to mix models

Embabel: Core Concepts

  • Agents, Actions, Goals, Conditions
  • Planning toward goals (extensible, no modification)
  • Rich domain model: domain object methods exposed as LLM tools
  • Annotation-driven, Spring-style

Embabel Planning Model

  • PlanningSystem: set of actions & goals
  • Planner: plans from current world state to goal
  • @Agent, @Action, @Condition: expose logic as tools
  • LLMs can call domain methods directly

embabel

Example: Annotated Actions

@Agent
class PresentationMaker @Autowired constructor(...) {
    @Action
    fun identifyResearchTopics(request: PresentationRequest): List<Topic>

    @Action
    fun researchTopics(topics: List<Topic>): List<ResearchReport>

    @Action
    fun createDeck(...): SlideDeck
    // ...more actions
}
  • Modular, composable steps
  • Each @Action is a discrete, callable step, either prompted or Kotlin or Java
  • Designed for easy unit and integration testing

The Narrative: kotlinconf_presentation.yml

  • Defines slide count, presenter, and brief
  • Requests (does not choose) code examples, images, objectives
  • Enables agentic presentation creation
  • Agent mixes multiple LLM calls for extensive research and content creation with programmatic actions for generating deck with MARP and expanding images

Why Kotlin + Spring for Agents?

  • Spring: Access to existing code and infrastructure, convenient configuration
  • Kotlin: Concise, null-safe, modern language
  • Together: Build robust, maintainable, intelligent agents

Next Steps

  • Try Embabel: See the code that built this deck
  • Experience agentic systems powered by Kotlin + Spring
  • Help us build the future on Kotlin and Spring!

Thank You!

embabel

References

_background: url('https://raw.githubusercontent.com/embabel/embabel-agent/refs/heads/main/embabel-agent-api/images/315px-Meister_der_Weltenchronik_001.jpg')