Skip to content

Keep Java Runtime.exec replacements out of non-Java sources - #990

Draft
martinfrancois wants to merge 1 commit into
openrewrite:mainfrom
martinfrancois:repro/runtime-exec-kotlin-guard
Draft

Keep Java Runtime.exec replacements out of non-Java sources#990
martinfrancois wants to merge 1 commit into
openrewrite:mainfrom
martinfrancois:repro/runtime-exec-kotlin-guard

Conversation

@martinfrancois

@martinfrancois martinfrancois commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Suggested review order: 10 of 52 (Score: 8)
Review first: #1006

What's changed?

Restricts ReplaceDeprecatedRuntimeExecMethods to Java compilation units by combining its Java 18 precondition with JavaFileChecker.

The Kotlin regression test is now a passing no-change test. The complete ReplaceDeprecatedRuntimeExecMethodsTest class has 10 passing tests, including the existing Java transformations.

What's your motivation?

Recipe: org.openrewrite.staticanalysis.ReplaceDeprecatedRuntimeExecMethods.

ReplaceDeprecatedRuntimeExecMethods.getVisitor() previously checked only for Java 18. That version marker also exists on Kotlin source, so the JavaIsoVisitor applied a Java template to Kotlin.

Before

class A {
    fun method() {
        val process = Runtime.getRuntime().exec("ls -a")
    }
}

Actual after the recipe

class A {
    fun method() {
        val process = Runtime.getRuntime().exec(new String[] {"ls", "-a"})
    }
}

new String[] {...} is Java syntax and does not compile as Kotlin.

Expected after the recipe

(unchanged)

The recipe MUST NOT apply Java-only templates to non-Java compilation units.

I found this while preparing #976, which fixes a separate defect in the same recipe. Its description disclosed this Kotlin failure but does not fix it.

Confirmed real-world execution

The project uses JDK 25. The released recipe changes its Kotlin Runtime.exec(String) call to Java new String[] {...} syntax, which is invalid Kotlin.

Anything in particular you'd like reviewers to focus on?

Please review the positive JavaFileChecker guard. It keeps the existing Java 18 requirement and excludes Kotlin and other non-Java compilation units from the Java-specific implementation.

Have you considered any alternatives or workarounds?

A Kotlin-specific implementation can use arrayOf("ls", "-a"). That expands the recipe's supported languages and requires separate Kotlin transformation logic. This change instead preserves the recipe's existing Java behavior and prevents invalid output in other languages.

Any additional context

Pre-existing tests changed: None.

This change was prepared with AI assistance. I reviewed the implementation, Kotlin output, tests, and contribution text.

Checklist

@martinfrancois martinfrancois changed the title ReplaceDeprecatedRuntimeExecMethods: add failing test for Kotlin sources Restrict ReplaceDeprecatedRuntimeExecMethods to Java sources Aug 15, 2026
@martinfrancois
martinfrancois force-pushed the repro/runtime-exec-kotlin-guard branch from 4d47237 to 129ba8b Compare August 15, 2026 21:20
@martinfrancois martinfrancois changed the title Restrict ReplaceDeprecatedRuntimeExecMethods to Java sources Keep Java Runtime.exec replacements out of non-Java sources Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant