…context is closed #9983

The directory /tmp/tomcat-* are not deleted when stopping a Spring Boot application. This PR provide a solution with backward compatibility

  • Add a parameter server.tmp-deletion-strategy with 3 possible value :
  • DELETE_ON_EXIT : The default strategy. when the context is shutdown, the created temporary directory is deleted. If the temporary directory is not empty, then it will not be deleted.
  • RECURSIVE_DELETE : When the context is shutdown, then created temporary directory is deleted with all its content.
  • NOTHING : When the context is shutdown, we keep all the created temporary directory. With this configuration, if you need to remove the directory, you need to do it manually or with a cron task.
  • Use this parameter when the Servlet needs to create a temporary directory

by default, the behaviour is the same. but if you want to delete everything, you need to add in your application.properties ;

server.tmp-deletion-strategy=RECURSIVE_DELETE

Comment From: pivotal-cla

@CharlesLgn Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

Comment From: pivotal-cla

@CharlesLgn Thank you for signing the Contributor License Agreement!

Comment From: wilkinsona

Thanks for the proposal. Unfortunately, we can't use a shutdown hook for the reasons described in https://github.com/spring-projects/spring-boot/issues/9983#issuecomment-483998979. #9983 probably should have been labelled as pending-design-work as we don't really know the best way to proceed here and currently suspect that it'll require API changes. Thanks anyway and apologies for any wasted time.

Comment From: CharlesLgn

Unfortunately, we can't use a shutdown hook for the reasons described in #9983 (comment).

@wilkinsona is that also the case for Jetty, Netty and other API.

one other approch I had imagine was to have in AbstractConfigurableWebServerFactory:

protected final File createTempDir(String prefix) {
    try {
        File tempDir = Files.createTempDirectory(prefix + "." + getPort() + ".").toFile();
        runInShutdown(() -> this.deletionStrategy.deleteOnShutdown(tempDir));
        return tempDir;
    }
    catch (IOException ex) {
        throw new WebServerException(
                "Unable to create tempDir. java.io.tmpdir is set to " + System.getProperty("java.io.tmpdir"), ex);
    }
}

protected void runInShutdown(Runnable shutdownHook) {
    Runtime.getRuntime().addShutdownHook(new Thread(shutdownHook));
}

and in TomcatReactiveWebServerFactory :

@Override
protected void runInShutdown(Runnable shutdownHook) {
    serverLifecycleListeners.add(
        event -> {
            if (event.getType().equals(Lifecycle.AFTER_DESTROY_EVENT) {
                shutdownHook.run();
            }
        }
    );
}

what do you think about something like that ?

Comment From: wilkinsona

is that also the case for Jetty, Netty and other API.

IIRC, Netty isn't affected as it doesn't use a temporary directory. It is the case for Jetty, Tomcat, and Undertow, however.

Any web server that's using a temporary directory that we want to clean up may try to use it during shutdown. If we clean it up on a separate thread (as would happen when using a shutdown hook), there will be a race which may lead to unexpected failures or only partial clean up of the directory tree.

Let's continue any further design-related discussion on #9983, although please note that we have other priorities at the moment so it may be a little while before we can engage in that discussion.

Comment From: CharlesLgn

Let's continue any further design-related discussion on #9983, although please note that we have other priorities at the moment so it may be a little while before we can engage in that discussion.

Ok, no problemes. I will post the same thing in the discution to track the proposal