<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" 
  xmlns:content="http://purl.org/rss/1.0/modules/content/" 
  xmlns:dc="http://purl.org/dc/elements/1.1/" 
  xmlns:atom="http://www.w3.org/2005/Atom" 
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" 
  xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Tricks &amp; Tips on Solid Soft</title>
    <link>https://blog.solidsoft.pl/categories/tricks-tips/</link>
    <description>Recent content in Tricks &amp; Tips on Solid Soft</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>©{year}, All Rights Reserved</copyright>
    <lastBuildDate>Thu, 12 Mar 2020 14:00:00 +0200</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>2</sy:updateFrequency>
    
        <atom:link href="https://blog.solidsoft.pl/categories/tricks-tips/index.xml" rel="self" type="application/rss+xml" />
    
    
    

      
      <item>
        <title>Mysteriously broken reduction operation on parallel streams in Java (explained)</title>
        <link>https://blog.solidsoft.pl/2020/03/12/mysteriously-broken-reduction-operation-on-parallel-streams-in-java-explained/</link>
        <pubDate>Thu, 12 Mar 2020 14:00:00 +0200</pubDate>
        
        <atom:modified>Thu, 12 Mar 2020 14:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/03/12/mysteriously-broken-reduction-operation-on-parallel-streams-in-java-explained/</guid>
        <description>How to not get into trouble writing custom reduction operation (.reduce()) on (parallel) streams with Java 8+ (including Java 14).
  Introduction Recently&amp;hellip;, well this article has spent years in my freezer for the blog posts. Originally, I have encountered this problem back in 2014 while preparing my Java 8 training session (recently renamed to Java - functional thinking ). Then, I noticed that it is possible to achieve interesting results writing a custom reduce operation implementation when a parallel stream is used.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;How to not get into trouble writing custom reduction operation (&lt;code&gt;.reduce()&lt;/code&gt;) on (parallel) streams with Java 8+ (including Java 14).&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/java8-reduce-issue-parallel-stream.jpg&#34; alt=&#34;5 parallel streams of waterfall&#34; style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently&amp;hellip;, well this article has spent years in my freezer for the blog posts. Originally, I have encountered this problem back in 2014 while preparing my Java 8 training session (recently renamed to &lt;a href=&#34;https://blog.solidsoft.pl/training/&#34;&gt;Java - functional thinking&lt;/a&gt;
). Then, I noticed that it is possible to achieve interesting results writing a custom &lt;code&gt;reduce&lt;/code&gt; operation implementation when a parallel stream is used. For various reasons, the partially written article was waiting for its completion around 6 years. Time flies, however, the case is still valid with the latest - as a time of writing - Java 14. So, let&amp;rsquo;s check it out.&lt;/p&gt;
&lt;h2 id=&#34;our-case---simple-number-concatenation-using-reduce&#34;&gt;Our case - simple number concatenation using reduce&lt;/h2&gt;
&lt;p&gt;As a short introduction, a &lt;em&gt;reduction operation&lt;/em&gt; (also called a &lt;em&gt;fold&lt;/em&gt;) takes input elements (here of a stream) and collects them into combined summary result. Some well know specialized reduction variants, available in the Stream API, include, inter alia, &lt;code&gt;sum()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;count()&lt;/code&gt;. Nevertheless, we can write our custom, non-standard reduction operation (if needed).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s assume we would like to concatenate a list of numbers into a string. A case which could be easier to achieve in other ways, but simple enough to do not focus on realized logic, but rather a nuances of a reduction operation itself. A &lt;code&gt;reduce&lt;/code&gt; method on stream can be used:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldConcatNumbersUsingReduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//given
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Arrays&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;asList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;//when
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kd&#34;&gt;final&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;//then
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;assertThat&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isEqualToIgnoringCase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;1234&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//passes
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Very compact and does its work. Numbers are concatenated. Similar implementations are common in internet and everything is ok unless you try to use it with the parallel stream:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldConcatNumbersUsingReduceParallel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//broken!
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//given
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Arrays&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;asList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;//when
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parallelStream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;//then
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;assertThat&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;isEqualToIgnoringCase&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;1234&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//ups!
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This test fails with the assertion error similar to that:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;n&#34;&gt;java&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;lang&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;AssertionError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; 
&lt;span class=&#34;nl&#34;&gt;Expecting:&lt;/span&gt;
 &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;343421343421343421343421&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;be&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;equal&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
 &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;1234&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;It looks strange. Very often incomprehensible things are caused by some race condition in the parallel code which matches &lt;code&gt;parallelStream()&lt;/code&gt;. But first let&amp;rsquo;s analyze what happens in a reduction operation step by step (if you are savvy in sequential reduction operations skip to the subsequent section).&lt;/p&gt;
&lt;h2 id=&#34;reduction-in-sequential-stream&#34;&gt;Reduction in sequential stream&lt;/h2&gt;
&lt;p&gt;If you are not very familiar with method references the example can look a little bit cryptic. Let&amp;rsquo;s rewrite it using lambda expressions (instead method references):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
                &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;//accumulation
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//combining
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The new &lt;code&gt;StringBuilder&lt;/code&gt; is used as an initial value (identity). For every element from an input list the second line in reduce will be called (&lt;code&gt;(acc, x) -&amp;gt; acc.append(x)&lt;/code&gt;) with &lt;code&gt;acc&lt;/code&gt; (an accumulator) containing concatenated already processed elements and &lt;code&gt;x&lt;/code&gt; the current number. &lt;code&gt;x&lt;/code&gt; is appended to the previously concatenated elements.&lt;/p&gt;
&lt;p&gt;From the algorithm analysis, the expected values in subsequent iterations should be as follows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;iteration&lt;/th&gt;
&lt;th align=&#34;center&#34;&gt;0&lt;/th&gt;
&lt;th align=&#34;center&#34;&gt;1&lt;/th&gt;
&lt;th align=&#34;center&#34;&gt;2&lt;/th&gt;
&lt;th align=&#34;center&#34;&gt;3&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;acc&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;quot;&amp;rdquo;&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;1&amp;rdquo;&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;12&amp;rdquo;&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;123&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;1&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;2&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;3&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;returned&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;1&amp;rdquo;&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;12&amp;rdquo;&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;123&amp;rdquo;&lt;/td&gt;
&lt;td align=&#34;center&#34;&gt;&amp;ldquo;1234&amp;rdquo;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Is this ok? Let&amp;rsquo;s verify it in code.&lt;/p&gt;
&lt;p&gt;As debugging (prospectively) concurrent code is hard, especially in a blog post, let&amp;rsquo;s use plain old debug outputs, well known from C.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accString&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Accumulation: &amp;#39;{}&amp;#39;, x: &amp;#39;{}&amp;#39;, returned: &amp;#39;{}&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; 
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;                                     &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1String&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Combining: sb1: &amp;#39;{}&amp;#39;, sb2: &amp;#39;{}&amp;#39;, returned: &amp;#39;{}&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;                                 &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;We slightly complicated the code, but it is only for the test (debug) purpose. The output is as expected:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;18:09:05.839 [main] - Accumulation: acc: &amp;#39;    &amp;#39;, x: &amp;#39;   1&amp;#39;, returned: &amp;#39;   1&amp;#39;
18:09:05.844 [main] - Accumulation: acc: &amp;#39;   1&amp;#39;, x: &amp;#39;   2&amp;#39;, returned: &amp;#39;  12&amp;#39;
18:09:05.844 [main] - Accumulation: acc: &amp;#39;  12&amp;#39;, x: &amp;#39;   3&amp;#39;, returned: &amp;#39; 123&amp;#39;
18:09:05.844 [main] - Accumulation: acc: &amp;#39; 123&amp;#39;, x: &amp;#39;   4&amp;#39;, returned: &amp;#39;1234&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s skip for a while the log from the combining operation (line 14). It is not used in sequential streams.&lt;/p&gt;
&lt;p&gt;In the output, we also clearly see that all operations take place in the main thread. Which is expected for sequential synchronous stream processing.&lt;/p&gt;
&lt;h2 id=&#34;reduction-in-parallel-stream---behavior-in-working-implementation&#34;&gt;Reduction in parallel stream - behavior in working implementation&lt;/h2&gt;
&lt;p&gt;In a parallel stream, accumulation operations can be performed in different threads. Those partial results are later combined using lambda expression passed as the third argument (a combiner) in a &lt;code&gt;reduce&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at the diagnostic messages emitted during a sample execution with parallel stream.&lt;/p&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;One important note here. The output is from the correctly implemented reduction operation (presented at the end of the blog post) rather than the version above to make the whole thing easier to grasp.&lt;/div&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;[ForkJoinPool.commonPool-worker-3] - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   1&amp;#39;, returned: &amp;#39;   1&amp;#39;
[ForkJoinPool.commonPool-worker-1] - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   2&amp;#39;, returned: &amp;#39;   2&amp;#39;
[main]                             - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   3&amp;#39;, returned: &amp;#39;   3&amp;#39;
[ForkJoinPool.commonPool-worker-1] - Combining   : sb1: &amp;#39;   1&amp;#39;, sb2: &amp;#39;   2&amp;#39;, returned: &amp;#39;  12&amp;#39;
[ForkJoinPool.commonPool-worker-2] - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   4&amp;#39;, returned: &amp;#39;   4&amp;#39;
[ForkJoinPool.commonPool-worker-2] - Combining   : sb1: &amp;#39;   3&amp;#39;, sb2: &amp;#39;   4&amp;#39;, returned: &amp;#39;  34&amp;#39;
[ForkJoinPool.commonPool-worker-2] - Combining   : sb1: &amp;#39;  12&amp;#39;, sb2: &amp;#39;  34&amp;#39;, returned: &amp;#39;1234&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Let&amp;rsquo;s analyze it line by line.&lt;/p&gt;
&lt;p&gt;In the first 2 lines:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;[ForkJoinPool.commonPool-worker-3] - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   1&amp;#39;, returned: &amp;#39;   1&amp;#39;
[ForkJoinPool.commonPool-worker-1] - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   2&amp;#39;, returned: &amp;#39;   2&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;the accumulation operation is performed in parallel on the two first elements on the list. In the forth line those partial results are combined into a larger list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;[ForkJoinPool.commonPool-worker-1] - Combining   : sb1: &amp;#39;   1&amp;#39;, sb2: &amp;#39;   2&amp;#39;, returned: &amp;#39;  12&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The same situation, for the rest of the items, takes place in the line 3, 5 and 6.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;[main]                             - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   3&amp;#39;, returned: &amp;#39;   3&amp;#39;
...
[ForkJoinPool.commonPool-worker-2] - Accumulation: acc: &amp;#39;    &amp;#39;, x:   &amp;#39;   4&amp;#39;, returned: &amp;#39;   4&amp;#39;
[ForkJoinPool.commonPool-worker-2] - Combining   : sb1: &amp;#39;   3&amp;#39;, sb2: &amp;#39;   4&amp;#39;, returned: &amp;#39;  34&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;And the end, two partial result: &amp;lsquo;12&amp;rsquo; and &amp;lsquo;34&amp;rsquo; are combined together to provide the final result:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;[ForkJoinPool.commonPool-worker-2] - Combining   : sb1: &amp;#39;  12&amp;#39;, sb2: &amp;#39;  34&amp;#39;, returned: &amp;#39;1234&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Do you have - after logging at the listings - any suspicious what could be wrong with the original implementation? With the debug statements it much easier to spot it.&lt;/p&gt;
&lt;h2 id=&#34;reduction-in-parallel-stream-with-widespread-broken-implementation&#34;&gt;Reduction in parallel stream with widespread (broken) implementation&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s recall the widespread (broken when running in parallel) implementation once more:&lt;/p&gt;
&lt;div class=&#34;expand&#34;&gt;
  &lt;button type=&#34;button&#34; class=&#34;expand__button&#34; aria-label=&#34;Expand Button&#34;&gt;
    &lt;span class=&#34;expand-icon expand-icon__right&#34;&gt;
        &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34;&gt;&lt;path fill=&#34;currentColor&#34; d=&#34;M9.29 15.88L13.17 12 9.29 8.12c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0l4.59 4.59c.39.39.39 1.02 0 1.41L10.7 17.3c-.39.39-1.02.39-1.41 0-.38-.39-.39-1.03 0-1.42z&#34;/&gt;&lt;/svg&gt;
    &lt;/span&gt;
    click to expand
  &lt;/button&gt;
  &lt;div class=&#34;expand__content&#34;&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parallelStream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
                &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;      &lt;span class=&#34;c1&#34;&gt;//accumulation
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//combining
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;together with its debug enhanced variant:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parallelStream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accString&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Accumulation: &amp;#39;{}&amp;#39;, x: &amp;#39;{}&amp;#39;, returned: &amp;#39;{}&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; 
                                     &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;));&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1String&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Combining: sb1: &amp;#39;{}&amp;#39;, sb2: &amp;#39;{}&amp;#39;, returned: &amp;#39;{}&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb1String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;
                                 &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;%4s&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;));&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The output from the parallel processing execution:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;10:42:53.334 [ForkJoinPool.commonPool-worker-5]  - Accumulation: acc: &amp;#39;   3&amp;#39;, x: &amp;#39;   4&amp;#39;, returned: &amp;#39;  34&amp;#39;
10:42:53.334 [ForkJoinPool.commonPool-worker-23] - Accumulation: acc: &amp;#39; 342&amp;#39;, x: &amp;#39;   1&amp;#39;, returned: &amp;#39;3421&amp;#39;
10:42:53.334 [ForkJoinPool.commonPool-worker-19] - Accumulation: acc :&amp;#39;  34&amp;#39;, x: &amp;#39;   2&amp;#39;, returned: &amp;#39;3421&amp;#39;
10:42:53.334 [main]                              - Accumulation: acc :&amp;#39;    &amp;#39;, x: &amp;#39;   3&amp;#39;, returned: &amp;#39;   3&amp;#39;
10:42:53.339 [ForkJoinPool.commonPool-worker-19] - Combining: sb1: &amp;#39;3421&amp;#39;, sb2: &amp;#39;342134213421&amp;#39;, returned: &amp;#39;342134213421&amp;#39;
10:42:53.339 [main]                              - Combining: sb1: &amp;#39;3421&amp;#39;, sb2: &amp;#39;342134213421&amp;#39;, returned: &amp;#39;342134213421&amp;#39;
10:42:53.340 [main]                              - Combining: sb1: &amp;#39;342134213421&amp;#39;, sb2: &amp;#39;342134213421342134213421&amp;#39;, returned: &amp;#39;342134213421342134213421&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The strange things start to happen from the first line. Instead of having an empty accumulator (the &amp;ldquo;acc&amp;rdquo; variable) there is &amp;ldquo;3&amp;rdquo;. In the second line there is already &amp;ldquo;342&amp;rdquo; (still instead of an empty StringBuilder). We discover empty accumulator in the 3rd line, which anyway could be the 1st line (it is a matter of logging operations from multiple threads - they were executed at &amp;ldquo;the same moment&amp;rdquo;). Nonetheless, all the first 4 lines should have the accumulator empty. It clearly shows there is a problem with a mutable data structure shared across the threads, in both accumulation and combining phrases.&lt;/p&gt;
&lt;p&gt;A look at the &lt;code&gt;StringBuilder&lt;/code&gt; documentation ensures us that &amp;ldquo;append&amp;rdquo; adds a provided value to the &lt;code&gt;StringBuilder&lt;/code&gt; and returns its instance (aka &lt;code&gt;this&lt;/code&gt;). Mutating input variables is not recommended in the stream processing, however the root of the problem is a fact that initial &amp;ldquo;neutral&amp;rdquo; value (identity) passes to every initial accumulation operation is one and the same &lt;code&gt;StringBuilder&lt;/code&gt; instance. It is passed as the first element of the &amp;ldquo;reduce&amp;rdquo; method execution.&lt;/p&gt;
&lt;p&gt;Someone could say: &amp;ldquo;let&amp;rsquo;s use &lt;code&gt;StringBuffer&lt;/code&gt; - its operations are thread safe&amp;rdquo;. However, it will not fix the situation here. Having multiple threads operating on the same structure (even thread safe) is also broken assuming that all initial operations assumes a private accumulator instance to create an independent list of elements which will be concatenated into the biggest one in the following steps.&lt;/p&gt;
&lt;h2 id=&#34;reduction-in-parallel-stream---working-implementation&#34;&gt;Reduction in parallel stream - working implementation&lt;/h2&gt;
&lt;h3 id=&#34;main-case&#34;&gt;Main case&lt;/h3&gt;
&lt;p&gt;With &lt;code&gt;StringBuffer&lt;/code&gt; and string concatenation the only required modification is not mutating the input objects:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parallelStream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;                &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;acc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;                &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StringBuilder&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sb2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In every iteration the new &lt;code&gt;StringBuilder&lt;/code&gt; instance is created. Thanks to that there is no mutation of the initial &lt;code&gt;identity&lt;/code&gt; element shared across threads. In general mutation of the stream elements (or doing side effects in general) can lead to some unpredictable situations, especially in the parallel execution.&lt;/p&gt;
&lt;h3 id=&#34;java-api-limitations&#34;&gt;Java API limitations&lt;/h3&gt;
&lt;p&gt;The above change solves the problem (at the cost of greatly increased number of created objects, but let&amp;rsquo;s skip it for a moment). Unfortunately, many structures, especially those from Java Collection Framework which remembers Java 1.2 (releases 1998 - over 20 years ago!), does not provide so friendly API to perform operations with the method chaining syntax/approach.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at the (artificial) working example of using the &lt;code&gt;java.util.List&lt;/code&gt; API in a reduce operation simulating mapping to double every element of the input list:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;doubledValues&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;reduce&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Collections&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;emptyList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(),&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resultList&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ArrayList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;resultList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resultList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;},&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Integer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resultList&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ArrayList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;resultList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;addAll&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;list2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;);&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resultList&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;
            &lt;span class=&#34;o&#34;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;True one-liners with a method chaining would make this code more readable.&lt;/p&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;Please note that the aforementioned logic (doubling list elements) can be implemented easily in native operations available in Java 8+. However, the reduce operation has its own usages and that example emphatically depicts and limitation of the collection API.&lt;/div&gt;

&lt;h3 id=&#34;immutable-collections&#34;&gt;Immutable collections&lt;/h3&gt;
&lt;p&gt;In addition to more verbose syntax, Java collections are in general mutable. This makes it harder (more error prone) to use them in (to share the instance between) multiple threads. &lt;a href=&#34;https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/concurrent/package-summary.html&#34; target=&#34;_blank&#34;&gt;Thread safety&lt;/a&gt;
 for collections might help, but as I already mentioned in that case it will not (as the initial empty collection is distributed across diffrent threads). However, in some more functional languages such as Scala, not to mention Haskel, it is quite popular to use immutable collections.&lt;/p&gt;
&lt;p&gt;They typically has the &amp;ldquo;first&amp;rdquo; element, called head and the rest called tail. Adding a new element before head is cheap as the new head can share the old one as tail (which is immutable, remember?). Of course, in some other use cases (such as putting elements between other elements) they cannot keep up with a classic mutable counterparts. and it can be used in different use cases. Nevertheless, it might be an alternative worth consideration. For Java, there is - among others - the &lt;a href=&#34;https://www.vavr.io/vavr-docs/#_data_structures_in_a_nutshell&#34; target=&#34;_blank&#34;&gt;collections API in Vavr&lt;/a&gt;
.&lt;/p&gt;
&lt;h3 id=&#34;mutable-reduction-operation&#34;&gt;Mutable reduction operation&lt;/h3&gt;
&lt;p&gt;To deal with cases where mutable operation are much more memory/CPU effective a dedicated Collector can be written which realizes &lt;a href=&#34;https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#MutableReduction&#34; target=&#34;_blank&#34;&gt;mutable reduction operation&lt;/a&gt;
. More info about writing a custom &lt;code&gt;Collector&lt;/code&gt; can be found in this interesting &lt;a href=&#34;https://www.nurkiewicz.com/2014/07/introduction-to-writing-custom.html&#34; target=&#34;_blank&#34;&gt;blog post&lt;/a&gt;
 by Tomasz Nurkiewicz.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;I hope that you were hard enough to get with me to the end of this (quite long and quite low level) blog post :-).&lt;/p&gt;
&lt;p&gt;Using this example with reduce, I wanted to show one of the possible problems while dealing with parallel execution and its explaination. It is not a bug in JDK, but rather a presumption in the (parallel) stream API which - as I observe during my &lt;a href=&#34;https://blog.solidsoft.pl/training/&#34;&gt;testing classes&lt;/a&gt;
 - are not emphasised enough to be common knowledge. It is good to know your tools and use it properly, as well as extend ones awareness about new and alternative solutions. And remember, state mutation is problematic. Prefer immutable data structures if only possible (and feasible).&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/free-photos-242387/&#34;&gt;Free-Photos&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/photos/waterfall-rocks-trees-forest-woods-802003/&#34;&gt;Pixabay&lt;/a&gt;, Pixabay License.&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl//images/posts/2020/java8-reduce-issue-parallel-stream-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl//images/posts/2020/java8-reduce-issue-parallel-stream-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>java</category>
            
          
            
              <category>java8</category>
            
          
            
              <category>java14</category>
            
          
            
              <category>streams</category>
            
          
            
              <category>parallel</category>
            
          
            
              <category>bug</category>
            
          
        
        
          
            
              <category>Deep Dive</category>
            
          
            
              <category>Tricks &amp; Tips</category>
            
          
        
        
      </item>
      
      <item>
        <title>PIT, JUnit 5 and Gradle - with just one extra line of configuration</title>
        <link>https://blog.solidsoft.pl/2020/02/27/pit-junit-5-and-gradle-with-just-one-extra-line-of-configuration/</link>
        <pubDate>Thu, 27 Feb 2020 00:00:00 +0000</pubDate>
        
        <atom:modified>Thu, 27 Feb 2020 00:00:00 +0000</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/02/27/pit-junit-5-and-gradle-with-just-one-extra-line-of-configuration/</guid>
        <description>Discover dead simple, improved PIT and JUnit 5 configuration in Gradle (with gradle-pitest-plugin 1.4.7+).
  JUnit 5 is undeniably more and more popular nowadays. While there is a dedicated plugin for PIT for JUnit 5 and it has been supported by gradle-pitest-plugin for years, it was required to add a few lines of boilerplate code to achieve that. Recently, I&amp;rsquo;ve got a question if it could be simplified. I liked it.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Discover dead simple, improved PIT and JUnit 5 configuration in Gradle (with gradle-pitest-plugin 1.4.7+).&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/pit-junit5-gradle.png&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;br&gt;
&lt;p&gt;JUnit 5 is undeniably more and more popular nowadays. While there is a dedicated plugin for PIT for JUnit 5 and it has been supported by gradle-pitest-plugin for years, it was required to add a few lines of boilerplate code to achieve that. Recently, I&amp;rsquo;ve got a &lt;a href=&#34;https://github.com/szpak/gradle-pitest-plugin/issues/177&#34; target=&#34;_blank&#34;&gt;question&lt;/a&gt;
 if it could be simplified. I liked it. Challenge accepted :-).&lt;/p&gt;
&lt;h2 id=&#34;generic-approach-with-buildscript-&#34;&gt;Generic approach with &amp;lsquo;buildscript {}&amp;rsquo;&lt;/h2&gt;
&lt;p&gt;First, take a look at the generic approach with the &lt;code&gt;buildscrip {}&lt;/code&gt; code block, which remembers times of Gradle 0.x:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;buildscript&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
   &lt;span class=&#34;n&#34;&gt;repositories&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;mavenCentral&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;gradlePluginPortal&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//optionally, if any plugin is not available in Maven Central
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;configurations&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;maybeCreate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pitest&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;classpath&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.4.6&amp;#39;&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;       &lt;span class=&#34;n&#34;&gt;pitest&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.pitest:pitest-junit5-plugin:0.12&amp;#39;&lt;/span&gt;
&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;apply&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;plugin:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;java&amp;#39;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;apply&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;plugin:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;info.solidsoft.pitest&amp;#39;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;pitest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;testPlugin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;junit5&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Just 3 extra lines. Acceptable, however &lt;code&gt;buildscript {}&lt;/code&gt; for plugin configuration is somehow verbose by itself.&lt;/p&gt;
&lt;h2 id=&#34;modern-approach-with-plugins-br-with-older-gradle-pitest-plugin&#34;&gt;Modern approach with &amp;lsquo;plugins {}&amp;lsquo;&lt;br&gt; (with older gradle-pitest-plugin)&lt;/h2&gt;
&lt;p&gt;The modern variant with &lt;code&gt;plugins {}&lt;/code&gt; should be shorter:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;n&#34;&gt;buildscript&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;repositories&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;       &lt;span class=&#34;n&#34;&gt;mavenCentral&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;   &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;configurations&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;maybeCreate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pitest&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;   &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;       &lt;span class=&#34;n&#34;&gt;pitest&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.pitest:pitest-junit5-plugin:0.12&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;   &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;plugins&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;java&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;info.solidsoft.pitest&amp;#39;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1.4.6&amp;#39;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;pitest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;hl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;testPlugin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;junit5&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Unfortunately, the compact syntax of the &lt;code&gt;plugin {}&lt;/code&gt; block is wasted by a need to add an extra dependency &lt;code&gt;pitest-junit5-plugin&lt;/code&gt; used by &lt;code&gt;gradle-pitest-plugin&lt;/code&gt; in runtime in the &lt;code&gt;buildscript {}&lt;/code&gt; block - 10 lines extra. Highly disappointing ;-).&lt;/p&gt;
&lt;h2 id=&#34;modern-improved-approach-with-plugins-br-and-gradle-pitest-plugin-147&#34;&gt;Modern improved approach with &amp;lsquo;plugins {}&amp;lsquo;&lt;br&gt; and gradle-pitest-plugin 1.4.7+&lt;/h2&gt;
&lt;p&gt;With just released &lt;code&gt;gradle-pitest-plugin&lt;/code&gt; 1.4.7 we can forget about all the boilerplate code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;plugins&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;java&amp;#39;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;info.solidsoft.pitest&amp;#39;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1.4.7&amp;#39;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;pitest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;//adds dependency to org.pitest:pitest-junit5-plugin and sets &amp;#34;testPlugin&amp;#34; to &amp;#34;junit5&amp;#34;
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;junit5PluginVersion&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;0.12&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Just one line &lt;code&gt;junit5PluginVersion = &#39;0.12&#39;&lt;/code&gt; which under the hood adds a &lt;code&gt;pitest-junit5-plugin&lt;/code&gt; dependency in the required versions and activates &lt;code&gt;junit5&lt;/code&gt; as &lt;code&gt;testPlugin&lt;/code&gt; used by PIT. Doesn&amp;rsquo;t it look nice? :-)&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;In this short blog post I presented how the configuration of the PIT, JUnit 5 and Gradle(-pitest-plugin) could be simplified with just a few changes in the plugin itself. All thanks to the question by &lt;a href=&#34;https://github.com/szpak/gradle-pitest-plugin/issues/177&#34; target=&#34;_blank&#34;&gt;John Scancella&lt;/a&gt;
 and the idea that sprang into my mind how to implement it in the smart way.&lt;/p&gt;
&lt;p&gt;Therefore, I encourage you to report (sensible) ideas for improvements and things that limit you in the projects you use (or even better a pull/merge request after the initial discussion with the maintainer). Maybe it will implemented (accepted) for common good :-).&lt;/p&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/pit-junit5-gradle-ratio.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>pit</category>
            
          
            
              <category>junit5</category>
            
          
            
              <category>gradle</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>java</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
            
              <category>Tricks &amp; Tips</category>
            
          
        
        
      </item>
      
      <item>
        <title>Auto-switchable multiple Git identities on one computer - Git Tricks #1</title>
        <link>https://blog.solidsoft.pl/2019/08/27/auto-switchable-multiple-git-identities-on-one-computer-git-tricks-1/</link>
        <pubDate>Tue, 27 Aug 2019 00:00:00 +0000</pubDate>
        
        <atom:modified>Tue, 27 Aug 2019 00:00:00 +0000</atom:modified>
        <guid>https://blog.solidsoft.pl/2019/08/27/auto-switchable-multiple-git-identities-on-one-computer-git-tricks-1/</guid>
        <description>Have you even committed to Git using wrong email address working on/for different projects/companies? Luckily with a little configuration Git can auto-switch the identities for you.
 (Too long) introduction and reasoning Being an (experienced) IT professional can give you an opportunity to work on different things in the same time frame. For instance, in addition to work for the main client, I do some consultancy stuff with code quality &amp;amp; testing and Continuoues Delivery for other companies.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Have you even committed to Git using wrong email address working on/for different projects/companies? Luckily with a little configuration Git can auto-switch the identities for you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;too-long-introduction-and-reasoning&#34;&gt;(Too long) introduction and reasoning&lt;/h2&gt;
&lt;p&gt;Being an (experienced) IT professional can give you an opportunity to work on different things in the same time frame. For instance, in addition to work for the main client, I do some consultancy stuff with code quality &amp;amp; testing and Continuoues Delivery for other companies. What&amp;rsquo;s more, I also conduct training sessions (will a lot of exercises with code) and work on my own and other&amp;rsquo;s FOSS projects. Usually, it is convenient to do it on the same computer. It can happen to commit something with the wrong email address (to be detected later on by an external auditor ;-) ) and a push with force to a remote master after rebase is not the best possible solution :-). I started with some &lt;a href=&#34;https://fishshell.com/&#34; target=&#34;_blank&#34;&gt;Fish&lt;/a&gt;
-based script to deal with it, but in the end I have found a built-in mechanism in Git itself.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;. This particular blog post doesn&amp;rsquo;t treat about anything new or revolutionary. However, I&amp;rsquo;ve been living in unawareness long enough to give my blog readers a chance to know that mechanism right now.&lt;/p&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2019/superhero-git-identities.jpg&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;project-situation&#34;&gt;Project situation&lt;/h2&gt;
&lt;p&gt;My &lt;code&gt;~/Code&lt;/code&gt; directory structure could be simplified to something like that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Code/
├── gradle-nexus-staging-plugin
├── mockito-java8
├── spock-global-unroll
├── ...
├── external-foss
│   ├── ...
│   ├── awaitility
│   └── spock
├── training
│   ├── ...
│   ├── code-testing
│   ├── java11
│   └── jenkins-as-code
└── work
    ├── ...
    ├── codearte
    └── companyX
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The goal is to keep an email address in the company&amp;rsquo;s projects appropriate.&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution&lt;/h2&gt;
&lt;p&gt;The first idea which can spring to your mind is to manually override &lt;code&gt;git config user.email &amp;quot;...&amp;quot;&lt;/code&gt; in every clonned company repository. However, it&amp;rsquo;s tedious and error prone (especially in the microservice-based architecture :) ).&lt;/p&gt;
&lt;p&gt;Luckily, one of the features introduces in &lt;a href=&#34;https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.13.0.txt&#34; target=&#34;_blank&#34;&gt;Git 2.13.0&lt;/a&gt;
 (long time ago - May 2017) is a conditional configuration applying (aka &lt;a href=&#34;https://git-scm.com/docs/git-config#_includes&#34; target=&#34;_blank&#34;&gt;Conditional includes&lt;/a&gt;
). Armed with it our task is pretty simple.&lt;/p&gt;
&lt;p&gt;First, keep your default name and email defined in the &lt;code&gt;[user]&lt;/code&gt; section in &lt;code&gt;~/.gitconfig&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span class=&#34;k&#34;&gt;[user]&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;Marcin Zajączkowski
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;  email = foss.hacker@mydomain.example.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Next, create a company related config file in the home directory, e.g. &lt;code&gt;~/.gitconfig-companyX&lt;/code&gt; with just overriden email address:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span class=&#34;k&#34;&gt;[user]&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;email&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;marcin.zajaczkowski@companyx.example.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Glue it together by placing in &lt;code&gt;~/.gitconfig&lt;/code&gt; the following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cfg&#34; data-lang=&#34;cfg&#34;&gt;&lt;span class=&#34;k&#34;&gt;[includeIf &amp;#34;gitdir:~/Code/work/companyX/&amp;#34;]&lt;/span&gt;
  &lt;span class=&#34;na&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;.gitconfig-companyX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;.gitconfig-companyX&lt;/code&gt; is applied only if a current path prefix matches the one defined in &lt;code&gt;includeIf&lt;/code&gt;. Simple, yet powerful. That mechanism can be also used to configure different things - such as conditionally using GPG to sign your commits.&lt;/p&gt;
&lt;p&gt;Btw, being a paranoid you can even remove the email field from the root configuration to be notified if you forgot to add an email for any new company you colaborate with.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Thanks to the &lt;code&gt;includeIf&lt;/code&gt; mechanism you will never (*) again commit to a repo with wrong name or email. That and other Git related tricks and commands/aliases (such as collected in &lt;a href=&#34;https://github.com/szpak/gitkurka/&#34; target=&#34;_blank&#34;&gt;git-kurka&lt;/a&gt;
 make it easier to focus on delivering the stuff :).&lt;/p&gt;
&lt;p&gt;Feel free to leave your favorite Git tips &amp;amp; tricks in the comments.&lt;/p&gt;
&lt;p&gt;Update. From the comment made on priv:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git works great in that case, but for more generic changes in the environment variables &lt;a href=&#34;https://mobile.twitter.com/wybczu&#34; target=&#34;_blank&#34;&gt;Wybczu&lt;/a&gt;
 suggested very powerful &lt;a href=&#34;https://direnv.net/&#34; target=&#34;_blank&#34;&gt;direnv&lt;/a&gt;
 (with support for bash, zsh, tcsh, fish and elvish)&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;The lead photo based on the &lt;a href=&#34;https://pixabay.com/users/EliasSch-3372715/&#34;&gt;Elias Sch&lt;/a&gt; &amp;lsquo;s work published in &lt;a href=&#34;https://pixabay.com/&#34;&gt;Pixabay&lt;/a&gt;, Pixabay License.&lt;/span&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2019/superhero-git-identities.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>git</category>
            
          
            
              <category>git-tricks</category>
            
          
            
              <category>git-kurka</category>
            
          
        
        
          
            
              <category>Tricks &amp; Tips</category>
            
          
        
        
      </item>
      
      <item>
        <title>Simplify integration testing of legacy applications with Spock 1.2</title>
        <link>https://blog.solidsoft.pl/2018/09/14/simplify-integration-testing-of-legacy-applications-with-spock-1.2/</link>
        <pubDate>Fri, 14 Sep 2018 10:00:00 +0200</pubDate>
        
        <atom:modified>Fri, 14 Sep 2018 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2018/09/14/simplify-integration-testing-of-legacy-applications-with-spock-1.2/</guid>
        <description>Learn how leverage Spock 1.2 to slice a Spring context of a legacy application writing integration tests.
 Have you ever wanted, having some legacy application which you were starting to work on, to write some tests to get know what is going on and possibly be notified about regressions? That feeling when you want to instantiate a single class and it fails with NullPointerException. 6 replaced (with difficulty) dependencies later there are still some errors from the classes that you haven&amp;rsquo;t heard about before.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Learn how leverage Spock 1.2 to slice a Spring context of a legacy application writing integration tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Have you ever wanted, having some legacy application which you were starting to work on, to write some tests to get know what is going on and possibly be notified about regressions? That feeling when you want to instantiate a single class and it fails with &lt;code&gt;NullPointerException&lt;/code&gt;. 6 replaced (with difficulty) dependencies later there are still some errors from the classes that you haven&amp;rsquo;t heard about before. Sounds familiar?&lt;/p&gt;
&lt;p&gt;There are different techniques to deal with hidden dependencies. There is the whole dedicated &lt;a href=&#34;https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052&#34; target=&#34;_blank&#34;&gt;book&lt;/a&gt;
 about that (and probably a few other that I haven&amp;rsquo;t read). Occasionally, it may be feasible to start with the integration tests and run through some process. It may be even more &amp;ldquo;entertaining&amp;rdquo; to see what exotic components are required to just setup the context, even if they are completely not needed in our case. Thank you (too wide and carelessly used) &lt;code&gt;@ComponentScan&lt;/code&gt; :).&lt;/p&gt;
&lt;p&gt;Injecting stubs/mocks inside the test context is a way to go as an emergency assistance (see the last paragraph, there are better, yet harder approaches). It can be achieved &amp;ldquo;manually&amp;rdquo; with an extra bean definition with the &lt;code&gt;@Primary&lt;/code&gt; annotation (usually a reason to think twice before doing that) for every dependency at which level we want to make a cut of (or for every unneeded bean which is instantiated by the way). &lt;code&gt;@MockBean&lt;/code&gt; placed on a field in a test is more handy, but still, it is needed to define a field in our tests and put the annotation on it (5? 10? 15 beans?). Spock 1.2 introduces somehow less know feature which may be useful here - &lt;code&gt;@StubBeans&lt;/code&gt;.&lt;/p&gt;




  



  &lt;div class=&#34;featured-image__wrapper&#34;&gt;
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2018/mocked-dependencies-spring.png&#34; alt=&#34;Featured Image&#34; class=&#34;featured-image&#34; style=&#34;width: 680px;height: 356px;&#34;&gt;
  &lt;/div&gt;

&lt;p&gt;It can be used to simply provide a list of classes which (possible) instances should be replaced with stubs in the Spring test context. Of course before the real objects are being instantiated (to prevent for example NPE in a constructor). Thanks to that up to several lines of stubbing/mock injections:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@RunWith&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SpringRunner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;class&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//Spring Boot + Mockito
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@SpringBootTest&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//possibly some Spring configuration with @ComponentScan is imported in this legacy application
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BasicPathReportGeneratorInLegacyApplicationITTest&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//usual approach
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KafkaClient&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;kafkaClientMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FancySelfieEnhancer&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fancySelfieEnhancerMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastTwitterSubscriber&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fastTwitterSubscriberMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WaterCoolerWaterLevelAterter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;waterCoolerWaterLevelAterterMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@MockBean&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NsaSilentNotifier&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nsaSilentNotifierMock&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;//a few more - remember, this is legacy application, genuine since 1999 ;)
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//...
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ReportGenerator&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reportGenerator&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;;&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Test&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;shouldGenerateEmptyReportForEmptyInputData&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;can be replaced with just one (long) line:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@SpringBootTest&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//possibly some Spring configuration with @ComponentScan is imported
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@StubBeans&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;KafkaClient&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FancySelfieEnhancer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FastTwitterSubscriber&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WaterCoolerWaterLevelAterter&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NsaSilentNotifier&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/(, ... */&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;//all classes of real beans which should be replaced with stubs
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BasicPathReportGeneratorInLegacyApplicationITSpec&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Specification&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;

    &lt;span class=&#34;nd&#34;&gt;@Autowired&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ReportGenerator&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reportGenerator&lt;/span&gt;

    &lt;span class=&#34;kt&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;should generate empty report for empty input data&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;....&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;(tested with Spock 1.2-RC2)&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s worth to mention that &lt;code&gt;@StubBeans&lt;/code&gt; is intended just to provide placeholders. In a situation it is required to provide stubbing and/or an invocation verification &lt;code&gt;@SpringBean&lt;/code&gt; or &lt;code&gt;@SpringSpy&lt;/code&gt; (also introduced in Spock 1.2) are better. I wrote more about it in my previous &lt;a href=&#34;https://solidsoft.wordpress.com/2018/09/03/spock-1-2-hassle-free-spring-beans-mocking-in-integration-tests/&#34; target=&#34;_blank&#34;&gt;blog post&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;There is one important aspect to emphasize&lt;/strong&gt;. &lt;code&gt;@StubBeans&lt;/code&gt; are handy to be used in a situation when we have some &amp;ldquo;legacy&amp;rdquo; project and want to start writing integration regression tests quickly to see the results. However, as a colleague of mine &lt;a href=&#34;https://stackoverflow.com/users/719633/roadrunner&#34; target=&#34;_blank&#34;&gt;Darek Kaczyński&lt;/a&gt;
 brightly summarized, blindly replacing beans which &amp;ldquo;explode&amp;rdquo; in tests is just &amp;ldquo;sweeping problems under carpet&amp;rdquo;. After the initial phase, when we are starting to understand what is going on, it is a good moment to rethink the way the context - both in production and in tests - is created. The already mentioned too wide &lt;code&gt;@ComponentScan&lt;/code&gt; is very often the root of all evil. An ability to setup a partial context and put it together (if needed) is a good place to start. Using &lt;code&gt;@Profile&lt;/code&gt; or conditional beans are the very powerful mechanisms in tests (and not only there). &lt;code&gt;@TestConfiguration&lt;/code&gt; and proper bean selection to improve context caching are something worth to keep in your mind. However, I started this article to present the new mechanism in Spock which might be useful in some cases and I want to keep it short. There could be an another, more generic blog post just about managing the Spring context in the integration tests. I have to seriously thing about it :).&lt;/p&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2018/mocked-dependencies-spring.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>groovy</category>
            
          
            
              <category>integration-testing</category>
            
          
            
              <category>mocking</category>
            
          
            
              <category>mockito</category>
            
          
            
              <category>spock</category>
            
          
            
              <category>spock-1.2</category>
            
          
            
              <category>spring</category>
            
          
            
              <category>spring-boot</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>tests</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
            
              <category>Tricks &amp; Tips</category>
            
          
        
        
      </item>
      
      <item>
        <title>Deploy to Maven Central using API key (aka auth token)</title>
        <link>https://blog.solidsoft.pl/2015/09/08/deploy-to-maven-central-using-api-key-aka-auth-token/</link>
        <pubDate>Tue, 08 Sep 2015 10:00:00 +0200</pubDate>
        
        <atom:modified>Mon, 06 Apr 2020 22:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2015/09/08/deploy-to-maven-central-using-api-key-aka-auth-token/</guid>
        <description>How to communicate with Maven Central/Nexus without using the password kept locally unencrypted (especially with Gradle, but not limited to it).
 Rationale Unfortunately, Gradle (and many other build tools) does not provide any mechanism to locally keep passwords encrypted (or at least encoded). Without that even such a simple activity like showing your global Gradle configuration (~/.gradle/gradle.properties) to a colleague is uncomfortable, not to mention more serious risks associated with storing passwords on a disk in a plain-text form (see among others Sony Pictures Entertainment hack ).</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;How to communicate with Maven Central/Nexus without using the password kept locally unencrypted (especially with Gradle, but not limited to it).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;rationale&#34;&gt;Rationale&lt;/h2&gt;
&lt;p&gt;Unfortunately, Gradle (and many other build tools) does not provide any mechanism to locally keep passwords encrypted (or at least encoded). Without that even such a simple activity like showing your global Gradle configuration (&lt;code&gt;~/.gradle/gradle.properties&lt;/code&gt;) to a colleague is uncomfortable, not to mention more serious risks associated with storing passwords on a disk in a plain-text form (see among others &lt;a href=&#34;https://en.wikipedia.org/wiki/Sony_Pictures_Entertainment_hack&#34; target=&#34;_blank&#34;&gt;Sony Pictures Entertainment hack&lt;/a&gt;
). It is Gradle, so with all Groovy magic under the hood it would be possible to implement an integration with a system keyring on Linux to fetch a password, but I’m not aware of any existing plugin/mechanism to do that and I would rather prefer not to write it.&lt;/p&gt;
&lt;p&gt;Another issue is that nowadays, in the world of ubiquitous automation and cloud environments it is common to use API keys which allow to perform given operation(s). However, its lost doesn’t provide an attacker a possibility to hijack the account (e.g. token cannot be used neither to log into an administration panel nor to change of email or password which requires additional authentication).&lt;/p&gt;
&lt;p&gt;It is very important if you need to keep valid credentials on a CI server to make automatic or even continuous releases. Thanks to my &lt;del&gt;&lt;a href=&#34;https://github.com/Codearte/gradle-nexus-staging-plugin/&#34; target=&#34;_blank&#34;&gt;gradle-nexus-staging-plugin&lt;/a&gt;
&lt;/del&gt; (&lt;strong&gt;Update 2021&lt;/strong&gt;. Check out my new plugin &lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/&#34; target=&#34;_blank&#34;&gt;gradle-nexus-publish-plugin&lt;/a&gt;
) there is no need to do any manual steps in Nexus GUI to promote artifacts to Maven Central, so this was the next issue I wanted to deal with for my &lt;a href=&#34;https://github.com/szpak/&#34; target=&#34;_blank&#34;&gt;private&lt;/a&gt;
 and our FOSS projects in &lt;a href=&#34;https://github.com/Codearte/&#34; target=&#34;_blank&#34;&gt;Codearte&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;nexus-api-key-generation&#34;&gt;Nexus API key generation&lt;/h2&gt;
&lt;p&gt;Internet search for “maven central api key” wasn’t helpful, so I started digging into Nexus REST API documentation and I’ve found that in fact there is a (non widely known) way to generate and use an API key (aka an auth token).&lt;/p&gt;
&lt;ol start=&#34;0&#34;&gt;
&lt;li&gt;Log into Nexus hosting Sonatype &lt;a href=&#34;https://oss.sonatype.org/&#34; target=&#34;_blank&#34;&gt;OSS Repository Hosting&lt;/a&gt;
 (or your own instance of Nexus).&lt;/li&gt;
&lt;li&gt;Click on your login name in right-upper corner and choose “Profile”.&lt;/li&gt;
&lt;li&gt;From the drop-down list with “Summary” text select “User Token”.&lt;/li&gt;
&lt;li&gt;Click “Access User Token”.&lt;/li&gt;
&lt;/ol&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/archive/deploy-maven-central-api-key.png&#34; alt=&#34;nexus generate API key&#34; style=&#34;width:908px;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Enter your password&lt;/li&gt;
&lt;li&gt;Copy and paste your API username and API key (into your &lt;code&gt;~/.gradle/gradle.properties&lt;/code&gt; file or a CI server configuration).&lt;/li&gt;
&lt;li&gt;Work as usual with a little safer way.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;It is good that using API keys is possible to deploy artifacts to Maven Central/Nexus and it is very easy to set it up. Someone could argue that the permission policy is coarse-grained (nothing or all operations except password/email change), but in my opinion it seems to be enough for the artifact repository system class. In addition, such an approach should work also with Sbt, Ivy, Leiningen and everything else that tries to upload artifacts into Maven Central (including Maven itself by removing limitations of the master password encryption with settings-security.xml). Hopefully, that post will make it widely known.&lt;/p&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/archive/deploy-maven-central-api-key.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        
        
          
            
              <category>gradle</category>
            
          
            
              <category>maven</category>
            
          
            
              <category>maven-central</category>
            
          
            
              <category>my-tools</category>
            
          
            
              <category>nexus</category>
            
          
            
              <category>release</category>
            
          
            
              <category>security</category>
            
          
            
              <category>tutorial</category>
            
          
        
        
          
            
              <category>Tricks &amp; Tips</category>
            
          
        
        
      </item>
      

    
  </channel>
</rss>