views:

508

answers:

1

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 container 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

  1. 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>
    
  2. 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?

A: 

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 a java.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>
Pascal Thivent
It seems that even when my jetty-plus.xml is a broken XML (like having an unclosed '/Call>' tag), I am getting the very same exception as if the configuration file is completely ignored by Jetty. I copy the configuration from the jetty-plus.xml into the [jetty]/etc/jetty.xml and correct the XML the datasources are still not registered with JNDI.
peter
@peter Hard to say anything without seeing what you're doing. But these instructions http://docs.codehaus.org/display/JETTY/JNDI definitely work.
Pascal Thivent