Home > Mobile >  Jenkins: No Such DSL Method when adding a plugin DSL function to a shared library function
Jenkins: No Such DSL Method when adding a plugin DSL function to a shared library function

Time:10-20

We are working with a jenkins shared library defined as follows using JCasC:

controller:
  JCasC:
    configScripts:
      jenkins-casc-unclassified: |
        unclassified:
          globalLibraries:
            libraries:
            - defaultVersion: "master"
              implicit: true
              name: "com.company.jenkins"
              retriever:
                modernSCM:
                  scm:
                    github:
                      configuredByUrl: true
                      credentialsId: "..."
                      id: "..."
                      repoOwner: "Company"
                      repository: "Company_CICD"
                      repositoryUrl: "https://github.com/company/Company_CICD.git"
                      traits:
                      - gitHubBranchDiscovery:
                          strategyId: 1
                      - gitHubPullRequestDiscovery:
                          strategyId: 1
                      - gitHubForkDiscovery:
                          strategyId: 1
                          trust: "gitHubTrustPermissions"

We have made a convienience function for the Kubernetes Plugin that allows us to shorten the code considerably. However, the attempt to eliminate just 2 lines, we have hit a strange error we would like clarified:

java.lang.NoSuchMethodError: No such DSL method 'getPodTemplate'

What is strange about this is that without changing either the import or the function name, it shows up.

For example, this works:

// src/com/company/jenkins/Util.groovy
package com.onscale.jenkins

def getPodTemplate(String label, List<String> containers, List<String> volumes, String yaml) {
    containers = containers.collect {
        value -> return getContainerTemplate(value)
    }
    volumes = volumes.collect {
        value -> return getVolume(value)
    }
    return [
      label: label,
      yaml: yaml,
      containers: containers,
      volumes: volumes
    ]
}
// Jenkinsfile
def util = new com.onscale.jenkins.Util()
podTemplate (
  util.getPodTemplate(
    'jenkinsbuild', // Label
    ['jnlp', 'docker', 'kubectl'], // Containers
    ['host-path'], // Volumes
    podSpec
  )
)

But this doesn't:

// src/com/company/jenkins/Util.groovy
package com.onscale.jenkins

def getPodTemplate(String label, List<String> containers, List<String> volumes, String yaml) {
    containers = containers.collect {
        value -> return getContainerTemplate(value)
    }
    volumes = volumes.collect {
        value -> return getVolume(value)
    }
    return podTemplate(
      label: label,
      yaml: yaml,
      containers: containers,
      volumes: volumes
    )
}
// Jenkinsfile
def util = new com.onscale.jenkins.Util()
util.getPodTemplate(
  'jenkinsbuild', // Label
  ['jnlp', 'docker', 'kubectl'], // Containers
  ['host-path'], // Volumes
  podSpec
)

All that is changed between the two is if getPodTemplate returns podTemplate.

We have searched around. This stack overflow confuses us because we are not using the var/function.groovy method of making a shared library (I'm not really sure what each "kind" of shared library is called), we are importing using "new" and a globalLibrary.

Any Ideas?

CodePudding user response:

This job DSL error seems to happen when a function doesn't compile. In this case the function doesn't compile because groovy does this thing where you can call functions without parentheses.

Examples:

def foo(name, closure) {println name; println closure()}

Can be called in all the following ways.

foo(“asdf”,{return “asdf”})
foo “asdf” {return “asdf”}
foo(“asdf”) {return “asdf”}

With both parentheses and not parentheses

However this:

foo(“asdf”)

Will throw an error MissingMethodException because foo needs 2 parameters. Whereas I originally assumed it would return a partial.

So when we return podTemplate without a closure as it's last parameter we actually break the compilation of that method and thus we get a DSL error because the shared library can't compile.

The solution is to add a closure final parameter and pass it as the last argument to podTemplate

  • Related