Open vlad-ivanov-name opened 1 year ago
The only workaround I found is to convert SomeClass
and Utils
to Java. But it's not a very good solution, I would certainly prefer to have them in groovy as well.
It appears to be caused by having two methods with the same name in src/
and vars/
, regardless of their class hierarchy.
// src/com/example/HardMath.groovy
package com.example
class HardMath implements Serializable {
Object script = null
int complexOperation(int a, int b) {
script.echo "Adding ${a} to ${b}"
return a + b
}
}
// vars/complexOperation.groovy
import com.example.HardMath
int call(int a, int b) {
return new HardMath(script: this).complexOperation(a, b)
}
In this example, you can see the complexOperation
symbol is defined twice. After debugging, the interceptor is redirecting the HardMath#complexOperation
call back to the step defined in vars causing recursion.
https://github.com/axieum/jenkinspipelineunit-issue-585
I've pushed up a reproduction (bare minimum) of this StackOverflowError
, simply clone the repository and run ./gradlew test
.
It appears our global steps defined in vars/
are loaded into the helper#allowedMethodCallbacks
first - this is important later.
The src/
path is added to the Groovy class loader.
https://github.com/jenkinsci/JenkinsPipelineUnit/blob/70482cb5ad4027b5eb585abe62b38ba176975cdc/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryLoader.groovy#L106-L111
The InterceptingGCL
Groovy class loader overrides the #parseClass
method to intercept method calls,
https://github.com/jenkinsci/JenkinsPipelineUnit/blob/70482cb5ad4027b5eb585abe62b38ba176975cdc/src/main/groovy/com/lesfurets/jenkins/unit/InterceptingGCL.groovy#L55-L61
..which in turn replaces our class method call with a reference to the already registered global step - causing recursion: https://github.com/jenkinsci/JenkinsPipelineUnit/blob/70482cb5ad4027b5eb585abe62b38ba176975cdc/src/main/groovy/com/lesfurets/jenkins/unit/InterceptingGCL.groovy#L18-L26
So, regardless of whether complexOperation#call(int, int)
or com.example.HardMath#complexOperation(int, int)
is called, we can see it looks up against the complexOperation
name only which just so happens to match a step defined in helper#allowedMethodCallbacks
.
Jenkins and plugins versions report
Environment
```text Jenkins: 2.361.3 OS: Linux - 5.10.147+ --- PrioritySorter:4.1.0 ace-editor:1.1 ansicolor:1.0.2 antisamy-markup-formatter:155.v795fb_8702324 apache-httpcomponents-client-4-api:4.5.13-138.v4e7d9a_7b_a_e61 authentication-tokens:1.4 authorize-project:1.4.0 basic-branch-build-strategies:71.vc1421f89888e blueocean:1.25.8 blueocean-autofavorite:1.2.5 blueocean-bitbucket-pipeline:1.25.8 blueocean-commons:1.25.8 blueocean-config:1.25.8 blueocean-core-js:1.25.8 blueocean-dashboard:1.25.8 blueocean-display-url:2.4.1 blueocean-events:1.25.8 blueocean-git-pipeline:1.25.8 blueocean-github-pipeline:1.25.8 blueocean-i18n:1.25.8 blueocean-jwt:1.25.8 blueocean-personalization:1.25.8 blueocean-pipeline-api-impl:1.25.8 blueocean-pipeline-editor:1.25.8 blueocean-pipeline-scm-api:1.25.8 blueocean-rest:1.25.8 blueocean-rest-impl:1.25.8 blueocean-web:1.25.8 bootstrap4-api:4.6.0-5 bootstrap5-api:5.2.1-3 bouncycastle-api:2.26 branch-api:2.1046.v0ca_37783ecc5 build-timeout:1.24 caffeine-api:2.9.3-65.v6a_47d0f4d1fe checks-api:1.8.0 cloudbees-bitbucket-branch-source:791.vb_eea_a_476405b cloudbees-folder:6.758.vfd75d09eea_a_1 command-launcher:90.v669d7ccb_7c31 commons-lang3-api:3.12.0-36.vd97de6465d5b_ commons-text-api:1.10.0-27.vb_fa_3896786a_7 copyartifact:1.47 credentials:1189.vf61b_a_5e2f62e credentials-binding:523.vd859a_4b_122e6 display-url-api:2.3.6 docker-commons:1.21 docker-workflow:528.v7c193a_0b_e67c durable-task:501.ve5d4fc08b0be echarts-api:5.4.0-1 email-ext:2.92 favorite:2.4.1 font-awesome-api:6.2.0-3 gcp-secrets-manager-credentials-provider:0.3.1 generic-webhook-trigger:1.85.2 git:4.13.0 git-client:3.13.0 git-server:99.va_0826a_b_cdfa_d github:1.36.0 github-api:1.303-400.v35c2d8258028 github-branch-source:1696.v3a_7603564d04 github-scm-trait-notification-context:1.1 google-compute-engine:4.3.12 google-login:1.6 google-oauth-plugin:1.0.7 handlebars:3.0.8 handy-uri-templates-2-api:2.1.8-22.v77d5b_75e6953 htmlpublisher:1.31 instance-identity:116.vf8f487400980 ionicons-api:31.v4757b_6987003 jackson2-api:2.13.4.20221013-295.v8e29ea_354141 jakarta-activation-api:2.0.1-2 jakarta-mail-api:2.0.1-2 javax-activation-api:1.2.0-5 javax-mail-api:1.6.2-8 jaxb:2.3.7-1 jdk-tool:63.v62d2fd4b_4793 jenkins-design-language:1.25.8 jjwt-api:0.11.5-77.v646c772fddb_0 jnr-posix-api:3.1.15-2 job-dsl:1.81 jquery3-api:3.6.1-2 jsch:0.1.55.61.va_e9ee26616e7 junit:1156.vcf492e95a_a_b_0 ldap:2.12 lockable-resources:2.18 mailer:438.v02c7f0a_12fa_4 matrix-auth:3.1.5 matrix-project:785.v06b_7f47b_c631 mina-sshd-api-common:2.9.1-44.v476733c11f82 mina-sshd-api-core:2.9.1-44.v476733c11f82 momentjs:1.1.1 oauth-credentials:0.5 okhttp-api:4.9.3-108.v0feda04578cf opentelemetry:2.9.2 pam-auth:1.10 pipeline-build-step:2.18 pipeline-github-lib:38.v445716ea_edda_ pipeline-graph-analysis:195.v5812d95a_a_2f9 pipeline-groovy-lib:613.v9c41a_160233f pipeline-input-step:456.vd8a_957db_5b_e9 pipeline-milestone-step:101.vd572fef9d926 pipeline-model-api:2.2118.v31fd5b_9944b_5 pipeline-model-definition:2.2118.v31fd5b_9944b_5 pipeline-model-extensions:2.2118.v31fd5b_9944b_5 pipeline-rest-api:2.27 pipeline-stage-step:296.v5f6908f017a_5 pipeline-stage-tags-metadata:2.2118.v31fd5b_9944b_5 pipeline-stage-view:2.27 pipeline-utility-steps:2.13.1 plain-credentials:139.ved2b_9cf7587b plugin-util-api:2.18.0 popper-api:1.16.1-3 popper2-api:2.11.6-2 pubsub-light:1.17 resource-disposer:0.20 scm-api:621.vda_a_b_055e58f7 script-security:1189.vb_a_b_7c8fd5fde simple-theme-plugin:136.v23a_15f86c53d slack:629.vf00ea_cb_40d53 snakeyaml-api:1.32-86.ve3f030a_75631 sse-gateway:1.26 ssh-agent:295.v9ca_a_1c7cc3a_a_ ssh-credentials:305.v8f4381501156 ssh-slaves:2.854.v7fd446b_337c9 sshd:3.249.v2dc2ea_416e33 structs:324.va_f5d6774f3a_d throttle-concurrents:2.9 timestamper:1.21 token-macro:308.v4f2b_ed62b_b_16 trilead-api:2.72.v2a_3236754f73 variant:59.vf075fe829ccb workflow-aggregator:590.v6a_d052e5a_a_b_5 workflow-api:1200.v8005c684b_a_c6 workflow-basic-steps:994.vd57e3ca_46d24 workflow-cps:3520.va_8fc49e2f96f workflow-durable-task-step:1210.va_1e5d77e122b workflow-job:1254.v3f64639b_11dd workflow-multibranch:716.vc692a_e52371b_ workflow-scm-step:400.v6b_89a_1317c9a_ workflow-step-api:639.v6eca_cd8c04a_a_ workflow-support:839.v35e2736cfd5c ws-cleanup:0.43 ```What Operating System are you using (both controller, and any agents involved in the problem)?
The issue occurs only in tests; tests run on MacOS
Reproduction steps
I have the following directory tree:
With the following
pom.xml
:What I'm trying to accomplish:
1)
SomeClass
can be imported bypipelineFunction.groovy
2)Utils
class has static methods thatSomeClass
methods can callExpected Results
I can invoke static methods
Actual Results
I'm getting a stack overflow with the following set of frames repeating:
Anything else?
I don't actually need to intercept methods in that part of code; is there something I can do to just disable interception there?