<?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>gradle on Solid Soft</title>
    <link>https://blog.solidsoft.pl/tags/gradle/</link>
    <description>Recent content in gradle on Solid Soft</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>©{year}, All Rights Reserved</copyright>
    <lastBuildDate>Fri, 19 Nov 2021 00:10:00 +0200</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>2</sy:updateFrequency>
    
        <atom:link href="https://blog.solidsoft.pl/tags/gradle/index.xml" rel="self" type="application/rss+xml" />
    
    
    

      
      <item>
        <title>Running Spock with unsupported Groovy version (Gradle &#43; Maven)</title>
        <link>https://blog.solidsoft.pl/2021/11/19/running-spock-with-unsupported-groovy-version-gradle-maven/</link>
        <pubDate>Fri, 19 Nov 2021 00:10:00 +0200</pubDate>
        
        <atom:modified>Wed, 02 Feb 2022 23:50:00 +0100</atom:modified>
        <guid>https://blog.solidsoft.pl/2021/11/19/running-spock-with-unsupported-groovy-version-gradle-maven/</guid>
        <description>Stuck with the &amp;lsquo;The Spock compiler plugin cannot execute because Spock 1.3-groovy-2.5 (3.0) is not compatible with Groovy 3.0 (4.0)&amp;rsquo; error message? Find out what can be done about that (using Gradle and Maven).
  Historical background In the dim and distance past, when Groovy 1.x occasionally had some unpleasant (also runtime) backward compatibility issues, Spock had started to be built for the particular Groovy version individually. There were spock-0.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Stuck with the &amp;lsquo;The Spock compiler plugin cannot execute because Spock 1.3-groovy-2.5 (3.0) is not compatible with Groovy 3.0 (4.0)&amp;rsquo; error message? Find out what can be done about that (using Gradle and Maven).&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2021/spock2-groovy4.jpg&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;historical-background&#34;&gt;Historical background&lt;/h2&gt;
&lt;p&gt;In the dim and distance past, when Groovy 1.x occasionally had some unpleasant (also runtime) backward compatibility issues, Spock had started to be built for the particular Groovy version individually. There were &lt;code&gt;spock-0.5-groovy-1.6&lt;/code&gt;, &lt;code&gt;spock-0.5-groovy-1.7&lt;/code&gt; and &lt;code&gt;spock-0.5-groovy-1.8&lt;/code&gt; for instance. To help people choose the right Spock and the Groovy versions, the runtime check was added to fail the compilation (at the AST transformation level) with the meaningful error message, in the situation Spock was compiled with the different Groovy version that is available at runtime, e.g.:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The Spock compiler plugin refused to run because Spock 1.3-groovy-2.5 is not compatible with Groovy 3.0.4. For more information,
see http://versioncheck.spockframework.org Spock location: .../spock-1.3-groovy-2.5.jar, Groovy location: .../groovy-3.0.4.jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The error message is very clear. The reasoning behind this decision is good, and definitely it can help developers to detect problems with the dependencies. However, it can also greatly complicate development, especially taking into account rather rarely released new Spock versions.&lt;/p&gt;
&lt;p&gt;If you are here, because of that error visible in your build, jump to the proper section to see what can be done about the problem.&lt;/p&gt;
&lt;h2 id=&#34;possible-options&#34;&gt;Possible options&lt;/h2&gt;
&lt;h3 id=&#34;spock-13-and-groovy-30&#34;&gt;Spock 1.3 and Groovy 3.0&lt;/h3&gt;
&lt;p&gt;Unfortunately, you are out of luck. If you stuck with Spock 1.3 (e.g. migration to Spock 2.0 is blocked for some reasons) there are two (mediocre) options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Switch to &lt;code&gt;Spock 1.3-SNAPSHOT&lt;/code&gt;. The version compatibility check is relaxed in the SNAPSHOT builds of Spock 1.3. What&amp;rsquo;s more, there were multiple reports that (in the majority of cases - some corner cases remains) Spock &lt;code&gt;1.3-groovy-2.5-SNAPSHOT&lt;/code&gt; works fine with Groovy &lt;code&gt;3.0.x&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are no plans to release any new maintenance release of Spock 1.x. However, you can still &lt;a href=&#34;https://github.com/spockframework/spock/issues&#34; target=&#34;_blank&#34;&gt;create a new issue on GitHub&lt;/a&gt;
 and try to convince The Spock Developers to make 1.3.1 with that change :-).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;spock-20-and-groovy-30&#34;&gt;Spock 2.0+ and Groovy 3.0&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;The Spock compiler plugin refused to run because Spock 2.0-groovy-2.5 is not compatible with Groovy 3.0.9.
For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;). 
Spock location: .../spock-2.0-groovy-2.5.jar
Groovy location: .../groovy-3.0.9.jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That a trivial case. Just change Spock version from 2.0-groovy-2.5 to 2.0-groovy-3.0, and you are set.&lt;/p&gt;
&lt;h3 id=&#34;spock-2021-and-groovy-40&#34;&gt;Spock 2.0/2.1 and Groovy 4.0&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;The Spock compiler plugin refused to run because Spock 2.0-groovy-3.0 is not compatible with Groovy 4.0.0-beta-2.
For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;). 
Spock location: .../spock-2.0-groovy-3.0.jar
Groovy location: .../groovy-4.0.0-beta-2.jar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This variant assumes that you use Groovy 4 (SNAPSHOT, beta or a regular version) and Spock 2.0-groovy-3.0 (or 2.1). The error message is even more precise than in Spock 1.3, suggesting the &lt;a href=&#34;http://spockframework.org/spock/docs/2.0-M3/known_issues.html#_groovy_version_compatibility&#34; target=&#34;_blank&#34;&gt;&amp;lsquo;Known Issues&amp;rsquo;&lt;/a&gt;
 section in the Spock documentation. We can leverage a brand-new system property &lt;code&gt;spock.iKnowWhatImDoing.disableGroovyVersionCheck&lt;/code&gt;, introduced right in Spock 2.0-M3, which allows to disable the version check - of course, at your own risk :-).&lt;/p&gt;
&lt;p&gt;Btw, if you in a hurry (e.g. just to test something), it is also possible just to switch Spock to SNAPSHOT version which accepts (almost) any Groovy version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Btw2, if you prefer to just jump into code, there is a &lt;a href=&#34;https://github.com/szpak/code-examples-and-poc/tree/master/spock2-groovy4-gradle-maven&#34; target=&#34;_blank&#34;&gt;code repository&lt;/a&gt;
 with working examples for Gradle and Maven.&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;gradle&#34;&gt;Gradle&lt;/h4&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;As Groovy 4 changed its &lt;code&gt;groupId&lt;/code&gt; from &lt;code&gt;org.codehaus.groovy&lt;/code&gt; to &lt;code&gt;org.apache.groovy&lt;/code&gt; it is required to &lt;strong&gt;add implicit exclusion for spock-2.0-groovy-3.0 transitive dependencies&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;testImplementation(&amp;quot;org.spockframework:spock-core:2.0-groovy-3.0&amp;quot;) {
    exclude group: &#39;org.codehaus.groovy&#39;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to avoid conflicting Groovy versions on a classpath (it&amp;rsquo;s nice that Gradle is able to detect that!):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task &#39;:compileTestGroovy&#39;.
&amp;gt; Could not resolve all files for configuration &#39;:testCompileClasspath&#39;.
   &amp;gt; Could not resolve org.apache.groovy:groovy:4.0.0-beta-2.
     Required by:
         project :
         project : &amp;gt; org.apache.groovy:groovy:4.0.0-beta-2 &amp;gt; org.apache.groovy:groovy-bom:4.0.0-beta-2
      &amp;gt; Module &#39;org.apache.groovy:groovy&#39; has been rejected:
           Cannot select module with conflict on capability &#39;org.codehaus.groovy:groovy:4.0.0-beta-2&#39; also provided by [org.codehaus.groovy:groovy:3.0.8(compile)]
   &amp;gt; Could not resolve org.codehaus.groovy:groovy:3.0.8.
     Required by:
         project : &amp;gt; org.spockframework:spock-core:2.0-groovy-3.0
      &amp;gt; Module &#39;org.codehaus.groovy:groovy&#39; has been rejected:
           Cannot select module with conflict on capability &#39;org.codehaus.groovy:groovy:3.0.8&#39; also provided by [org.apache.groovy:groovy:4.0.0-beta-2(groovyApiElements)]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It won&amp;rsquo;t be required for Spock 2.0-groovy-4.0, once available.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;&lt;strong&gt;To be able use Groovy 4, Gradle 6.7+ is &lt;a href=&#34;https://github.com/gradle/gradle/issues/13657&#34;&gt;required&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With earlier Gradle version you might got some misleading errors about not resolvable dependency to &lt;code&gt;org.codehaus.groovy:groovy:4.0.0-beta-2&lt;/code&gt;, even though you configured &lt;code&gt;org.apache.groovy:groovy:4.0.0-beta-2&lt;/code&gt; with the correct, changed group id.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Execution failed for task &#39;:compileTestGroovy&#39;.
&amp;gt; Could not resolve all files for configuration &#39;:detachedConfiguration1&#39;.
   &amp;gt; Could not find org.codehaus.groovy:groovy:4.0.0-beta-2.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The obvious way to add system properties to the Gradle execution itself is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./gradlew check -Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true     //wrong way
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately it doesn&amp;rsquo;t work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED
startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/spock-core-2.0-groovy-3.0.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 2.0-groovy-3.0 is not compatible with Groovy 4.0.0-beta-2. For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;).
Spock artifact: file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/.../spock-core-2.0-groovy-3.0.jar
Groovy artifact: file:/home/foobar/.gradle/caches/modules-2/files-2.1/org.apache.groovy/groovy/4.0.0-beta-2/.../groovy-4.0.0-beta-2.jar

1 error


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task &#39;:compileTestGroovy&#39;.
&amp;gt; Compilation failed; see the compiler error output for details.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After some searching on the Internet, we can find out that tests in Gradle are (by default) executed in a separate JVM, to it is required to pass the aforementioned system property to the &lt;code&gt;test&lt;/code&gt; task:&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-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;systemProperty&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//doesn&amp;#39;t work
&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;However, it still fails:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED
startup failed:
Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hmm, maybe it would be better to refer the Gradle test task by type?&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-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Test&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configureEach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;systemProperty&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//doesn&amp;#39;t work either
&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;It fails with the same error message :-/. What is wrong?&lt;/p&gt;
&lt;p&gt;The key difference - quite easy to miss - is the fact the exception is thrown not during the test execution, but during the compilation phrase. Then, the main Spock AST transformation checks if it could be applied:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy FAILED   &amp;lt;--------- :compileTestGroovy not :test !
startup failed:
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is definitely less popular case, and I had a problem to find any sensible source of wisdom proposing a complete solution. One of the possible option (which I talk about deeper in the article about &lt;a href=&#34;https://blog.solidsoft.pl/2020/03/02/enable-java-14-preview-features-in-gradle-maven-and-idea/&#34;&gt;enabling preview features&lt;/a&gt;
 of the new Java versions) is &lt;code&gt;CompileOptions&lt;/code&gt; (e.g. &lt;code&gt;options.compilerArgs.add(&#39;--enable-preview&#39;)&lt;/code&gt; in the &lt;a href=&#34;https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/compile/GroovyCompile.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;GroovyCompile&lt;/code&gt;&lt;/a&gt;
 task. The second might be &lt;code&gt;GroovyCompileOptions&lt;/code&gt; also in &lt;code&gt;GroovyCompile&lt;/code&gt;. However, it does not bring expected result. After some digging, I was able to find out, that as the Groovy compilation is performed in the forked JVM and the right way to achieve the goal is:&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-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;n&#34;&gt;tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GroovyCompile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configureEach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;forkOptions&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;jvmArgs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;-Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true&amp;#39;&lt;/span&gt;    &lt;span class=&#34;c1&#34;&gt;//it works! But be aware that &amp;#34;options&amp;#34; not &amp;#34;groovyOptions&amp;#34;!
&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;And it works as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; Task :compileTestGroovy
Executing Spock 2.0-groovy-3.0 with NOT compatible Groovy version 4.0.0-beta-2 due to set spock.iKnowWhatImDoing.disableGroovyVersionCheck system property set. This is unsupported and may result in weird runtime errors!

&amp;gt; Task :test
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;displaying a nice disclaimer :). Spock 2.0-groovy-3.0 is used together with Groovy 4.&lt;/p&gt;
&lt;p&gt;Btw, if you see just not very helpful error message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at
jar:file:/.../spock-core-.../org.codehaus.groovy.transform.ASTTransformation
because of exception java.lang.reflect.InvocationTargetException
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;it is caused by &lt;a href=&#34;https://issues.apache.org/jira/browse/GROOVY-9469&#34; target=&#34;_blank&#34;&gt;GROOVY-9469&lt;/a&gt;
 which affects Groovy 3 and was fixed in 3.0.3. Upgrade Groovy to see more verbose error message.&lt;/p&gt;
&lt;h4 id=&#34;maven&#34;&gt;Maven&lt;/h4&gt;
&lt;div class=&#34;alert alert-warning&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;p&gt;As Groovy 4 changed its &lt;code&gt;groupId&lt;/code&gt; from &lt;code&gt;org.codehaus.groovy&lt;/code&gt; to &lt;code&gt;org.apache.groovy&lt;/code&gt; it is required to &lt;strong&gt;add implicit exclusion for spock-2.0-groovy-3.0 transitive dependencies&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.spockframework&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spock-core&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;${spock.version}&amp;lt;/version&amp;gt;
        &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;exclusions&amp;gt;
            &amp;lt;!-- to do not have conflicting Groovy versions - Groovy 4 changed groupId from &amp;quot;org.codehaus.groovy&amp;quot; to &amp;quot;org.apache.groovy&amp;quot; --&amp;gt;
            &amp;lt;exclusion&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.groovy&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;*&amp;lt;/artifactId&amp;gt;
            &amp;lt;/exclusion&amp;gt;
        &amp;lt;/exclusions&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.apache.groovy&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;groovy&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;4.0.0-beta-2&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to have your tests executed with Groovy 4 instead of (silently) with Groovy 3, taken from a transitive dependency of Spock 2.0-groovy-3.0!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[INFO] --- gmavenplus-plugin:1.13.0:compileTests (default) @ spock2-groovy4-maven ---
[INFO] Using isolated classloader, without GMavenPlus classpath.
[INFO] Using Groovy 3.0.8 to perform compileTests.     &amp;lt;---- Without exclusion, it is executed &amp;quot;silently&amp;quot; with old Groovy! 
[INFO] Parallel parsing disabled.
[INFO] Compiled 1 file.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It won&amp;rsquo;t be required for Spock 2.0-groovy-4.0, once available.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Writing my Spock, Groovy and modern Java related tutorials, I try to cover also the Maven users, which still is quite popular build tool :-). Usually, it takes much more (XML) lines to achieve the same in Maven in comparison to Gradle, however, sometimes it just works flawlessly without any additional effort. Unfortunately, it was not the case this time.&lt;/p&gt;
&lt;p&gt;The build with Spock-2.0-groovy-3.0 and Groovy 4.0.0 by default fails with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ERROR] Failed to execute goal org.codehaus.gmavenplus:gmavenplus-plugin:1.8.1:compileTests (default) on project spock2-migration-maven: Error occurred while calling a method on a Groovy class from classpath. InvocationTargetException: startup failed:
[ERROR] Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/spock-core-2.0-groovy-3.0.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation  because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 2.0-groovy-3.0 is not compatible with Groovy 4.0.0-beta-2. For more information (including enforce mode), see http://docs.spockframework.org (section &#39;Known Issues&#39;).
[ERROR] Spock artifact: file:/home/foobar/.m2/repository/org/spockframework/spock-core/2.0-groovy-3.0/spock-core-2.0-groovy-3.0.jar
[ERROR] Groovy artifact: file:/home/foobar/.m2/repository/org/apache/groovy/groovy/4.0.0-beta-2/groovy-4.0.0-beta-2.jar
[ERROR] 
[ERROR] 1 error
[ERROR] -&amp;gt; [Help 1]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To make the long story short, I started with the plain Maven properties:&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;/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-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;project&amp;gt;&lt;/span&gt;
...
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
     &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- doesn&amp;#39;t work --&amp;gt;&lt;/span&gt;
     &lt;span class=&#34;nt&#34;&gt;&amp;lt;spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/spock.iKnowWhatImDoing.disableGroovyVersionCheck&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
...
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/project&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 fails. Next, I added the following to the compiler parameters:&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;/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-xml&#34; data-lang=&#34;xml&#34;&gt;    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-compiler-plugin&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.8.1&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- doesn&amp;#39;t work --&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;compilerArgs&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;-v&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;arg&amp;gt;&lt;/span&gt;-Dspock.iKnowWhatImDoing.disableGroovyVersionCheck=true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/arg&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/compilerArgs&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- ... --&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;however, it doesn&amp;rsquo;t affect Groovy compilation itself. I even took a look at the &lt;code&gt;gmavenplus&lt;/code&gt; plugin parameters and Groovy&amp;rsquo;s &lt;a href=&#34;https://docs.groovy-lang.org/latest/html/api/org/codehaus/groovy/control/CompilerConfiguration.html&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;CompilerConfiguration&lt;/code&gt;&lt;/a&gt;
, but without any effect. In the end, I was able to achieve that with another plugin &lt;code&gt;properties-maven&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;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;/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-xml&#34; data-lang=&#34;xml&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codehaus.mojo&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;properties-maven-plugin&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;set-system-properties&lt;span class=&#34;nt&#34;&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;c&#34;&gt;&amp;lt;!-- works fine --&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
                            &lt;span class=&#34;nt&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;spock.iKnowWhatImDoing.disableGroovyVersionCheck&lt;span class=&#34;nt&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
                            &lt;span class=&#34;nt&#34;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;true&lt;span class=&#34;nt&#34;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
                        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
                    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;
                &lt;span class=&#34;nt&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;nt&#34;&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;nt&#34;&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;/plugin&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;resulting in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[INFO] --- gmavenplus-plugin:1.8.1:compileTests (default) @ spock2-migration-maven ---
[INFO] Using isolated classloader, without GMavenPlus classpath.
[INFO] Using Groovy 4.0.0-beta-2 to perform compileTests.
Executing Spock 2.0-groovy-3.0 with NOT compatible Groovy version 4.0.0-beta-2 due to set spock.iKnowWhatImDoing.disableGroovyVersionCheck system property set. This is unsupported and may result in weird runtime errors!
[INFO] Compiled 10 files.
[INFO] 
[INFO] --- maven-surefire-plugin:3.0.0-M4:test (default-test) @ spock2-migration-maven ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It turned out to be quite easy (if you know what to use :-) ), but - unless I missed something - it is somehow not much covered in the existing tutorials or documentation.&lt;/p&gt;
&lt;h3 id=&#34;potential-issue-in-intellij-idea&#34;&gt;Potential issue in IntelliJ IDEA&lt;/h3&gt;
&lt;p&gt;Even though, having your up-and-running Maven project configured as above, you might still encounter the incompatibility error after importing it in Idea:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Groovyc: While compiling [tests of spock2-groovy4-gradle.test]: Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at jar:file:/home/&amp;hellip;/spock-core-2.0-groovy-3.0.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation because of exception java.lang.NullPointerException: Cannot invoke &amp;ldquo;java.net.URL.toString()&amp;rdquo; because the return value of &amp;ldquo;java.security.CodeSource.getLocation()&amp;rdquo; is null&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;del&gt;The problem is caused by a limitation of Idea (&lt;a href=&#34;https://youtrack.jetbrains.com/issue/IDEA-287642&#34; target=&#34;_blank&#34;&gt;IDEA-287642&lt;/a&gt;
), which does not allow providing custom system properties for groovyc compilation (just for javac). You might want to vote for that issue.&lt;/del&gt; In fact, as &lt;a href=&#34;https://youtrack.jetbrains.com/issue/IDEA-287642#focus=Comments-27-5733123.0-0&#34; target=&#34;_blank&#34;&gt;Paul King&lt;/a&gt;
 pointed out, there is a way to set that property for all the compilers used in the project with &lt;code&gt;Settings → Compiler → Shared build process VM options&lt;/code&gt;. In the context of Spock, it should be enough.&lt;/p&gt;
&lt;p&gt;The error itself is not very meaningful (&lt;code&gt;NullPointerException&lt;/code&gt;) which in turn is caused by an unexpected behavior of Idea, reported as &lt;a href=&#34;https://youtrack.jetbrains.com/issue/IDEA-287643&#34; target=&#34;_blank&#34;&gt;IDEA-287643&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;It is worth to mention, the same problem might occur also with Gradle, once &amp;ldquo;Build and run&amp;rdquo; is manually set to &amp;ldquo;Idea&amp;rdquo; (instead of &amp;ldquo;Gradle&amp;rdquo; - default behavior, but not the fastest one).&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The main reason, I implemented that feature in Spock was development of Groovy 4. I didn&amp;rsquo;t feel comfortable seeing The Groovy Team to be forced to use the Spock snapshot version in the master (Groovy 4.x) builds. With Spock-2.0-M3 it was &lt;a href=&#34;https://github.com/apache/groovy/pull/1281&#34; target=&#34;_blank&#34;&gt;simplified&lt;/a&gt;
. The same construction can be used in your project while playing with Groovy 4 (in beta as of XI 2021), in the way I precised for Gradle and Maven (which in turn can be really confusing on their own way which motivated me to write this short post :-) ). There is &lt;a href=&#34;https://github.com/spockframework/spock/issues/1374#issuecomment-932374972&#34; target=&#34;_blank&#34;&gt;a plan&lt;/a&gt;
 to add the official support for Groovy 4 in Spock, once it is closer to Groovy 4.0.0-final.&lt;/p&gt;
&lt;p&gt;Btw, there is a &lt;a href=&#34;https://github.com/szpak/code-examples-and-poc/tree/master/spock2-groovy4-gradle-maven&#34; target=&#34;_blank&#34;&gt;code repository&lt;/a&gt;
 with working examples for Gradle and Maven.&lt;/p&gt;
&lt;p&gt;P.S. If you bumped into that topic during Spock 1.3 -&amp;gt; 2.0 migration, there is a dedicated &lt;a href=&#34;https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/&#34;&gt;migration guide article&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated 2021-01-31&lt;/strong&gt;. Added section about potential issue with IntelliJ IDEA.&lt;br /&gt;
&lt;strong&gt;Updated 2021-02-02&lt;/strong&gt;. Add workaround suggested by &lt;a href=&#34;https://twitter.com/paulk_asert&#34; target=&#34;_blank&#34;&gt;Paul King&lt;/a&gt;
 about the potential issue with IntelliJ IDEA.&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/geralt-9301/&#34;&gt;geralt&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/illustrations/place-name-sign-plan-success-749613/&#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/2021/spock2-groovy4-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2021/spock2-groovy4-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>spock</category>
            
          
            
              <category>spock2</category>
            
          
            
              <category>spock-2.0</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>groovy</category>
            
          
            
              <category>groovy4</category>
            
          
            
              <category>gradle</category>
            
          
            
              <category>maven</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>Unified Gradle projects releasing to Maven Central in 2021 &#43; migration guide</title>
        <link>https://blog.solidsoft.pl/2021/02/26/unified-gradle-projects-releasing-to-maven-central-in-2021-migration-guide/</link>
        <pubDate>Fri, 26 Feb 2021 10:00:00 +0200</pubDate>
        
        <atom:modified>Fri, 26 Feb 2021 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2021/02/26/unified-gradle-projects-releasing-to-maven-central-in-2021-migration-guide/</guid>
        <description>As a counterbalance to an imminent JCenter shutdown, get know the unified (and united) power of releasing to Maven Central with a brand new Gradle Nexus Publish Plugin. A migration guide from the old plugins is included.
  
TL;TR. A brand new Gradle Nexus Publish Plugin is currently the best solution for releasing projects to Maven Central. 2 big things in Q1 2021 The beginning of 2021 electrified the JVM ecosystem by an unexpected decision of the fast upcoming shutdown of JCenter , a quite popular place to keep FOSS projects&amp;rsquo; binary artifacts.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;As a counterbalance to an imminent JCenter shutdown, get know the unified (and united) power of releasing to Maven Central with a brand new Gradle Nexus Publish Plugin. A migration guide from the old plugins is included.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2021/unified-releasing-gradle-2021.jpg&#34;  style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;strong&gt;TL;TR&lt;/strong&gt;. A brand new &lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/&#34; target=&#34;_blank&#34;&gt;Gradle Nexus Publish Plugin&lt;/a&gt; is currently the best solution for releasing projects to Maven Central.&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;2-big-things-in-q1-2021&#34;&gt;2 big things in Q1 2021&lt;/h2&gt;
&lt;p&gt;The beginning of 2021 electrified the JVM ecosystem by an unexpected decision of the fast &lt;a href=&#34;https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/&#34; target=&#34;_blank&#34;&gt;upcoming shutdown of JCenter&lt;/a&gt;
, a quite popular place to keep FOSS projects&amp;rsquo; binary artifacts. Business is for making money, not for supporting the community that helped the company got to the successful IPO a few months earlier, so the need &amp;ldquo;to streamline the productivity of the JFrog Platform&amp;rdquo; has to be understood.&lt;/p&gt;
&lt;p&gt;As a (positive) side effect, I and Marc Phillip &lt;em&gt;streamlined&lt;/em&gt; our focus to release a stable version of our unified Gradle plugin for publishing projects to Maven Central. &lt;strong&gt;&lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/&#34; target=&#34;_blank&#34;&gt;1.0.0&lt;/a&gt;
&lt;/strong&gt; hit the repository soon after. That version provides an initial set of functionality which should allow the majority of the Gradle projects to publish artifacts to Maven Central (aka The Central Repository).&lt;/p&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;Please note, this is &lt;strong&gt;not&lt;/strong&gt; an article about migration from JCenter to Maven Central, only about migration from the Gradle Nexus Staging Plugin and Nexus Publish Plugin duo to the new, unified &lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/&#34;&gt;Gradle Nexus Publish Plugin&lt;/a&gt;. People switching their projects from JCenter definitely can use the new plugin, but I plan to cover the migration from JCenter in a separate post, but in the meantime you can take a look at &lt;a href=&#34;https://github.com/rwinch/gradle-publish-ossrh-sample&#34;&gt;this sample project&lt;/a&gt;.&lt;/div&gt;

&lt;h2 id=&#34;a-story-of-three-plugins&#34;&gt;A story of three plugins&lt;/h2&gt;
&lt;p&gt;In 2015, &lt;a href=&#34;https://blog.solidsoft.pl/&#34; target=&#34;_blank&#34;&gt;I&lt;/a&gt;
 created &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;
 which was providing - not available earlier for the Gradle users - an ability to close and release staging repositories in Nexus repository manager without touching Nexus UI. It opened an opportunity to manage releasing Gradle projects to Maven Central completely from code (also using a CI server). Over the years, it has been adopted by the various projects and companies &lt;a href=&#34;https://github.com/Codearte/gradle-nexus-staging-plugin/#notable-users&#34; target=&#34;_blank&#34;&gt;across the globe&lt;/a&gt;
, however there was a small problem. Due to technical limitations in the publishing process in Gradle, it was required to use heuristics to track implicitly created staging repositories, what often failed for multiple repositories in a given state. The situation became even worse when Travis changed its network architecture in late 2019 and the majority of releases started to fail.&lt;br /&gt;
Here, &lt;a href=&#34;https://github.com/marcphilipp/&#34; target=&#34;_blank&#34;&gt;Marc Philipp&lt;/a&gt;
 entered the stage who created &lt;a href=&#34;https://github.com/marcphilipp/nexus-publish-plugin&#34; target=&#34;_blank&#34;&gt;Nexus Publish Plugin&lt;/a&gt;
 which was enriching the publishing mechanism in Gradle to explicitly create staging repositories and publish (upload) artifacts directly to it.&lt;/p&gt;
&lt;p&gt;Those two plugins nicely worked together, providing a reliable way to handle publishing artifacts to Maven Central (and to other Nexus instances in general). However, the need of using two plugins was very often confusing for users. As a result, an idea to create one plugin mixing the aforementioned capabilities emerged. It took us some time, but sunsetting JCenter motivated us to intensify work and &lt;strong&gt;&lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/&#34; target=&#34;_blank&#34;&gt;Gradle Nexus Publish Plugin 1.0.0&lt;/a&gt;
&lt;/strong&gt; has been released in February 2021 as joint effort.&lt;/p&gt;
&lt;h2 id=&#34;migration-guide&#34;&gt;Migration guide&lt;/h2&gt;
&lt;p&gt;The new plugin was intended as a natural successor of the aforementioned two plugins. We tried to keep the syntax unchanged where feasible. As a result a migration guide - in the majority of cases - is straightforward.&lt;/p&gt;
&lt;h3 id=&#34;plugins&#34;&gt;Plugins&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start with the plugins declaration.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;plugins {   //old
    id &amp;quot;io.codearte.nexus-staging&amp;quot; version &amp;quot;0.22.0&amp;quot;
    id &amp;quot;de.marcphilipp.nexus-publish&amp;quot; version &amp;quot;0.4.0&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The old two has to be replaced with the new one:&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-gradle&#34; data-lang=&#34;gradle&#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;s2&#34;&gt;&amp;#34;io.github.gradle-nexus.publish-plugin&amp;#34;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1.0.0&amp;#34;&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;h3 id=&#34;configuration---simple-case&#34;&gt;Configuration - simple case&lt;/h3&gt;
&lt;p&gt;If only default plugins settings were used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nexusStaging {   //old
    packageGroup = &amp;quot;com.example.mycompany.myproject&amp;quot;
    stagingProfileId = &amp;quot;yourStagingProfileId&amp;quot;
}

nexusPublishing {
    repositories {
        sonatype()
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;packageGroup&lt;/code&gt; and &lt;code&gt;stagingProfileId&lt;/code&gt; have to be moved to the &lt;code&gt;nexusPublishing&lt;/code&gt; section:&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;/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-gradle&#34; data-lang=&#34;gradle&#34;&gt;&lt;span class=&#34;n&#34;&gt;nexusPublishing&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;packageGroup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;com.example.mycompany.myproject&amp;#34;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//defaults to &amp;#39;project.group&amp;#39;
&lt;/span&gt;&lt;span class=&#34;c1&#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;sonatype&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//custom repository name - &amp;#39;sonatype&amp;#39; is pre-configured
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;                     &lt;span class=&#34;c1&#34;&gt;//for Sonatype Nexus (OSSRH) which is used for The Central Repository
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;stagingProfileId&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;yourStagingProfileId&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//can reduce execution time by even 10 seconds
&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;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;Due to the improved support for releasing to multiple Nexus instances in one project, the credentials configuration has changed in non-backward compatible way. gradle-nexus-staging-plugin by default was using &lt;code&gt;nexusUsername&lt;/code&gt; and &lt;code&gt;nexusPassword&lt;/code&gt; project properties which could be reused by nexus-publish-plugin. With the new plugin it has been unified to &lt;code&gt;sonatypeUsername&lt;/code&gt; and &lt;code&gt;sonatypePassword&lt;/code&gt;, where a prefix reflects a name of a configured repository (here &lt;code&gt;sonatype&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&#34;configuration---more-customizations&#34;&gt;Configuration - more customizations&lt;/h3&gt;
&lt;p&gt;Having more customizations in place:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;//majority of the properties is optional, you might just don&#39;t have them in your project       //old
nexusStaging {
    packageGroup = &amp;quot;com.example.mycompany.myproject&amp;quot;
    stagingProfileId = &amp;quot;yourStagingProfileId&amp;quot;

    //by default project properties &#39;nexusUsername&#39; and &#39;nexusPassword&#39; are used
    username = project.findProperty(&amp;quot;...&amp;quot;)   
    password = project.findProperty(&amp;quot;...&amp;quot;)
    numberOfRetries = 40
    delayBetweenRetriesInMillis = 3000
}

nexusPublishing {
    repositories {
        sonatype {
            //by default value from above &#39;nexusStaging&#39; closure is used (alternative project properties &#39;sonatypeUsername&#39; and &#39;sonatypePassword&#39;)
            username = project.findProperty(&amp;quot;...&amp;quot;)  
            password = project.findProperty(&amp;quot;...&amp;quot;)
        }
    }

    clientTimeout = Duration.ofSeconds(300)
    connectTimeout = Duration.ofSeconds(60)

}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;they also have to be moved to the &lt;code&gt;nexusPublishing&lt;/code&gt; closure:&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;/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-gradle&#34; data-lang=&#34;gradle&#34;&gt;&lt;span class=&#34;n&#34;&gt;nexusPublishing&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;packageGroup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;com.example.mycompany.myproject&amp;#34;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;//defaults to &amp;#39;project.group&amp;#39;
&lt;/span&gt;&lt;span class=&#34;c1&#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;sonatype&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;   &lt;span class=&#34;c1&#34;&gt;//or custom repository name
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;stagingProfileId&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;yourStagingProfileId&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;//can reduce execution time by even 10 seconds
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
            &lt;span class=&#34;c1&#34;&gt;//defaults to project properties &amp;#39;sonatypeUsername&amp;#39; and &amp;#39;sonatypePassword&amp;#39;, where &amp;#39;sonatype&amp;#39; is name of configured repository
&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;n&#34;&gt;username&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;project&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  
            &lt;span class=&#34;n&#34;&gt;password&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;project&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;findProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;...&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;n&#34;&gt;clientTimeout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Duration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ofSeconds&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;connectTimeout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Duration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ofSeconds&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;transitionCheckOptions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;maxRetries&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;delayBetween&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&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;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;Duration&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ofMillis&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3000&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;It is worth to mention - in addition to changed default project properties to read credentials from - that the configuration of retries during the close and release attempts has been renamed to &lt;code&gt;transitionCheckOptions&lt;/code&gt; with more modern duration types.&lt;/p&gt;
&lt;h3 id=&#34;tasks---simple-case&#34;&gt;Tasks - simple case&lt;/h3&gt;
&lt;p&gt;At the task level - due to support for multiple repositories - the following common execution:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./gradlew publish closeAndReleaseRepository        //old
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;has to be enhanced with a repository name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To short the second task name slightly, there is still a simplified variant &lt;code&gt;closeAndReleaseStagingRepository&lt;/code&gt; which closes and releases the staging repositories in all configured Nexus instances (one by default).&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;For the new projects, using &lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/&#34; target=&#34;_blank&#34;&gt;gradle-nexus-publish-plugin&lt;/a&gt;
 is the only logical choice&lt;/strong&gt;. The main authors&amp;rsquo; effort will be put in its development. The whole process of onboarding to Soantype Nexus (together with a sample project) is nicely described by &lt;a href=&#34;https://github.com/rwinch/gradle-publish-ossrh-sample&#34; target=&#34;_blank&#34;&gt;Rob Winch&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;For the projects migrating from releasing from JCenter to Maven Central - I plan to cover it in a separate blog post - it also holds.&lt;/p&gt;
&lt;p&gt;I hope this short blog post clearly showed that migration - in the majority of cases - from the old due-solution should be trouble-free. All the projects should - eventually - migrate to the new plugin.&lt;/p&gt;
&lt;p&gt;For existing projects, temporary staying with the already working (old) duo-solution also is an acceptable choice. The migration might wait for the next big configuration change in the project (e.g. a migration to Gradle 7). The new plugin is less mature and there might be some features missing. In that case, however, please &lt;a href=&#34;https://github.com/gradle-nexus/publish-plugin/issues&#34; target=&#34;_blank&#34;&gt;let us know&lt;/a&gt;
!&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/thedigitalartist-202249/&#34;&gt;TheDigitalArtist&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/photos/birds-flock-flying-nature-4261965/&#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/2021/unified-releasing-gradle-2021-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2021/unified-releasing-gradle-2021-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>gradle</category>
            
          
            
              <category>maven-central</category>
            
          
            
              <category>my-tools</category>
            
          
            
              <category>nexus-staging-plugin</category>
            
          
            
              <category>nexus-publish-plugin</category>
            
          
            
              <category>GNPP</category>
            
          
            
              <category>jcenter</category>
            
          
            
              <category>bintray</category>
            
          
            
              <category>migration</category>
            
          
        
        
          
            
              <category>Tools</category>
            
          
        
        
      </item>
      
      <item>
        <title>Simpler and safer artifact signing on CI server with Gradle</title>
        <link>https://blog.solidsoft.pl/2020/06/03/simpler-and-safer-artifact-signing-on-ci-server-with-gradle/</link>
        <pubDate>Wed, 03 Jun 2020 10:00:00 +0200</pubDate>
        
        <atom:modified>Wed, 03 Jun 2020 10:00:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/06/03/simpler-and-safer-artifact-signing-on-ci-server-with-gradle/</guid>
        <description>Check out how to simplify your Gradle configuration for artifact signing (and releasing) on a CI server (and along the way avoid CVE-2020-13165 in Gradle &amp;lt;6.5).
  
TL;TR. To get just the short migration recipe, jump to the second to last section. Releasing from a CI server Testing, build and releasing (deploying) from CI servers has been more and more popular in the recent years. In many organizations this is something natural.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Check out how to simplify your Gradle configuration for artifact signing (and releasing) on a CI server (and along the way avoid CVE-2020-13165 in Gradle &amp;lt;6.5).&lt;/p&gt;
&lt;/blockquote&gt;


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

&lt;p&gt;&lt;br /&gt;&lt;br /&gt;
&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34; data-dir=&#34;ltr&#34;&gt;&lt;strong&gt;TL;TR&lt;/strong&gt;. To get just the short migration recipe, jump to the &lt;a href=&#34;#simpler-and-safer-artifact-signing&#34;&gt;second to last section&lt;/a&gt;.&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;releasing-from-a-ci-server&#34;&gt;Releasing from a CI server&lt;/h2&gt;
&lt;p&gt;Testing, build and releasing (deploying) from CI servers has been more and more popular in the recent years. In many organizations this is something natural. Also multiple FOSS project has started to publish their artifacts to Maven Central (aka The Central Repository) directly from a CI server. This is very nice, as it reduces time to market (or time to release), makes the process less error-prone and removes all the release-related legwork (&lt;code&gt;git commit -m &amp;quot;Trigger release&amp;quot; -m &amp;quot;[#DO_RELEASE]&amp;quot; --allow-empty &amp;amp;&amp;amp; git push&lt;/code&gt; in many cases can be just enough!).&lt;/p&gt;
&lt;p&gt;However, there are also drawbacks of that approach. The CI server - especially in non enterprise environments - is very often a place which has access to all secrets needed to sign and release the software (e.g. the private signing PGP key or the artifacts repository credentials). A data breach from one of the popular SaaS CI servers could open an opportunity to inject malicious code into various popular FOSS projects&amp;hellip; Luckily, usually it works fine (or is not actively exploited), however, I cannot resist to mention &lt;a href=&#34;https://blog.travis-ci.com/2016-11-23-security-vulnerability-environment-variables/&#34; target=&#34;_blank&#34;&gt;the vulnerability&lt;/a&gt;
 I have found in Travis back in 2016 which was causing - in some circumstances - to have the build secrets available to anybody in plain text :-/.&lt;/p&gt;
&lt;p&gt;There are also some other possible vectors of attack, however, in that article I would like to focus on mitigating the risk of revealing secrets in the system logs, which very often - especially in the FOSS projects - are publicly available.&lt;/p&gt;
&lt;h2 id=&#34;gradle-and-security&#34;&gt;Gradle and security&lt;/h2&gt;
&lt;p&gt;Recently, it is pretty visible that the Gradle team takes security very seriously. In January 2020, the HTTP access for Gradle services has been disabled. In February, the verification of Gradle Wrapper was &lt;a href=&#34;https://blog.gradle.org/gradle-wrapper-checksum-verification-github-action&#34; target=&#34;_blank&#34;&gt;added&lt;/a&gt;
 as an official action for GitHub Actions. A few weeks later, Gradle 6.2 &lt;a href=&#34;https://docs.gradle.org/6.2/release-notes.html#dependency-verification&#34; target=&#34;_blank&#34;&gt;introduced&lt;/a&gt;
 a built-in ability to verify the checksums (and signatures) of the artifacts used in the build process. Starting with Gradle 6.4, using the &lt;code&gt;DEBUG&lt;/code&gt; log statement clearly states that it may reveal some secrets and shouldn&amp;rsquo;t be used in non private builds.&lt;/p&gt;
&lt;p&gt;Just released Gradle 6.5 fixes another vulnerability (&lt;a href=&#34;https://github.com/gradle/gradle/security/advisories/GHSA-ww7h-4fx5-8c2j&#34; target=&#34;_blank&#34;&gt;CVE-2020-13165&lt;/a&gt;
) which I discovered and reported to the Gradle team recently. The earlier Gradle versions might reveal the passphrase for a PGP key used to sign published artifacts, if gpg2 was used together with the &lt;code&gt;INFO&lt;/code&gt; log level. This mostly affects CI servers, especially those with the limited (and faulty) secret masking.&lt;/p&gt;
&lt;p&gt;I will use CVE-2020-13165 as an excuse to present the simpler artifact signing in Gradle, designed especially for CI servers, which unfortunately is very little-known (an order of magnitude less results on GitHub that a regular &lt;code&gt;useGpgCmd()&lt;/code&gt; for GnuPG 2).&lt;/p&gt;
&lt;h2 id=&#34;pgp-artifact-signing-in-gradle&#34;&gt;PGP artifact signing in Gradle&lt;/h2&gt;
&lt;p&gt;Originally, Gradle was using the Bouncy Castle library to deal with keys stored in the GnuPG 1 format. However, GnuPG 2 changed the way how keys are kept and their handling has been delegated to a gpg2 process spawn during the Gradle build (which also made it possible to use a system defined gpg-agent program). It was not very convenient on a CI server, where the key usually had to be kept in the encrypted way in the code repository, decrypted with some shell magic during a build using the provided secret and imported into the locally stoped keyring. The procedure was not fully CI server agnostic. In addition, that file could persist on a file system, which especially combined with not using a passphrase could generate some security risk.&lt;/p&gt;
&lt;h2 id=&#34;simpler-and-safer-artifact-signing&#34;&gt;Simpler and safer artifact signing&lt;/h2&gt;
&lt;p&gt;In April 2019, Gradle 5.4 introduced a very nice feature which unfortunately was not even mentioned in the release notes :-(. &lt;a href=&#34;https://github.com/marcphilipp/&#34; target=&#34;_blank&#34;&gt;Marc Philipp&lt;/a&gt;
 (who you may know from his work in JUnit 4/5) implemented a &lt;a href=&#34;https://docs.gradle.org/current/userguide/signing_plugin.html#sec:in-memory-keys&#34; target=&#34;_blank&#34;&gt;PGP artifact signing&lt;/a&gt;
 optimized for CI servers. Having that in place remote artifact signing is a piece of cake ;-).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Export the private OpenPGP key intended for the CI environment to the ascii-armored form:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;$ gpg --export-secret-keys --armor KEY_ID &amp;gt; private-ci.key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Create two secret environment variables on a CI server:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;na&#34;&gt;ORG_GRADLE_PROJECT_signingKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;lt;content of exported private key file&amp;gt;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ORG_GRADLE_PROJECT_signingPassword&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;lt;key passphrase&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Enable in-memory signatory provider:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gradle&#34; data-lang=&#34;gradle&#34;&gt;&lt;span class=&#34;n&#34;&gt;signing&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;useInMemoryPgpKeys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;findProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;signingKey&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;findProperty&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;signingPassword&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;sign&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;/div&gt;&lt;p&gt;And that&amp;rsquo;s all. Isn&amp;rsquo;t is simple?&lt;/p&gt;
&lt;p&gt;Btw, that mechanism &lt;a href=&#34;https://docs.gradle.org/current/userguide/signing_plugin.html#sec:subkeys&#34; target=&#34;_blank&#34;&gt;supports&lt;/a&gt;
 also using subkeys (which provide &lt;a href=&#34;https://wiki.debian.org/Subkeys&#34; target=&#34;_blank&#34;&gt;some benefits&lt;/a&gt;
).&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;As a bonus to simplicity of using the in-memory signatory provider, that method prevents aforementioned passphrase revealing, even in Gradle &amp;lt;6.5. Therefore, it hard to find a good argument against migration :).&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;Lead photo by &lt;a href=&#34;https://pixabay.com/users/stevepb-282134/&#34;&gt;Steve Buissinne&lt;/a&gt;, published in &lt;a href=&#34;https://pixabay.com/photos/padlock-lock-chain-key-security-597495/&#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/gradle-artifact-signing-thumbnail.jpg" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/gradle-artifact-signing-ratio.jpg" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>gradle</category>
            
          
            
              <category>security</category>
            
          
            
              <category>vulnerability</category>
            
          
            
              <category>openpgp</category>
            
          
            
              <category>ci</category>
            
          
            
              <category>cd</category>
            
          
            
              <category>releasing</category>
            
          
            
              <category>foss</category>
            
          
        
        
          
            
              <category>Tools</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>Migrating Spock 1.3 tests to Spock 2.0</title>
        <link>https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/</link>
        <pubDate>Thu, 02 Jan 2020 10:00:00 +0200</pubDate>
        
        <atom:modified>Wed, 11 Mar 2020 22:21:00 +0200</atom:modified>
        <guid>https://blog.solidsoft.pl/2020/01/02/migrating-spock-1.3-tests-to-spock-2.0/</guid>
        <description>Get know what you can expect from Spock 2.0 M2 (based on JUnit 5), how to migrate to it in Gradle and Maven, and why it is important to report spotted problems :).
 Important note. I definitely do not encourage you to migrate your serious real-life project to Spock 2.0 M1 or M2 for good! This is the first (pre-)release of 2.x with not finalized API, intended to gather user feedback related to internal Spock migration to JUnit Platform.</description>
        <content:encoded>&lt;blockquote&gt;
&lt;p&gt;Get know what you can expect from Spock 2.0 M2 (based on JUnit 5), how to migrate to it in Gradle and Maven, and why it is important to report spotted problems :).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt;. I definitely do &lt;strong&gt;not&lt;/strong&gt; encourage you to migrate your serious real-life project to Spock 2.0 M1 or M2 for good! This is the first (pre-)release of 2.x with not finalized API, intended to gather user feedback related to internal Spock migration to JUnit Platform.&lt;/p&gt;
&lt;p&gt;This blog post arose to try to encourage you to make a &lt;strong&gt;test&lt;/strong&gt; migration of your projects to Spock 2.0, see what started to fail, fix it (if caused by your tests) or report it (if it is a regression in Spock itself). As a result - at the Spock side - it will be possible to improve the code base before Milestone 2. The benefit for you - in addition to contribution to the FOSS project :-) - will be awareness of required changes (kept in a side branch) and readiness to migration once Spock 2.0 is more mature.&lt;/p&gt;
&lt;p&gt;I plan to update this blog post when the next Spock 2 versions are available.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updated 2020-02-10 to cover Spock 2.0 M2 with a dedicated Groovy 3 support.&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;Updated 2020-03-05&lt;/strong&gt;. New point about dealing with &lt;code&gt;NoClassDefFoundError: LambdaExpression&lt;/code&gt;.&lt;br /&gt;
&lt;strong&gt;Updated 2020-03-11&lt;/strong&gt;. Detecting &amp;ldquo;no tests&amp;rdquo; issue with multiple test tasks.&lt;/p&gt;


&lt;figure &gt;
  
    &lt;img src=&#34;https://blog.solidsoft.pl/images/posts/2020/spock2-junit5-logo-grey-horiz.png&#34; alt=&#34;Spock 2 &amp;#43; JUnit 5 with Gradle and Maven&#34; style=&#34;width:;height:;&#34;/&gt;
  
  
&lt;/figure&gt;

&lt;h2 id=&#34;powered-by-junit-platform&#34;&gt;Powered by JUnit Platform&lt;/h2&gt;
&lt;p&gt;The main change in Spock 2.0 M1 is migration to JUnit 5 (precisely speaking to execute tests with JUnit Platform 1.5, part of JUnit 5 instead of the JUnit 4 runner API). This is very convenient as Spock tests should be automatically recognized and executed everywhere the JUnit Platform is supported (IDEs, build tools, quality tools, etc.). In addition, the features provided by the platform itself (such as parallel test execution) should be (eventually) available also for Spock.&lt;/p&gt;
&lt;h3 id=&#34;gradle&#34;&gt;Gradle&lt;/h3&gt;
&lt;p&gt;To bring Spock 2 to a Gradle project it is needed to bump the Spock version:&lt;/p&gt;
&lt;div class=&#34;highlight&#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;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and activate tests execution by JUnit Platform:&lt;/p&gt;
&lt;div class=&#34;highlight&#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;test&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;useJUnitPlatform&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;/div&gt;&lt;p&gt;&lt;strong&gt;Update 20200218&lt;/strong&gt;. It is enough, but as Tomek Przybysz reminded in his comment, Gradle by default doesn&amp;rsquo;t fail if not tests are found. It may lead to a situation when after making that switch a build finished successfully, giving a false sense of security, while there are no tests executed at all.&lt;br /&gt;
It is a &lt;a href=&#34;https://github.com/gradle/gradle/issues/7452&#34; target=&#34;_blank&#34;&gt;known issue&lt;/a&gt;
 in Gradle, not only limited to Spock. As a workaround the aforementioned configuration might to extended to:&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;/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;test&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;afterSuite&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&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;-&amp;gt;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parent&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;k&#34;&gt;if&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;testCount&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&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;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;No tests were found. Failing the build&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;Or the more sophisticated version for multiple test tasks (e.g. unit/integration and functional):&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;/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;tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;withType&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Test&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configureEach&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;testTask&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testTask&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;configure&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;useJUnitPlatform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;afterSuite&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&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;-&amp;gt;&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;parent&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;k&#34;&gt;if&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;testCount&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&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;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;No tests were found. Failing the build&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;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;h3 id=&#34;maven&#34;&gt;Maven&lt;/h3&gt;
&lt;p&gt;With Maven on the other hand, it is still required to switch to a never Spock version:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.spockframework&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spock-core&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0-M2-groovy-2.5&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but that is all. The Surefire plugin (if you use version 3.0.0+) executes JUnit Platform tests by default, if junit-platform-engine (a transitive dependency of Spock 2) is found.&lt;/p&gt;
&lt;p&gt;The minimal working project for Gradle i Maven is available from &lt;a href=&#34;https://github.com/szpak/code-examples-and-poc/tree/master/spock2-migration-gradle-maven&#34; target=&#34;_blank&#34;&gt;GitHub&lt;/a&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;other-changes&#34;&gt;Other changes&lt;/h2&gt;
&lt;p&gt;Having such big change as migration to JUnit Platform, number of other changes in Spock 2.0 M1 is limited, to make finding a reason of potential regressions a little bit easier. As a side effects of the migration itself, the required Java version is 8.&lt;/p&gt;
&lt;p&gt;In addition, all parameterized tests are (finally) &amp;ldquo;unrolled&amp;rdquo; automatically. That is great, however, currently there is &lt;a href=&#34;https://github.com/spockframework/spock/issues/967&#34; target=&#34;_blank&#34;&gt;no way&lt;/a&gt;
 to &amp;ldquo;roll&amp;rdquo; particular tests, as known from &lt;a href=&#34;https://github.com/szpak/spock-global-unroll&#34; target=&#34;_blank&#34;&gt;spock-global-unroll&lt;/a&gt;
 for Spock 1.x.&lt;/p&gt;
&lt;p&gt;Some other changes (such as temporarily disabled &lt;code&gt;SpockReportingExtension&lt;/code&gt;) can be found in the &lt;a href=&#34;https://github.com/spockframework/spock/blob/master/docs/release_notes.adoc#20-m1-31122019&#34; target=&#34;_blank&#34;&gt;release notes&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;More (possibly breaking) changes are expected to be merged into Milestone 2.&lt;/p&gt;
&lt;h2 id=&#34;issue-with-junit-4-rules&#34;&gt;Issue with JUnit 4 rules&lt;/h2&gt;
&lt;p&gt;The tests using JUnit 4 &lt;code&gt;@Rule&lt;/code&gt;s (or &lt;code&gt;@ClassRule&lt;/code&gt;s) are expected to fail with an error message suggesting that requested objects were not created/initialized before a test (e.g. &lt;code&gt;NullPointerException&lt;/code&gt; or &lt;code&gt;IllegalStateException: the temporary folder has not yet been created&lt;/code&gt;) or were not verified/cleaned up after it (e.g. soft assertions from AssertJ). The Rules API is no longer supported by JUnit Platform. However, to make the migration easier (&lt;code&gt;@TemporaryFolder&lt;/code&gt; is probably very often used in Spock-based integration tests), there is a dedicated &lt;code&gt;spock-junit4&lt;/code&gt; which internally wraps JUnit 4 rules into the Spock extensions and executes it in the Spock&amp;rsquo;s lifecycle. As it is implemented as a global extension, the only required thing to add is another dependency. In Gradle:&lt;/p&gt;
&lt;div class=&#34;highlight&#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;testImplementation&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-junit4:2.0-M2-groovy-2.5&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or in Maven:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.spockframework&lt;span class=&#34;nt&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spock-junit4&lt;span class=&#34;nt&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0-M2-groovy-2.5&lt;span class=&#34;nt&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nt&#34;&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class=&#34;nt&#34;&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That makes migration easier, but it is good to think about a switch to native Spock counterpart, if available/feasible.&lt;/p&gt;
&lt;h2 id=&#34;groovy-3-support&#34;&gt;Groovy 3 support&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Updated 2020-02-10&lt;/strong&gt;. The whole Groovy 3 section was added to cover changes in Spock 2.0 Milestone 2.&lt;/p&gt;
&lt;p&gt;After my complains about runtime failure when Spock 2.0 M1 is used with Groovy 3.0, I rolled up my sleeves to check how hard would it be to provide that support. It took me some time, however, after after &lt;a href=&#34;https://github.com/spockframework/spock/pull/1075&#34; target=&#34;_blank&#34;&gt;23 (multiple times rebased) commits&lt;/a&gt;
, constructive feedback from other Spock contributors and fruitful discussion with the Groovy developers, the support for Groovy 3 has been merged and is available as the main feature of Spock 2.0 M2, released right after Groovy 3.0.0 final.&lt;/p&gt;
&lt;p&gt;To use Spock 2.0 M2 with Groovy 3 it is enough to just use the &lt;code&gt;spock-*-2.0-M1&lt;/code&gt; artifacts with the &lt;code&gt;-groovy-3.0&lt;/code&gt; suffix.&lt;/p&gt;
&lt;p&gt;It is worth noting that Groovy 3 is not backward compatible with Groovy 2. To keep one Spock codebase, there is a layer of abstraction in Spock to allow to build (and use) the project with both Groovy 2 and 3. As a result, an extra artifact &lt;code&gt;spock-groovy2-compat&lt;/code&gt; is (automatically) used in projects with Groovy 2. It is &lt;strong&gt;very important&lt;/strong&gt; to &lt;strong&gt;do not mix&lt;/strong&gt; the &lt;code&gt;spock-*-2.x-groovy-2.5&lt;/code&gt; artifacts with the &lt;code&gt;groovy-*-3.x&lt;/code&gt; artifacts on a classpath. This may result in weird runtime errors.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m really happy that developers can immediately start testing the new Groovy 3.0.0 with Spock 2.0-M2 in their projects. In addition, as Spock is quite important (and low level) project in the Groovy ecosystem, it was nice to confirm that Groovy 3 works properly with it (and to report - along the way - a few minor detected issues to make Groovy even better ;-) ).&lt;/p&gt;
&lt;h2 id=&#34;other-issues-and-limitations&#34;&gt;Other issues and limitations&lt;/h2&gt;
&lt;h3 id=&#34;noclassdeffounderror-lambdaexpression-with-groovy-25&#34;&gt;NoClassDefFoundError: LambdaExpression with Groovy 2.5&lt;/h3&gt;
&lt;p&gt;Using Spock 2.0-M2 with Groovy 2.5 it is possible to get the following errors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java.lang.NoClassDefFoundError: org/codehaus/groovy/ast/expr/LambdaExpression
java.lang.NoClassDefFoundError: org/codehaus/groovy/ast/expr/MethodReferenceExpression
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As Groovy 2 and 3 are not backward compatible, there is an abstraction layer which allows to build (and use) Spock with two different Groovy versions. However, to achieve that it was necessary to add dummy &lt;code&gt;LambdaExpression&lt;/code&gt; and &lt;code&gt;MethodReferenceExpression&lt;/code&gt; in an extra Spock dependency &lt;code&gt;spock-groovy2-compat&lt;/code&gt; used in the &lt;code&gt;-groovy-2.5&lt;/code&gt; variant.&lt;/p&gt;
&lt;p&gt;It is automatically fetched by Maven/Gradle for &lt;code&gt;spock-core&lt;/code&gt;, but in the situation you disabled transitive dependency for Spock:&lt;/p&gt;
&lt;div class=&#34;highlight&#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;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&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;transitive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&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;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;div class=&#34;highlight&#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;@Grab&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5;transitive=false&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;they are missing. In that case you might want to add &lt;code&gt;spock-groovy2-compat&lt;/code&gt; dependency explicitly, e.g.:&lt;/p&gt;
&lt;div class=&#34;highlight&#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;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&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;transitive&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-groovy2-compat:2.0-M2-groovy-2.5&amp;#39;&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;/div&gt;&lt;p&gt;or exclude just Groovy dependencies (not all of them):&lt;/p&gt;
&lt;div class=&#34;highlight&#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;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;testImplementation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;org.spockframework:spock-core:2.0-M2-groovy-2.5&amp;#39;&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;exclude&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;group:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;org.codehaus.groovy&amp;#39;&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;/div&gt;&lt;p&gt;Thanks to &lt;a href=&#34;https://twitter.com/paulk_asert&#34; target=&#34;_blank&#34;&gt;Paul King&lt;/a&gt;
 for suggesting that point.&lt;/p&gt;
&lt;h3 id=&#34;missing-groovy-3-support&#34;&gt;&lt;del&gt;Missing Groovy 3 support&lt;/del&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Updated 2020-02-10&lt;/strong&gt;. This section originally refereed to limitations of Spock 2.0 M1. Milestone 2 supports Groovy 3.&lt;/p&gt;
&lt;span style=&#34;opacity: 0.6&#34;&gt;&lt;p&gt;Spock 2.0 M1 is compiled and tested only with Groovy 2.5.8. As of M1, execution with Groovy 3.0 is currently blocked at runtime. Unfortunately, instead of a clear error message about incompatible Groovy version there is only a very cryptic error message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Could not instantiate global transform class org.spockframework.compiler.SpockTransform specified at
jar:file:/.../spock-core-2.0-M1-groovy-2.5.jar!/META-INF/services/org.codehaus.groovy.transform.ASTTransformation
because of exception java.lang.reflect.InvocationTargetException
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is already &lt;a href=&#34;https://github.com/spockframework/spock/issues/1067&#34;&gt;reported&lt;/a&gt; and should be enhanced by M2.&lt;/p&gt;
&lt;/span&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 here to expand outdated information about lack of Groovy 3 support in Spock 2.0-M1
  &lt;/button&gt;
  &lt;div class=&#34;expand__content&#34;&gt;
    &lt;span style=&#34;opacity: 0.6&#34;&gt;Sadly, the limitation to Groovy 2.5 only, reduces potential feedback from people experimenting with Groovy 3 which is pretty close to a stable version (RC2 as of 2019/2020). It’s especially inconvenient as many Spock tests just work with Groovy 3 (of course there are some corner cases). There is a chance that Spock 2 before getting final will be adjusted to changes in Groovy 3 or at least the aforementioned hard limitation will be lifted. In the meantime, it is required to test Groovy 3 support with the snapshot version - &lt;code&gt;2.0-groovy-2.5-SNAPSHOT&lt;/code&gt; (which has that check disabled).&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;The action to do after reading this post is simple. Try to &lt;em&gt;temporarily&lt;/em&gt; play with Spock 2.0 M2 in your projects and &lt;a href=&#34;https://github.com/spockframework/spock/issues&#34; target=&#34;_blank&#34;&gt;report&lt;/a&gt;
 any spotted issues, to help make Spock 2.0 even better :).&lt;/p&gt;
</content:encoded>
        <dc:creator>Marcin Zajączkowski</dc:creator>
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock2-junit5-logo-grey-horiz.png" medium="image"><media:title type="html">featured image</media:title></media:content>
        
        <media:content url="https://blog.solidsoft.pl/images/posts/2020/spock2-junit5-logo-grey-horiz-ratio.png" medium="image"><media:title type="html">meta image</media:title></media:content>
        
          
            
              <category>gradle</category>
            
          
            
              <category>junit5</category>
            
          
            
              <category>maven</category>
            
          
            
              <category>migration</category>
            
          
            
              <category>spock</category>
            
          
            
              <category>spock2</category>
            
          
            
              <category>spock-2.0</category>
            
          
            
              <category>testing</category>
            
          
            
              <category>tests</category>
            
          
        
        
          
            
              <category>Tools</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>