From 14e11cbfce0b731639b5a0b9d7822d586d8f9c95 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 10:45:41 -0400 Subject: [PATCH 1/9] Install Java on Windows CI --- .github/workflows/pull_request.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 6b21c8b..d0dbe5c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -14,6 +14,7 @@ jobs: with: enable_windows_checks: true windows_swift_versions: '["nightly-main"]' + windows_pre_build_command: winget install Microsoft.OpenJDK.21 enable_macos_checks: true macos_pre_build_command: brew install openjdk enable_ios_checks: false From 0d92a7dd20089e615bb4a5f177d8c44c90984e10 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 10:58:18 -0400 Subject: [PATCH 2/9] Check for Java environment variables --- .github/workflows/pull_request.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d0dbe5c..188b6ac 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -14,7 +14,10 @@ jobs: with: enable_windows_checks: true windows_swift_versions: '["nightly-main"]' - windows_pre_build_command: winget install Microsoft.OpenJDK.21 + windows_pre_build_command: | + winget install Microsoft.OpenJDK.21 + Get-ChildItem Env: + java -version enable_macos_checks: true macos_pre_build_command: brew install openjdk enable_ios_checks: false From fc5c0ee9627f1adf499a22b2785c0a1ee78935bf Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 11:49:21 -0400 Subject: [PATCH 3/9] Download and install Java manually in windows_pre_build_command --- .github/workflows/pull_request.yml | 39 ++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 188b6ac..09ed8a5 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -15,9 +15,44 @@ jobs: enable_windows_checks: true windows_swift_versions: '["nightly-main"]' windows_pre_build_command: | - winget install Microsoft.OpenJDK.21 + $jdkVersion = "21" + $msiUrl = "https://aka.ms/download-jdk/microsoft-jdk-$jdkVersion-windows-x64.msi" + $installerPath = "$env:TEMP\microsoft-jdk-$jdkVersion.msi" + $jdkInstallDir = "C:\Program Files\Microsoft\jdk-$jdkVersion" + + # Download the MSI + Write-Host "Downloading Microsoft OpenJDK $jdkVersion..." + Invoke-WebRequest -Uri $msiUrl -OutFile $installerPath + + # Install silently + Write-Host "Installing Microsoft OpenJDK $jdkVersion..." + Start-Process msiexec.exe -ArgumentList "/i `"$installerPath`" /quiet /norestart INSTALLDIR=`"$jdkInstallDir`"" -Wait -NoNewWindow + + # Set JAVA_HOME (system-wide, requires admin) + Write-Host "Setting JAVA_HOME..." + [System.Environment]::SetEnvironmentVariable("JAVA_HOME", $jdkInstallDir, [System.EnvironmentVariableTarget]::Machine) + + # Add to system PATH if not already present + $currentPath = [System.Environment]::GetEnvironmentVariable("PATH", [System.EnvironmentVariableTarget]::Machine) + if ($currentPath -notlike "*$jdkInstallDir\bin*") { + [System.Environment]::SetEnvironmentVariable("PATH", "$currentPath;$jdkInstallDir\bin", [System.EnvironmentVariableTarget]::Machine) + Write-Host "Added JDK bin to system PATH." + } + + # Refresh current session + $env:JAVA_HOME = $jdkInstallDir + $env:PATH = "$env:PATH;$jdkInstallDir\bin" + + # Verify + Write-Host "`nVerifying installation..." + & "$jdkInstallDir\bin\java.exe" -version + + Write-Host "`nDone! JAVA_HOME = $env:JAVA_HOME" + + # Clean up installer + Remove-Item $installerPath -Force + Get-ChildItem Env: - java -version enable_macos_checks: true macos_pre_build_command: brew install openjdk enable_ios_checks: false From 3639a3eb8a9a9af6e4fe8b3746f9d1f567975a51 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 12:11:19 -0400 Subject: [PATCH 4/9] Update search path for jvm.dll on Windows --- .../VirtualMachine/JavaVirtualMachine.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift b/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift index e5fdd3d..6444475 100644 --- a/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift +++ b/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift @@ -480,13 +480,21 @@ private func loadLibJava() throws -> DylibType { let javaHomeURL = URL(fileURLWithPath: javaHome, isDirectory: true) let ext = FileManager.libraryExtension - let libjvmPaths = [ + let libjvmPaths: [URL] + + #if os(Windows) + libjvmPaths = [ + URL(fileURLWithPath: "bin\\server\\jvm.dll", relativeTo: javaHomeURL), + ] + #else + libjvmPaths = [ // look through some standard locations relative to JAVA_HOME URL(fileURLWithPath: "jre/lib/server/libjvm.\(ext)", relativeTo: javaHomeURL), URL(fileURLWithPath: "lib/server/libjvm.\(ext)", relativeTo: javaHomeURL), URL(fileURLWithPath: "lib/libjvm.\(ext)", relativeTo: javaHomeURL), URL(fileURLWithPath: "libexec/openjdk.jdk/Contents/Home/lib/server/libjvm.\(ext)", relativeTo: javaHomeURL), ] + #endif guard let libjvmPath = libjvmPaths.first(where: { From a1353f2688b990143fcf20825bb038f7be9e894c Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 12:18:05 -0400 Subject: [PATCH 5/9] Update Windows testing From 461157ac031d29865ba04c076bb2328058d21eb1 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 14:00:22 -0400 Subject: [PATCH 6/9] Try failing tests to ensure all builds fail --- Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift index d2dedd5..82ffb84 100644 --- a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift +++ b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift @@ -57,6 +57,6 @@ struct JavaVirtualMachineTests { methodID, nil ) - #expect(timeMillis > 0, "Expected a positive timestamp, got \(timeMillis)") + #expect(timeMillis < 0, "Expected a positive timestamp, got \(timeMillis)") } } From 64cf088e403aa43091deb88a0014cbc9355ba8f1 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 15:04:56 -0400 Subject: [PATCH 7/9] Control whether to run Java tests with SWIFT_JAVA_JNI_TEST_JVM environment --- .../VirtualMachine/JavaVirtualMachine.swift | 2 +- .../JavaVirtualMachineTests.swift | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift b/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift index 6444475..225c433 100644 --- a/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift +++ b/Sources/SwiftJavaJNICore/VirtualMachine/JavaVirtualMachine.swift @@ -484,7 +484,7 @@ private func loadLibJava() throws -> DylibType { #if os(Windows) libjvmPaths = [ - URL(fileURLWithPath: "bin\\server\\jvm.dll", relativeTo: javaHomeURL), + URL(fileURLWithPath: "bin\\server\\jvm.dll", relativeTo: javaHomeURL) ] #else libjvmPaths = [ diff --git a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift index 82ffb84..5346f7c 100644 --- a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift +++ b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift @@ -13,6 +13,11 @@ //===----------------------------------------------------------------------===// import Testing +#if canImport(FoundationEssentials) +import class FoundationEssentials.ProcessInfo +#else +import class Foundation.ProcessInfo +#endif @testable import SwiftJavaJNICore @@ -22,11 +27,14 @@ struct JavaVirtualMachineTests { static var isSupportedPlatform: Bool { #if os(Android) // Android tests are not currently run within an .apk and so do not have any ambient JVM - return false + // This can be overridden for a test hadness harness that supports running within an .apk, like: + // skip android test --apk --env SWIFT_JAVA_JNI_TEST_JVM=1 + let testSentinel = "0" #else - // disable test when we cannot find a system Java - return systemJavaHome() != nil + // tests for every other platform should be run in an environment with Java available unless explicitly disabled + let testSentinel = "1" #endif + return (ProcessInfo.processInfo.environment["SWIFT_JAVA_JNI_TEST_JVM"] ?? testSentinel) != "0" } @Test(.enabled(if: isSupportedPlatform)) @@ -57,6 +65,6 @@ struct JavaVirtualMachineTests { methodID, nil ) - #expect(timeMillis < 0, "Expected a positive timestamp, got \(timeMillis)") + #expect(timeMillis > 0, "Expected a positive timestamp, got \(timeMillis)") } } From 86c67892a5361d2632157bada799f5d60067ebe3 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 15:26:55 -0400 Subject: [PATCH 8/9] Formatting fix --- Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift index 5346f7c..db0d08e 100644 --- a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift +++ b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift @@ -13,14 +13,14 @@ //===----------------------------------------------------------------------===// import Testing + +@testable import SwiftJavaJNICore + #if canImport(FoundationEssentials) import class FoundationEssentials.ProcessInfo #else import class Foundation.ProcessInfo #endif - -@testable import SwiftJavaJNICore - @Suite struct JavaVirtualMachineTests { From 492300f871a7354560e24130e78626808c0ad49d Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 12 Mar 2026 15:28:28 -0400 Subject: [PATCH 9/9] Typo fix [skip ci] --- Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift index db0d08e..8246be7 100644 --- a/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift +++ b/Tests/SwiftJavaJNICoreTests/JavaVirtualMachineTests.swift @@ -26,8 +26,8 @@ struct JavaVirtualMachineTests { static var isSupportedPlatform: Bool { #if os(Android) - // Android tests are not currently run within an .apk and so do not have any ambient JVM - // This can be overridden for a test hadness harness that supports running within an .apk, like: + // Android tests are not currently run within an .apk and so do not have any ambient JVM. + // This can be overridden for a test harness that supports running within an .apk, like: // skip android test --apk --env SWIFT_JAVA_JNI_TEST_JVM=1 let testSentinel = "0" #else