web-dev-qa-db-fra.com

Création d'un service dans Ubuntu 16.04 pour une application Java jsvc

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.

2
Yantes

Trouvé la solution, devait définir EnvironmentFile=/etc/environment et Type=forking option dans mon fichier .service puis cela a bien fonctionné.

1
Yantes