Groovy code in Pipeline and CPS trouble

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Groovy code in Pipeline and CPS trouble

Ramanathan Muthaiah
Hello All,

I have tested the below snippet of code in myjenkinsurl/script and it works fine.

However, same code (embedded or loaded via external Groovy code) in Pipeline workflow script fails, inspite of CPS annotation (with the stacktrace that's given after this code snippet) ?

NOTE:
First print statement in 'getjobName' function successfully matches the job (using regex).

#!/usr/bin/env groovy

import org.jenkinsci.plugins.workflow.job.*

@NonCPS
def getjobName(String job) {
    for (item in Jenkins.instance.items) {
        if (item =~ /metamon-alert-configs/ ) {
            println item.getName()
            jobname = item
        }
    }
    
    for (build in jobname.Builds()) {
        println build
    }
}


node('master') {
    stage('getlog') {
        def jobname = getjobName("mon-alert-configs")
    }
}


Reading (novice at it) the stacktrace suggests it's to do with serialization of variables but the annotation should take care of that, isn't it ?

an exception which occurred:
	in field groovy.lang.Closure.delegate
	in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@72ae419a
	in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@401a5d46
	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@401a5d46
Caused: java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob
	at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
	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.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
	at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
. . . . .
. . . . .

/Ram

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/68199c67-9ccf-42e2-8bf3-f38fe4708350%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Groovy code in Pipeline and CPS trouble

David Karr
On Thu, Dec 28, 2017 at 6:17 AM, Ramanathan Muthaiah
<[hidden email]> wrote:

> Hello All,
>
> I have tested the below snippet of code in myjenkinsurl/script and it works
> fine.
>
> However, same code (embedded or loaded via external Groovy code) in Pipeline
> workflow script fails, inspite of CPS annotation (with the stacktrace that's
> given after this code snippet) ?
>
> NOTE:
> First print statement in 'getjobName' function successfully matches the job
> (using regex).
>
> #!/usr/bin/env groovy
>
> import org.jenkinsci.plugins.workflow.job.*
>
> @NonCPS
> def getjobName(String job) {
>     for (item in Jenkins.instance.items) {
>         if (item =~ /metamon-alert-configs/ ) {
>             println item.getName()
>             jobname = item
>         }
>     }
>
>     for (build in jobname.Builds()) {
>         println build
>     }
> }
>
>
> node('master') {
>     stage('getlog') {
>         def jobname = getjobName("mon-alert-configs")
>     }
> }
>
>
> Reading (novice at it) the stacktrace suggests it's to do with serialization
> of variables but the annotation should take care of that, isn't it ?
>
> an exception which occurred:
> in field groovy.lang.Closure.delegate
> in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@72ae419a
> in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
> in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@401a5d46
> in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@401a5d46
> Caused: java.io.NotSerializableException:
> org.jenkinsci.plugins.workflow.job.WorkflowJob
> at
> org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
> 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.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
> at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
> . . . . .
> . . . . .

No, the annotation wouldn't help with this, I believe.

The problem is, when "job steps" execute, objects are deserialized
before and after.  If Jenkins has to try to serialize something in
scope that is not serializable, you will get that exception. What is
often very frustrating is that the stacktrace won't tell you which
variable contains something that is not serializable. What it will
usually tell you is what type was not serializable. If you're lucky,
it will be obvious what variable has a value of that type. In your
case, I believe is it obvious.

The other thing that is not obvious is that "println" is a job step.

If you really need to do a println, then right before you call it, you
have to assign "null" to variables containing values of
non-serializable types.

In your "getjobName" method, it's odd that your formal parameter is
called "job", when it's really "jobName", and then you appear to
assign to "jobname", which isn't defined anywhere, but the value
actually represents a "Job", not a "jobname".

>
>
> /Ram
>
> --
> You received this message because you are subscribed to the Google Groups
> "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [hidden email].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jenkinsci-users/68199c67-9ccf-42e2-8bf3-f38fe4708350%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/CAA5t8VrrGDF7OJrLxeQeySmAUT4sT3mppRZY9_in1-iBbx3s1w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Groovy code in Pipeline and CPS trouble

Ramanathan Muthaiah
> Reading (novice at it) the stacktrace suggests it's to do with serialization

> of variables but the annotation should take care of that, isn't it ?
>
> an exception which occurred:
> in field groovy.lang.Closure.delegate
> in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@72ae419a
> in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
> in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@401a5d46
> in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@401a5d46
> Caused: java.io.NotSerializableException:
> org.jenkinsci.plugins.workflow.job.WorkflowJob
> at
> org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
> 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.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
> at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
> . . . . .
> . . . . .

No, the annotation wouldn't help with this, I believe.

The problem is, when "job steps" execute, objects are deserialized
before and after.  If Jenkins has to try to serialize something in
scope that is not serializable, you will get that exception. What is
often very frustrating is that the stacktrace won't tell you which
variable contains something that is not serializable. What it will
usually tell you is what type was not serializable. If you're lucky,
it will be obvious what variable has a value of that type. In your
case, I believe is it obvious.

The other thing that is not obvious is that "println" is a job step.

If you really need to do a println, then right before you call it, you
have to assign "null" to variables containing values of
non-serializable types.

In your "getjobName" method, it's odd that your formal parameter is
called "job", when it's really "jobName", and then you appear to
assign to "jobname", which isn't defined anywhere, but the value
actually represents a "Job", not a "jobname".

Thanks for the notes on deserialization. 

Immediately after posting my query to this forum, I  did few changes to the code, like, assigning null values to some of the variables.

This did solve the problem for me!

/Ram

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/bdc42815-bdce-4a5a-a050-a81d53a4e927%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.