DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Top 10 C# Keywords and Features
  • Why and How To Integrate Elastic APM in Apache JMeter
  • Xcode Plugins and Extensions: Enhancing Your Development Experience
  • Transitioning From Groovy to Kotlin for Gradle Android Projects

Trending

  • Failure Handling Mechanisms in Microservices and Their Importance
  • Zero Trust for AWS NLBs: Why It Matters and How to Do It
  • Scaling InfluxDB for High-Volume Reporting With Continuous Queries (CQs)
  • Apache Doris vs Elasticsearch: An In-Depth Comparative Analysis
  1. DZone
  2. Coding
  3. Languages
  4. Groovy Goodness: Adding Extra Methods Using Extension Modules

Groovy Goodness: Adding Extra Methods Using Extension Modules

By 
Hubert Klein Ikkink user avatar
Hubert Klein Ikkink
·
Feb. 04, 13 · Interview
Likes (0)
Comment
Save
Tweet
Share
13.5K Views

Join the DZone community and get the full member experience.

Join For Free

Groovy 2.0 brought us extension modules. An extension module is a JAR file with classes that provide extra methods to existing other classes like in the JDK or third-party libraries. Groovy uses this mechanism to add for example extra methods to the File class. We can implement our own extension module to add new extension methods to existing classes. Once we have written the module we can add it to the classpath of our code or application and all the new methods are immediately available.

We define the new extension methods in helper classes, which are part of the module. We can create instance and static extension methods, but we need a separate helper class for each type of extension method. We cannot mix static and instance extension methods in one helper class. First we create a very simple class with an extension method for the String class. The first argument of the extension method defines the type or class we want the method to be added to. The following code shows the method likeAPirate. The extension method needs to be public and static even though we are creating an instance extension method.

// File: src/main/groovy/com/mrhaki/groovy/PirateExtension.groovy
package com.mrhaki.groovy

class PirateExtension {
    static String likeAPirate(final String self) {
        // List of pirate language translations.
        def translations = [
            ["hello", "ahoy"], ["Hi", "Yo-ho-ho"],
            ['are', 'be'], ['am', 'be'], ['is', 'be'],
            ['the', "th'"], ['you', 'ye'], ['your', 'yer'],
            ['of', "o'"]
        ]
        
        // Translate the original String to a 
        // pirate language String.
        String result = self
        translations.each { translate ->
                result = result.replaceAll(translate[0], translate[1])
        }
        result
    }
}

Next we need to create an extension module descriptor file. In this file we define the name of the helper class, so Groovy will know how to use it. The descriptor file needs to be placed in the META-INF/services directory of our module archive or classpath. The name of the file is org.codehaus.groovy.runtime.ExtensionModule. In the file we define the name of our module, version and the name of the helper class. The name of the helper class is defined with the property extensionClasses:

# File: src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
moduleName = pirate-module
moduleVersion = 1.0
extensionClasses = com.mrhaki.groovy.PirateExtension

Now are extension module is ready. The easiest way to distribute the module is by packaging the code and descriptor file in a JAR file and put it in a artifact repository manager. Other developers can then use build tools like Gradle or Maven to include the extension module in their projects and applications. If we use Gradle to create a JAR file we only needs this small build script:

/ File: build.gradle
apply plugin: 'groovy'

repositories.mavenCentral()

dependencies {
    // Since Gradle 1.4 we don't use the groovy configuration
    // to define dependencies. We can simply use the
    // compile and testCompile configurations.
    compile 'org.codehaus.groovy:groovy-all:2.0.6'
}

Now we can invoke $ gradle build and we got ourselves an extension module.

Let's add a test for our new extension method. Because we use Gradle the test classpath already will contain our extension module helper class and descriptor file. In our test we can simply invoke the method and test the results. We are going to use Spock to write a simple specification:

// File: src/test/groovy/com/mrhaki/groovy/PirateExtensionSpec.groovy
package com.mrhaki.groovy

import spock.lang.Specification

class PirateExtensionSpec extends Specification {

    def "likeAPirate method should work as instance method on a String value"() {
        given:
        final String originalText = "Hi, Groovy is the greatest language of the JVM."

        expect:
        originalText.likeAPirate() == "Yo-ho-ho, Groovy be th' greatest language o' th' JVM."
    }

}

We add the dependency to Spock in our Gradle build file:

/ File: build.gradle
apply plugin: 'groovy'

repositories.mavenCentral()

dependencies {
    // Since Gradle 1.4 we don't use the groovy configuration
    // to define dependencies. We can simply use the
    // compile and testCompile configurations.
    compile 'org.codehaus.groovy:groovy-all:2.0.6'

    testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
}

We can run $ gradle test to run the Spock specification and test our new extension method.

To add a static method to an existing class we need to add an extra helper class to our extension module and an extra property to our descriptor file to register the helper class. The first argument of the extension method define the type we want to add a static method to. In the following helper class we add the extension method talkLikeAPirate() to the String class.

/ File: src/main/groovy/com/mrhaki/groovy/PirateStaticExtension.groovy
package com.mrhaki.groovy

class PirateStaticExtension {
    static String talkLikeAPirate(final String type) {
        "Arr, me hearty,"
    }

We change the descriptor file and add the staticExtensionClasses property:

# File: src/main/resources/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
moduleName = pirate-module
moduleVersion = 1.0
extensionClasses = com.mrhaki.groovy.PirateExtension
staticExtensionClasses = com.mrhaki.groovy.PirateStaticExtension

In our Spock specification we add an extra test for our new static method talkLikeAPirate() on the String class:

// File: src/test/groovy/com/mrhaki/groovy/PirateExtensionSpec.groovy
package com.mrhaki.groovy

import spock.lang.Specification

class PirateExtensionSpec extends Specification {

    def "likeAPirate method should work as instance method on a String value"() {
        given:
        final String originalText = "Hi, Groovy is the greatest language of the JVM."

        expect:
        originalText.likeAPirate() == "Yo-ho-ho, Groovy be th' greatest language o' th' JVM."
    }

    def "talkLikeAPirate method should work as static method on String class"() {
        expect:
        "Arr, me hearty, Groovy rocks!" == String.talkLikeAPirate() + " Groovy rocks!"
    }

}

Written with Groovy 2.1





 

Groovy (programming language) Extension method

Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Top 10 C# Keywords and Features
  • Why and How To Integrate Elastic APM in Apache JMeter
  • Xcode Plugins and Extensions: Enhancing Your Development Experience
  • Transitioning From Groovy to Kotlin for Gradle Android Projects

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!