I am writing a systemd unit file for a Java application and I'd like to control the version of Java used to start it up. My (simplified) service file is[Service]Type=simpleEnvironmentFile=%h/Documents/apps/app/app-%i/app.cfgExecStart=${JAVA_HOME}/bin/java ${JAVA_OPTS} -jar %h/Documents/apps/app/app-%i/myapp.jarSuccessExitStatus=143When trying to start it up I get an error backApr 28 12:43:37 rombert systemd[1613]: [/home/robert/.config/systemd/user/app@.service:7] Executable path is not absolute, ignoring: ${JAVA_HOME}/bin/java ${JAVA_OPTApr 28 12:43:37 rombert systemd[1613]: app@1.0.0.service lacks both ExecStart= and ExecStop= setting. Refusing.I know that JAVA_HOME is correctly set ; if I change the ExecStart line to start with /usr/bin/java and then add something like -DsomeOption=${JAVA_HOME} I can see it just fine.The obvious workaround is to create a wrapper script but I feel that it defeats the point of using a service file.How can I set JAVA_HOME for my Java application using a unit file?
Writing a systemd unit file with a environment-set executable path
systemd;java
From the Command lines section in systemd.service(5):Note that the first argument (i.e. the program to execute) may not be a variable.I was going to suggest using the instance specifier %i (you can read more about it in systemd.unit(5)), but (now we're back in systemd.service(5)):the first argument of the command line (i.e. the program to execute) may not include specifiers.I think the best option at this point really is creating a shell script that wraps the execution of the java binary as suggested by Warren Young or you could ExecStart a shell directly like in the example for shell command lines in the Command Lines section of systemd.service(5) which has the following example:ExecStart=/bin/sh -c 'dmesg | tac'so you could do (untested):ExecStart=/bin/sh -c '${JAVA_HOME}....'