Use JNA/WMI instead of PowerShell to list Windows processes - #4718
Use JNA/WMI instead of PowerShell to list Windows processes#4718janhoy wants to merge 2 commits into
Conversation
SolrProcessManager previously spawned a powershell.exe process running Get-CimInstance to obtain command lines of Java processes on Windows. Replace this with a WMI (Win32_Process) query via JNA, avoiding an external process spawn and the dependency on PowerShell being present. - Add net.java.dev.jna:jna-platform dependency to solr-core - Drop the PowerShell JSON parsing helper and its test - Remove the broad "<<ALL FILES>>" execute grant from the test security policy (only needed to exec powershell) and add the JNA native-library load / jna.* property-read permissions instead
| new WmiQuery<>("Win32_Process", ProcessProperty.class).execute(); | ||
| Map<Long, String> pidToCommandLine = new HashMap<>(); | ||
| for (int i = 0; i < result.getResultCount(); i++) { | ||
| Object name = result.getValue(ProcessProperty.NAME, i); | ||
| if (name == null || !name.toString().toLowerCase(Locale.ROOT).contains("java")) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
One question on the query: it doesn't push the java filter into the WQL itself. JNA's WmiQuery javadoc notes the class name may include a WHERE clause with filtering conditions. so "Win32_Process WHERE NAME LIKE '%java%'" would let WMI do the filtering and make the name check in the loop redundant. Also, the LIKE is case-insensitive according to MS-WMI, so it should match the old -like '*java*' behaviour.
(I noticed this is still a draft, so ignore it if this is already on your radar.)
| new WmiQuery<>("Win32_Process", ProcessProperty.class).execute(); | |
| Map<Long, String> pidToCommandLine = new HashMap<>(); | |
| for (int i = 0; i < result.getResultCount(); i++) { | |
| Object name = result.getValue(ProcessProperty.NAME, i); | |
| if (name == null || !name.toString().toLowerCase(Locale.ROOT).contains("java")) { | |
| continue; | |
| } | |
| new WmiQuery<>("Win32_Process WHERE NAME LIKE '%java%'", ProcessProperty.class).execute(); | |
| Map<Long, String> pidToCommandLine = new HashMap<>(); | |
| for (int i = 0; i < result.getResultCount(); i++) { |
There was a problem hiding this comment.
Not on my radar, definitely an improvement. Do you by chance have a Windows system to test on?
There was a problem hiding this comment.
I am on Mac (M-series), so no native windows, but happy to spin up a windows 11 ARM VM and test it out. Will report back later.
Although it will be aarch64 rather than x86-64, that shouldn't affect the WQL semantics.
There was a problem hiding this comment.
@janhoy, I have tested the WHERE clause works through WmiQuery and matching is case-insensitive.
Environment: Windows 11 VM, amd64, JNA 5.19.1, with two java processes running
no filter -> 144 rows
System Idle Process
System
Registry
smss.exe
...
'%java%' -> 2 rows
java.exe
java.exe
'%JAVA%' -> 2 rows
java.exe
java.exe
'%Java%' -> 2 rows
java.exe
java.exe
Name -> 2 rows
java.exe
java.exe
NAME upper -> 2 rows
java.exe
java.exe
name lower -> 2 rows
java.exe
java.exe
All three literal casings return the same rows, so it matches the old -like '*java*' behaviour. Property name casing doesn't matter either: Name, NAME & name.
Correction: I said aarch64 earlier but I ended up on the x64 JDK, so it loaded JNA's win32-x86-64 native under emulation which is closer to the usual deployment.
Happy to share the probe if this is helpful.
Description
On Windows,
SolrProcessManager(used by thebin/solr statusCLI) discovers running Solr processes by reading each Java process's command line. SinceProcessHandledoes not expose command lines on Windows, it previously spawnedpowershell.exerunningGet-CimInstance -ClassName Win32_Process ... | ConvertTo-Jsonand parsed the JSON.This PR replaces that with a direct WMI (
Win32_Process) query via JNA (jna-platform), so no external process is spawned and PowerShell no longer needs to be present/enabled.Changes
net.java.dev.jna:jna-platformtosolr-core.commandLinesWindows()to useCoInitializeEx→WmiQuery→CoUninitialize; drop the PowerShell JSON parsing helper and its unit test.<<ALL FILES>>executegrant (only needed to exec powershell) and add the JNA native-library load /jna.*property-read permissions instead.Notes
Constants.WINDOWS); Linux/macOS behaviour is unchanged and all static checks +SolrProcessManagerTestpass. The live WMI query has not been exercised on real Windows yet.Draft pending validation on a Windows runner.