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.
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
).
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.
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.
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));
}
}
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);
}
}
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
}
}