Spring ApplicationContext - Resource leak: 'context' is never closed

Since the app context is a ResourceLoader (i.e. I/O operations) it consumes resources that need to be freed at some point. It is also an extension of AbstractApplicationContext which implements Closable. Thus, it's got a close() method and can be used in a try-with-resources statement.

try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/userLibrary.xml")) {
  service = context.getBean(UserLibrary.class);
}

Whether you actually need to create this context is a different question (you linked to it), I'm not gonna comment on that.

It's true that the context is closed implicitly when the application is stopped but that's not good enough. Eclipse is right, you need to take measures to close it manually for other cases in order to avoid classloader leaks.


As the Application context has an instance of ClassPathXmlApplicationContext and the same has a close() method. I would simply CAST the appContext object and invoke the close() method as below.

ApplicationContext appContext = new ClassPathXmlApplicationContext("spring.xml");
//do some logic
((ClassPathXmlApplicationContext) appContext).close();

This will fix the Resource Leak warning.


A simple cast solves the issue:

((ClassPathXmlApplicationContext) fac).close();

close() is not defined in ApplicationContext interface.

The only way to get rid of the warning safely is the following

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...);
try {
    [...]
} finally {
    ctx.close();
}

Or, in Java 7

try(ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(...)) {
    [...]
}

The basic difference is that since you instantiate the context explicitly (i.e. by use of new) you know the class you are instantiating, so you can define your variable accordingly.

If you were not instantiating the AppContext (i.e. using the one provided by Spring) then you couldn't close it.