# Calling a declaratively defined closure from Jenkins Shared Library

**URL:** <https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234>\
**Category:** Ask a question\
**Created:** [October 19, 2022, 9:04pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234 "2022-10-19T21:04:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![parthivi95](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/parthivi95/32/2521_2.png) [@parthivi95](https://community.jenkins.io/u/parthivi95)\
**Post date:** [October 19, 2022, 9:04pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/1 "2022-10-19T21:04:25Z")

</div>

Hi Everyone!  
I have been working on creating a jenkins shared library, and it works perfectly for a generalized pipeline template. Recently I had the need to pass an extra user-defined stage to my generalized pipeline. I am using closure to do so, but facing some issues with it.  
I would like for the closure to return a declarative stage which has its own agent, steps and other components as shown in the code samples below (refer the following images) :

Closure defined in .jenkinsfile | Call to closure from jenkins shared library | Error Message :

 ![all_in_one](https://europe1.discourse-cdn.com/flex013/uploads/jenkins/original/2X/6/644808b3f18416cc9a47c6f0bdf653196b4cc297.png)

Please let me know how can I achieve the above functionality.

---

<div class="post-metadata">

**Author:** ![mlasevich](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/mlasevich/32/231_2.png) [@mlasevich](https://community.jenkins.io/u/mlasevich)\
**Post date:** [October 19, 2022, 9:11pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/2 "2022-10-19T21:11:48Z")

</div>

I am not that familiar with declarative stuff, but it is mostly because it doesn’t (or at least didn’t in the past) support this sort of a thing due to how declarative works (it needs to know the structure of the entire pipeline before executing, which is hard if your stage is being dynamically generated)

My suggestion is if you want this sort of functionality, just use scripted pipelines, esp in combination with Pipeline Libraries

---

<div class="post-metadata">

**Author:** ![parthivi95](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/parthivi95/32/2521_2.png) [@parthivi95](https://community.jenkins.io/u/parthivi95)\
**Post date:** [October 19, 2022, 9:47pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/3 "2022-10-19T21:47:00Z")

</div>

Noted, thanks for a quick response!

---

<div class="post-metadata">

**Author:** ![parthivi95](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/parthivi95/32/2521_2.png) [@parthivi95](https://community.jenkins.io/u/parthivi95)\
**Post date:** [October 20, 2022, 8:00pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/4 "2022-10-20T20:00:35Z")

</div>

Hey I have multiple projects running with declarative pipeline, to change the code to scripted, I’ll have to redo all those project. Do you think there’s any other solution available to achieve this?

---

<div class="post-metadata">

**Author:** ![halkeye](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/halkeye/32/8_2.png) [@halkeye](https://community.jenkins.io/u/halkeye)\
**Post date:** [October 20, 2022, 9:37pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/5 "2022-10-20T21:37:39Z")

</div>

shortcuts tend to cause problems later, as witnessed by this.

> [@parthivi95](#):
>
> Hey I have multiple projects running with declarative pipeline, to change the code to scripted, I’ll have to redo all those project. Do you think there’s any other solution available to achieve this?

script {} is a block of scripted pipeline. You don’t need your entire pipeline to be scripted, just the stuff you put into script {} tag. There’s no way to have declarative code inside script {} tag.

---

<div class="post-metadata">

**Author:** ![parthivi95](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/parthivi95/32/2521_2.png) [@parthivi95](https://community.jenkins.io/u/parthivi95)\
**Post date:** [October 20, 2022, 10:53pm UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/6 "2022-10-20T22:53:20Z")

</div>

So that means I should not wrap the call to closure in script tag, right?

---

<div class="post-metadata">

**Author:** ![mlasevich](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/mlasevich/32/231_2.png) [@mlasevich](https://community.jenkins.io/u/mlasevich)\
**Post date:** [October 21, 2022, 12:55am UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/7 "2022-10-21T00:55:18Z")

</div>

I am a bit confused, but any valid non-declarative groovy should work inside a script tag - but no declarative code. So you can call your closure and as long as the closure does not have declarative stuff in it, it should work

---

<div class="post-metadata">

**Author:** ![mlasevich](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/mlasevich/32/231_2.png) [@mlasevich](https://community.jenkins.io/u/mlasevich)\
**Post date:** [October 21, 2022, 1:06am UTC](https://community.jenkins.io/t/calling-a-declaratively-defined-closure-from-jenkins-shared-library/4234/8 "2022-10-21T01:06:34Z")

</div>

Looking at your example above, the point is that the declarative bits should be in your pipeline, but you can make your tests be a closure, (or better yet a method to avoid the complexity of closure context management)

so something like(I am too lazy to look up correct syntax or commands I do not remember offhand, so you may need to edit it, but close enough:

```auto
def hardwareBenchTest(){
  node('ABC'){ // allocate a node workspace
    def retcode = sh script: 'run some commands', returnStdout: true
    if (retcode) {
       echo 'do something when failed (set build to unstable?)'
    } else {
       echo 'do something when success (throw a party?)'
    }
    echo 'This will always run'
  } // deallocate a node workspace
  return retcode // dont need to return, but may be useful
}

```
