I am currently building a simple shared library for testing commands output.
EDIT: Alexander asked me to make my question more explicit: My goal is to create a shared library that run multiple commands from a CSV file, and log every output and status code, so that means the command is given as a string. I tried running the string command with sh "${commandToRun}" to no avail (most likely a heavy me issue). But even then I resorted to use "commandToRun.execute()" as it allowed me to get both stdout, stderror, AND the status code whether or not it was valid.
Here is the code I am running (everything has been print debugged up to writeFile, stdOutput and status are updated correctly).
// config.cmd -> command to run
// config.expOutput -> expected output to stdin
// config.expStatus -> expected return status
// config.logPath -> logFile to write result into (if any)
// config.errorPath -> file to log errors into
//@NonCPS
def call(Map config = [:]) {
def String commandToRun = config.cmd
if ( commandToRun == null )
return 84
def String expOutput = config.expOutput
def String expStatus = config.expStatus
def String logPath = config.logPath
if ( logPath == null )
logPath = "Result.log"
def int status = 0
def String stdOutput = ""
def process = null
//Running command
try {
process = commandToRun.execute()
def bob = process.isAlive()
if ( bob == true ) {
echo "${commandToRun}:\tProcess still running."
} else {
echo "${commandToRun}:\tProcess stoped."
}
process.waitFor()
status = process.exitValue() //Updated correctly
stdOutput = process.getText().trim() //Updated correctly
} catch (Exception e) {
echo "!!! Exception: ${e.message}"
}
process.destroy()
def boolean outputResult = false
if ( stdOutput == expOutput ) {
outputResult = true
}
def boolean statusResult = false
if ( status == expStatus ) {
statusResult = true
}
echo "Before write in ${logPath}." ////////// Outputs: "Before write in Result.log."
/// the last thing that is printed
script {
writeFile(file: logPath, text: "Hello world\n", encoding: "UTF-8") //////////good bye
.........
I struggled for hour on the same exception, and after researching I understood that it was due to the way binary data is structured and I updated the code accordingly (I was using sh to echo the variable). Another SO post recommended to use "@NonCPS", it worked perfectly except for the following warning: "callWorkflowScript.runAndLogCommand but wound up catching sh;" that I am trying to fix.
However, I have no clue why a simple writeFile is causing the following issue:
an exception which occurred:
in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@77b9daf4
in field com.cloudbees.groovy.cps.impl.CpsClosureDef.capture
in object com.cloudbees.groovy.cps.impl.CpsClosureDef@37cb4451
in field com.cloudbees.groovy.cps.impl.CpsClosure.def
in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@3e1889d8
in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@424a3cfc
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@424a3cfc
Also: org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: c964a208-dde3-4c11-b1eb-e9068668c6cb
Caused: java.io.NotSerializableException: java.lang.ProcessImpl
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:278)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.base/java.io.ObjectOutputStream.writeObject(Unknown Source)
at java.base/java.util.HashMap.internalWriteEntries(Unknown Source)
at java.base/java.util.HashMap.writeObject(Unknown Source)
Does anyone can help me or guide me ? I have no experience on Java whatsoever and I couldn't find any in-depth documentation for writeFile and java.lang.ProcessImpl. Thank you !