Jetty datasource with Atomikos UserTransaction
I have two datasources in my Web application (principalDB and backupDB) on two Postgresql DBs, and a web container managed transaction manager (with Atomikos) for them. Spring FW and Hibernate are my building blocks for the application. The problem I am running into is that Jetty 6.1.3 web containe开发者_StackOverflow中文版r does not seem to load the app specific WEB-INF/jetty-env.xml that declares the resources so I am getting an exception:
Caused by: javax.naming.NameNotFoundException; remaining name 'env/jdbc/principalDB' at org.mortbay.naming.NamingContext.lookup(NamingContext.java:634) at org.mortbay.naming.NamingContext.lookup(NamingContext.java:665) at org.mortbay.naming.NamingContext.lookup(NamingContext.java:680) at org.mortbay.naming.java.javaRootURLContext.lookup(javaRootURLContext.java:112) at javax.naming.InitialContext.lookup(InitialContext.java:351) at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:155) at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:88) at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:153) at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178) at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95) at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105) at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:200) at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:186) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1368) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1334) ... 43 more
Here is how I configured the two datasources
in the
WEB-INF/web.xml
I have declared the two resources with resource-ref as:<resource-ref> <description>The principal datasource</description> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-ref-name>jdbc/principalDB</res-ref-name> </resource-ref> <resource-ref> <description>The backup datasource</description> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-ref-name>jdbc/backupDB</res-ref-name> </resource-ref>
in the
WEB-INF/jetty-env.xml
I have<New id="principalDB" class="org.mortbay.jetty.plus.naming.Resource"> <Arg><Ref id="wac"/></Arg> <Arg>jdbc/principalDB</Arg> <Arg> <New class="com.atomikos.jdbc.nonxa.NonXADataSourceBean"> <Set name="driverClassName">org.postgresql.jdbc3.Jdbc3ConnectionPool</Set> <Set name="ServerName">localhost</Set> <Set name="PortNumber">5432</Set> <Set name="DatabaseName">first</Set> <Set name="Url">jdbc:postgresql://localhost:5432/first</Set> <Set name="user">test</Set> <Set name="password">password</Set> </New> </Arg> </New> <New id="backupDB" class="org.mortbay.jetty.plus.naming.Resource"> <Arg><Ref id="wac"/></Arg> <Arg>jdbc/backupDB</Arg> <Arg> <New class="com.atomikos.jdbc.nonxa.NonXADataSourceBean"> <Set name="driverClassName">org.postgresql.jdbc3.Jdbc3ConnectionPool</Set> <Set name="ServerName">localhost</Set> <Set name="PortNumber">5432</Set> <Set name="DatabaseName">second</Set> <Set name="Url">jdbc:postgresql://localhost:5432/second</Set> <Set name="user">testSec</Set> <Set name="password">password</Set> </New> </Arg> </New>
What am I doing wrong?
Make sure you followed Step 1 and Step 2 of http://docs.codehaus.org/display/JETTY/Atomikos (assuming you are using Atomikos 3.3 and onwards).
Then, for the Step 3, pay a special attention to this note:
as the
NonXADataSourceBean
uses only the class name and url of ajava.sql.Driver
, you can use it with any database providing a JDBC driver.
So your current setup contains too much things but, more important, the driver class name looks wrong, it should be org.postgresql.Driver
.
But the PostgreSQL JDBC driver does support XADatasource
(with the org.postgresql.xa.PGXADataSource
implementation) so I'd rather configure a AtomikosDataSourceBean
(the first option of Step 3). Something like that:
<New id="mydatasource" class="org.mortbay.jetty.plus.naming.Resource">
<Arg><Ref id='wac'/></Arg>
<Arg>jdbc/mydatasource</Arg>
<Arg>
<New class="com.atomikos.jdbc.AtomikosDataSourceBean">
<Set name="minPoolSize">2</Set>
<Set name="maxPoolSize">20</Set>
<Set name="xaDataSourceClassName">org.postgresql.xa.PGXADataSource</Set>
<Set name="xaProperties">
<New class="java.util.Properties">
<Call name="setProperty"><Arg>databaseName</Arg><Arg>testdb</Arg></Call>
<Call name="setProperty"><Arg>serverName</Arg><Arg>localhost</Arg></Call>
<Call name="setProperty"><Arg>portNumber</Arg><Arg>5432</Arg></Call>
<Call name="setProperty"><Arg>user</Arg><Arg>test</Arg></Call>
<Call name="setProperty"><Arg>password</Arg><Arg>p4ssw0rd</Arg>/Call>
</New>
</Set>
<Set name="UniqueResourceName">mydatasource</Set>
</New>
</Arg>
</New>
精彩评论