Skip to content
Open
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
6 changes: 3 additions & 3 deletions .github/workflows/manual-publish-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
cache: 'maven'

- name: Build Native Binary
run: ./mvnw clean package -Pnative,prod -DskipTests
run: ./mvnw clean package -Pprod -DskipTests

- name: Log in to the Container registry
uses: docker/login-action@v3
Expand All @@ -56,8 +56,8 @@ jobs:
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.native
build-args: BINARY=prebuilt
file: ./Dockerfile
build-args: JAR_SOURCE=build
platforms: ${{ matrix.platform }}
push: true
tags: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ jobs:
run: mvn -B versions:set -DnewVersion=${{ needs.prepare-release.outputs.release-version }} -DgenerateBackupPoms=false

- name: Build Native Binary
run: ./mvnw clean package -Pnative,prod -DskipTests
run: ./mvnw clean package -Pprod -DskipTests

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
Expand All @@ -149,8 +149,8 @@ jobs:
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.native
build-args: BINARY=prebuilt
file: ./Dockerfile
build-args: JAR_SOURCE=build
platforms: ${{ matrix.platform }}
push: true
tags: |
Expand Down
40 changes: 32 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# Build arg to select JAR source: "build" (compile from source) or "prebuilt" (use pre-built JAR)
ARG JAR_SOURCE=build

# Builder stage — compiles JAR from source with frontend (default)
FROM eclipse-temurin:25-jdk AS build
WORKDIR /build
COPY .mvn .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline -B
COPY src src
RUN ./mvnw clean package -Pprod -DskipTests \
&& cp target/turtorial-*.jar /turtorial.jar

# Prebuilt stage — copies JAR from build context (CI or local pre-built)
FROM scratch AS prebuilt
COPY target/turtorial-*.jar /turtorial.jar

# Select JAR source based on ARG (BuildKit skips unused stages)
FROM ${JAR_SOURCE} AS jar

FROM ubuntu:24.04 AS base

# Set install locations
Expand All @@ -22,9 +42,15 @@ RUN apt-get update && apt-get install -y \
nano \
&& rm -rf /var/lib/apt/lists/*

# Install Temurin JDK 25
RUN mkdir -p $JAVA_HOME \
&& curl -L "https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.1%2B8/OpenJDK25U-jdk_aarch64_linux_hotspot_25.0.1_8.tar.gz" | tar -xz -C $JAVA_HOME --strip-components=1
# Install Temurin JDK 25 (detect architecture automatically)
RUN ARCH=$(uname -m) \
&& case "$ARCH" in \
x86_64) TEMURIN_ARCH="x64" ;; \
aarch64) TEMURIN_ARCH="aarch64" ;; \
*) echo "Unsupported architecture: $ARCH" && exit 1 ;; \
esac \
&& mkdir -p $JAVA_HOME \
&& curl -L "https://api.adoptium.net/v3/binary/latest/25/ga/linux/${TEMURIN_ARCH}/jdk/hotspot/normal/eclipse?project=jdk" | tar -xz -C $JAVA_HOME --strip-components=1

# Install Maven
RUN mkdir -p $MAVEN_HOME \
Expand All @@ -48,10 +74,8 @@ RUN mkdir -p /home/turtorial/.ssh \
# Create app directory
WORKDIR /app

# Copy the built application
# Assumes `mvn clean package` has been run locally
ARG JAR_FILE=target/turtorial-*-SNAPSHOT.jar
COPY ${JAR_FILE} /app/turtorial.jar
# Copy the JAR from the selected source
COPY --from=jar /turtorial.jar /app/turtorial.jar

# Change ownership of the app directory
RUN chown -R turtorial:turtorial /app
Expand All @@ -69,4 +93,4 @@ EXPOSE 8080
RUN mkdir -p /app/lessons

# Run the application
ENTRYPOINT ["java", "-jar", "/app/turtorial.jar"]
ENTRYPOINT ["java", "-jar", "/app/turtorial.jar"]
18 changes: 17 additions & 1 deletion examples/moderne-spring-boot-migration/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ FROM turtorial:latest AS base
################################################################################

USER root

# # Install Temurin JDK 17 (needed for Spring Boot 2.7 migration workshop)
# # Note: turtorial:latest installs Java 25 to /opt/java/openjdk
# RUN mkdir -p /opt/java/openjdk17 \
# && curl -L "https://api.adoptium.net/v3/binary/latest/17/ga/linux/aarch64/jdk/hotspot/normal/eclipse" | tar -xz -C /opt/java/openjdk17 --strip-components=1

# # Set JAVA_HOME to Java 17 for the workshop exercises
# ENV JAVA_HOME=/opt/java/openjdk17
# ENV PATH=$JAVA_HOME/bin:$PATH

ARG MODERNE_CLI_STAGE=stable
ARG MODERNE_CLI_VERSION
# Set the environment variable MODERNE_CLI_VERSION
Expand Down Expand Up @@ -67,4 +77,10 @@ RUN mkdir -p /home/turtorial/workspaces/step1 \
# Copy over our lessons
COPY --chown=turtorial:turtorial lessons /app/lessons

WORKDIR /home/turtorial
WORKDIR /home/turtorial

ENV SPRING_PROFILES_ACTIVE=prod

# Run the application
# ENTRYPOINT ["/app/turtorial"]
ENTRYPOINT ["java", "-jar", "/app/turtorial.jar"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Workshop Overview
section: Introduction
order: 1
---
# Preparing for Spring Boot Migration

Spring Boot migrations are rarely just a version bump. You need to understand your repositories, identify hidden dependencies, align build tooling, and plan release waves so downstream services can upgrade safely. This workshop walks you through a realistic, end-to-end prep flow using the Moderne CLI so you can move into a Spring Boot 4 migration with fewer surprises.

## Workshop Overview

In this workshop, you will:

1. **Assess**: Run an initial migration and gather code insight data.
2. **Plan**: Analyze dependencies and organize upgrade waves.
3. **Baseline**: Normalize Maven, Java, and Spring Boot versions.
4. **Smoke Test**: Upgrade to Java 17 and run a Spring Boot 4 smoke test.
5. **Migrate**: Finish the migration in waves using custom recipes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: Environment Setup
section: Introduction
order: 2
---
# Environment Setup

This tutorial runs in a pre-configured environment with the Moderne CLI (`mod`) and necessary build tools (Maven, Java).

The example repositories have been cloned into your workspace at `/home/turtorial/moderne-migration-practice` (referred to as `$WORKSHOP`).

Let's start by setting up some environment variables to make the commands easier to run.

```bash
export WORKSHOP=/home/turtorial/moderne-migration-practice
export WORKSPACE=/home/turtorial/workspaces/migration-practice-workspace
export PROJECTS=/home/turtorial/projects
```

Now, let's create our workspace directory and sync the repositories.

```bash
mkdir -p $WORKSPACE
cd $WORKSPACE

# Sync the repositories from the workshop configuration
mod git sync csv $WORKSPACE $WORKSHOP/repos.csv --with-sources
```

Verify that the repositories are synced:

```bash
ls -F $WORKSPACE
```

You should see a directory structure corresponding to the repositories.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: Build LSTs
section: Introduction
order: 3
---
# Build LSTs

To run recipes, we need to build Lossless Semantic Trees (LSTs) for the projects.

```bash
mod build $WORKSPACE
```

This might take a few minutes as it compiles the projects and generates the LSTs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Install Recipes
section: Introduction
order: 4
---
# Install Recipes

We'll install the necessary recipes for this workshop.

```bash
mod config recipes jar install \
io.moderne.recipe:rewrite-spring:0.19.0 \
org.openrewrite.recipe:rewrite-migrate-java:3.24.0 \
org.openrewrite.recipe:rewrite-java-dependencies:1.48.0 \
org.openrewrite:rewrite-java:8.69.0 \
org.openrewrite:rewrite-maven:8.69.0 \
io.moderne.recipe:rewrite-devcenter:1.13.1 \
org.openrewrite.recipe:rewrite-spring:6.21.0 \
org.openrewrite.recipe:rewrite-testing-frameworks:3.24.0
```

Now you are ready to start the assessment!

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: Full Migration Dry Run
section: Assessment
order: 5
---
# Exercise 1: Run the Full Migration Recipe (Dry Run)

In this module, you will run the Spring Boot 4 migration recipe to find the biggest risks and blockers. The idea is to see what breaks before investing time in fixes.

First, let's run a "dry run" of the full Spring Boot 4 migration recipe. This will not modify the code but will identify what changes would be made and what errors might occur.

```bash
mod run $WORKSPACE --recipe io.moderne.java.spring.boot4.UpgradeSpringBoot_4_0 --dry-run
```

Review the output. You might see warnings or errors related to missing types or compilation failures. This is expected!

Specifically, look for errors related to `QueryDSL` (generated code issues) or missing dependencies.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Identify Java Version
section: Assessment
order: 6
---
# Exercise 2: Identify Java Version Usage

Let's see what Java versions are currently in use across the repositories.

```bash
mod run $WORKSPACE --recipe org.openrewrite.java.migrate.search.PlanJavaMigration --dry-run
```

To see the data table produced by this recipe:

```bash
mod study $WORKSPACE --last-recipe-run --data-table org.openrewrite.java.migrate.table.JavaVersionMigrationPlan
```

You should see that most projects are on Java 8.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: Inspect Spring Boot Version
section: Assessment
order: 7
---
# Exercise 3: Inspect Spring Boot Versions

Now, let's find out which Spring Boot versions are currently used.

```bash
mod run $WORKSPACE --recipe org.openrewrite.java.dependencies.DependencyInsight --dry-run \
--recipe-option groupPattern=org.springframework.boot \
--recipe-option artifactPattern=* \
--recipe-option scope=runtime
```

Check the results:

```bash
mod study $WORKSPACE --last-recipe-run --data-table org.openrewrite.maven.table.DependenciesInUse
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Find javax.* Usage
section: Assessment
order: 8
---
# Exercise 4: Find `javax.*` Usage

Spring Boot 3+ (and thus 4) moves from `javax.*` to `jakarta.*`. High usage of `javax.*` means more work.

```bash
mod run $WORKSPACE --recipe org.openrewrite.java.search.FindTypes --dry-run \
--recipe-option fullyQualifiedTypeName=javax..*
```

Check the results:

```bash
mod study $WORKSPACE --last-recipe-run --data-table org.openrewrite.java.search.TypeUses
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Locate Code Generators
section: Assessment
order: 9
---
# Exercise 5: Locate Code Generators (QueryDSL)

Code generators like QueryDSL can be major blockers. Let's find where they are used.

```bash
mod run $WORKSPACE --recipe org.openrewrite.maven.search.FindPlugin --dry-run \
--recipe-option groupId=com.mysema.maven \
--recipe-option artifactId=apt-maven-plugin
```

Check the results:

```bash
mod study $WORKSPACE --last-recipe-run --data-table org.openrewrite.maven.table.SearchResults
```

You should see usage in several services.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Assessment Quiz
section: Assessment
order: 10
---
# Quiz

Why is it important to run a dry run and code insight recipes before starting the actual migration?

1. To generate more code.
2. To identify blockers, dependencies, and plan the migration strategy.
3. To fix bugs automatically without checking.
4. To update the Java version immediately.

**Correct Answer**: 2
Loading