Atomikos Forum |
|
I am using Tomcat 6.0.29 and Atomikos 3.6.5.
I have configured all steps as described in http://www.atomikos.com/Documentation/Tomcat6Integration35 When I try to deploy the dbtest.war sample application to a Tomcat 6.0.29, everything seems to work fine. However, if I reload the application (hot deployment) and then try to run it, I always get following stacktrace: DBTest >> javax.naming.NamingException: error creating AtomikosDataSourceBean [Root exception is com.atomikos.jdbc.AtomikosSQLException: Cannot initialize AtomikosDataSourceBean] at com.atomikos.tomcat.BeanFactory.getObjectInstance(BeanFactory.java:76) at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:140) at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304) at org.apache.naming.NamingContext.lookup(NamingContext.java:793) at org.apache.naming.NamingContext.lookup(NamingContext.java:140) at org.apache.naming.NamingContext.lookup(NamingContext.java:781) at org.apache.naming.NamingContext.lookup(NamingContext.java:140) at org.apache.naming.NamingContext.lookup(NamingContext.java:781) at org.apache.naming.NamingContext.lookup(NamingContext.java:140) at org.apache.naming.NamingContext.lookup(NamingContext.java:781) at org.apache.naming.NamingContext.lookup(NamingContext.java:153) at org.apache.naming.SelectorContext.lookup(SelectorContext.java:152) at javax.naming.InitialContext.lookup(InitialContext.java:392) at foo.DBTest.init(DBTest.java:24) at org.apache.jsp.test_jsp._jspService(test_jsp.java:63) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:92) at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:409) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: com.atomikos.jdbc.AtomikosSQLException: Cannot initialize AtomikosDataSourceBean at com.atomikos.jdbc.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:19) at com.atomikos.jdbc.AbstractDataSourceBean.init(AbstractDataSourceBean.java:253) at com.atomikos.tomcat.BeanFactory.getObjectInstance(BeanFactory.java:72) ... 36 more Caused by: javax.naming.NamingException: Another resource already exists with name jdbc/myDB - pick a different name at com.atomikos.util.IntraVmObjectFactory.createReference(IntraVmObjectFactory.java:69) at com.atomikos.jdbc.AbstractDataSourceBean.getReference(AbstractDataSourceBean.java:335) at com.atomikos.jdbc.AbstractDataSourceBean.init(AbstractDataSourceBean.java:242) ... 37 more Now I have to completely stop my tomcat server and restart it before the problem is solved. The context file of the dbtest.war looks like this: <Context antiJARLocking="true"> <Resource name="jdbc/myDB" auth="Container" type="com.atomikos.jdbc.AtomikosDataSourceBean" factory="com.atomikos.tomcat.BeanFactory" uniqueResourceName="jdbc/myDB" xaDataSourceClassName="org.apache.derby.jdbc.EmbeddedXADataSource" maxPoolSize="3" xaProperties.databaseName="../work/users1" xaProperties.createDatabase="create" /> </Context> It appears that tomcat bounds this resource to a unique name and this is not unloaded after the application is unloaded. If it is restarted, it tries to bind this again which fails because it is already loaded. Regular JDBC resources do not experience this behavior. Does anybody recognize this problem? Is there a solution for this so that the application can be reloaded without completely stopping the server? Frederick
Guy,
The problem is that this datasource is not managed by Spring but by the Tomcat instance. This is loaded in JNDI and then used by Spring as a datasource bean. Do you have any idea how I can unload the datasource when the application is unloaded or prevent it from being reloaded when already loaded? It is only a problem when I use the AtomikosDatasourceBean, other datasource driver do not seem to have this problem. Is it a possibility to adapt the behaviour of the datasource so that it re-uses the same datasource if this is already loaded by an (external) container? Frederick
Tomcat does not provide a lifecycle management for JNDI resources. The resource is created with the first request for a this resource. But the resource will never be closed by Tomcat when the web app is stopped.
A solution is to write your own JNDI lifecycle manager for Tomcat. Guy already mentioned another solution to let spring manage the resources.
Hi, I did a workaround for Tomcat hot-deploy "resource name exists" issue.
I just added following code in my BeanFactory.java try { Object o = IntraVmObjectRegistry.getResource(myName); if (o != null) { AbstractDataSourceBean o1 = (AbstractDataSourceBean)o; o1.close(); IntraVmObjectRegistry.removeResource(myName); } } catch (Exception e) { } It works fine in my development environment. But I am not sure is it suitable for production. Any input will be of great help! Thank you. Albert |