Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ static Exceptional<JDK> of(final Path path) {
home = home.getParent();
}

if (!home.resolve("bin/java").toFile().exists()) {
LOGGER.warn("The JDK Home [{0}] does not contain bin/java", home);
if (!home.resolve("bin/java").toFile().exists() && !home.resolve("bin/java.exe").toFile().exists()) {
LOGGER.warn("The JDK Home [{0}] does not contain bin/java or bin/java.exe", home);
return Exceptional.empty();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import build.spawn.application.option.Orphanable;
import build.spawn.jdk.AbstractTemplatedJDKLauncher;
import build.spawn.jdk.JDKApplication;
import build.spawn.jdk.OperatingSystem;
import build.spawn.jdk.agent.SpawnAgent;
import build.spawn.jdk.agent.SpawnAgentArchiveBuilder;
import build.spawn.jdk.option.JDKAgent;
Expand Down Expand Up @@ -74,7 +75,11 @@ public class LocalJDKLauncher

@Override
public Optional<Executable> getExecutable(final ConfigurationBuilder options) {
return Optional.of(Executable.of(options.get(JDKHome.class).get() + "/bin/java"));
// the JDK is launched on this LocalMachine, so the host's own OperatingSystem determines
// whether the java executable carries a .exe suffix
final var javaExecutable = OperatingSystem.current() == OperatingSystem.WINDOWS ? "bin/java.exe" : "bin/java";

return Optional.of(Executable.of(options.get(JDKHome.class).get() + "/" + javaExecutable));
}

@Override
Expand Down
9 changes: 9 additions & 0 deletions spawn-local-jdk/src/main/resources/java.home.properties
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,12 @@ unix@local-java = /usr/local/*java*
unix@sdkman = ${user.home}/.sdkman/candidates/java/*
unix@homebrew = /home/linuxbrew/.linuxbrew/opt/openjdk*/libexec
unix@github-actions = /opt/hostedtoolcache/Java_*/*/*

windows@oracle = C:/Program Files/Java/jdk-*
windows@zulu = C:/Program Files/Zulu/zulu-*
windows@adoptium = C:/Program Files/Eclipse Adoptium/jdk-*
windows@microsoft = C:/Program Files/Microsoft/jdk-*
windows@corretto = C:/Program Files/Amazon Corretto/jdk*
windows@sdkman = ${user.home}/.sdkman/candidates/java/*
windows@scoop = ${user.home}/scoop/apps/*jdk*/current
windows@github-actions = C:/hostedtoolcache/windows/Java_*/*/*
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,30 @@ void shouldFallBackToHostPlatformWhenReleaseFileOmitsOsInfo(@TempDir final Path
assertThat(jdk.architecture()).isEqualTo(Architecture.current());
}

/**
* Ensure a staged Windows JDK — which only ships {@code bin/java.exe}, not {@code bin/java} — is
* still recognized as a valid Java Home rather than rejected outright.
*/
@Test
void shouldDetectWindowsJDKWithOnlyJavaExe(@TempDir final Path tempDir) throws IOException {
final var bin = tempDir.resolve("bin");
Files.createDirectories(bin);
Files.createFile(bin.resolve("java.exe"));
Files.writeString(tempDir.resolve("release"), """
JAVA_VERSION="21.0.1"
OS_NAME="Windows Server 2022"
OS_ARCH="x86_64"
""");

final Exceptional<JDK> result = JDKDetector.of(tempDir);

assertThat(result.isPresent()).isTrue();

final var jdk = result.orElseThrow();
assertThat(jdk.operatingSystem()).isEqualTo(OperatingSystem.WINDOWS);
assertThat(jdk.architecture()).isEqualTo(Architecture.X86_64);
}

/**
* Stages a minimal, fake JDK home: a {@code bin/java} placeholder (so {@link JDKDetector#of(Path)}
* accepts it as a JDK home) and the specified {@code release} file content.
Expand Down
Loading