java - starter - spring boot templates
Cómo cerrar una aplicación de línea de comandos Spring Boot (6)
Estoy creando una aplicación java de línea de comandos utilizando Spring Boot para que funcione rápidamente.
La aplicación carga diferentes tipos de archivos (por ejemplo, CSV) y los carga en una base de datos Cassandra. NO utiliza ningún componente web, no es una aplicación web.
El problema que tengo es detener la aplicación cuando finalice el trabajo. Estoy utilizando la interfaz Spring CommandLineRunner con un @Component
para ejecutar las tareas, como se muestra a continuación, pero cuando se completa el trabajo, la aplicación no se detiene, se sigue ejecutando por alguna razón y no puedo encontrar una manera de detenerla.
@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();
}
}
ACTUALIZACIÓN : el problema parece ser spring-cassandra
, ya que no hay nada más en el proyecto. ¿Alguien sabe por qué mantiene los subprocesos ejecutándose en segundo plano que evitan que la aplicación se detenga?
ACTUALIZACIÓN : el problema desapareció al actualizar a la última versión de arranque de primavera.
Encontré una solución. Puedes usar esto:
public static void main(String[] args) {
SpringApplication.run(RsscollectorApplication.class, args).close();
System.out.println("done");
}
Sólo tiene que utilizar .close en ejecución.
Esta es una combinación de la respuesta de @EliuX con one. ¡Gracias a los dos!
La principal diferencia es que paso el código de respuesta SpringApplication.exit (contexto) como parámetro a System.exit (), por lo que si se produce un error al cerrar el contexto Spring, notará.
El SpringApplication.exit () cerrará el contexto de Spring.
El System.exit () cerrará la aplicación.
@Component
public class OneTimeRunner implements CommandLineRunner {
@Autowired
private ConfigurableApplicationContext context;
@Override
public void run(String... args) throws Exception {
System.exit(SpringApplication.exit(context));
}
}
La respuesta depende de qué es lo que todavía está haciendo el trabajo. Probablemente pueda descubrirlo con un volcado de hilos (por ejemplo, usando jstack). Pero si es algo que comenzó Spring, debería poder utilizar ConfigurableApplicationContext.close()
para detener la aplicación en su método main () (o en CommandLineRunner
).
Puedes probar esto ...
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
}
}
También me encontré con este problema en mi proyecto actual (aplicación de arranque de primavera). Mi solución es:
// releasing all resources
((ConfigurableApplicationContext) ctx).close();
// Close application
System.exit(0);
context.close()
no detiene nuestra aplicación de consola, solo está liberando los recursos.
Utilice org.springframework.boot.SpringApplication#exit
. P.ej
@Component
public class OneTimeRunner implements CommandLineRunner {
@Autowired
private ConfigurableApplicationContext context;
@Override
public void run(String... args) throws Exception {
SpringApplication.exit(context);
}
}