java - How to Close HikariCP JNDI DataSource on Shutdown/Redeploy -
i using hikaricp 2.3.3 spring , jetty 9 , trying resolve fact when hot deploy new war file, of hikari database pool connections mysql left open , idle. using jndi lookup in spring applicationcontext file retrieve datasource jetty context file.
since cannot specify destroy-method in jndi-lookup can if define datasource bean, referred question: should close jndi-obtained data source?, mentions can attempt close datasource in contextdestroyed() method of servletcontextlistener. in case using tomcat , c3po i'm not sure how example relates.
i have tried following in contextdestroyed method:
initialcontext initial; datasource ds; try { initial = new initialcontext(); ds = (datasource) initial.lookup("jdbc/mydb"); if (ds.getconnection() == null) { throw new runtimeexception("failed find jndi datasource"); } hikaridatasource hds = (hikaridatasource) ds; hds.close(); } catch (namingexception | sqlexception ex) { logger.getlogger(settingsinitializer.class.getname()).log(level.severe, null, ex); }
but @ hikaridatasource hds = (hikaridatasource) ds; following exception: java.lang.classcastexception: com.zaxxer.hikari.hikaridatasource cannot cast com.zaxxer.hikari.hikaridatasource
i have tried following after reading issue on github: is essential call shutdown()
on hikaridatasource?:
initialcontext initial; datasource ds; try { initial = new initialcontext(); ds = (datasource) initial.lookup("jdbc/mydb"); ds.unwrap(hikaridatasource.class).close(); } catch (namingexception | sqlexception ex) { logger.getlogger(settingsinitializer.class.getname()).log(level.severe, null, ex); }
but following exception: java.sql.sqlexception: wrapped connection not instance of class com.zaxxer.hikari.hikaridatasource @ com.zaxxer.hikari.hikaridatasource.unwrap(hikaridatasource.java:177)
i feel i'm close working solution can't quite it. proper way close jndi hikaricp data source, whether in contextdestroyed() or elsewhere?
i can't find 2.3.3 code lines hikaridatasource.java:177
line number above. 1 suggestion upgrading latest hikaricp version, 2.3.8.
while code looks correct, suspect running classloader issue, whereby hikaridatasource (class) loaded jetty/spring classloader , registered in jndi not same classloader loading hikaridatasource in web app.
one quick way check log/print both class instances so:
... ds = (datasource) initial.lookup("jdbc/mydb"); logger.info("jndi hikaridatasource : " + system.identityhashcode(ds.getclass())); logger.info("local hikaridatasource: " + system.identityhashcode(hikaridatasource.class)); ...
if 2 class objects have different hashcodes, not same class. in case have investigate whether jndi instance registered in "global jndi context". if is, datasource can shared across web app instances, , not appropriate web app unilaterally shut down.
update: sorry missed it. re-reading question, guess correct. original error:
java.lang.classcastexception: com.zaxxer.hikari.hikaridatasource cannot cast com.zaxxer.hikari.hikaridatasource
is clear indication there 2 classloaders have loaded 2 separate instances of hikaridatasource class. first jetty classloader (jndi), , second web application classloader.
this indicates pool shared across web applications , should not try shut down application context.
Comments
Post a Comment