Skip to content

scip-java: index fails on Windows — Maven wrapper resolved as mvnw, never mvnw.cmd #991

Description

@carheart

scip-java: index fails on Windows — Maven wrapper resolved as mvnw, never mvnw.cmd

Repo: scip-code/scip-java
Affected: v0.12.3 (Scala) and v0.13.1 (Kotlin rewrite) — verified in both
Platform: Windows (any); reproduced on Windows 11 Pro 10.0.26200, x64
Severity: blocks scip-java index entirely on Windows for every Maven-wrapper project


Summary

MavenBuildTool selects the Maven executable by probing for a file literally named mvnw. On
Windows the Maven wrapper is mvnw.cmd; mvnw is a POSIX shell script with no PE header, so
ProcessBuilder.start() fails immediately with CreateProcess error=193.

The fallback branch (else "mvn") is only reached when mvnw is absent — but the file is present
in a standard Maven-wrapper checkout, so on Windows the code takes the broken branch precisely when
a wrapper exists.

Reproduction

git clone https://github.com/spring-projects/spring-petclinic
cd spring-petclinic
scip-java index

On Windows:

java.io.IOException: Cannot run program "c:\…\spring-petclinic\mvnw"
  (in directory "c:\…\spring-petclinic"): CreateProcess error=193,
  %1 is not a valid Win32 application
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1170)
    at os.proc.spawn(ProcessOps.scala:129)
    at com.sourcegraph.scip_java.commands.IndexCommand.process(IndexCommand.scala:122)
    at com.sourcegraph.scip_java.buildtools.MavenBuildTool.generateSemanticdb(MavenBuildTool.scala:72)
    at com.sourcegraph.scip_java.buildtools.MavenBuildTool.generateScip(MavenBuildTool.scala:21)
Caused by: java.io.IOException: CreateProcess error=193, %1 is not a valid Win32 application

(mvnw.cmd sits in the same directory, unused.)

Source

scip-java/src/main/kotlin/org/scip_code/scip_java/buildtools/MavenBuildTool.kt (v0.13.1, L22-25):

val mvnw = index.workingDirectory.resolve("mvnw")
val mavenScript =
    if (Files.isRegularFile(mvnw) && Files.isExecutable(mvnw)) mvnw.toString()
    else "mvn"

Identical logic existed in the Scala MavenBuildTool.scala:72 at v0.12.3. Confirmed independently
by extracting strings from the published MavenBuildTool.class in the 0.12.3 release artifact: it
contains exactly mvnw and mvn, with no .cmd variant and no OS branch.

Note Files.isExecutable(mvnw) returns true on Windows for a text file — NTFS has no execute
bit and the JDK reports read access — so the guard does not prevent the bad branch.

Suggested fix

private val isWindows =
    System.getProperty("os.name").orEmpty().startsWith("Windows", ignoreCase = true)

val mavenScript = sequenceOf(
        if (isWindows) index.workingDirectory.resolve("mvnw.cmd") else null,
        index.workingDirectory.resolve("mvnw"),
    )
    .filterNotNull()
    .firstOrNull { Files.isRegularFile(it) }
    ?.toString()
    ?: if (isWindows) "mvn.cmd" else "mvn"

Preferring mvnw.cmd on Windows and keeping mvnw elsewhere is the minimal change. The PATH
fallback likely also wants mvn.cmd on Windows, since a PATH mvn may be a shell script there too.

GradleBuildTool has the same shape at L77 (resolve("gradlew") with no gradlew.bat) and is
worth fixing in the same pass — though in practice Gradle projects fail earlier, for the separate
reason in the companion issue.

Impact

Windows users get a hard failure with a stack trace pointing at ProcessBuilder, which reads as an
environment problem rather than a wrapper-selection bug. There is no flag to work around it:
--build-tool gradle routes to GradleBuildTool, which fails for a different Windows-specific
reason (see companion issue).

Environment

  • Windows 11 Pro 10.0.26200 (x64), 24 cores
  • Eclipse Temurin JDK 17.0.20 and 21.0.12 both present
  • scip-java 0.12.3 launched via Coursier (cs launch com.sourcegraph:scip-java_2.13:0.12.3)
  • Fixture: spring-petclinic (ships both mvnw and mvnw.cmd)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions