You are specifying a user in your .service file, hence you should not need to do any of the su magic in your script.
Replace this:
su -s /bin/sh $user -c "cd /app/myworkingdir ; java -jar myjar.jar >> /var/log/systemout.log 2>> /var/log/systemerr.log"
with this:
cd /app/myworkingdir
java -jar myjar.jar >> /var/log/systemout.log 2>> /var/log/systemerr.log"
Besides, I see two further issues in your script:
You are grepping the process table to find the PID for your service. This may fail if there is another running process with a command line that contains the same characters (the system may end up picking the wrong process to terminate).
echoright after launching java is a safer way of accomplishing this.pid_file
The service type is
simple, yet your script forks it as a separate process and then returns. This will confuse systemd, and your service will fail to start.
Both of these might be easy to solve. I assume you need the PID only to stop the service, and doing so is as simple as sending it a SIGINT. In that case you can take advantage of the fact that, in the absence of ExecStop, systemd will simply send a SIGINT to the service process to stop it.
Drop the ampersand after the java call, and prefix it with
execinstead. That way, the java process becomes will be treated as the daemon process by systemd.Drop the PID magic after the java call altogether.
In the
.servicefile, remove theExecStopentry.Instead, also under
[Service], addSuccessExitStatus=143. (When terminated with a signal, the JVM will exit with a nonzero exit status, namely 128 plus the signal. By default, systemd treats an exit status of 143 as a failure; this entry will tell systemd that 143 stands for graceful exit.)
You could take this one step further and drop the script altogether:
- Specify the java command line as
ExecStart - Pass the full path to the java binary (as reported by
which java) - Drop the redirections: by default, systemd will redirect stdout and stderr to the journal. (This can be configured in the
.servicefile as well.)
You may not need the shell script. You can start the process from the myService.service file provided you use the full path to both the java binary and the jar file. It should look something like
ExecStart=/usr/bin/java -jar /home/pruss/dev/ServerDeploy5-4.1/Server/resources/MyServer.jar
Works on CentOS 7.2.
Not sure who gave this a thumbs down..
I found the solution and post it to save others the effort.
What you see above works. However, the final service is thus:
[Unit]
Description=MyProgramThing
[Service]
ExecStart=/home/prus/dev/Blah-4.1/Server/runServer.sh
Type=simple
User=prus
[Install]
WantedBy=multi-user.target
Importantly, inside my shell script, I needed to put in the full path the the .jar file. java -jar /home/myprog.jar etc
i.e. ./myJar.jar did not work. Hope that helps.
You could use the Linux kernel support for miscellaneous binary formats (binfmt_misc). This allows you to register an interpreter (e.g. Java) to execute a file based on the first few bytes in the file (e.g. a jar file). See https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst for more information.
Your error is from system's attempt to parse jar-file searching for an interpreter directive - #!/interpreter.
One way would be to just create shell-script called rating-gateway-0.0.1-SNAPSHOT.jar and run your Java application from it.
So you will end up with 2 files:
/opt/rating-gateway/rating-gateway-0.0.1-SNAPSHOT.realjar.jar- your actual jar-file/opt/rating-gateway/rating-gateway-0.0.1-SNAPSHOT.jar- simple shell-script with the following content:
#!/usr/bin/env sh
java -jar /opt/rating-gateway/rating-gateway-0.0.1-SNAPSHOT.jar