powershelljenkinsserviceio-redirectionstderr

Call Java.exe with parameters with Powershell shows info as error


Description

As part of a an open-source project, I am writing a script that will allow to host Jenkins agent as a service.

Jenkins is running on Java, so I had to call Java.exe.

What I Tried

For this, I need to make sure that when the script is being terminated, the java process is being terminated as well.

I found that using CMD /c or Start-Process is starting a new process, and because of this, stopping the PowerShell script does not stop the java.exe as well. The only thing that worked was the call operator, &.

However, as you see below it treats the infomration returned from JAVA as an exception. IT IS FALSE-POSITIVE.

What I tried and Need

I need to make sure the actual information is being sent to output as usual, not hidden.

This rules out $ErrorActionPreference = 'SilentlyContinue'

Also tried 2>&1 and *>&1 but same result

Any ideas will be great.

The Code

& "$Java\java.exe" -jar "$JenkinsPath\agent.jar" -url "$JenkinsURL/" -secret $Secret -name $env:computername -workDir "$JenkinsPath" *>>"$JenkinsPath\agent.log"

The Error

java.exe : Aug 04, 2024 5:14:14 PM org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir
At line:1 char:1
+ & "$Java\java.exe" -jar "$JenkinsPath\agent.jar" -url "$JenkinsURL/"  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Aug 04, 2024 5:...itializeWorkDir:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
INFO: Using D:\Jenkins\remoting as a remoting work directory
Aug 04, 2024 5:14:14 PM org.jenkinsci.remoting.engine.WorkDirManager setupLogging
INFO: Both error and output logs will be printed to D:\Jenkins\remoting
Aug 04, 2024 5:14:14 PM hudson.remoting.Launcher createEngine

Thanks in advance.


Solution

  • Your problem is the unexpected rendering of stderr lines, which inappropriately render as if they were errors.[1] Do the following to avoid the problem:

    # java.exe arguments omitted for brevity
    & "$Java\java.exe" ... 2>&1 | % ToString >>"$JenkinsPath\agent.log"
    

    Simpler alternative, via Add-Content:

    # java.exe arguments omitted for brevity
    & "$Java\java.exe" ... 2>&1 | Add-Content "$JenkinsPath\agent.log"
    

    [1] Specifically, it is the first stderr line output by an external program such as java.exe that is rendered this way when a 2> or *> redirection (or a >> variant) is applied to an external-program call. In the console (terminal), subsequent stderr lines render by their text only, but are printed in red too. When redirecting such output to a file, such as in your case, coloring is lost, so it is only the first, error-like representation that stands out. A simple test command:
    cmd /c 'echo stderr1 >&2 & echo stdout1 & echo stderr2 >&2' 2>&1
    Note that the original output order among the stdout and stderr streams isn't always maintained - see GitHub issue #5424 for a discussion.

    [2] By contrast, use of > / >> / Out-File results in implicit stringification that uses the rich for-display representations you also see when outputting to the PowerShell console, via PowerShell's output-formatting system - except when stderr output from an external program isn't captured, i.e. prints directly to the display, in which case stderr lines print normally, as uncolored strings.