Over a million developers have joined DZone.

Groovy Goodness: Magic Package to Add Custom MetaClass

· Java Zone

Discover how AppDynamics steps in to upgrade your performance game and prevent your enterprise from these top 10 Java performance problems, brought to you in partnership with AppDynamics.

Groovy is very dynamic. We can add methods to classes at runtime that don't exist at compile time. We can add our own custom MetaClass at startup time of our application if we follow the magic package naming convention. The naming convention is groovy.runtime.metaclass.[package].[class]MetaClass. For example if we want to change the behavior of the java.lang.String class, then we must write a custom MetaClass with the package name groovy.runtime.metaclass.java.lang and class name StringMetaClass. We can do the same for classes we create ourselves. For example if we have a class myapp.RunApp than the custom metaclass implementation RunAppMetaClass would be in package groovy.runtime.metaclass.myapp.

Our custom MetaClass is extended from DelegatingMetaClass and besides the name of the class and the package we can write our code the way we want.

We must first compile the custom MetaClass and then we must put it in the classpath of the application code that is going to use the MetaClass.

// File: StringMetaClass.groovy
package groovy.runtime.metaclass.java.lang

class StringMetaClass extends DelegatingMetaClass {

    StringMetaClass(MetaClass meta) {
        super(meta)
    }

    Object invokeMethod(Object object, String method, Object[] arguments) {
        if (method == 'hasGroovy') {
            object ==~ /.*[Gg]roovy.*/
        } else {
            super.invokeMethod object, method, arguments
        }
    }
}

The code that will use the delegating metaclass implementation:

// File: StringDelegateSample.groovy

// Original methods are still invoked.
assert 'mrhaki'.toUpperCase() == 'MRHAKI'

// Invoke 'hasGroovy' method we added via the DelegatingMetaClass.
assert !'Java'.hasGroovy()
assert 'mrhaki loves Groovy'.hasGroovy()
assert 'Groovy'.toLowerCase().hasGroovy()

First we compile our StringMetaClass:

$ groovyc StringMetaClass.groovy

Next we can run the StringDelegateSample.groovy file if we put the generated class file in our classpath:

$ groovy -cp . StringDelegateSample

From http://mrhaki.blogspot.com/2011/11/groovy-goodness-magic-package-to-add.html

The Java Zone is brought to you in partnership with AppDynamics. AppDynamics helps you gain the fundamentals behind application performance, and implement best practices so you can proactively analyze and act on performance problems as they arise, and more specifically with your Java applications. Start a Free Trial.

Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}