add extension module to groovy class

2020-03-27 17:57发布

问题:

I am trying to create simple extension module.

I created Main.groovy file

class Item {
   String item
}

new Item().sayHello() // this method supposed to be extension

I compiled it (not ran).

I created ItemExtension.groovy class

class ItemExtension {
    def sayHello(Item self) {
        println "hello world"
    }
}

This is my org.codehaus.groovy.runtime.ExtensionModule descriptor

moduleName=Item extension module
moduleVersion=1.0
extensionClasses=ItemExtension

I compiled ItemExtension.groovy using groovyc (I precompiled Main.groovy in order to get Item class)

groovyc ItemExtension.groovy

Compiled ItemExtension.class with META-INF I put into .jar file (renamed .rar). Its structure looks like this

META-INF\services\org.codehaus.groovy.runtime.ExtensionModule
ItemExtension.class

I put ItemExtension.jar in the same folder as Main.groovy and compiled it again but with cp argument to add jar.

groovyc -cp ItemExtension.jar Main.groovy

But when I try to run it

groovy Main

I get this exception

Caught: groovy.lang.MissingMethodException: No signature of method: Item.sayHell
o() is applicable for argument types: () values: []
groovy.lang.MissingMethodException: No signature of method: Item.sayHello() is a
pplicable for argument types: () values: []
    at Main.run(Main.groovy:6)

What I did wrong?

回答1:

Your extension method has to be static to be recognized (because extension modules have to be stateless) and the Item class has to live into its own source file to be recognized (because otherwise it's an inner class of the script).

Here is a bash script that does what you want:

#!/bin/bash

echo "Create Item.groovy"
cat > 'Item.groovy' <<-EOF
class Item {
    String item
}
EOF

echo "Compile Item.groovy"
groovyc Item.groovy -d classes

echo "Create extension module class"
cat > 'ItemExtension.groovy' <<-EOF
class ItemExtension {
    static def sayHello(Item self) {
        println "hello world"
    }
}
EOF

echo "Create extension module descriptor"
mkdir -p classes/META-INF/services
cat > classes/META-INF/services/org.codehaus.groovy.runtime.ExtensionModule <<-EOF
moduleName=Item extension module
moduleVersion=1.0
extensionClasses=ItemExtension
EOF

echo "Compile extension module"
groovyc -cp classes ItemExtension.groovy -d classes

echo "Creating script.groovy"
cat > 'script.groovy' <<-EOF
new Item().sayHello()
EOF

echo "Run script"
groovy -cp classes script.groovy