Comment créer un service pour mon application Java où je dois l'exécuter avec le démon jsvc Apache commons. Le service doit être démarré au démarrage du système. J'ai cherché et cherché, lu et lu et essayé beaucoup de choses, et rien ne semble fonctionner.
J'ai créé un script .sh dans le chemin /etc/init.d/
et exécuter toutes les commandes nécessaires suggérées par le "Web", comme chmod 755 mydaemon.sh
et ou chmod +x mydaemon.sh
, ne fonctionne pas sans le .sh
, alors je ne sais pas pourquoi les gens le suggèrent. Mais il semble que cela puisse être une vieille approche avant la v.15 ou à peu près. Bien au moins, j'ai trouvé que certaines personnes disent que c'est obsolète et que systemd est le nouveau noir.
J'ai également essayé de créer un fichier mydamon.service dans /etc/systemd/system
en pointant ExecStart et Stop vers mon script .sh. J'ai fait tous les systemctl daemon-realod
-> systemctl start myservice
. Voici un exemple de mon fichier .service
[Unit]
Description=Scheduler Test
[Service]
ExecStart=/etc/init.d/myscheduler.sh start
ExecStop=/etc/init.d/myscheduler.sh stop
[Install]
WantedBy=multi-user.target
voici un exemple de mon script .sh
#!/bin/sh
### BEGIN INIT INFO
#
# Provides: myscheduler
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start the myscheduler service
# Description: This file is used to start the daemon and should be placed in /etc/init.d
### END INIT INFO
NAME="myscheduler"
DESC="MyScheduler service"
EXEC=/usr/bin/jsvc
FILE_PATH="/usr/local/$NAME"
#Java_HOME=/usr/lib/jvm/Java-8-openjdk-AMD64
CLASS_PATH="$FILE_PATH/lib/commons-daemon-1.0.15.jar":"$FILE_PATH/myscheduler.jar"
CLASS="com.example.ApiApplication"
USER="root"
PID=$FILE_PATH/example.pid
LOG_OUT=$FILE_PATH/example.out
LOG_ERR=$FILE_PATH/example.err
jsvc_exec()
{
cd $FILE_PATH
$EXEC -home $Java_HOME -cp $CLASS_PATH -user $USER -outfile $LOG_OUT -errfile $LOG_ERR -pidfile $PID $1 $CLASS
}
case "$1" in
start)
echo "Starting the $DESC..."
jsvc_exec
echo "The $DESC has started."
;;
stop)
echo "Stopping the $DESC..."
jsvc_exec "-stop"
echo "The $DESC has stopped."
;;
restart)
if [ -f "$PID" ]; then
echo "Restarting the $DESC..."
jsvc_exec "-stop"
jsvc_exec
echo "The $DESC has restarted."
else
echo "Service $DESC not running, no action taken."
exit 1
fi
;;
*)
echo "usage: daemon {start|stop|restart}" >&2
exit 3
;;
esac
Mais rien ne se passe lorsque j'essaie de le démarrer, actuellement, il démarre et s'arrête immédiatement. Il semble que mon application ne puisse pas lire l'un de mes fichiers de propriétés que je pointe dans le fichier /etc/environment
:
quartzconfig="/usr/local/myscheduler/quartz.properties"
La classe principale de mon application est visible ci-dessous:
public class ApiApplication implements Daemon{
private static Scheduler scheduler;
public static void main(String[] args) {
try {
String path = System.getenv("quartzconfig");
System.out.println(path);
Properties props = new Properties();
Parameters parameters = new Parameters();
FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
.configure(parameters.properties().setFileName(path));
Configuration config = builder.getConfiguration();
props = ConfigurationConverter.getProperties(config);
SchedulerFactory sf = new StdSchedulerFactory(props);
scheduler = sf.getScheduler();
scheduler.start();
} catch (SchedulerException se){
se.printStackTrace();
} catch(ConfigurationException ioe){
ioe.printStackTrace();
System.err.println("Could not load properties... something went wrong!");
}
}
@Override
public void init(DaemonContext daemonContext) throws DaemonInitException, Exception {
System.out.println("initializing...");
}
@Override
public void start() throws Exception {
System.out.println("starting...");
main(null);
}
@Override
public void stop() throws Exception {
System.out.println("stopping...");
// if process is stopped gracefully shutdown the scheduler
scheduler.shutdown();
}
@Override
public void destroy() {
System.out.println("done.");
}
}
Et comme je peux le voir dans la journalisation, path
est nul.
Mais ce qui est plus étrange, c'est que je peux lancer mon application "jsvc" si je place par exemple mon myscheduler.sh
dans ex. /home/john/Downloads/test
et démarrez-le manuellement comme sh myscheduler.sh start
alors tout fonctionne correctement, mais ne semble pas pouvoir fonctionner en tant que service et au démarrage du système update-rc.d ...
.
Je suis nouveau sur Linux, ou du moins je ne le connais pas très bien. Je pense que cela pourrait être une permission d'accès aux dossiers de fichiers, j'aimerais donner à tous un chmod -R 777
mais je suis bien conscient des conséquences et ce qu'il pourrait faire à mon système, essayé une ou deux fois avant xD. Exécutant Ubuntu 16.04 sur VirtualBox, je crée donc une nouvelle image si elle se brise.
Trouvé la solution, devait définir EnvironmentFile=/etc/environment
et Type=forking
option dans mon fichier .service
puis cela a bien fonctionné.