Bianconeri1988
Bianconeri1988

Reputation: 25

How to configure JDBC Resource in Embedded Tomcat 8?

I need to set up a connection pool for an application that uses an embedded Tomcat 8 application server. Normally, I would configure a new resource in the context.xml file. But of course, such a file does not exist when using the embedded version. The definition of the resource would look like this:

<Context>
    <Resource name="jdbc/dbname" auth="Container" type="javax.sql.DataSource" username="username" password="password" driverClassName="org.postgresql.Driver" description="Database" url="jdbc:postgresql://localhost:5432/dbname" maxActive="20" maxIdle="3" />
</Context> 

Therefore, there must be another solution for adding resources to a context. Is it possible to add the data source resource directly to the Standardcontext in code? If yes, how? Or how else can this be done when using the embedded version?

Upvotes: 1

Views: 1607

Answers (2)

John LaBarge
John LaBarge

Reputation: 158

The question was about embedded tomcat.

Upvotes: 0

SkyWalker
SkyWalker

Reputation: 29168

You can write your own factory and integrate it into Tomcat, and then configure the use of this factory in the element for the web application.

1. Write A Resource Factory Class

You must write a class that implements the JNDI service provider javax.naming.spi.ObjectFactory interface. Every time your web application calls lookup() on a context entry that is bound to this factory (assuming that the factory is configured with singleton="false"), the getObjectInstance() method is called.

To create a resource factory that knows how to produce MyBean instances, you might create a class like this:

package com.mycompany;

import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

public class MyBeanFactory implements ObjectFactory {

  public Object getObjectInstance(Object obj,
      Name name2, Context nameCtx, Hashtable environment)
      throws NamingException {

      // Acquire an instance of our specified bean class
      MyBean bean = new MyBean();

      // Customize the bean properties from our attributes
      Reference ref = (Reference) obj;
      Enumeration addrs = ref.getAll();
      while (addrs.hasMoreElements()) {
          RefAddr addr = (RefAddr) addrs.nextElement();
          String name = addr.getType();
          String value = (String) addr.getContent();
          if (name.equals("foo")) {
              bean.setFoo(value);
          } else if (name.equals("bar")) {
              try {
                  bean.setBar(Integer.parseInt(value));
              } catch (NumberFormatException e) {
                  throw new NamingException("Invalid 'bar' value " + value);
              }
          }
      }

      // Return the customized instance
      return (bean);

  }

}

In this example, we are unconditionally creating a new instance of the com.mycompany.MyBean class, and populating its properties based on the parameters included in the element that configures this factory (see below). You should note that any parameter named factory should be skipped - that parameter is used to specify the name of the factory class itself (in this case, com.mycompany.MyBeanFactory) rather than a property of the bean being configured.

2. Declare Your Resource Requirements

Next, modify your web application deployment descriptor (/WEB-INF/web.xml) to declare the JNDI name under which you will request new instances of this bean. The simplest approach is to use a element, like this:

<resource-env-ref>
  <description>
    Object factory for MyBean instances.
  </description>
  <resource-env-ref-name>
    bean/MyBeanFactory
  </resource-env-ref-name>
  <resource-env-ref-type>
    com.mycompany.MyBean
  </resource-env-ref-type>
</resource-env-ref>

WARNING - Be sure you respect the element ordering that is required by the DTD for web application deployment descriptors! See the Servlet Specification for details.

3. Code Your Application's Use Of This Resource

A typical use of this resource environment reference might look like this:

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
MyBean bean = (MyBean) envCtx.lookup("bean/MyBeanFactory");

writer.println("foo = " + bean.getFoo() + ", bar = " +
               bean.getBar());

4. Configure Tomcat's Resource Factory

To configure Tomcat's resource factory, add an elements like this to the element for this web application.

<Context ...>
  ...
  <Resource name="bean/MyBeanFactory" auth="Container"
            type="com.mycompany.MyBean"
            factory="com.mycompany.MyBeanFactory"
            singleton="false"
            bar="23"/>
  ...
</Context>

Resource Link:

  1. Adding Custom Resource Factories
  2. How to Configure JNDI DataSource in Tomcat 8 with Java Configuration:

For adding external resource in tomcat 8, you can follow this link: Adding external resources to class-path in Tomcat 8

Upvotes: 1

Related Questions