readFileFromWorkspace causes NPE when running generated Multi Branch pipeline job

308 views
Skip to first unread message

Torsten Reinhard

unread,
Aug 10, 2017, 12:01:05 PM8/10/17
to job-dsl-plugin
Hi,

I´m using job-dsl 1.48 and today I tried to move my *.groovy code (pipeline) to separated files in the workspace, located in the resources directory.
The code looks like:

String script = readFileFromWorkspace("resources/workflowLibs_pipeline2.groovy"))
def multiPipeline = new BitbucketMultiPipeline(
        description
: script,
        name
: 'CD/DEV_workflowLibs-multibranch',
        displayName
: 'Multi branch pipeline test',
        bitbucketProjectOwner
: "cd",
        repoName
: "workflowlibs",
        includeBranches
: ['master*', 'feature/*', 'bugfix/*'],
        customScript
: script,
        usePeriodicTrigger
: true
).build(this)


The utility class is doing this DSL commands:

        def job = dslFactory.multibranchPipelineJob(name) {
            description
(description)
            displayName
(displayName)

            orphanedItemStrategy
{
                discardOldItems
{
                    numToKeep
(10)
               
}
           
}

           
if(usePeriodicTrigger) {
                triggers
{
                   
// Triggers a build periodically if not otherwise run.
                    periodic
(5)
               
}
           
}

            configure
{ project ->

                project
/ sources / data / 'jenkins.branch.BranchSource' / source(class: 'com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource') {
                    credentialsId
"*****" // For scan
                    checkoutCredentialsId
"Bitbucket_Access"
                    repoOwner
(this.bitbucketProjectOwner)
                    repository
(this.repoName)
                    includes
("${includeBranches.join(' ')}")
                    excludes
()
                    bitbucketServerUrl
"https://licdci01.mycompany.net:7993"
                    autoRegisterHook
true
                    sshPort
('7999')
               
}

               
if(customScript) {
                   
def factory = project / factory(class: 'com.cloudbees.workflow.multibranch.CustomBranchProjectFactory', plugin: "cloudbees-workflow-template@2.6")

                    factory
<< owner(class: "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject", reference: "../..")
                    factory
<< marker()
                    factory
/ definition(class: "org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition", plugin: "workfl...@2.29") {
                        script
(customScript)
                        sandbox
true
                   
}
               
}
           
}
       
}


The job looks fine locally written using FileManagement, and also the generate job in Jenkins looks fine when invoking /configure on it.

The config.xml looks like:

<?xml version="1.0" encoding="UTF-8"?><org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>
    <actions/>
    <description>// workflowLibs_pipeline_it.groovy
</description>
    <properties>
        <com.cloudbees.hudson.plugins.folder.properties.EnvVarsFolderProperty/>
    </properties>
    <icon class="com.cloudbees.hudson.plugins.folder.icons.StockFolderIcon"/>
    <views>
        <hudson.model.AllView>
            <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../../.."/>
            <name>All</name>
            <filterExecutors>false</filterExecutors>
            <filterQueue>false</filterQueue>
            <properties class="hudson.model.View$PropertyList"/>
        </hudson.model.AllView>
    </views>
    <viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
    <primaryView>All</primaryView>
    <healthMetrics>
        <com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric/>
    </healthMetrics>
    <triggers>
        <com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger>
            <spec>* * * * *</spec>
            <interval>300000</interval>
        </com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger>
    </triggers>
    <sources class="jenkins.branch.MultiBranchProject$BranchSourceList">
        <data>
            <jenkins.branch.BranchSource>
                <source class="com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource">
                    <credentialsId>********</credentialsId>
                    <checkoutCredentialsId>Bitbucket_Access</checkoutCredentialsId>
                    <repoOwner>cd</repoOwner>
                    <repository>workflowlibs</repository>
                    <includes>master* feature/* bugfix/*</includes>
                    <excludes/>
                    <bitbucketServerUrl>https://licdci01.mycompany.net:7993</bitbucketServerUrl>
                    <autoRegisterHook>true</autoRegisterHook>
                    <sshPort>7999</sshPort>
                </source>
            </jenkins.branch.BranchSource>
        </data>
        <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
    </sources>
    <factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory">
        <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
    </factory>
    <displayName>Multi branch pipeline test</displayName>
    <orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy">
        <pruneDeadBranches>true</pruneDeadBranches>
        <daysToKeep>-1</daysToKeep>
        <numToKeep>10</numToKeep>
    </orphanedItemStrategy>
    <factory plugin="cloudbees-workflow-template@2.6" class="com.cloudbees.workflow.multibranch.CustomBranchProjectFactory">
        <owner reference="../.." class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"/>
        <marker/>
        <definition plugin="workfl...@2.29" class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition">
            <script>// workflowLibs_pipeline_it.groovy
</script>
            <sandbox>true</sandbox>
        </definition>
    </factory>
</org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>


When running that job in of the Branches, I got this error:

Loading library cd_workflowLibs@FOR_INTEGRATION_TESTING
 
> git rev-parse --is-inside-work-tree # timeout=10
Setting origin to ssh://g...@licdci01.mycompany.net:7999/cd/workflowlibs.git
 
> git config remote.origin.url ssh://g...@licdci01.mycompany.net:7999/cd/workflowlibs.git # timeout=10
Fetching origin...
Fetching upstream changes from origin
 
> git --version # timeout=10
using GIT_SSH to set credentials SSH Bitbucket Access
 
> git fetch --tags --progress origin +refs/heads/*:refs/remotes/origin/*
 > git rev-parse FOR_INTEGRATION_TESTING^{commit} # timeout=10
java.lang.NullPointerException
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: Loading libraries failed

1 error

        at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
        at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
        at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
        at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
        at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
        at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
        at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
        at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
        at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
        at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:129)
        at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:123)
        at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:516)
        at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:479)
        at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:268)
        at hudson.model.ResourceController.execute(ResourceController.java:97)
        at hudson.model.Executor.run(Executor.java:405)

The strange thing now is that the generated job works as expected when using a hardcoded String instead of readFileFromWorkspace
// readFileFromWorkspace(...)
def multiPipeline =

Any idea why using readFileFromWorkspace will lead to a broken job, while using String = "// my code" will work ??

I have no idea and played around over hours with File encoding - but without any result yet.

Thanx for your help

Torsten

Torsten Reinhard

unread,
Aug 14, 2017, 6:44:40 AM8/14/17
to job-dsl-plugin
After executing the Job DSL on another Jenkins instance (with different plugin versions) I got a better stacktrace of the mentioned "NullPointerException".

The root cause was am (empty) missing

<properties/>

Element inside here:

<properties>
   
<com.cloudbees.hudson.plugins.folder.properties.EnvVarsFolderProperty plugin="cloudbees-folders-plus@3.1">
     
<properties></properties>
   
</com.cloudbees.hudson.plugins.folder.properties.EnvVarsFolderProperty>
</properties>



After fixing that, the job was working.
Reply all
Reply to author
Forward
0 new messages