You could do something like:
public static void main(String... args) throws Exception {
while(true){
try(ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args)) {
CompletableFuture<Throwable> throwableFuture = new CompletableFuture<>();
Thread.setDefaultUncaughtExceptionHandler(
(thread, throwable) -> throwableFuture.completeExceptionally(throwable));
throwableFuture.get();
} catch (Exception | VirtualMachineError t) {
//log error
}
}
}
This will wait for any threads to throw an uncaught exception.
The try-with-resources statement will close the context and cleanup any resources associated with it.
The while loop will then recreate the context.
You will need to make sure that any resources you create(like thread factories) and being properly disposed of when the context closes, otherwise you will still run out of memory.
A better approach would be to have your java service restarted by an external service manager like systemd.