I have spring mvc application and Tomcat 7.0.21 as a servlet container.
And when I'm trying to use jdbcTemplate in my application it doesn't redeploy correctly -
it prevents jvm from cleaning PermGen memory.
The simple example of bad code is the following
(of course breaking mvc concept for the sake of simplicity):
@Controller
class MainController {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@RequestMapping("/")
public String mainPage() {
jdbcTemplate.queryForObject("SELECT val FROM tbl WHERE id=1",
String.class);
return "main";
}
}
without jdbcTemplate.queryForObject(...)
it works perfectly, but
with it when deploying to tomcat it says that:
Sep 21, 2011 1:54:38 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/my] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Sep 21, 2011 1:54:38 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/my] appears to have started a thread named [Timer-0] but has failed to stop it. This is very likely to create a memory leak.
And after that I can see in VisualVM a growth in PermGen each time the app is redeployed.
Of course I can just restart my production server each time when I want
to redeploy my app, but I want to figure out what's wrong.
P.S.: datasource implementation:
@Configuration
public class ApplicationConfig {
@Bean
DataSource dataSource(@Value("${jdbc.driver}") String driver,
@Value("${jdbc.url}") String url, @Value("${jdbc.user}") String user,
@Value("${jdbc.password}") String password) {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(user);
ds.setPassword(password);
return ds;
}
}