Unable to get Groovy extension module to work

753 views Asked by At

I am trying to create an extension module and then use it in a different project/script but unable to get it to work. Here is what I am doing:

Step-1: Created a file named TemperatureUtils.groovy which is a category-like class. Here is the source:

package utils

class TemperatureUtils {

    Double toFahrenheit(Number celcius) {
        (9 * celcius / 5) + 32
    }

    Double toCelcius(Number fahrenheit) {
        (fahrenheit - 32) * 5 / 9
    }
}

Step-2: Created the extension module descriptor - org.codehaus.groovy.runtime.ExtensionModule with the following contents:

moduleName=Some-Utils
moduleVersion=1.0
extensionClasses=utils.TemperatureUtils
staticExtensionClasses=

Step-3: Compiled the class and hand-created a jar file with the following structure:

extensionUtils.jar
  |-- utils
  |     |-- TemperatureUtils.class
  |
  |-- META-INF
        |-- services
              |-- org.codehaus.groovy.runtime.ExtensionModule

Step-4: Created a new script to use the extension module. Script source:

import org.codehaus.groovy.control.CompilerConfiguration

def groovyScript = '''
//Following line just confirms that the jar file is indeed on the classpath of this script
assert 25 == (new utils.TemperatureUtils()).toCelcius(77)

//Actually using the category now
assert 77.toCelcius()       == 25
assert 25.toFahrenheit()    == 77
'''

def compilerConfig = new CompilerConfiguration()

compilerConfig.setClasspath(/E:\temp\jar\extensionUtils.jar/)

def shell = new GroovyShell(compilerConfig)
shell.evaluate(groovyScript)

Step-5: Executed the script. Here, I am getting the following exception:

groovy.lang.MissingMethodException: No signature of method: java.lang.Integer.toCelcius() is applicable for argument types: () values: []
    at Script1.run(Script1.groovy:6)
    at ConsoleScript2.run(ConsoleScript2:16)

Now, I have tried a few things but couldn't get it to work:

  • Removed the last line - "staticExtensionClasses=" from the extension module descriptor but it didn't work.
  • Changed the TemperatureUtils.groovy class to be an actual category by using the @Category(Number) annotation and removing the arguments from both methods (and using 'this' instead of 'celcius' and 'fahrenheit' param-names in methods' bodies) but it still did not work.
  • Googled it but didn't find much information. Also stumbled upon this, but that didn't help me either.

Would appreciate any help that the wonderful stackoverflow community can offer! :)

1

There are 1 answers

0
Michael Easter On

The following works for me, using Groovy 2.4.5. Based on this post.

First, change TemperatureUtils to have static methods:

package utils

class TemperatureUtils {
    static Double toFahrenheit(Number celcius) {
        (9 * celcius / 5) + 32
    }

    static Double toCelcius(Number fahrenheit) {
        (fahrenheit - 32) * 5 / 9
    }
}

Then, I would not use CompilerConfiguration but simply set the CLASSPATH. E.g.

$ export CLASSPATH=../utils/build/libs/temp.jar
$ groovy client.groovy

where Client.groovy is simply:

def groovyScript = '''
//Following line just confirms that the jar file is indeed on the classpath of this script
assert 25 == (new utils.TemperatureUtils()).toCelcius(77)

//Actually using the category now
assert 77.toCelcius()       == 25
assert 25.toFahrenheit()    == 77
'''

def shell = new GroovyShell() 
shell.evaluate(groovyScript)