How do I get the current working directory when using a Spring Boot LaunchScript

Viewed 219

No not this one

    var cwd = Path.of( "" );
    log.info( "user.dir: {}", Path.of( System.getProperty( "user.dir" ) ) );
    log.info( "cwd: {}", cwd.toAbsolutePath() );
    log.info( "PWD: {}", System.getenv( "PWD" ) );
❯ ./modules/app/build/libs/brix-0.1.0.jar --logging.level.com.xenoterracide.brix=info java module foo                                      # brix -> ccushing/release !
INFO  - Starting Application using Java 11.0.11 on CarbonX1-8-Manjaro with PID 51641 (/home/xeno/IdeaProjects/brix/modules/app/build/libs/brix-0.1.0.jar started by xeno in /home/xeno/IdeaProjects/brix/modules/app/build/libs) - com.xenoterracide.brix.Application
INFO  - No active profile set, falling back to default profiles: default - com.xenoterracide.brix.Application
INFO  - Started Application in 0.843 seconds (JVM running for 1.633) - com.xenoterracide.brix.Application
INFO  - user.dir: /home/xeno/IdeaProjects/brix/modules/app/build/libs - com.xenoterracide.brix.configloader.service.ConfigValueProcessor
INFO  - cwd: /home/xeno/IdeaProjects/brix/modules/app/build/libs - com.xenoterracide.brix.configloader.service.ConfigValueProcessor
INFO  - PWD: /home/xeno/IdeaProjects/brix/modules/app/build/libs - com.xenoterracide.brix.configloader.service.ConfigValueProcessor
Overwrite [yN] module/src/test/java/com/xenoterracide/TestApplication.java 
❯ pwd                                                                                                                                      # brix -> ccushing/release !
/home/xeno/IdeaProjects/brix ####!!!!! THIS ONE

^ that last one, in a cross platform compatible way.

I'm using a Spring Boot jar launch script.

tasks.withType<BootJar> {
  mainClass.set("com.xenoterracide.brix.Application")
  archiveBaseName.set("brix")
  launchScript {
    properties(
      mapOf(
        "spring.config.location" to "classpath:application.properties"
      )
    )
  }
}

how can I get the real working directory?

1 Answers

You can’t with the default launch script. It uses the directory that contains the jar file as the working directory. This is primarily aimed at applications that are used as services rather than a CLI application and isn’t customisable with the default script.

I’d recommend using Spring Boot’s ability to build a fully-executable jar file with a custom launch script that meets your needs. You can do so with the script property:

tasks.getByName<BootJar>("bootJar") {
    launchScript {
        script = file("src/custom.script")
    }
}

Here is a script from a CLI application that may provide a useful starting point:


#!/bin/bash

[[ -n "$DEBUG" ]] && set -x

working_directory="$(pwd)"

# Follow symlinks to find the real jar
cd "$(dirname "$0")" || exit 1
[[ -z "$jarfile" ]] && jarfile=$(pwd)/$(basename "$0")
while [[ -L "$jarfile" ]]; do
  jarfile=$(readlink "$jarfile")
  cd "$(dirname "$jarfile")" || exit 1
  jarfile=$(pwd)/$(basename "$jarfile")
done

cd "$working_directory"

# Find Java
if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then
    javaexe="$JAVA_HOME/bin/java"
elif type -p java > /dev/null 2>&1; then
    javaexe=$(type -p java)
elif [[ -x "/usr/bin/java" ]];  then
    javaexe="/usr/bin/java"
else
    echo "Unable to find Java"
    exit 1
fi

arguments=(-Dsun.misc.URLClassPath.disableJarChecking=true $JAVA_OPTS -jar "$jarfile" $RUN_ARGS "$@")

"$javaexe" "${arguments[@]}"
exit $?
Related