Reputation: 1116
I have a Groovy file that looks like this (currently).
main.groovy
import org.packages.mystuff.JavaClassIAmUsing;
public class MyObject {
def rate(item){
def o = evaluate(new File (new File(getClass().protectionDomain.codeSource.location.path).parent),"CommonFunctions.groovy");
println o.whoami();
}
}
i have another groovy file called
CommonFunctions.groovy
def whoami() {return 'no body';}
I'm trying to include the CommonFunctions script in to main script, BUT the location of the script are not known at build time (i.e. i can not hardcode a absolute file path in the script or absoulte path of the java process in relation to where the scripts will be stored).
All i know is that the scripts will be together or at a location relative to the calling script (say sub directory).
I've attempted to try and location the calling script location, but i get the error
No signature of method: MyObject.evaluate()
How can i referance this script, considering the main script is accessed at runtime using a GroovyClassLoader.parseClass(File) method.
Upvotes: 4
Views: 6545
Reputation: 5950
I'm not really sure why you want to do it this way, I think it would be much simpler to make a class of CommonsFunctions
that you could instantiate normally and use everywhere.
However, it is possible to achieve what you want; with Groovy, there are not that many limitations...
There are two problems with your suggested solution:
MyObject
class naturally refers to ... the MyObject
class, so your attempt to find the location of the script will fail. You're on the right track, but you need to resolve the script location using the surrounding Script class.evaluate
doesn't really work the way you think it does. The result of the evaluate
method is the result of the script, not an instance of the Script
class. One way to remedy this, is to rewrite the methods in CommonFunction
as closure properties. These properties will be available in the shell Binding
object when evaluating the script.So, with these rewrites, you end up with something like this:
main.groovy
class MyObject {
def scriptDir
def rate(item) {
def commonFunctionsScriptFile = new File(scriptDir, "CommonFunctions.groovy")
def binding = new Binding()
new GroovyShell(binding).evaluate(commonFunctionsScriptFile)
println binding.variables.whoami()
}
}
scriptFile = new File(getClass().protectionDomain.codeSource.location.path)
new MyObject(scriptDir: scriptFile.parentFile).rate(null)
Here, the script file location is resolved in the script, not in the inner class.
CommonFunctions.groovy
whoami = { 'no body' }
Here, whoami
is no longer a method, but a closure property which will be added to the binding. Make sure that you don't prefix this property with def
, since then it will be a local variable instead of a property added to the binding object.
Output after these rewrites is the expected: no body
.
Upvotes: 3