If you update to Guava 21+ and try to run a Pipeline build you will get
java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor()Lcom/google/common/util/concurrent/ListeningExecutorService;
at org.jenkinsci.plugins.workflow.support.concurrent.Futures.addCallback(Futures.java:90)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.runInCpsVmThread(CpsFlowExecution.java:738)
at ...
due to this removal. (Note that the method was not deprecated or even marked @Beta in Guava 11, which we currently compile against—the deprecation happened later.)
Hey jglick, I started working on this over the weekend and achieved some preliminary success converting workflow-support to work with both Guava 11 and Guava 28.1. You can see my work-in-progress changes here.
While running some integration tests with the above, I found three remaining odds and ends.
In workflow-basic-steps's TimeoutStepExecution we directly call MoreExecutors.sameThreadExecutor, which was removed in Guava 21:
import com.google.common.util.concurrent.MoreExecutors;
[…]
// TODO would use Futures.addCallback but this is still @Beta in Guava 19 and the Pipeline copy is in workflow-support on which we have no dep
currentExecutions.addListener(newRunnable() {
@Override public void run() {
[…]
}
}, MoreExecutors.sameThreadExecutor());
In workflow-api's FlowExecutionList we call com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) directly (as opposed to org.jenkinsci.plugins.workflow.support.concurrent.Futures#addCallback(ListenableFuture, FutureCallback)):
import com.google.common.util.concurrent.Futures;
[…]
Futures.addCallback(e.getCurrentExecutions(false), new FutureCallback<List<StepExecution>>() {
[…]
});
com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) was removed in Guava 26, yielding errors like this even with my workflow-support fixes:
java.lang.NoSuchMethodError: com.google.common.util.concurrent.Futures.addCallback(Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/FutureCallback;)V
at org.jenkinsci.plugins.workflow.flow.FlowExecutionList$ItemListenerImpl.onLoaded(FlowExecutionList.java:180)
at jenkins.model.Jenkins.<init>(Jenkins.java:989)
at hudson.model.Hudson.<init>(Hudson.java:85)
This hasn't changed in the latest version of Guava, but it makes me nervous that we are using com.google.common.util.concurrent.Futures anywhere in Pipeline rather than the safer org.jenkinsci.plugins.workflow.support.concurrent.Futures.
What is to be done for these three cases? workflow-api depends on workflow-step-api and workflow-support depends on workflow-api. So one solution would be to move the org.jenkinsci.plugins.workflow.support.concurrent package out of workflow-support. But where should it go? Since it is an internal API for pipeline, I think a logical place would be a org.jenkinsci.plugins.workflow.concurrent package in workflow-api. But then workflow-step-api wouldn't have access to it. Putting the org.jenkinsci.plugins.workflow.concurrent package in workflow-step-api doesn't seem like a good place either, since it isn't clearly related to the Step API. And making a whole new plugin for this seems overkill. So I can't think of a good solution here. Maybe we should put it in workflow-api and copy and paste a private restricted copy in workflow-step-api? That isn't the cleanest solution, but it's the best compromise I can think of right now.
Here's my proposed plan of action. Let me know what you think.
Open PR ① against workflow-api to copy the org.jenkinsci.plugins.workflow.support.concurrent package from workflow-support into a org.jenkinsci.plugins.workflow.concurrent package in workflow-api.
Open PR ② against workflow-api (downstream of PR ①) with the changes from here to make org.jenkinsci.plugins.workflow.concurrent.Futures work with newer Guava versions.
Open PR ③ against workflow-step-api (downstream of PR ②) to make a restricted copy of the needed org.jenkinsci.plugins.workflow.concurrent classes from PR ② and consume them in StepExecution.
Open PR ④ against workflow-support (downstream of PRs ② and ③) to replace usages of org.jenkinsci.plugins.workflow.support.concurrent with usages of org.jenkinsci.plugins.workflow.concurrent and deprecate all org.jenkinsci.plugins.workflow.support.concurrent classes.
Open PR ⑤ against workflow-cps (downstream of PRs ②, ③, and ④) to replace usages of org.jenkinsci.plugins.workflow.support.concurrent with usages of org.jenkinsci.plugins.workflow.concurrent and to update CpsThreadGroup to use org.jenkinsci.plugins.workflow.concurrent.Futures rather than com.google.common.util.concurrent.Futures.
Open PRs ⑥, ⑦, and ⑧ against workflow-basic-steps, workflow-durable-task, and workflow-job (downstream of PRs ②, ③, ④, and ⑤) to replace usages of org.jenkinsci.plugins.workflow.support.concurrent with usages of org.jenkinsci.plugins.workflow.concurrent and to start using org.jenkinsci.plugins.workflow.concurrent.Futures#addCallback in TimeoutStepExecution rather than the current code referenced above which uses MoreExecutors directly.
Open "do not merge" PRs ⑨, ⑩, ⑪, ⑫, ⑬, ⑭, and ⑮ against workflow-api, workflow-step-api, workflow-support, workflow-cps, workflow-basic-steps, workflow-durable-task, and workflow-job (downstream of the preceding PRs above) with a Guava update to Guava 28.1 to demonstrate that all preceding work results in Pipeline being compatible with the newest version of Guava. The preceding PRs would have demonstrated that it still works with Guava 11.
This is a formidable amount of work, so before I get started I wanted to get your feedback.
Basil Crow
added a comment - Hey jglick , I started working on this over the weekend and achieved some preliminary success converting workflow-support to work with both Guava 11 and Guava 28.1. You can see my work-in-progress changes here .
While running some integration tests with the above, I found three remaining odds and ends.
In workflow-basic-steps 's TimeoutStepExecution we directly call MoreExecutors.sameThreadExecutor , which was removed in Guava 21:
workflow-basic-steps-plugin/src/main/java/org/jenkinsci/plugins/workflow/steps/TimeoutStepExecution.java
import com.google.common.util.concurrent.MoreExecutors;
[…]
// TODO would use Futures.addCallback but this is still @Beta in Guava 19 and the Pipeline copy is in workflow-support on which we have no dep
currentExecutions.addListener( new Runnable () {
@Override public void run() {
[…]
}
}, MoreExecutors.sameThreadExecutor());
In workflow-api 's FlowExecutionList we call com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) directly (as opposed to org.jenkinsci.plugins.workflow.support.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) ):
workflow-api-plugin/src/main/java/org/jenkinsci/plugins/workflow/flow/FlowExecutionList.java
import com.google.common.util.concurrent.Futures;
[…]
Futures.addCallback(e.getCurrentExecutions( false ), new FutureCallback<List<StepExecution>>() {
[…]
});
com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) was removed in Guava 26, yielding errors like this even with my workflow-support fixes:
java.lang.NoSuchMethodError: com.google.common.util.concurrent.Futures.addCallback(Lcom/google/common/util/concurrent/ListenableFuture;Lcom/google/common/util/concurrent/FutureCallback;)V
at org.jenkinsci.plugins.workflow.flow.FlowExecutionList$ItemListenerImpl.onLoaded(FlowExecutionList.java:180)
at jenkins.model.Jenkins.<init>(Jenkins.java:989)
at hudson.model.Hudson.<init>(Hudson.java:85)
Finally, workflow-step-api 's StepExecution uses Futures#allAsList :
workflow-step-api-plugin/src/main/java/org/jenkinsci/plugins/workflow/steps/StepExecution.java
import com.google.common.util.concurrent.Futures;
[…]
return Futures.allAsList(futures);
This hasn't changed in the latest version of Guava, but it makes me nervous that we are using com.google.common.util.concurrent.Futures anywhere in Pipeline rather than the safer org.jenkinsci.plugins.workflow.support.concurrent.Futures .
What is to be done for these three cases? workflow-api depends on workflow-step-api and workflow-support depends on workflow-api . So one solution would be to move the org.jenkinsci.plugins.workflow.support.concurrent package out of workflow-support . But where should it go? Since it is an internal API for pipeline, I think a logical place would be a org.jenkinsci.plugins.workflow.concurrent package in workflow-api . But then workflow-step-api wouldn't have access to it. Putting the org.jenkinsci.plugins.workflow.concurrent package in workflow-step-api doesn't seem like a good place either, since it isn't clearly related to the Step API. And making a whole new plugin for this seems overkill. So I can't think of a good solution here. Maybe we should put it in workflow-api and copy and paste a private restricted copy in workflow-step-api ? That isn't the cleanest solution, but it's the best compromise I can think of right now.
Here's my proposed plan of action. Let me know what you think.
Open PR ① against workflow-api to copy the org.jenkinsci.plugins.workflow.support.concurrent package from workflow-support into a org.jenkinsci.plugins.workflow.concurrent package in workflow-api .
Open PR ② against workflow-api (downstream of PR ①) with the changes from here to make org.jenkinsci.plugins.workflow.concurrent.Futures work with newer Guava versions.
Open PR ③ against workflow-step-api (downstream of PR ②) to make a restricted copy of the needed org.jenkinsci.plugins.workflow.concurrent classes from PR ② and consume them in StepExecution .
Open PR ④ against workflow-support (downstream of PRs ② and ③) to replace usages of org.jenkinsci.plugins.workflow.support.concurrent with usages of org.jenkinsci.plugins.workflow.concurrent and deprecate all
org.jenkinsci.plugins.workflow.support.concurrent classes.
Open PR ⑤ against workflow-cps (downstream of PRs ②, ③, and ④) to replace usages of org.jenkinsci.plugins.workflow.support.concurrent with usages of org.jenkinsci.plugins.workflow.concurrent and to update CpsThreadGroup to use org.jenkinsci.plugins.workflow.concurrent.Futures rather than com.google.common.util.concurrent.Futures .
Open PRs ⑥, ⑦, and ⑧ against workflow-basic-steps , workflow-durable-task , and workflow-job (downstream of PRs ②, ③, ④, and ⑤) to replace usages of org.jenkinsci.plugins.workflow.support.concurrent with usages of org.jenkinsci.plugins.workflow.concurrent and to start using org.jenkinsci.plugins.workflow.concurrent.Futures#addCallback in TimeoutStepExecution rather than the current code referenced above which uses MoreExecutors directly.
Open "do not merge" PRs ⑨, ⑩, ⑪, ⑫, ⑬, ⑭, and ⑮ against workflow-api , workflow-step-api , workflow-support , workflow-cps , workflow-basic-steps , workflow-durable-task , and workflow-job (downstream of the preceding PRs above) with a Guava update to Guava 28.1 to demonstrate that all preceding work results in Pipeline being compatible with the newest version of Guava. The preceding PRs would have demonstrated that it still works with Guava 11.
This is a formidable amount of work, so before I get started I wanted to get your feedback.
After writing the above, I started wondering whether it would be possible to bundle the latest version of Guava with Pipeline and have Pipeline use that instead of the Guava that is bundled with Jenkins core. I'm not sure offhand if this is possible and I haven't done any experiments yet. If possible, maybe we could follow an alternative plan along these lines:
Open PR ① against workflow-step-api to update the Guava dependency to 28.1 in dependencyManagement.
Open PR ② against workflow-api (downstream of PR ①) to update the Guava dependency to 28.1 in dependencyManagement.
Open PR ③ against workflow-support (downstream of PRs ① and ②) to deprecate all org.jenkinsci.plugins.workflow.support.concurrent classes, update the Guava dependency to 28.1 in dependencyManagement, and replace any usages of org.jenkinsci.plugins.workflow.support.concurrent with com.google.common.util.concurrent.
Open PR ④ against workflow-cps (downstream of PRs ①, ②, and ③) to update the Guava dependency to 28.1 in dependencyManagement and replace any usages of org.jenkinsci.plugins.workflow.support.concurrent with com.google.common.util.concurrent.
Open PRs ⑤, ⑥, and ⑦ against workflow-basic-steps, workflow-durable-task, and workflow-job (downstream of PRs ①, ②, ③, ④ as applicable) to update the Guava dependency to 28.1 in dependencyManagement, replace any usages of org.jenkinsci.plugins.workflow.support.concurrent with com.google.common.util.concurrent, and to start using com.google.common.util.concurrent.Futures#addCallback in TimeoutStepExecution rather than the current code referenced above which uses MoreExecutors directly.
Basil Crow
added a comment - After writing the above, I started wondering whether it would be possible to bundle the latest version of Guava with Pipeline and have Pipeline use that instead of the Guava that is bundled with Jenkins core. I'm not sure offhand if this is possible and I haven't done any experiments yet. If possible, maybe we could follow an alternative plan along these lines:
Open PR ① against workflow-step-api to update the Guava dependency to 28.1 in dependencyManagement .
Open PR ② against workflow-api (downstream of PR ①) to update the Guava dependency to 28.1 in dependencyManagement .
Open PR ③ against workflow-support (downstream of PRs ① and ②) to deprecate all org.jenkinsci.plugins.workflow.support.concurrent classes, update the Guava dependency to 28.1 in dependencyManagement , and replace any usages of org.jenkinsci.plugins.workflow.support.concurrent with com.google.common.util.concurrent .
Open PR ④ against workflow-cps (downstream of PRs ①, ②, and ③) to update the Guava dependency to 28.1 in dependencyManagement and replace any usages of org.jenkinsci.plugins.workflow.support.concurrent with com.google.common.util.concurrent .
Open PRs ⑤, ⑥, and ⑦ against workflow-basic-steps , workflow-durable-task , and workflow-job (downstream of PRs ①, ②, ③, ④ as applicable) to update the Guava dependency to 28.1 in dependencyManagement , replace any usages of org.jenkinsci.plugins.workflow.support.concurrent with com.google.common.util.concurrent , and to start using com.google.common.util.concurrent.Futures#addCallback in TimeoutStepExecution rather than the current code referenced above which uses MoreExecutors directly.
After writing the above, I started wondering whether it would be possible to bundle the latest version of Guava with Pipeline and have Pipeline use that instead of the Guava that is bundled with Jenkins core.
After reading JENKINS-36779 I think I see why this is not possible: because Pipeline calls into Jenkins core, and Jenkins core needs the old version of Guava. So I think the plan from my second comment is not viable, but the plan from my first comment still seems viable.
Basil Crow
added a comment - After writing the above, I started wondering whether it would be possible to bundle the latest version of Guava with Pipeline and have Pipeline use that instead of the Guava that is bundled with Jenkins core.
After reading JENKINS-36779 I think I see why this is not possible: because Pipeline calls into Jenkins core, and Jenkins core needs the old version of Guava. So I think the plan from my second comment is not viable, but the plan from my first comment still seems viable.
We could only bundle a newer Guava by shading it, which is possible but
would increase download size quite a bit (unless we set a build-time option to strip unused methods/classes)
makes life harder if we ever need to ship, say, an emergency security update
So if possible I would prefer to use the version from core.
I think it is OK to put shared utilities into workflow-step-api if they are @Restricted(Beta.class) and clearly documented as being solely for the use of other workflow-* plugins.
dnusbaum as maintainer (last I checked) should weigh in here.
Jesse Glick
added a comment - We could only bundle a newer Guava by shading it, which is possible but
would increase download size quite a bit (unless we set a build-time option to strip unused methods/classes)
makes life harder if we ever need to ship, say, an emergency security update
So if possible I would prefer to use the version from core.
I think it is OK to put shared utilities into workflow-step-api if they are @Restricted(Beta.class) and clearly documented as being solely for the use of other workflow-* plugins.
dnusbaum as maintainer (last I checked) should weigh in here.
I think it is OK to put shared utilities into workflow-step-api if they are @Restricted(Beta.class) and clearly documented as being solely for the use of other workflow-* plugins.
Sounds like jglick and I are in agreement so far that we should follow the plan roughly outlined by my first comment, modulo putting the org.jenkinsci.plugins.workflow.concurrent package in workflow-step-api rather than workflow-api.
At this point I just need confirmation from dnusbaum about this plan of action. Then I will begin submitting PRs.
Basil Crow
added a comment - I think it is OK to put shared utilities into workflow-step-api if they are @Restricted(Beta.class) and clearly documented as being solely for the use of other workflow-* plugins.
Sounds like jglick and I are in agreement so far that we should follow the plan roughly outlined by my first comment, modulo putting the org.jenkinsci.plugins.workflow.concurrent package in workflow-step-api rather than workflow-api .
At this point I just need confirmation from dnusbaum about this plan of action. Then I will begin submitting PRs.
That plan seems fine to me, but I'm not sure I really understand the motivation, since I agree with Jesse that we should keep using the version from core rather than trying to bundle a newer version. I guess it's just nice to have it working on both versions of Guava in case all of the problems caused by the Guava update in other plugins get fixed eventually and core updates? Not sure how likely that is to ever happen, but seems fine to try to improve the situation here if you want to work on it.
Devin Nusbaum
added a comment - That plan seems fine to me, but I'm not sure I really understand the motivation, since I agree with Jesse that we should keep using the version from core rather than trying to bundle a newer version. I guess it's just nice to have it working on both versions of Guava in case all of the problems caused by the Guava update in other plugins get fixed eventually and core updates? Not sure how likely that is to ever happen, but seems fine to try to improve the situation here if you want to work on it.
I guess it's just nice to have it working on both versions of Guava in case all of the problems caused by the Guava update in other plugins get fixed eventually and core updates?
Yes, exactly.
Not sure how likely that is to ever happen
I'm a fighter, not a quitter!
Basil Crow
added a comment - Thanks for the reply!
I guess it's just nice to have it working on both versions of Guava in case all of the problems caused by the Guava update in other plugins get fixed eventually and core updates?
Yes, exactly.
Not sure how likely that is to ever happen
I'm a fighter, not a quitter!
I guess it's just nice to have it working on both versions of Guava in case all of the problems caused by the Guava update in other plugins get fixed eventually and core updates?
I ran into this just trying to run integration tests on a plugin using a newer Guava legitimately (pluginFirstClassLoader). Of course JENKINS-41827 is the real issue.
Jesse Glick
added a comment - I guess it's just nice to have it working on both versions of Guava in case all of the problems caused by the Guava update in other plugins get fixed eventually and core updates?
I ran into this just trying to run integration tests on a plugin using a newer Guava legitimately ( pluginFirstClassLoader ). Of course JENKINS-41827 is the real issue.
Unassigned
Jesse Glick
Votes:
0Vote for this issue
Watchers:
4Start watching this issue
Created:
Updated:
{"searchers":{"groups":[{"searchers":[{"name":"Project","id":"project","key":"issue.field.project","isShown":true,"lastViewed":1740469513578},{"name":"Summary","id":"summary","key":"issue.field.summary","isShown":true},{"name":"Type","id":"issuetype","key":"issue.field.issuetype","isShown":true,"lastViewed":1740469513579},{"name":"Status","id":"status","key":"issue.field.status","isShown":true,"lastViewed":1740469513585},{"name":"Priority","id":"priority","key":"issue.field.priority","isShown":true},{"name":"Resolution","id":"resolution","key":"issue.field.resolution","isShown":true},{"name":"Creator","id":"creator","key":"issue.field.creator","isShown":true},{"name":"Component","id":"component","key":"issue.field.components","isShown":true},{"name":"% Limits","id":"workratio","key":"issue.field.workratio","isShown":true},{"name":"Link types","id":"issue_link_type","key":"issue.field.issuelinks","isShown":true},{"name":"Environment","id":"environment","key":"issue.field.environment","isShown":true},{"name":"Description","id":"description","key":"issue.field.description","isShown":true},{"name":"Comment","id":"comment","key":"issue.field.comment","isShown":true},{"name":"Label","id":"labels","key":"issue.field.labels","isShown":true,"lastViewed":1740469513597},{"name":"Query","id":"text","key":"text","isShown":true},{"name":"Bonfire Browser","id":"customfield_10229","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Bonfire Operating System","id":"customfield_10231","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Bonfire Screen Resolution","id":"customfield_10244","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Bonfire URL","id":"customfield_10237","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Bonfire User Agent","id":"customfield_10226","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Bonfire jQuery Version","id":"customfield_10252","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Business Value","id":"customfield_10333","key":"com.atlassian.jira.plugin.system.customfieldtypes:float","isShown":false},{"name":"Development","id":"customfield_10720","key":"com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary","isShown":true},{"name":"Epic Color","id":"customfield_10328","key":"com.pyxis.greenhopper.jira:gh-epic-color","isShown":false},{"name":"Epic Link","id":"customfield_10325","key":"com.pyxis.greenhopper.jira:gh-epic-link","isShown":true},{"name":"Epic Name","id":"customfield_10327","key":"com.pyxis.greenhopper.jira:gh-epic-label","isShown":true},{"name":"Epic Status","id":"customfield_10326","key":"com.pyxis.greenhopper.jira:gh-epic-status","isShown":false},{"name":"Epic/Theme","id":"customfield_10331","key":"com.atlassian.jira.plugin.system.customfieldtypes:labels","isShown":true},{"name":"Flagged","id":"customfield_10330","key":"com.atlassian.jira.plugin.system.customfieldtypes:multicheckboxes","isShown":true},{"name":"GitHub Users to Authorize as Committers","id":"customfield_10323","key":"com.atlassian.jira.plugin.system.customfieldtypes:textarea","isShown":true},{"name":"Issue Tracker","id":"customfield_11320","key":"com.atlassian.jira.plugin.system.customfieldtypes:select","isShown":true},{"name":"JIRA Capture Browser","id":"customfield_10228","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Browser","id":"customfield_10230","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Document Mode","id":"customfield_10258","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Operating System","id":"customfield_10232","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Operating System","id":"customfield_10233","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Operating System","id":"customfield_10234","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Operating System","id":"customfield_10236","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Operating System","id":"customfield_10238","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Operating System","id":"customfield_10239","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Screen Resolution","id":"customfield_10245","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Screen Resolution","id":"customfield_10246","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Screen Resolution","id":"customfield_10247","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Screen Resolution","id":"customfield_10248","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Screen Resolution","id":"customfield_10249","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture Screen Resolution","id":"customfield_10250","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture URL","id":"customfield_10240","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture URL","id":"customfield_10241","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture URL","id":"customfield_10242","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture URL","id":"customfield_10243","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture User Agent","id":"customfield_10225","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture User Agent","id":"customfield_10227","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture jQuery Version","id":"customfield_10251","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture jQuery Version","id":"customfield_10253","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture jQuery Version","id":"customfield_10254","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture jQuery Version","id":"customfield_10255","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture jQuery Version","id":"customfield_10256","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"JIRA Capture jQuery Version","id":"customfield_10257","key":"com.atlassian.bonfire.plugin:bonfire-text","isShown":true},{"name":"Meeting minutes URL","id":"customfield_10020","key":"com.atlassian.jira.plugin.system.customfieldtypes:url","isShown":false},{"name":"New Repository Name","id":"customfield_10321","key":"com.atlassian.jira.plugin.system.customfieldtypes:textfield","isShown":true},{"name":"Original story points","id":"customfield_11423","key":"com.atlassian.jpo:jpo-custom-field-original-story-points","isShown":true},{"name":"Parent Link","id":"customfield_11420","key":"com.atlassian.jpo:jpo-custom-field-parent","isShown":false},{"name":"Plugin Description","id":"customfield_10322","key":"com.atlassian.jira.plugin.system.customfieldtypes:textarea","isShown":true},{"name":"Raised During","id":"customfield_10220","key":"com.atlassian.bonfire.plugin:bonfire-session-cft","isShown":false},{"name":"Raised During","id":"customfield_10221","key":"com.atlassian.bonfire.plugin:bonfire-session-cft","isShown":false},{"name":"Rank","id":"customfield_10324","key":"com.pyxis.greenhopper.jira:gh-lexo-rank","isShown":true},{"name":"Released As","id":"customfield_10620","key":"com.atlassian.jira.plugin.system.customfieldtypes:textfield","isShown":true},{"name":"Repository URL","id":"customfield_10320","key":"com.atlassian.jira.plugin.system.customfieldtypes:url","isShown":true},{"name":"Similar Issues","id":"customfield_10520","key":"com.suggestimate:similar-issues-custom-field","isShown":true},{"name":"Sprint","id":"customfield_10329","key":"com.pyxis.greenhopper.jira:gh-sprint","isShown":true},{"name":"Story Points","id":"customfield_10332","key":"com.atlassian.jira.plugin.system.customfieldtypes:float","isShown":false},{"name":"Team","id":"customfield_11424","key":"com.atlassian.teams:rm-teams-custom-field-team","isShown":true},{"name":"Test Sessions","id":"customfield_10222","key":"com.atlassian.bonfire.plugin:bonfire-multi-session-cft","isShown":false},{"name":"Test Sessions","id":"customfield_10223","key":"com.atlassian.bonfire.plugin:bonfire-multi-session-cft","isShown":false},{"name":"Test Sessions","id":"customfield_10224","key":"com.atlassian.bonfire.plugin:bonfire-multi-session-cft","isShown":false},{"name":"Testing Status","id":"customfield_10259","key":"com.atlassian.bonfire.plugin:bonfire-testing-status-cft","isShown":false},{"name":"URL","id":"customfield_10000","key":"com.atlassian.jira.plugin.system.customfieldtypes:url","isShown":true}],"type":"DETAILS","title":"Details"},{"searchers":[{"name":"Created Date","id":"created","key":"issue.field.created","isShown":true},{"name":"Updated Date","id":"updated","key":"issue.field.updated","isShown":true},{"name":"Resolution Date","id":"resolutiondate","key":"issue.field.resolution.date","isShown":true},{"name":"Target end","id":"customfield_11422","key":"com.atlassian.jpo:jpo-custom-field-baseline-end","isShown":true},{"name":"Target start","id":"customfield_11421","key":"com.atlassian.jpo:jpo-custom-field-baseline-start","isShown":true}],"type":"DATES","title":"Dates"},{"searchers":[{"name":"Assignee","id":"assignee","key":"issue.field.assignee","isShown":true,"lastViewed":1740469513586},{"name":"Reporter","id":"reporter","key":"issue.field.reporter","isShown":true}],"type":"PEOPLE","title":"People"}]},"values":{"issuetype":{"name":"Type","editHtml":"\n\n\n\n <div class=\"field-group aui-field-issuetype\" >\n <label for=\"searcher-type\">Type</label> <select class=\"select js-default-checkboxmultiselect\"\n id=\"searcher-type\"\n multiple=\"multiple\"\n name=\"type\"\n data-max-inline-results-displayed=\"100\"\n data-placeholder-text=\"Find Issue Types...\">\n <optgroup>\n \n <option class=\" \"\n id=\"type_-2\"\n title=\"All Standard Issue Types\"\n value=\"-2\">All Standard Issue Types</option>\n </optgroup>\n\n <optgroup label=\"Standard Issue Types\">\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/secure/viewavatar?size=xsmall&avatarId=14673&avatarType=issuetype\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_1\"\n title=\"Bug\"\n value=\"1\">Bug</option>\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/images/icons/issuetypes/epic.png\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_10001\"\n title=\"Epic\"\n value=\"10001\">Epic</option>\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/secure/viewavatar?size=xsmall&avatarId=14680&avatarType=issuetype\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_4\"\n title=\"Improvement\"\n value=\"4\">Improvement</option>\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/secure/viewavatar?size=xsmall&avatarId=14681&avatarType=issuetype\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_2\"\n title=\"New Feature\"\n value=\"2\">New Feature</option>\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/secure/viewavatar?size=xsmall&avatarId=14670&avatarType=issuetype\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_5\"\n title=\"Patch\"\n value=\"5\">Patch</option>\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/secure/viewavatar?size=xsmall&avatarId=14685&avatarType=issuetype\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_10002\"\n title=\"Story\"\n value=\"10002\">Story</option>\n \n <option class=\" imagebacked 10730 \"\n data-icon=\"/secure/viewavatar?size=xsmall&avatarId=14688&avatarType=issuetype\"\n data-fallback-icon=\"/images/icons/issuetypes/blank.png\"\n id=\"type_3\"\n title=\"Task\"\n value=\"3\">Task</option>\n </optgroup>\n\n <optgroup label=\"Sub-Task Issue Types\">\n </optgroup>\n </select>\n </div>\n ","validSearcher":true,"isShown":true},"project":{"name":"Project","editHtml":" \n <div class=\"field-group aui-field-project\" >\n <label for=\"searcher-pid\">Project</label> <select class=\"js-project-checkboxmultiselect\"\n data-placeholder-text=\"Find Projects...\"\n id=\"searcher-pid\"\n multiple=\"multiple\"\n name=\"pid\">\n <optgroup label=\"Recent Projects\">\n </optgroup>\n <optgroup label=\"All Projects\" >\n \n <option data-icon=\"/secure/projectavatar?pid=10172&size=small\"\n title=\"Jenkins\"\n value=\"10172\">\n Jenkins (JENKINS)\n </option>\n <option data-icon=\"/secure/projectavatar?pid=10050&size=small\"\n title=\"test\"\n value=\"10050\">\n test (TEST)\n </option>\n </optgroup>\n </select>\n </div>\n \n\n","validSearcher":true,"isShown":true},"assignee":{"name":"Assignee","editHtml":"\n \n <div class=\"field-group aui-field-userlist\" >\n <label for=\"searcher-assigneeSelect\">Assignee</label> <fieldset rel=\"assignee\" class=\"hidden user-group-searcher-params\">\n </fieldset>\n <select class=\"js-usergroup-checkboxmultiselect\" multiple=\"multiple\" id=\"assignee\" name=\"assignee\" data-placeholder-text=\"Enter username or group\">\n <optgroup>\n <option class=\"headerOption\" data-icon=\"https://issues.jenkins.io/secure/useravatar?size=xsmall&avatarId=10293\" value=\"empty\" title=\"Unassigned\">Unassigned</option>\n </optgroup>\n <optgroup>\n </optgroup>\n </select>\n <input type=\"hidden\" name=\"check_prev_assignee\" value=\"true\">\n </div>\n \n","validSearcher":true,"isShown":true},"status":{"name":"Status","editHtml":"\n <div class=\"field-group aui-field-constants\" >\n <label for=\"searcher-status\">Status</label> <select class=\"select js-default-checkboxmultiselectstatuslozenge\"\n data-placeholder-text=\"Find Statuses...\"\n id=\"searcher-status\"\n multiple=\"multiple\"\n name=\"status\"\n data-max-inline-results-displayed=\"100\"\n data-footer-text=\"-88 more options. Continue typing to refine further.\" data-status-lozenge=\"true\">\n <optgroup >\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/needinfo.png\" value=\"10001\" title=\"Untriaged\" data-simple-status=\"{"id":"10001","name":"Untriaged","description":"New issue sits in this state until a developer agrees that this is a security issue","iconUrl":"/images/icons/statuses/needinfo.png","statusCategory":{"id":2,"key":"new","colorName":"default"}}\">Untriaged</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/open.png\" value=\"1\" title=\"Open\" data-simple-status=\"{"id":"1","name":"Open","description":"The issue is open and ready for the assignee to start work on it.","iconUrl":"/images/icons/statuses/open.png","statusCategory":{"id":2,"key":"new","colorName":"default"}}\">Open</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/inprogress.png\" value=\"3\" title=\"In Progress\" data-simple-status=\"{"id":"3","name":"In Progress","description":"This issue is being actively worked on at the moment by the assignee.","iconUrl":"/images/icons/statuses/inprogress.png","statusCategory":{"id":4,"key":"indeterminate","colorName":"inprogress"}}\">In Progress</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/reopened.png\" value=\"4\" title=\"Reopened\" data-simple-status=\"{"id":"4","name":"Reopened","description":"This issue was once resolved, but the resolution was deemed incorrect. From here issues are either marked assigned or resolved.","iconUrl":"/images/icons/statuses/reopened.png","statusCategory":{"id":4,"key":"indeterminate","colorName":"inprogress"}}\">Reopened</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/information.png\" value=\"10005\" title=\"In Review\" data-simple-status=\"{"id":"10005","name":"In Review","description":"","iconUrl":"/images/icons/statuses/information.png","statusCategory":{"id":4,"key":"indeterminate","colorName":"inprogress"}}\">In Review</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/resolved.png\" value=\"10002\" title=\"Fix Prepared\" data-simple-status=\"{"id":"10002","name":"Fix Prepared","description":"A fix is implemented and is waiting for the next security release","iconUrl":"/images/icons/statuses/resolved.png","statusCategory":{"id":4,"key":"indeterminate","colorName":"inprogress"}}\">Fix Prepared</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/generic.png\" value=\"10000\" title=\"Verified\" data-simple-status=\"{"id":"10000","name":"Verified","description":"Verified","iconUrl":"/images/icons/statuses/generic.png","statusCategory":{"id":4,"key":"indeterminate","colorName":"inprogress"}}\">Verified</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/generic.png\" value=\"10203\" title=\"Fixed but Unreleased\" data-simple-status=\"{"id":"10203","name":"Fixed but Unreleased","description":"This change has been implemented and merged, but not yet released.","iconUrl":"/images/icons/statuses/generic.png","statusCategory":{"id":3,"key":"done","colorName":"success"}}\">Fixed but Unreleased</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/resolved.png\" value=\"5\" title=\"Resolved\" data-simple-status=\"{"id":"5","name":"Resolved","description":"A developer had implemented a fix and is waiting for a feedback from the reporter.","iconUrl":"/images/icons/statuses/resolved.png","statusCategory":{"id":3,"key":"done","colorName":"success"}}\">Resolved</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/closed.png\" value=\"6\" title=\"Closed\" data-simple-status=\"{"id":"6","name":"Closed","description":"The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.","iconUrl":"/images/icons/statuses/closed.png","statusCategory":{"id":3,"key":"done","colorName":"success"}}\">Closed</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/open.png\" value=\"10003\" title=\"To Do\" data-simple-status=\"{"id":"10003","name":"To Do","description":"","iconUrl":"/images/icons/statuses/open.png","statusCategory":{"id":2,"key":"new","colorName":"default"}}\">To Do</option>\n <option class=\"imagebacked\" data-icon=\"/images/icons/statuses/closed.png\" value=\"10004\" title=\"Done\" data-simple-status=\"{"id":"10004","name":"Done","description":"","iconUrl":"/images/icons/statuses/closed.png","statusCategory":{"id":3,"key":"done","colorName":"success"}}\">Done</option>\n </optgroup>\n</select>\n </div>\n \n","validSearcher":true,"isShown":true},"labels":{"name":"Label","viewHtml":" <div class=\"searcherValue\">\n \n <label class=\"fieldLabel\" for=\"fieldlabels\">Label:</label><span id=\"fieldlabels\" class=\"fieldValue\">\n \n guava\n</span></div>\n","editHtml":"\n <div class=\"field-group aui-field-labels\" >\n <label for=\"searcher-labels\">Labels</label> <select class=\"js-label-checkboxmultiselect\" multiple=\"multiple\" id=\"searcher-labels\" name=\"labels\" data-placeholder-text=\"Find Labels...\">\n <option value=\"guava\" title=\"guava\" selected=\"selected\">guava</option>\n </select>\n </div>\n \n","jql":"labels = guava","validSearcher":true,"isShown":true}}}
[{"id":-1,"name":"My open issues","jql":"assignee = currentUser() AND resolution = Unresolved order by updated DESC","isSystem":true,"sharePermissions":[],"requiresLogin":true},{"id":-2,"name":"Reported by me","jql":"reporter = currentUser() order by created DESC","isSystem":true,"sharePermissions":[],"requiresLogin":true},{"id":-4,"name":"All issues","jql":"order by created DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false},{"id":-5,"name":"Open issues","jql":"resolution = Unresolved order by priority DESC,updated DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false},{"id":-9,"name":"Done issues","jql":"statusCategory = Done order by updated DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false},{"id":-3,"name":"Viewed recently","jql":"issuekey in issueHistory() order by lastViewed DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false},{"id":-6,"name":"Created recently","jql":"created >= -1w order by created DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false},{"id":-7,"name":"Resolved recently","jql":"resolutiondate >= -1w order by updated DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false},{"id":-8,"name":"Updated recently","jql":"updated >= -1w order by updated DESC","isSystem":true,"sharePermissions":[],"requiresLogin":false}]
Hey jglick, I started working on this over the weekend and achieved some preliminary success converting workflow-support to work with both Guava 11 and Guava 28.1. You can see my work-in-progress changes here.
While running some integration tests with the above, I found three remaining odds and ends.
In workflow-basic-steps's TimeoutStepExecution we directly call MoreExecutors.sameThreadExecutor, which was removed in Guava 21:
In workflow-api's FlowExecutionList we call com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) directly (as opposed to org.jenkinsci.plugins.workflow.support.concurrent.Futures#addCallback(ListenableFuture, FutureCallback)):
com.google.common.util.concurrent.Futures#addCallback(ListenableFuture, FutureCallback) was removed in Guava 26, yielding errors like this even with my workflow-support fixes:
Finally, workflow-step-api's StepExecution uses Futures#allAsList:
This hasn't changed in the latest version of Guava, but it makes me nervous that we are using com.google.common.util.concurrent.Futures anywhere in Pipeline rather than the safer org.jenkinsci.plugins.workflow.support.concurrent.Futures.
What is to be done for these three cases? workflow-api depends on workflow-step-api and workflow-support depends on workflow-api. So one solution would be to move the org.jenkinsci.plugins.workflow.support.concurrent package out of workflow-support. But where should it go? Since it is an internal API for pipeline, I think a logical place would be a org.jenkinsci.plugins.workflow.concurrent package in workflow-api. But then workflow-step-api wouldn't have access to it. Putting the org.jenkinsci.plugins.workflow.concurrent package in workflow-step-api doesn't seem like a good place either, since it isn't clearly related to the Step API. And making a whole new plugin for this seems overkill. So I can't think of a good solution here. Maybe we should put it in workflow-api and copy and paste a private restricted copy in workflow-step-api? That isn't the cleanest solution, but it's the best compromise I can think of right now.
Here's my proposed plan of action. Let me know what you think.
org.jenkinsci.plugins.workflow.support.concurrent classes.
This is a formidable amount of work, so before I get started I wanted to get your feedback.