-
Notifications
You must be signed in to change notification settings - Fork 80
Windows actions #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows actions #30
Changes from all commits
d47c27c
ffb1663
5b76094
e8c7d6e
31dc4ef
d7801e5
12cd7c4
262748f
d18d08b
23cc222
e34b248
58a842f
179de21
44087c4
a4d5be3
6aa7f5e
ee34e2c
364f178
6b63167
87a445c
275cf81
79ee010
7c6b1cb
c0ddd8b
3143830
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| name: Reproduce WindowsAttachProvider ServiceConfigurationError | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| push: | ||
| branches: | ||
| - claude/reproduce-issue-7-Qj92G | ||
|
|
||
| jobs: | ||
| reproduce: | ||
| runs-on: windows-latest | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Temurin JDK 8 (JAVA_HOME will point here) | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| java-version: '8' | ||
| distribution: 'temurin' | ||
|
|
||
| - name: Build jar | ||
| run: mvn package -DskipTests -q | ||
|
|
||
| - name: Download Temurin JRE-only archive (simulates Oracle standalone JRE) | ||
| shell: pwsh | ||
| run: | | ||
| $url = "https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u442-b06/OpenJDK8U-jre_x64_windows_hotspot_8u442b06.zip" | ||
| Invoke-WebRequest -Uri $url -OutFile jre8.zip | ||
| Expand-Archive jre8.zip -DestinationPath jre8 | ||
| $jreHome = (Get-ChildItem jre8 -Directory)[0].FullName | ||
| echo "STANDALONE_JRE=$jreHome" >> $env:GITHUB_ENV | ||
|
|
||
| - name: Show preconditions | ||
| shell: pwsh | ||
| run: | | ||
| Write-Host "=== JDK (JAVA_HOME) ===" | ||
| Write-Host "Path : $env:JAVA_HOME" | ||
| Write-Host "tools.jar : $(Test-Path "$env:JAVA_HOME\lib\tools.jar")" | ||
| Write-Host "attach.dll : $(Test-Path "$env:JAVA_HOME\jre\bin\attach.dll")" | ||
| Write-Host "" | ||
| Write-Host "=== Standalone JRE (on PATH in real-world scenario) ===" | ||
| Write-Host "Path : $env:STANDALONE_JRE" | ||
| Write-Host "attach.dll : $(Test-Path "$env:STANDALONE_JRE\bin\attach.dll")" | ||
| Write-Host "tools.jar : $(Test-Path "$env:STANDALONE_JRE\lib\tools.jar")" | ||
| Write-Host "" | ||
| Write-Host "JVM library paths when launched from standalone JRE:" | ||
| & "$env:STANDALONE_JRE\bin\java.exe" -XshowSettings:property -version 2>&1 | | ||
| Select-String "library.path" | ||
|
|
||
| - name: Reproduce error | ||
| shell: pwsh | ||
| # Explicitly invoke the standalone JRE's java.exe (not the JDK's). | ||
| # JAVA_HOME still points to the JDK so tools.jar is found and | ||
| # the URLClassLoader path in AgentAttach is taken. | ||
| # sun.boot.library.path is derived from the standalone JRE's jvm.dll | ||
| # and points to a bin\ with no attach.dll -- causing UnsatisfiedLinkError | ||
| # inside WindowsAttachProvider's static initializer, which the SPI loader | ||
| # wraps into: | ||
| # ServiceConfigurationError: com.sun.tools.attach.spi.AttachProvider: | ||
| # Provider sun.tools.attach.WindowsAttachProvider could not be instantiated | ||
| run: | | ||
| # Remove all JDK bin directories from PATH so java.library.path | ||
| # also can't find any attach.dll as a fallback | ||
| $env:PATH = ($env:PATH -split ';' | | ||
| Where-Object { $_ -notmatch 'jdk|jre|java|hostedtoolcache' }) -join ';' | ||
|
|
||
| $java = "$env:STANDALONE_JRE\bin\java.exe" | ||
| $jar = (Get-ChildItem target\extract-tls-secrets-*.jar)[0].FullName | ||
|
|
||
| Write-Host "PATH: $env:PATH" | ||
| Write-Host "java.exe : $java (standalone JRE - no attach.dll)" | ||
| Write-Host "JAVA_HOME: $env:JAVA_HOME (JDK - has tools.jar)" | ||
| Write-Host "jar : $jar" | ||
| Write-Host "" | ||
| Write-Host "Running..." | ||
| & $java -jar $jar list | ||
| continue-on-error: true | ||
|
|
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,15 +3,45 @@ name: Integration Tests | |||||
| on: [push] | ||||||
|
|
||||||
| jobs: | ||||||
| build: | ||||||
|
|
||||||
| runs-on: ubuntu-latest | ||||||
| # build-linux: | ||||||
| # | ||||||
| # runs-on: ubuntu-latest | ||||||
| # | ||||||
| # steps: | ||||||
| # - uses: actions/checkout@v2 | ||||||
| # - name: Set up JDK 1.8 | ||||||
| # uses: actions/setup-java@v2 | ||||||
| # with: | ||||||
| # java-version: 1.8 | ||||||
| # distribution: adopt | ||||||
| # - name: Build and run tests | ||||||
| # run: mvn -B verify | ||||||
| # | ||||||
| build-windows: | ||||||
| runs-on: windows-latest | ||||||
|
|
||||||
| steps: | ||||||
| - uses: actions/checkout@v1 | ||||||
| - name: Set up JDK 1.8 | ||||||
| uses: actions/setup-java@v1 | ||||||
| with: | ||||||
| java-version: 1.8 | ||||||
| - name: Build and run tests | ||||||
| run: mvn -B verify | ||||||
| - uses: actions/checkout@v2 | ||||||
| - name: Set up JDK 1.8 | ||||||
| uses: actions/setup-java@v2 | ||||||
| with: | ||||||
| java-version: 8 | ||||||
| distribution: adopt | ||||||
| - name: Set up JRE 1.8 | ||||||
| uses: actions/setup-java@v2 | ||||||
| with: | ||||||
| java-version: 8 | ||||||
| distribution: adopt | ||||||
| java-package: jre | ||||||
| - name: Build and run tests | ||||||
| run: | | ||||||
| $env:JAVA_HOME = "C:\hostedtoolcache\windows\Java_Adopt_jdk\8.0.292-10\x64" | ||||||
| mvn -B package | ||||||
| $env:JAVA_HOME | ||||||
|
Comment on lines
+37
to
+40
|
||||||
| $env:PATH | ||||||
| dir $env:JAVA_HOME | ||||||
| dir $env:JAVA_HOME\bin | ||||||
| # dir $env:JAVA_HOME\jre\bin | ||||||
| which java | ||||||
|
||||||
| which java | |
| where.exe java |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||
| package name.neykov.secrets; | ||||||
|
|
||||||
| import java.io.File; | ||||||
| import java.lang.reflect.Field; | ||||||
| import java.lang.reflect.InvocationTargetException; | ||||||
| import java.lang.reflect.Method; | ||||||
| import java.net.URL; | ||||||
|
|
@@ -40,7 +41,7 @@ public static void main(String[] args) throws Exception { | |||||
|
|
||||||
| try { | ||||||
| attach(jarUrl, jarFile, pid, logFile); | ||||||
| } catch (MessageException e) { | ||||||
| } catch (FailureMessageException e) { | ||||||
| for (String line : e.msg) { | ||||||
| System.err.println(line); | ||||||
| } | ||||||
|
|
@@ -50,23 +51,45 @@ public static void main(String[] args) throws Exception { | |||||
|
|
||||||
| public static void attach(URL jarUrl, File jarFile, String pid, String logFile) throws Exception { | ||||||
| if (isAttachApiAvailable()) { | ||||||
| // Either Java 9 or tools.jar already on classpath | ||||||
| // Either Java 9+ or tools.jar already on classpath | ||||||
| AttachHelper.handle(jarFile.getAbsolutePath(), pid, logFile); | ||||||
| } else { | ||||||
| File toolsFile = getToolsFile(); | ||||||
| System.out.println("tools.jar: " + toolsFile.getAbsolutePath()); | ||||||
|
||||||
| System.out.println("tools.jar: " + toolsFile.getAbsolutePath()); | |
| System.err.println("tools.jar: " + toolsFile.getAbsolutePath()); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |||||
|
|
||||||
| import java.io.File; | ||||||
| import java.io.IOException; | ||||||
| import java.lang.reflect.Field; | ||||||
|
|
||||||
| import com.sun.tools.attach.AgentInitializationException; | ||||||
| import com.sun.tools.attach.AgentLoadException; | ||||||
|
|
@@ -15,7 +16,11 @@ | |||||
| //Byte Buddy (https://github.com/raphw/byte-buddy) abstracts | ||||||
| //the API, including a fallback implementing the attach api. | ||||||
| public class AttachHelper { | ||||||
| public static void handle(String jarPath, String pid, String logFile) throws MessageException { | ||||||
| public static void handle(String jarPath, String pid, String logFile) throws FailureMessageException { | ||||||
| // if (isWindows()) { | ||||||
| // loadAttachLibrary(); | ||||||
| // } | ||||||
|
|
||||||
| if (pid.equals("list")) { | ||||||
| System.out.print(AttachHelper.list()); | ||||||
| } else { | ||||||
|
|
@@ -24,11 +29,90 @@ public static void handle(String jarPath, String pid, String logFile) throws Mes | |||||
| System.out.println("Successfully attached to process ID " + pid + "."); | ||||||
| } catch (IllegalStateException e) { | ||||||
| String msg = e.getMessage() != null ? e.getMessage() : "Failed attaching to java process " + pid; | ||||||
| throw new MessageException(msg); | ||||||
| throw new FailureMessageException(msg); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| } | ||||||
|
|
||||||
| private static boolean isWindows() { | ||||||
| return System.getProperty("os.name").startsWith("Windows"); | ||||||
| } | ||||||
|
|
||||||
| private static void loadAttachLibrary() throws FailureMessageException { | ||||||
| try { | ||||||
| System.loadLibrary("attach"); | ||||||
| // All good - system is set up properly. Nothing to do. | ||||||
| } catch (UnsatisfiedLinkError e) { | ||||||
| // "attach.dll" not on the default search path, let's try some well known locations. | ||||||
| // Could happen if using the JRE with JAVA_HOME pointing to a JDK install. | ||||||
| if (!tryLoadLibrary("jre/bin/attach.dll")) { | ||||||
| throw new FailureMessageException( | ||||||
| "Failed loading attach provider. Make sure you are running with a JDK java executable. " + | ||||||
| "Alternatively locate 'attach.dll' on your system, typically found in " + | ||||||
| "'<jdk home>/jre/bin' folder for Oracle JDK installs, and pass the path at startup as: ", | ||||||
| " java -Djava.library.path=\"<jdk home>/jre/bin\" -jar extract-tls-secrets.jar" | ||||||
| ); | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private static File getJavaHome() throws FailureMessageException { | ||||||
| // Duplicated from AttachHelper, but can't be shared due to ClassLoader boundary | ||||||
|
||||||
| // Duplicated from AttachHelper, but can't be shared due to ClassLoader boundary | |
| // Duplicated from AgentAttach, but can't be shared due to ClassLoader boundary |
Copilot
AI
Apr 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This writes a diagnostic message to stdout while loading attach.dll. For the list command, stdout is the machine-readable process list; extra lines like this can break scripts. Consider removing this print or sending it to stderr / gating behind a debug flag.
| System.out.println("Loaded attach " + attachAbsolutePath.getAbsolutePath()); | |
| System.err.println("Loaded attach " + attachAbsolutePath.getAbsolutePath()); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package name.neykov.secrets; | ||
|
|
||
| class FailureMessageException extends Exception { | ||
| String[] msg; | ||
|
|
||
| protected FailureMessageException(String... msg) { | ||
| this.msg = msg; | ||
| } | ||
| } |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Linux CI job is commented out, so CI now only runs the Windows job (which uses
mvn packagerather thanmvn verify). This removes the existing Ubuntu-based integration test coverage (Docker-basedmvn verifyper pom.xml). Consider keeping the Linux verify job enabled and adding Windows as an additional job/matrix entry.