'Why this error? "No such property: Entry for class: java.util.Map"
I'm following an example from JENKINS-44085 issue very-bottom comments about creating a stage map almost to the T, but when I execute my code I get
No such property: Entry for class: java.util.Map
Here's my code. Variable 'pipeline' is defined somewhere else, and is valid.
def generateStage(String job, String targetVersion,
String rootVersion, Integer sleepTime=0) {
return {
stage("Deploying: ${job}") {
sleep sleepTime
pipeline.executeDeploymentPipeline(job,
targetVersion,
rootVersion)
}
}
}
def deployProcs(targetVersion, rootVersion) {
int sleepTime = 0
def procs = ["proc-proc", "proc-proc-high"]
def parallelStagesMap = procs.collectEntries {
["${it}" : generateStage(it, targetVersion, rootVersion, sleepTime)]
sleepTime += 5
}
parallel parallelStagesMap
}
Why is that?
Solution 1:[1]
It seems this is a bug in Jenkins pipelines. A related one was fixed after version 2.158. So upgrading Jenkins should resolve this.
Solution 2:[2]
Unlike what @Christian pointed out, this is still a bug as of 1.176.1
with all plugins up to date. The workaround is to convert the map entries into a [key, value]
list pair. To demonstrate, here is a simple code that can reproduce the OP's error:
['1':1].findAll { it.value > 0 }.collectEntries { it }
Here is the one with the workaround,
['1':1].collect { [it.key, it.value] }.findAll { it[1] > 0 }.collectEntries { it }
Note that .collectEntries()
works with list
pairs just fine, so no need to convert it back to any other form.
Solution 3:[3]
Not a direct answer, but I did this as a workaround, for the calling function.
def deployProcs(targetVersion, rootVersion) {
int sleepTime = 0
def procs = ["proc-proc", "proc-proc-high"]
Map parallelStagesMap = new TreeMap()
procs.each {
parallelStagesMap.put[it, generateStage(it, targetVersion, rootVersion, sleepTime))
sleepTime += 5
}
parallel parallelStagesMap
}
Still bothers me why the original code does not work.
Solution 4:[4]
I had the same problem. The solution proposed by @haridsv also works if you want to modify the map based on some conditions and return this modified map:
def b = [a: 'buba', b: 'cuba', c: 'cuda']
def s = true
def c = b
.collect { s ? [it.key, it.value -= 'c'] : it }
.collectEntries { it }
println c
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Christian |
Solution 2 | |
Solution 3 | Chris F |
Solution 4 | Adam Bogdan Boczek |