Monday, January 21, 2008

JNDI with jetty-env.xml

JNDI with jetty-env.xml

It toke me a couple hours to figure out how to setup a JNDI datasource in jetty-env.xml. So hopefully this will save some time for others trying to do the same.

In my case I'm using maven 2 to manage my web project and maven-jetty-plugin to quickly test the application. The project use JPA for ORM and I'm using Spring JPA support for configuration.

So this is what you need to do:

  1. Tell jetty the location of the jetty-env.xml files in the pom
    <build>
    <plugins>
    <plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <version>6.1.6</version>
    <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <jettyEnvXml>${basedir}/src/test/resources/jetty-env.xml</jettyEnvXml>
    </configuration>
    ....
    <dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-plus</artifactId>
    <version>6.1.6</version>
    </dependency>
    <dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty-naming</artifactId>
    <version>6.1.6</version>
    </dependency>
    </plugin>
    ....
    </plugins>
    ....
    </build>
  2. Create the jetty-env.xml configuration file, for example:
    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
    <Configure class="org.mortbay.jetty.webapp.WebAppContext">
    <Set name="contextPath">/dev</Set>
    <New id="LibraryDS" class="org.mortbay.jetty.plus.naming.Resource">
    <Arg>jdbc/LibraryDS</Arg>
    <Arg>
    <New class="org.apache.commons.dbcp.BasicDataSource">
    <Set name="Url">jdbc:mysql://localhost:3306/fornaxDS</Set>
    <Set name="DriverClassName">com.mysql.jdbc.Driver</Set>
    <Set name="Username">admin</Set>
    <Set name="Password">adminpasswd</Set>
    <Set name="MaxActive">30</Set>
    <Set name="MaxIdle">10</Set>
    <Set name="MinIdle">2</Set>
    <Set name="MaxWait">5000</Set>
    <Set name="MinEvictableIdleTimeMillis">25000</Set>
    <Set name="TimeBetweenEvictionRunsMillis">30000</Set>
    </New>
    </Arg>
    </New>
    </Configure>
        
  3. Add a resource-env-ref to your web.xml:
    <resource-env-ref>
    <resource-env-ref-name>jdbc/LibraryDS</resource-env-ref-name>
    <resource-env-ref-type>
    javax.sql.DataSource
    </resource-env-ref-type>
    </resource-env-ref>
  4. Define your sessionFactory as follow:
    <bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory">
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <prop key="hibernate.query.substitutions">true 1, false 0</prop>
    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>

    <prop key="hibernate.connection.datasource">java:comp/env/jdbc/LibraryDS</prop>
    <prop key="hibernate.cache.use_query_cache">true</prop>
    <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
    <prop key="hibernate.current_session_context_class">org.hibernate.context.ManagedSessionContext</prop>
    <prop key="hibernate.transaction.auto_close_session">false</prop>
    </props>
    </property>
    ....
    </bean>

What is not obvious (I did not read the document carefully enough) is that "Object bindings declared in jetty-env.xml will automatically be bound into the java:comp/env namespace",