Skip to main content

Proof of value (POV) process

Moderne automates code maintenance tasks like framework migrations, security vulnerability fixes, and code quality improvements. Work that traditionally takes months can be completed in minutes, freeing developers to focus on delivering business value.

This guide walks through a typical proof of value (POV) process to help you evaluate Moderne's capabilities. We recommend starting with lower-risk tasks like code quality improvements before moving to more complex migrations.

Progression from simple to complex automation tasks

Proof of value steps

  1. Platform provisioning - Moderne provisions an isolated platform in your chosen cloud provider and region (takes ~1 hour).

  2. Mass Ingest - Your team sets up an ingestion pipeline to build and publish LST artifacts for your repositories. You should start with 100 or more diverse repositories for best results. This step does not require you to make any changes to the repositories themselves (such as installing build plugins).

  3. Agent setup - Your team sets up the Moderne agent following our on-premise agent configuration doc. The agent runs as a Docker image or JAR and connects to your source code manager (SCM) and artifact repository using read-only service accounts (takes less than 1 hour with accounts ready).

  4. Run recipes - With everything set up, you can now run recipes against your code. We strongly recommend starting with simple code quality improvement recipes before progressing to complex migrations. You can find our recommended recipes to run and examples of what they do in the next section of this doc.

  5. Study results - After you've run a recipe, you should generate data tables and visualizations to learn more about what happened.

note

The recipes below progress from simple to complex. Links go to the public Moderne Platform where you can test on open-source repositories. You can also run these recipes using the CLI commands provided in each section.

Code quality recipes

Common static analysis issues

Resolves common static analysis issues (SAST issues) to improve code quality, fix mistakes, eliminate legacy patterns, and resolve performance issues.

CLI commands

mod run . --recipe org.openrewrite.staticanalysis.CommonStaticAnalysis
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Static analysis fixes

Logging improvements

Parameterize SLF4J logging statements

Converts string concatenation in log statements to parameterized logging for significant performance boosts, especially when log levels are disabled.

CLI commands

mod run . --recipe org.openrewrite.java.logging.slf4j.ParameterizedLogging
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Logging improvements

Complete exception logging

Ensures exceptions are logged with full stack traces rather than just messages. Many exception types lack useful messages, and stack traces are critical for debugging.

CLI commands

mod run . --recipe org.openrewrite.java.logging.slf4j.CompleteExceptionLogging
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Adding useful exceptions to logs

Dependency management

Dependency insight for Gradle and Maven

Finds all dependencies (including transitive) across Gradle and Maven projects. Useful for identifying version inconsistencies that can cause runtime issues.

CLI commands

# Example: Find all Jackson library versions
mod run . --recipe org.openrewrite.java.dependencies.DependencyInsight \
-P "groupIdPattern=com.fasterxml.jackson.*" \
-P "artifactIdPattern=*" \
-P "scope=runtime"

mod study . --last-recipe-run --data-table DependenciesInUse

Recipe results

A data table that includes information about what repositories use the dependency we specified above.

A visualization generated from the recipe results that shows the different versions of the specified dependencies across the selected repositories.

Update Gradle wrapper

Updates Gradle wrapper to the latest version, querying services.gradle.org for available releases while respecting your artifact repository configuration.

CLI commands

mod run . --recipe org.openrewrite.gradle.UpdateGradleWrapper
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Updating the Gradle wrapper

Update Gradle plugins

Updates Gradle plugins by ID to newer versions.

CLI commands

# Update specific plugin - adjust parameters for your plugins
mod run . --recipe org.openrewrite.gradle.plugins.UpgradePluginVersion \
--recipe-option "pluginIdPattern=org.springframework.boot" \
--recipe-option "newVersion=3.4.x"

mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

An example build.gradle change.

Security

Find secrets

Locates secrets like passwords, API keys, and tokens stored in plain text.

CLI commands

mod run . --recipe org.openrewrite.java.security.secrets.FindSecrets
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Example of a secret being found in the code.

Use secure random

Replaces java.util.Random with cryptographically secure java.security.SecureRandom.

CLI commands

mod run . --recipe org.openrewrite.java.security.SecureRandom
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Example demonstrating Random being replaced with SecureRandom.

Java security best practices

Applies multiple security improvements including XML parser XXE vulnerability fixes, secure temporary file creation, Zip slip vulnerability remediation, file descriptor leak prevention, and loop condition safety checks.

CLI commands

mod run . --recipe org.openrewrite.java.security.JavaSecurityBestPractices
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Example demonstrating how this recipe handles security issues such as the Zip slip vulnerability.

OWASP Top Ten

Identifies and remediates vulnerabilities from the OWASP Top Ten including broken access control, cryptographic failures, injection, security misconfiguration, vulnerable components, and data integrity failures.

CLI commands

mod run . --recipe org.openrewrite.java.security.OwaspTopTen
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Example demonstrating how this recipe fixes security issues such as CSRF attacks.

A vulnerability report that includes detailed information about the affected artifact and the corresponding CVEs.

The vulnerablity report also shows the severity of the CVE and the depth (transitivity) of the dependency. ~80% of vulnerable dependencies are transitive.

Find and fix vulnerable dependencies

Software composition analysis (SCA) tool that detects and upgrades dependencies with known CVEs. Uses GitHub Security Advisory Database which aggregates multiple vulnerability databases including the National Vulnerability Database.

CLI commands

mod run . --recipe org.openrewrite.java.dependencies.DependencyVulnerabilityCheck \
-P "scope=runtime" \
-P "overrideTransitive=True" \
-P "maximumUpgradeDelta=patch"

mod study . --last-recipe-run --data-table VulnerabilityReport

Recipe results

Example demonstrating how this recipe updates minor versions to get critical security fixes.

A vulnerability report that includes detailed information about the affected artifact and the corresponding CVEs.

The vulnerablity report also shows the severity of the CVE and the depth (transitivity) of the dependency. ~80% of vulnerable dependencies are transitive.

Test modernization

JUnit Jupiter best practices

Migrates to JUnit 5 and applies best practices to tests. This recipe will: migrate from JUnit 4.x to JUnit Jupiter, statically import JUnit Jupiter assertions, remove the test prefix and public visibility from JUnit 5 tests, add @ParameterizedTest annotations, and improve lifecycle methods – among other things.

CLI commands

mod run . --recipe org.openrewrite.java.testing.junit5.JUnit5BestPractices
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Applying best practices to JUnit tests.

AssertJ best practices

Migrates assertions to AssertJ for better readability. Migrates from JUnit, Hamcrest, Fest, and TestNG assertions, statically imports assertThat, simplifies chained assertions, and adopts type-specific assertions.

CLI commands

mod run . --recipe org.openrewrite.java.testing.assertj.Assertj
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Applying AssertJ best practices to a test class.

Major migrations

Major migrations are complex transformations that typically automate 80-90% of the work, with the remainder requiring manual developer intervention. They are typically composed of multiple, complex recipes.

Migrate to Java 21

Comprehensive migration from Java 8/11 to Java 21. Updates build files for Java 21 target/source, replaces deprecated APIs, adopts new language features, upgrades plugins to Java 21 compatible versions, and updates GitHub Actions configurations.

CLI commands

mod run . --recipe org.openrewrite.java.migrate.UpgradeToJava21
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Updating the Java version

Fixing deprecated methods

Spring Boot 3.5 best practices

Migrates to Spring Boot 3.5 and applies best practices. Includes upgrades from prior Spring Boot versions with configuration updates and dependency alignment.

CLI commands

mod run . --recipe io.moderne.java.spring.boot3.SpringBoot3BestPractices
mod study . --last-recipe-run --data-table SourcesFileResults

Recipe results

Applying Spring Boot best practices to a Java class.

Impact analysis

Impact analysis helps you understand the consequences of changes before making them. Use these recipes to identify what will be affected: