Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is "not serializable" in this shared library and how do I fix it?

When using the Jenkins pipeline plugin, the build fails with a java.io.NotSerializableException error, like below:

java.io.NotSerializableException: org.codehaus.groovy.control.ErrorCollector
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    ...
Caused by: an exception which occurred:
    in field collector
    in field abnormal
    in field outcome
    in field body
    in field step
    in field thread
    in field this$0
    in field returnAddress
    in field parent
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@6ae7e4f1
    ...
Finished: FAILURE

This happens when I use a custom library with some import statements. I've tried several things, like encapsulating the call in a method with @NonCPS, but the error remains.

Pipeline script

#!groovy
@Library('utils')

pipeline {
    agent any
    stages {
        stage('Run Script') {
            script {
                myScript param1
            }
        }
    }
}

vars/myScript.groovy

import com.company.jenkins.utils

def call(String param = "test") {
    def libScript = LibScript(this)
    libScript.printMessage("Hello World")
}

src/com/company/jenkins/utils/LibScript

package com.company.jenkins.utils;

// This import works fine
import groovy.json.*

// This one fails
import groovyx.net.http.RESTClient

class LibScript implements Serializable {
    def steps
    def client

    LibScript(steps) { this.steps = steps }

    def printMessage(String message) { steps.echo "Saying: " message }

    // This also fails
    @NonCPS
    def doSomething() { client = new groovyx.net.http.RESTClient( 'https://somehost/' ) }
}

Versions used:

  • Jenkins: 2.19.3
  • Pipeline plugin: 2.5
  • Pipeline Shared Groovy Libraries Plugin: 2.7
like image 764
JohanKees Avatar asked Jun 15 '17 08:06

JohanKees


2 Answers

As the accepted answer states, this (non-descriptive) error indicates some sort of compilation error. The issue then is tracking down what the compilation error is, since the error message tells you basically nothing.

It appears that getting this non-descriptive compilation error message is only an issue when using declarative pipelines. If you were to switch to a scripted pipeline, you would get a more specific error message.

However, you can get more descriptive errors out of declarative pipelines if you wrap the code in question with a try catch block. As an example from some of my code, I narrowed down the NotSerializableException from this block of pipeline code:

post { always { notifyOnBuildResults currentBuild : currentBuild } }

I changed the code to this

post { always { script { try { notifyOnBuildResults currentBuild : currentBuild } catch (Exception e) { echo e.toString() } } } }

and was able to see the specific compilation error.

like image 149
TheEllis Avatar answered Oct 07 '22 02:10

TheEllis


This error will come because of the compilation error. This is not a good stacktrace to be get. But you are having a non serializable object as one of your variable or in the middle of the string as well ( can have variable value as '.."$var"..' ). For this, I am attaching two links. Please go through them and you will understand what has gone wrong. Please run step by step to understand where went wrong.

1) https://issues.jenkins-ci.org/browse/JENKINS-40109

2) https://coderwall.com/p/zvsh5q/jenkins-load-command-can-t-found-why-i-have-a-java-io-notserializableexception

like image 43
SV Madhava Reddy Avatar answered Oct 07 '22 00:10

SV Madhava Reddy