jenkinsci / jenkinsci/workflow-cps-plugin
[JENKINS-54982] Using Java8 Streams evaluates whole expression to Boolean
- Dominant language
- Java
- Stars
- 186
- Forks
- 213
- Avg merge
- 12h 12m
- Merged PRs (30d)
- 8
Description
I'm trying to write a common library building Docker images from Dockerfile. I wrote a reusable global pipeline, where I'm iterating over Dockerfile lines. I tried to use Java 8 Streams, however I ended up with issue potentially related to JENKINS-26307 and JENKINS-42769, which is not related not to Groovy functional features, but Java 8 feature.
An example code used:
def getMissingLabels(Map<String, String> labels) {
['label1', 'label2', 'label3', 'label4'].stream()
.filter({ label -> !isLabelDefined(label, labels) })
.collect(Collectors.toList())
}
Whole stream execution results in "false" boolean result, instead of a list. Even complex streams are passing through, but evaluates to "false". When using more complex stream like:
Arrays.stream(splitted)
.filter { it.startsWith('LABEL') }
.map { it.replaceAll('(LABEL)|"', '') }
.map { it.trim() }
.map { it.split('=', 2) }
.collect(Collectors.toMap(
{ val -> val[0].toLowerCase() },
{ val -> val[1] }))
it enters only first filter expression and does not evaluate the rest.
When replaced functional style code with typical imperative style (for loop) it works.
---
Originally reported by filipowm, imported from: Using Java8 Streams evaluates whole expression to Boolean
Raw content of original issue
I'm trying to write a common library building Docker images from Dockerfile. I wrote a reusable global pipeline, where I'm iterating over Dockerfile lines. I tried to use Java 8 Streams, however I ended up with issue potentially related to
JENKINS-26307andJENKINS-42769, which is not related not to Groovy functional features, but Java 8 feature.An example code used:
def getMissingLabels(Map<String, String> labels) {
['label1', 'label2', 'label3', 'label4'].stream()
.filter({ label -> !isLabelDefined(label, labels) })
.collect(Collectors.toList())
}Whole stream execution results in "false" boolean result, instead of a list. Even complex streams are passing through, but evaluates to "false". When using more complex stream like:
Arrays.stream(splitted)
.filter { it.startsWith('LABEL') }
.map { it.replaceAll('(LABEL)|"', '') }
.map { it.trim() }
.map { it.split('=', 2) }
.collect(Collectors.toMap(
{ val -> val[0].toLowerCase() },
{ val -> val[1] }))it enters only first filter expression and does not evaluate the rest.
When replaced functional style code with typical imperative style (for loop) it works.
- environment:
Jenkins 2.153, Pipeline 2.6
Contributor guide
Research direction
Start by reproducing the two Java 8 Stream examples in the workflow-cps-plugin context described, using the reported Jenkins 2.153 and Pipeline 2.6 environment if available. Trace how the first filter and the later collect operation are handled; done means the examples return their expected list or map and execute every stream stage, with regression coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- groovy, java
- Domain
- ci-cd
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100