September 15, 2015

Groovy Goodness: Exclude Transitive Dependencies With Grape

The built-in dependency mechanism in Groovy is Grape. With Grape we can define dependencies in our code and Groovy will download them and make them available when we run our Groovy application. The easiest way to use it is with the @Grab annotation with a dependency as the value. If we want to exclude a transitive dependency we use the @GrabExclude annotation. We must specify the attributes group and module of the annotation with the dependency we want to exclude. An alternative syntax is a shorthand version where the group and module are combined into a single String value separated by a colon (:).

In the following Groovy script we have a very simple Spring application with Java (Groovy) based configuration. So we need a dependency on the spring-context module. But we don't want to use the standard Spring logging. Spring used Apache Commons logging and we want to replace it with an SLF4J API implementation: Logback. So we use the @GrabExclude annotation to exclude the commons logging dependency. And we add two extra dependencies to replace it: org.slf4j:jcl-over-slf4j and ch.qos.logback:logback-classic.

package com.mrhaki

// Exclude the commons-logging dependency 
// as Spring transitive dependency.
@GrabExclude(group = 'commons-logging', module='commons-logging') // Or 'commons-logging:commons-logging'
// Replace commons-logging with SLF4J 
// implementation Logback.
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.AnnotationConfigApplicationContext

// Define Spring Java (Groovy) configuration class.
class AppConfig {

    // Simple bean is a String.
    String obvious() {
        'Groovy is gr8!'

// Create new Spring application context and use
// our Groovy configuration class
final ApplicationContext appContext = 
    new AnnotationConfigApplicationContext(AppConfig)

// Check that bean is in application context.
assert appContext.getBean('obvious') == 'Groovy is gr8!'

Written with Groovy 2.4.4.