web-dev-qa-db-fra.com

Comment arrêter une application de ligne de commande Spring Boot

Je construis une application Java en ligne de commande à l'aide de Spring Boot pour la faire fonctionner rapidement.

L'application charge différents types de fichiers (par exemple, CSV) et les charge dans une base de données Cassandra. Il n'utilise aucun composant Web, ce n'est pas une application Web.

Le problème que je rencontre est d’arrêter l’application lorsque le travail est terminé. J'utilise l'interface Spring CommandLineRunner avec un @Component pour exécuter les tâches, comme indiqué ci-dessous, mais lorsque le travail est terminé, l'application ne s'arrête pas, elle continue de fonctionner pour une raison quelconque et je ne trouve pas le moyen de l'arrêter.

@Component
public class OneTimeRunner implements CommandLineRunner {

    @Autowired
    private CassandraOperations cassandra;

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void run(String... args) throws Exception {
        // do some work here and then quit
        context.close();
    }
}

UPDATE: le problème semble être spring-cassandra, puisqu'il n'y a rien d'autre dans le projet. Est-ce que quelqu'un sait pourquoi il garde les threads en arrière-plan qui empêchent l'application de s'arrêter?

UPDATE: le problème a disparu en mettant à jour la dernière version de Spring Boot.

19
ESala

La réponse dépend de ce qui fonctionne encore. Vous pouvez probablement le trouver avec un thread dump (par exemple, en utilisant jstack). Mais s'il s'agit de quelque chose qui a été lancé par Spring, vous devriez pouvoir utiliser ConfigurableApplicationContext.close() pour arrêter l'application dans votre méthode main () (ou dans la CommandLineRunner).

12
Dave Syer

J'ai trouvé une solution. Vous pouvez utiliser ceci:

public static void main(String[] args) {
    SpringApplication.run(RsscollectorApplication.class, args).close();
    System.out.println("done");
}

Il suffit d'utiliser .close à la course.

21
ACV

J'ai également rencontré ce problème dans mon projet actuel (application de démarrage de printemps). Ma solution est:

// releasing all resources
((ConfigurableApplicationContext) ctx).close();
// Close application
System.exit(0);

context.close() n'arrête pas notre application console, il s'agit simplement de libérer les ressources.

5
Quan Vo

Ceci est une combinaison de @EliuX answer avec @Quan Vo one. Merci à vous deux!

Le principal est que je transmette le code de réponse SpringApplication.exit (context) en tant que paramètre à System.exit (). En cas d'erreur de fermeture du contexte Spring, vous le remarquerez.

SpringApplication.exit () fermera le contexte Spring.

System.exit () va fermer l'application.

@Component
public class OneTimeRunner implements CommandLineRunner {

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void run(String... args) throws Exception { 
       System.exit(SpringApplication.exit(context));
    }
}
5
Abel ANEIROS

Utilisez org.springframework.boot.SpringApplication#exit. Par exemple.

@Component
public class OneTimeRunner implements CommandLineRunner {

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void run(String... args) throws Exception { 
        SpringApplication.exit(context);
    }
}
1
EliuX

Vous pouvez essayer ceci - 

public void run(String... arg0) throws Exception {
int response = -1;
try {
    /*Do you job here and get a response code*/

    System.exit(response); //success response

} catch (Exception e) {
    System.exit(response); //failure response
}
}