Groovy writeFile result in NotSerializableException: java.lang.ProcessImpl

65 Views Asked by At

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 !

0

There are 0 best solutions below