Grail metaprogramming

I understand that there are two obvious places in the Grails application where you can perform metaprogramming:

  • Closing init Bootstrap.groovy
  • Closing the doWithDynamicMethods Plugin

The meta-programming that I refer to should be visible throughout the application, typical examples include adding (or replacing) methods of third-party classes.

 String.metaClass.myCustomMethod = { /* implementation omitted */ } 

The disadvantage (1) is that metaprogramming will not be applied when the application is dynamically reloaded. The disadvantage (2) is that I need to create and maintain the entire plugin just for the sake of a little metaprogramming.

Is there a better place for such metaprogramming?

Update

Following Ted's suggestion below, I added the following class to src/groovy

 package groovy.runtime.metaclass.java.lang /** * Adds custom methods to the String class */ 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 } } } 

Then it restarted the application and ran the following code in the Grails console:

 assert 'mrhaki loves Groovy'.hasGroovy() 

I got the following exception

 groovy.lang.MissingMethodException: No signature of method: java.lang.String.hasGroovy() is applicable for argument types: () values: [] 

Am I doing something wrong or is there a reason why this does not work in a Grails application?

+7
metaprogramming grails groovy
source share
3 answers

Refuse to delegate MetaClass , it is part of groovy and turns your metaclass into part of the metaclass, which is used for each instance of this class from the very beginning. He works on a simple agreement and even works outside the grail.

+2
source share

Depending on your use case, Groovy AST transformations are the third option. AST conversion is a modification of bytecode at compile time. They are available with Groovy 1.6 and have been greatly improved in Groovy 1.7. Especially ASTBuilder is a very elegant way.

Remember that using AST inside Grails may require some assembly changes. Classes performing AST must be compiled before classes covered by AST. This can be easily done by connecting to the "CompileStart" event in the /_Events.groovy scripts and precompiling the conversion.

+1
source share

You can use the DelegatingMetaClass solution, but you need to pack it into a JAR file and then add it to the lib directory.

Create a new directory with the following Gradle build file:

 apply plugin: 'groovy' repositories.mavenCentral() dependencies { groovy: 'org.codehaus.groovy:groovy-all:1.8.6' } 

In the src / main / groovy directory, you can place the StringMetaClass source code. With the $ Gradle jar, you can create a JAR file and then copy it to the lib directory of your Grails application.

+1
source share

All Articles