This page looks best with JavaScript enabled

What happened to Groovy dependencies in Spock 2.0?

 ·  ☕ 3 min read

Spock 2.0(-M3) reduced number of provided Groovy dependencies. If you started to get various Groovy-related ClassNotFoundExceptions after migration and wonder why and what to do, read on.

Historical background

Originally Groovy was just one jar to rule them all. However, in process of time, that jar became bigger and bigger. Groovy 2 was the first version promoting the usage of (several at that time) Groovy modules, as a supplemental to groovy.jar. However the adoption of that approach was slowly and groovy-all remained prevalent in pom.xml and build.gradle files.

What even worse, having some projects use groovy.jar plus some modules (e.g. groovy-json.jar or groovy-xml.jar) while some other preferring good old groovy-all.jar could lead to version clashes as for Maven or Gradle those were independent packages. To avoid that it was quite common to see the defensive Groovy exclusions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<dependencies>
    <dependency>
        <groupId>org.codehaus.gmaven.runtime</groupId>
        <artifactId>YYY</artifactId>
        <version>1.2</version>
        <exclusions>
            <exclusion>
                <groupId>org.codehaus.groovy</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>${groovy.version}</version>
    </dependency>
</dependencies>

and declare all required Groovy dependencies on their own.

Groovy 2.5 switched to the model of Maven’s BOM (Bill Of Materials) where groovy-all isn’t a binary jar itself, but rather has the official Groovy modules as dependencies. Thanks to that, Maven and Gradle have easier to keep the versioning of the particular modules consistent. This holds for Groovy 3 which still provides the groovy-all BOM.

Groovy dependencies in Spock 1.3

Spock 1.2 switched from groovy-all.jar to groovy.jar + modules. Unfortunately due to historical reasons it was a lot of modules:

testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- org.spockframework:spock-core:2.0-M2-groovy-3.0
|    +--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-json:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-nio:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-macro:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-templates:3.0.0
|    |    +--- org.codehaus.groovy:groovy-xml:3.0.0
|    |    |    \--- org.codehaus.groovy:groovy:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-test:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-sql:3.0.0
|    |    \--- org.codehaus.groovy:groovy:3.0.0
|    +--- org.codehaus.groovy:groovy-xml:3.0.0 (*)
|    \--- org.junit.platform:junit-platform-engine:1.5.2
|         ...
...

As a result the following was quite common:

1
2
3
4
5
6
test('org.spockframework:spock-core:1.3-groovy-2.5') {
    exclude group: 'org.codehaus.groovy'    //get rid of all dependant groovy modules
}
test 'org.codehaus.groovy:groovy:2.5.11'    //apply only those needed
test 'org.codehaus.groovy:groovy-json:2.5.11'
test 'org.codehaus.groovy:groovy-templates:2.5.11'

However, it turned out that in fact all those extra modules are not needed internally for spock-core and they were rather provided as a convenience for end users.

Groovy dependencies in Spock 2.0+

Starting with Spock 2.0-M3 the Groovy dependencies were simplified to just groovy.jar. Thanks to that you safe some bandwidth on the initial build (what is well-timed ;-) ) and the CI builds without proper caching take slightly shorter.

testCompileClasspath - Compile classpath for source set 'test'.
+--- org.spockframework:spock-core:2.0-M3-groovy-3.0
|    +--- org.codehaus.groovy:groovy:3.0.4
|    +--- org.junit.platform:junit-platform-engine:1.7.1-M1
|         ...
...

As a downside, after the migration to Spock-2.0-M3+, in rare cases you might get ClassNotFoundException: groovy.sql.Sql, ClassNotFoundException: groovy.json.JsonSlurper or ClassNotFoundException: groovy.util.XmlParser. That error suggest that you use those classes somewhere in your tests, but the corresponding dependency is not declared implicitly in your build configuration (and it’s not accidentally provided by spock-core any longer). The quick fix is to add org.codehaus.groovy:groovy-sql:3.0.X, org.codehaus.groovy:groovy-json:3.0.X or similar explicitly.

P.S. If you bumped into that topic during Spock 1.3 -> 2.0 migration, there is a dedicated migration guide article .

Lead photo by Tumisu, published in Pixabay, Pixabay License.
Share on

Marcin Zajączkowski
WRITTEN BY
Marcin Zajączkowski
Software Craftsman & Software Architect
An experienced architect aiming for high quality solutions. Very engaged in evangelising Software Craftsmanship, Clean Code and Test-Driven Development as a conference speaker and a trainer. A specialist in Continuous Delivery and Continuous Inspection of Code Quality. An enthusiast of Reactive Systems and broadly defined concurrency.

Besides, open source author and contributor, a proud Linux user.


Don't want to use the Utterance bot? Comments can be also placed directly on GitHub.
What's on this Page