Including a groovy script in another groovy

前端 未结 12 1477
走了就别回头了
走了就别回头了 2020-11-27 12:07

I have read how to simply import a groovy file in another groovy script

I want to define common functions in one groovy file and call those functions from other groo

相关标签:
12条回答
  • 2020-11-27 12:39

    I think that the best choice is to organize utility things in form of groovy classes, add them to classpath and let main script refer to them via import keyword.

    Example:

    scripts/DbUtils.groovy

    class DbUtils{
        def save(something){...}
    }
    

    scripts/script1.groovy:

    import DbUtils
    def dbUtils = new DbUtils()
    def something = 'foobar'
    dbUtils.save(something)
    

    running script:

    cd scripts
    groovy -cp . script1.groovy
    
    0 讨论(0)
  • 2020-11-27 12:40

    After some investigation I have come to the conclusion that the following approach seems the best.

    some/subpackage/Util.groovy

    @GrabResolver(name = 'nexus', root = 'https://local-nexus-server:8443/repository/maven-public', m2Compatible = true)
    @Grab('com.google.errorprone:error_prone_annotations:2.1.3')
    @Grab('com.google.guava:guava:23.0')
    @GrabExclude('com.google.errorprone:error_prone_annotations')
    
    import com.google.common.base.Strings
    
    class Util {
        void msg(int a, String b, Map c) {
            println 'Message printed by msg method inside Util.groovy'
            println "Print 5 asterisks using the Guava dependency ${Strings.repeat("*", 5)}"
            println "Arguments are a=$a, b=$b, c=$c"
        }
    }
    

    example.groovy

    #!/usr/bin/env groovy
    Class clazz = new GroovyClassLoader().parseClass("${new File(getClass().protectionDomain.codeSource.location.path).parent}/some/subpackage/Util.groovy" as File)
    GroovyObject u = clazz.newInstance()
    u.msg(1, 'b', [a: 'b', c: 'd'])
    

    In order to run the example.groovy script, add it to your system path and type from any directory:

    example.groovy
    

    The script prints:

    Message printed by msg method inside Util.groovy
    Print 5 asterisks using the Guava dependency *****
    Arguments are a=1, b=b, c=[a:b, c:d]
    

    The above example was tested in the following environment: Groovy Version: 2.4.13 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux

    The example demonstrates the following:

    • How to use a Util class inside a groovy script.
    • A Util class calling the Guava third party library by including it as a Grape dependency (@Grab('com.google.guava:guava:23.0')).
    • The Util class can reside in a subdirectory.
    • Passing arguments to a method within the Util class.

    Additional comments/suggestions:

    • Always use a groovy class instead of groovy script for reusable functionality within your groovy scripts. The above example uses the Util class defined in the Util.groovy file. Using groovy scripts for reusable functionality is problematic. For example, if using a groovy script then the Util class would have to be instantiated at the bottom of the script with new Util(), but most importantly it would have to be placed in a file named anything but Util.groovy. Refer to Scripts versus classes for more details about the differences between groovy scripts and groovy classes.
    • In the above example I use the path "${new File(getClass().protectionDomain.codeSource.location.path).parent}/some/subpackage/Util.groovy" instead of "some/subpackage/Util.groovy". This will guarantee that the Util.groovy file will always be found in relation to the groovy script's location (example.groovy) and not the current working directory. For example, using "some/subpackage/Util.groovy" would result in searching at WORK_DIR/some/subpackage/Util.groovy.
    • Follow the Java class naming convention to name your groovy scripts. I personally prefer a small deviation where the scripts start with a lower letter instead of a capital one. For example, myScript.groovy is a script name, and MyClass.groovy is a class name. Naming my-script.groovy will result in runtime errors in certain scenarios because the resulting class will not have a valid Java class name.
    • In the JVM world in general the relevant functionality is named JSR 223: Scripting for the Java. In groovy in particular the functionality is named Groovy integration mechanisms. In fact, the same approach can be used in order to call any JVM language from within Groovy or Java. Some notable examples of such JVM languages are Groovy, Java, Scala, JRuby, and JavaScript (Rhino).
    0 讨论(0)
  • 2020-11-27 12:47

    A combination of @grahamparks and @snowindy answers with a couple of modifications is what worked for my Groovy scripts running on Tomcat:

    Utils.groovy

    class Utils {
        def doSth() {...}
    }
    

    MyScript.groovy:

    /* import Utils --> This import does not work. The class is not even defined at this time */
    Class groovyClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(new File("full_path_to/Utils.groovy")); // Otherwise it assumes current dir is $CATALINA_HOME
    def foo = groovyClass.newInstance(); // 'def' solves compile time errors!!
    foo.doSth(); // Actually works!
    
    0 讨论(0)
  • 2020-11-27 12:48

    For late-comers, it appears that groovy now support the :load file-path command which simply redirects input from the given file, so it is now trivial to include library scripts.

    It works as input to the groovysh & as a line in a loaded file:
    groovy:000> :load file1.groovy

    file1.groovy can contain:
    :load path/to/another/file invoke_fn_from_file();

    0 讨论(0)
  • 2020-11-27 12:50

    Groovy can import other groovy classes exactly like Java does. Just be sure the extension of the library file is .groovy.

        $ cat lib/Lib.groovy
        package lib
        class Lib {
           static saySomething() { println 'something' }
           def sum(a,b) { a+b }
        }
    
        $ cat app.gvy
        import lib.Lib
        Lib.saySomething();
        println new Lib().sum(37,5)
    
        $ groovy app
        something
        42
    
    0 讨论(0)
  • 2020-11-27 12:51

    How about treat the external script as a Java class? Based on this article: https://www.jmdawson.net/blog/2014/08/18/using-functions-from-one-groovy-script-in-another/

    getThing.groovy The external script

    def getThingList() {
        return ["thing","thin2","thing3"]
    }
    

    printThing.groovy The main script

    thing = new getThing()  // new the class which represents the external script
    println thing.getThingList()
    

    Result

    $ groovy printThing.groovy
    [thing, thin2, thing3]
    
    0 讨论(0)
提交回复
热议问题