How to schedule a child Free Style job programmatically from a parent Job in Jenkins Plugin Development?

46 views
Skip to first unread message

vinodhi...@gmail.com

unread,
Apr 1, 2015, 2:47:16 AM4/1/15
to jenkins...@googlegroups.com
 


 

 
Hello All,


I am working on Jenkins Plugin Development. I have a special Job type, that creates Free Style Projects on saving of the Project.

e.g: Jenkins > New Item/New Job > Enter Name (say "Special Project") and click "Build a Special Project" radio button > Click Save. On Clicking Save, the Free Style Projects (child Projects) would be created using the below code:

FreeStyleProject childProject = Jenkins.getInstance().createProject(FreeStyleProject.class,"newName");

FreeStyleProject childProject1 = Jenkins.getInstance().createProject(FreeStyleProject.class,"newName1");

I would like to trigger these childProject, childProject1 jobs when my "Special Project" is given a build (say by timer or by clicking "Build Now")

I tried the below code , but I get exception.

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.List;
import hudson.model.Action;
import hudson.model.Build;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.model.AbstractBuild;
import hudson.model.Cause;
import hudson.model.FreeStyleProject;


public class SpecialBuild extends Build<SpecialProject, SpecialBuild> {


    public SpecialBuild(SpecialProject project) throws IOException {
        super(project);     
    }


    public SpecialBuild(SpecialProject job, Calendar timestamp) {
        super(job, timestamp);
    }

    public SpecialBuild(SpecialProject project, File buildDir)
            throws IOException {
        super(project, buildDir);
    }


    @Override
    public void run() {
        execute(new ChildExecution(this));

//      if I use the below code : Executors are dead.
//Exception in thread "Executor #1 for master" java.lang.NullPointerException
//  at hudson.model.AbstractProject.getLastBuild(AbstractProject.java:1089)
//  at hudson.model.AbstractProject.getLastBuild(AbstractProject.java:152)
//  at hudson.model.Job.isLogUpdated(Job.java:293)
//  at hudson.model.AbstractProject.getCauseOfBlockage(AbstractProject.java:1285)
//  at hudson.model.AbstractProject.isBuildBlocked(AbstractProject.java:1222)
//  at hudson.model.Queue.isBuildBlocked(Queue.java:1021)
//  at hudson.model.Queue.maintain(Queue.java:1080)
//  at hudson.model.Queue.pop(Queue.java:935)
//  at hudson.model.Executor.grabJob(Executor.java:297)
//  at hudson.model.Executor.run(Executor.java:211)
// 
//      execute(new RunExecution(){
//          
//          @Override
//          public Result run(BuildListener listener) throws Exception,
//                  hudson.model.Run.RunnerAbortedException {
//              System.out.println("Special main running");
//              if(project != null){
//                  List<FreeStyleProject> kids = project.getChildren();
//                  for(FreeStyleProjecteachKid : kids){
//                      eachKid.scheduleBuild2(0);
//                  }
//              }
//              
//              return Result.SUCCESS;
//          }
//
//          @Override
//          public void post(BuildListener listener) throws Exception {
//              // do nothing
//
//          }
//
//          @Override
//          public void cleanUp(BuildListener listener) throws Exception {
//              // do nothing
//
//          }
//      });

    }

    private class ChildExecution extends BuildExecution {

        private AbstractBuild build;

        public ChildExecution() {
            super();
        }

        public ChildExecution(SpecialBuild build){
            this.build= (AbstractBuild)build;
        }

        @Override
         public Result run(BuildListener listener) throws Exception {
            Result result = super.run(listener);
            System.out.println("Special main running");
            if(project != null){
                List<FreeStyleProject> kids = project.getChildren();
                for(FreeStyleProject eachKid : kids){
                    eachKid.scheduleBuild2(eachKid.getQuietPeriod(),new Cause(){
                        @Override
                        public String getShortDescription() {
                            return "Special job execution";
                        }

                    },new Action[1]);
                }
            }


            if (isAborted())
                return Result.ABORTED;
            if (isFailure())
                return Result.FAILURE;
            if (isUnstable())
                return Result.UNSTABLE;
            return result;

         }
        private boolean isAborted() {
            return evaluateResult(Result.FAILURE);
        }

        private boolean isFailure() {
            return evaluateResult(Result.UNSTABLE);
        }

        private boolean isUnstable() {
            return evaluateResult(Result.SUCCESS);
        }

        private boolean evaluateResult(Result result) {
            List<FreeStyleProject> children = project.getChildren();
            for (FreeStyleProject child : children) {
//              child.getLas
//              Class<FreeStyleProject> buildClass = child.getBuildClass();
//                if (!child.isRetry() && !child.isAbort()) {
//                    Result buildResult = child.getResult();
//                    if (buildResult != null && buildResult.isWorseThan(result)) {
//                        return true;
//                    }
//                }
//              buildClass.
            }
            return false;
        }

    }
}

Exception:

SEVERE: Executor threw an exception
java.lang.RuntimeException: Failed to serialize hudson.model.Actionable#actions for class hudson.model.FreeStyleBuild
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:208)
    at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:176)
    at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:135)
    at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:161)
    at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:102)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
    at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
    at com.thoughtworks.xstream.XStream.marshal(XStream.java:898)
    at com.thoughtworks.xstream.XStream.marshal(XStream.java:887)
    at com.thoughtworks.xstream.XStream.toXML(XStream.java:860)
    at hudson.XmlFile.write(XmlFile.java:183)
    at hudson.model.Run.save(Run.java:1834)
    at hudson.model.Run.execute(Run.java:1721)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46)
    at hudson.model.ResourceController.execute(ResourceController.java:88)
    at hudson.model.Executor.run(Executor.java:246)
Caused by: java.lang.RuntimeException: Failed to serialize hudson.model.CauseAction#causes for class hudson.model.CauseAction
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:208)
    at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:176)
    at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:135)
    at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:161)
    at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:102)
    at hudson.util.XStream2$PassthruConverter.marshal(XStream2.java:364)
    at hudson.util.XStream2$AssociatedConverterImpl.marshal(XStream2.java:334)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:55)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
    at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:217)
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:204)
    ... 18 more
Caused by: java.lang.RuntimeException: Failed to serialize com.SpecialBuild$ChildExecution$1#this$1 for class com.SpecialBuild$ChildExecution$1
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:208)
    at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:176)
    at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:135)
    at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:161)
    at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:102)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:55)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
    at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:217)
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:204)
    ... 35 more
Caused by: java.lang.RuntimeException: Failed to serialize hudson.model.AbstractBuild$AbstractBuildExecution#launcher for class com.SpecialBuild$ChildExecution
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:208)
    at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:176)
    at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:135)
    at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:161)
    at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:102)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
    at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:217)
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:204)
    ... 50 more
Caused by: java.lang.RuntimeException: Failed to serialize hudson.Launcher#listener for class hudson.Launcher$LocalLauncher
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:208)
    at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:176)
    at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:135)
    at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:161)
    at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:102)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
    at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
    at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
    at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:217)
    at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:204)
    ... 59 more
Caused by: com.thoughtworks.xstream.converters.ConversionException: Could not call hudson.model.StreamBuildListener.writeObject() : Could not call hudson.remoting.RemoteOutputStream.writeObject() : null


Also, I had gone through the MultiJob Jenkins Plugin https://wiki.jenkins-ci.org/display/JENKINS/Multijob+Plugin . But, there all the child jobs are executed via a separate Thread and not via Executors.

Could someone help me in this issue?

Thank you in advance!!



Christopher Orr

unread,
Apr 1, 2015, 3:13:06 AM4/1/15
to jenkins...@googlegroups.com
Hi there,

This is a question better suited to the developers' mailing list
(jenkinsci-dev).

I only very quickly scrolled through the code below, but I would guess
that your anonymous Cause class ("new Cause() { ... }") in
ChildExecution may be causing problems, as it cannot be serialized (to
disk in this case).

Try making that a named class.

Regards,
Chris
> --
> 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 jenkinsci-use...@googlegroups.com
> <mailto:jenkinsci-use...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jenkinsci-users/cd73c8f7-9ba5-4f23-8d1a-0b229c19986b%40googlegroups.com
> <https://groups.google.com/d/msgid/jenkinsci-users/cd73c8f7-9ba5-4f23-8d1a-0b229c19986b%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

vinodhi...@gmail.com

unread,
Apr 1, 2015, 7:06:49 AM4/1/15
to jenkins...@googlegroups.com
Hello Chris,

Thank you so much!. It worked for me.

I created a new Cause class as shown below and used the same instead of Anonymous Class:

public static class SpecialCause extends Cause {
        private String note;

        public SpecialCause (String note) {
            this.note = note;
        }

        @Override
        public String getShortDescription() {
            if(note != null) {
                return note;
            } else {
                return "Parent build triggered this build ";
            }
        }

        @Override
        public boolean equals(Object o) {
            return o instanceof SpecialCause;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 83 * hash + (this.note != null ? this.note.hashCode() : 0);
            return hash;
        }
    }


Thanks again!!

Regards,
Vinodhini
Reply all
Reply to author
Forward
0 new messages