Serialization of TaskListener

44 views
Skip to first unread message

pallen

unread,
Aug 31, 2016, 8:27:19 AM8/31/16
to Jenkins Developers

Hi Guys,


I have been writing a Groovy extension to support a P4 (Perforce) Object.  The serialization seems ok when running remotely on slaves for normal use.  However, I noticed an error in my unit tests when I wrap the job with assertBuildStatusSuccess(job.scheduleBuild2(0)).  


@Test
public
void testP4GroovyConnectAndSync() throws Exception {

  WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "p4groovy");

  job.setDefinition(new CpsFlowDefinition("" + "node() {\n"

    + "   ws = [$class: 'StreamWorkspaceImpl', charset: 'none', format: 'jenkins-${NODE_NAME}-${JOB_NAME}', pinHost: false, streamName: '//stream/main']\n"

    + "   p4 = p4(credential: '" + auth.getId() + "', workspace: ws)\n"

    + "   p4.run('sync', '//...')\n"

    + "}"));

  job.save();

  WorkflowRun run = jenkins.assertBuildStatusSuccess(job.scheduleBuild2(0));

  jenkins.assertLogContains("p4 sync //...", run);

  jenkins.assertLogContains("totalFileCount 10", run);

}


The 'p4' Groovy object uses a String, a Workspace (made up of other Strings, ints and booleans) and a TaskListener.  I have double checked the Serialization of Workspace, perhaps TaskListener is the issue? The error sort of suggests that...


Aug 31, 2016 1:06:28 PM org.jenkinsci.plugins.workflow.cps.CpsThreadGroup saveProgram

WARNING: program state save failed

java.lang.NullPointerException

at hudson.remoting.RemoteOutputStream.writeObject(RemoteOutputStream.java:82)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)

at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)

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:343)

at hudson.util.StreamTaskListener.writeObject(StreamTaskListener.java:161)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)

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.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:343)

at java.util.HashMap.writeObject(HashMap.java:1129)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)

at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)

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:343)

at com.cloudbees.groovy.cps.SerializableScript.writeObject(SerializableScript.java:26)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)

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.doWriteSerializableObject(RiverMarshaller.java:967)

at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)

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:343)

at java.util.HashMap.writeObject(HashMap.java:1129)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:606)

at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)

at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)

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.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)

at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)

at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:133)

at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:341)

at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:325)

at org.jenkinsci.plugins.workflow.cps.CpsStepContext$3.onSuccess(CpsStepContext.java:469)

at org.jenkinsci.plugins.workflow.cps.CpsStepContext$3.onSuccess(CpsStepContext.java:465)

at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution$4$1.run(CpsFlowExecution.java:519)

at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.run(CpsVmExecutorService.java:32)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

at java.util.concurrent.FutureTask.run(FutureTask.java:262)

at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:111)

at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)

at java.util.concurrent.FutureTask.run(FutureTask.java:262)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:745)

Caused by: an exception which occurred:

in field listener

in field delegate

in field closures

in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@229a0711


Aug 31, 2016 1:06:28 PM org.jenkinsci.plugins.workflow.job.WorkflowRun finish

INFO: p4groovy #1 completed: SUCCESS

Aug 31, 2016 1:06:28 PM org.jenkinsci.plugins.p4.client.ConnectionHelper <init>

INFO: (p4):cmd:... p4 info




Sorry I don't have any more info to share at this point.  Any help or suggestions would be great.


Kind regards,

Paul


Jesse Glick

unread,
Aug 31, 2016, 10:20:26 AM8/31/16
to Jenkins Dev
On Wed, Aug 31, 2016 at 8:27 AM, pallen <pal...@perforce.com> wrote:
> The serialization seems ok when running remotely on slaves for normal use.
> However, I noticed an error in my unit tests when I wrap the job with
> assertBuildStatusSuccess(job.scheduleBuild2(0)).

Probably just got lucky. To be safe, use `RestartableJenkinsRule` and
prove that your code survives restarts.

> The 'p4' Groovy object uses a String, a Workspace (made up of other Strings,
> ints and booleans) and a TaskListener. I have double checked the
> Serialization of Workspace, perhaps TaskListener is the issue?

No, you may not serialize a `TaskListener`. Why do you think you need to?

Paul Allen

unread,
Aug 31, 2016, 10:52:41 AM8/31/16
to jenkin...@googlegroups.com
Hi Jesse,

I was passing TaskListener to allow logging/reporting in the Console Output. Is there a static method I can call instead?

My code gets invoked by FileCallable<>:
T invoke(File f, VirtualChannel channel) throws IOException, InterruptedException;

Alternatively I might be able to mark TaskListener as transient.

Thanks,
Paul
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CANfRfr3D_qWVG3BeMsyLN3B6idawh4KurOrB2D3ZTGezuNL36g%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

<p style"color: gray;font-size: 10pt;font-family: arial, helvetica, sans-serif;">
--------------------------------------------------------------------------------
This email and any files transmitted with it are confidential and intended
solely for the use of the individual or entity to whom they are addressed. If
you have received this email in error please notify the system manager. Please
note that any views or opinions presented in this email are solely those of the
author and do not necessarily represent those of Perforce Software. Finally,
the recipient should check this email and any attachments for the presence of
viruses. Perforce Software accepts no liability for any damage caused by any
virus transmitted by this email.

Perforce Software UK Ltd is registered in England and Wales as company no.
3816019 at the following address: West Forest Gate, Wellington Road, Wokingham,
RG40 2AQ, UK
--------------------------------------------------------------------------------
</p>

Jesse Glick

unread,
Aug 31, 2016, 3:11:22 PM8/31/16
to Jenkins Dev
On Wed, Aug 31, 2016 at 10:52 AM, Paul Allen <pal...@perforce.com> wrote:
> I was passing TaskListener to allow logging/reporting in the Console Output. Is there a static method I can call instead?

No.

> My code gets invoked by FileCallable<>:
> T invoke(File f, VirtualChannel channel) throws IOException, InterruptedException;

How is this related to the creation of a Groovy extension, which I
presume has something to do with Pipeline?

I feel like you are doing something too “creative” and getting derailed.

Paul Allen

unread,
Sep 1, 2016, 10:51:55 AM9/1/16
to Jenkins Developers
I submitted the experimental change here:

https://github.com/jenkinsci/p4-plugin/commit/ce55b6cfa989373d9cdf8421d102306a21bab88b

P4Groovy is the main object passed back to the user with GetP4Step and GetP4Task wrapping it up. P4Groovy calls out to the Perforce API, which has a callback for message handling.

The code seems to work and unit tests pass, the original error seems to be related to the assertBuildStatusSuccess() method and some other internal serialisation of the console data.

Any feedback on the code would be appreciated, especially if there is a simpler way to achieve the same result.

Kind regards,
Paul
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CANfRfr3zyS23M%3D7P2%2BSAoUJca1Vk0MhKUE%3DHWLkZV-ux-M%3DKwA%40mail.gmail.com.

Jesse Glick

unread,
Sep 2, 2016, 7:23:57 PM9/2/16
to Jenkins Dev
Not really following what you are trying to do, but what you have
tried is not going to work.

Keep it simple. Define Pipeline steps that return simple primitive
types or structs with `@Whitelisted` getters, and which take argument
types which are mappable via Jenkins databinding, which limits them
basically to `String`, `boolean`, and some `Describable`
constructions. If you really need a higher-level convenience DSL,
write it in Groovy using those steps, plus existing ones like `sh`, as
building blocks.

Paul Allen

unread,
Sep 5, 2016, 12:52:17 PM9/5/16
to jenkin...@googlegroups.com
Thanks for the comments on GitHub, I have switch over to use MasterToSlaveCallable.

The code seems to work well and my tests are passing, also tested it manually on remote slaves with no issue. P4Groovy is just a wrapper for the Strings/Booleans that describe the Credentials and Workspace configuration details. Importantly P4Groovy exposes methods to allow users to call our inner P4Java API. This opens up all Perforce commands to a user from Groovy, quite useful for a lot of Perforce users.
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CANfRfr2sn0E5qOF68PVb2eFGwkW8ihvFyfj5SdM8cxOsOFyFMQ%40mail.gmail.com.

Jesse Glick

unread,
Sep 6, 2016, 12:10:50 PM9/6/16
to Jenkins Dev
On Mon, Sep 5, 2016 at 12:52 PM, Paul Allen <pal...@perforce.com> wrote:
> P4Groovy exposes methods to allow users to call our inner P4Java API.

This is the problem—anything “active” you want to do from a `Step`.
Reply all
Reply to author
Forward
0 new messages