Documentation Home

Configuring JNDI Datasources with Tomcat

Tomcat Resources

We will need to make a few configuration changes to the tomcat context to add database resources.

You can configure the resources that are available to all applications deployed in tomcat in the context.xml file in the tomcat/conf directory. There are 3 different database connections for Broadleaf, 4 if you are using Broadleaf's eventing system which is the default for commercial customers. These must be defined as the following Spring beans:

  • webDS - where the majority of the Broadleaf entities are stored. This data source should have the most connections
  • webStorageDS - only used if image binary data is stored in the database, not the default. This can be set very low (1 connection)
  • webSecureDS - only used if storing credit card numbers in the database, not the default and not recommended. Also can be set very low at 1 connection
  • webEventDS - used with Broadleaf's eventing system. Connections do not need to be quite as high as webDS but this is dependent on how many Broadleaf background jobs you use or admin users that use sandboxing

Below is an example of creating the 4 data sources the Broadleaf requires in JNDI:

<Resource name="jdbc/web" auth="Container" type="javax.sql.DataSource"
               maxActive="30" maxIdle="60" maxWait="10000"
               username="username" password="password" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost/broadleaf?useUnicode=true;characterEncoding=utf8;"/>
<Resource name="jdbc/secure" auth="Container" type="javax.sql.DataSource"
               maxActive="1" maxIdle="1" maxWait="10000"
               username="username" password="password" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost/broadleaf?useUnicode=true;characterEncoding=utf8;"/>
<Resource name="jdbc/storage" auth="Container" type="javax.sql.DataSource"
               maxActive="1" maxIdle="1" maxWait="10000"
               username="username" password="password" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost/broadleaf?useUnicode=true;characterEncoding=utf8;"/>
<Resource name="jdbc/event" auth="Container" type="javax.sql.DataSource"
               maxActive="15" maxIdle="30" maxWait="10000"
               username="username" password="password" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost/broadleaf?useUnicode=true;characterEncoding=utf8;"/>

You can also externalize the majority of this configuration by setting environment variables on startup:

<Resource name="jdbc/web" auth="Container" type="javax.sql.DataSource"
               maxActive="30" maxIdle="60" maxWait="10000"
               username="${database.user}" password="${database.password}" driverClassName="${database.driver}"
               connectionProperties="useUnicode=true;characterEncoding=utf8;"
               url="${database.url}"/>
<Resource name="jdbc/secure" auth="Container" type="javax.sql.DataSource"
               maxActive="30" maxIdle="60" maxWait="10000"
               username="${database.user}" password="${database.password}" driverClassName="${database.driver}"
               connectionProperties="useUnicode=true;characterEncoding=utf8;"
               url="${database.url}"/>
<Resource name="jdbc/storage" auth="Container" type="javax.sql.DataSource"
               maxActive="30" maxIdle="60" maxWait="10000"
               username="${database.user}" password="${database.password}" driverClassName="${database.driver}"
               connectionProperties="useUnicode=true;characterEncoding=utf8;"
               url="${database.url}"/>
<Resource name="jdbc/event" auth="Container" type="javax.sql.DataSource"
               maxActive="30" maxIdle="60" maxWait="10000"
               username="${database.user}" password="${database.password}" driverClassName="${database.driver}"
               connectionProperties="useUnicode=true;characterEncoding=utf8;"
               url="${database.url}"/>

and then populate the properties in bin/setenv.sh (Unix) or bin/setenv.bat (Windows):

Unix bin/setenv.sh

export CATALINA_OPTS="-Xmx1536M -Ddatabase.user=username -Ddatabase.password=password -Ddatabase.driver=com.mysql.jdbc.Driver -Ddatabase.url=jdbc:mysql://localhost/broadleaf?useUnicode=true;characterEncoding=utf8;"

Windows bin/setenv.bat

set "CATALINA_OPTS=-Xmx1536M -Ddatabase.user=username -Ddatabase.password=password -Ddatabase.driver=com.mysql.jdbc.Driver -Ddatabase.url=jdbc:mysql://localhost/broadleaf?useUnicode=true;characterEncoding=utf8;"
exit /b 0

Next, you need to make sure that tomcat has access to the jar file that contains the driver class name that you specified for your database connection. This is done by placing the jar file in the tomcat/lib directory. In the example we are using MYSQL, so we downloaded the jar (https://dev.mysql.com/downloads/connector/j/) and then placed the mysql-connector-java.jar in the lib directory.

JNDI Datasource Lookup

Now that tomcat is configured with a datasource, we need to configure our project to use it. Spring makes this really easy with their JndiDataSourceLookup class. All we need to do is define a new spring bean for the datasource we want to specify and return the datasource that we have looked up by name, example:

@Bean
public DataSource webDS() throws NamingException {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    DataSource dataSource = dataSourceLookup.getDataSource("jdbc/web");
    return dataSource;
}

@Bean
public DataSource webSecureDS() throws NamingException {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    DataSource dataSource = dataSourceLookup.getDataSource("jdbc/secure");
    return dataSource;
}

@Bean
public DataSource webStorageDS() throws NamingException {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    DataSource dataSource = dataSourceLookup.getDataSource("jdbc/storage");
    return dataSource;
}

@Bean
public DataSource webEventDS() throws NamingException {
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    DataSource dataSource = dataSourceLookup.getDataSource("jdbc/event");
    return dataSource;
}