How do you get the path of the running script in groovy?

Groovy

Groovy Problem Overview


I'm writing a groovy script that I want to be controlled via a properties file stored in the same folder. However, I want to be able to call this script from anywhere. When I run the script it always looks for the properties file based on where it is run from, not where the script is.

How can I access the path of the script file from within the script?

Groovy Solutions


Solution 1 - Groovy

You are correct that new File(".").getCanonicalPath() does not work. That returns the working directory.

To get the script directory

scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent

To get the script file path

scriptFile = getClass().protectionDomain.codeSource.location.path

Solution 2 - Groovy

As of Groovy 2.3.0 the @SourceURI annotation can be used to populate a variable with the URI of the script's location. This URI can then be used to get the path to the script:

import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths

@SourceURI
URI sourceUri

Path scriptLocation = Paths.get(sourceUri)

Note that this will only work if the URI is a file: URI (or another URI scheme type with an installed FileSystemProvider), otherwise a FileSystemNotFoundException will be thrown by the Paths.get(URI) call. In particular, certain Groovy runtimes such as groovyshell and nextflow return a data: URI, which will not typically match an installed FileSystemProvider.

Solution 3 - Groovy

This makes sense if you are running the Groovy code as a script, otherwise the whole idea gets a little confusing, IMO. The workaround is here: https://issues.apache.org/jira/browse/GROOVY-1642

Basically this involves changing startGroovy.sh to pass in the location of the Groovy script as an environment variable.

> As long as this information is not provided directly by Groovy, it's possible to modify the groovy.(sh|bat) starter script to make this property available as system property: > For unix boxes just change $GROOVY_HOME/bin/groovy (the sh script) to do > lang-shell > export JAVA_OPTS="$JAVA_OPTS -Dscript.name=$0" > > before calling startGroovy > For Windows: > In startGroovy.bat add the following 2 lines right after the line with > the :init label (just before the parameter slurping starts): > lang-none > @rem get name of script to launch with full path > set GROOVY_SCRIPT_NAME=%~f1 > > A bit further down in the batch file after the line that says "set > JAVA_OPTS=%JAVA_OPTS% -Dgroovy.starter.conf="%STARTER_CONF%" add the > line > lang-none > set JAVA_OPTS=%JAVA_OPTS% -Dscript.name="%GROOVY_SCRIPT_NAME%" >

Solution 4 - Groovy

For gradle user

I have same issue when I'm starting to work with gradle. I want to compile my thrift by remote thrift compiler (custom by my company).

Below is how I solved my issue:

task compileThrift {
doLast {
        def projectLocation = projectDir.getAbsolutePath(); // HERE is what you've been looking for.
        ssh.run {
            session(remotes.compilerServer) {
                // Delete existing thrift file.
                cleanGeneratedFiles()
                new File("$projectLocation/thrift/").eachFile() { f ->
                    def fileName=f.getName()
                    if(f.absolutePath.endsWith(".thrift")){
                        put from: f, into: "$compilerLocation/$fileName"
                    }
                }
                execute "mkdir -p $compilerLocation/gen-java"
                def compileResult = execute "bash $compilerLocation/genjar $serviceName", logging: 'stdout', pty: true
                assert compileResult.contains('SUCCESSFUL')
                get from: "$compilerLocation/$serviceName" + '.jar', into: "$projectLocation/libs/"
            }
        }
    }
}

Solution 5 - Groovy

One more solution. It works perfect even you run the script using GrovyConsole

File getScriptFile(){
    new File(this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI())
}

println getScriptFile()

Solution 6 - Groovy

workaround: for us it was running in an ANT environment and storing some location parent (knowing the subpath) in the Java environment properties (System.setProperty( "dirAncestor", "/foo" )) we could access the dir ancestor via Groovy's properties.get('dirAncestor').
maybe this will help for some scenarios mentioned here.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDan WoodwardView Question on Stackoverflow
Solution 1 - GroovyseansandView Answer on Stackoverflow
Solution 2 - GroovyM. JustinView Answer on Stackoverflow
Solution 3 - GroovyJoshua DavisView Answer on Stackoverflow
Solution 4 - GroovyLiem LeView Answer on Stackoverflow
Solution 5 - GroovyNaeel MaqsudovView Answer on Stackoverflow
Solution 6 - GroovyAndreas CovidiotView Answer on Stackoverflow