1. Overview

In this article, We will see Spring boot JNDI datasource Example.  JNDI Datasource needs to be configured at the server level in our case it will be in tomcat configuration.  Main advantages JNDI data sources is that application does not worry about database configuration because it defined in tomcat’s configuration and another advantage is that multiple application in the same tomcat can use same JNDI datasouce.

2. Example

Spring boot JNDI Datasource Example

Spring boot JNDI Datasource Example

2.1 pom.xml

  • spring-boot-starter-jdbc contains JDBC related class of spring.
  • mysql-connector-java is MySQL Driver
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>spring-boot-example</groupId>
    <artifactId>spring-boot-datasource-example</artifactId>
    <version>1.0-SNAPSHOT</version>
    <description>Spring boot JNDI datasource Example</description>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>   <!--It contains database base related classes-->
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>
    <!-- Package as an executable jar -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.2 SpringBootConfig

  • Spring boot provide embedded tomcat, so here we have created TomcatEmbeddedServletContainerFactory and define JNDI database configuration in ContextResource. If want to  deploy .war file inside tomcat then create define JNDI properties inside tomcat XML configurations.
  • DataSource bean has been created using JNDI data source.
  • If we do not like Java configuration for Lookup JNDI data source then spring boot also provides spring.datasource.jndi-name configuration that we can write in application.properties
package com.javadeveloperzone;
import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.ContextResource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.jndi.JndiObjectFactoryBean;
import javax.naming.NamingException;
import javax.sql.DataSource;
/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */
@SpringBootApplication
@ComponentScan
// Using a root package also allows the @ComponentScan annotation to be used without needing to specify a basePackage attribute
public class SpringBootConfig {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootConfig.class, args);            // it wil start application
    }
    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatFactory() {  // if datasouce defind in tomcat xml configuration then no need to create this bean
        return new TomcatEmbeddedServletContainerFactory() {
            @Override
            protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                    Tomcat tomcat) {
                tomcat.enableNaming();
                return super.getTomcatEmbeddedServletContainer(tomcat);
            }
            @Override                   // create JNDI resource
            protected void postProcessContext(Context context) {
                ContextResource resource = new ContextResource();
                resource.setName("jndiDataSource");
                resource.setType(DataSource.class.getName());
                resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
                resource.setProperty("url", "jdbc:mysql://localhost/demo_database");
                resource.setProperty("username", "root");
                resource.setProperty("password", "");
                context.getNamingResources().addResource(resource);
            }
        };
    }
    @Bean
    public DataSource jndiDataSource() throws IllegalArgumentException,
                                              NamingException {
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();           // create JNDI data source
        bean.setJndiName("java:/comp/env/jndiDataSource");  // jndiDataSource is name of JNDI data source 
        bean.setProxyInterface(DataSource.class);
        bean.setLookupOnStartup(false);
        bean.afterPropertiesSet();
        return (DataSource) bean.getObject();
    }
}

2.3 EmployeeController

The controller will return the list of Employee which are available in specified data source using JNDI.

package com.javadeveloperzone.controller;
import com.javadeveloperzone.dao.EmployeeDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * Created by JavaDeveloperZone on 19-07-2017.
 */
@RestController
public class EmployeeController {
    @Autowired
    private EmployeeDAO employeeDAO;
    @RequestMapping("/getEmployeeList")
    public java.util.List getEmployeeList() {
        return employeeDAO.getEmployeeList();
    }
}

2.4 EmployeeDAO

Here, We have fetched all Employee which are available inside employee table using JDBC Templates.

package com.javadeveloperzone.dao;
import com.javadeveloperzone.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * Created by JavaDeveloperZone on 03-08-2017.
 */
@Component
public class EmployeeDAO {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public java.util.List<Employee> getEmployeeList() {
        List<Map<String, Object>> employees = jdbcTemplate.queryForList("select * from employee");
        return employees.stream().map(e -> {
            Employee employee = new Employee();
            employee.setEmployeeName((String)e.get("employeeName"));
            employee.setEmployeeId((Integer) e.get("employeeId"));
            employee.setEmployeeRole((String) e.get("employeeRole"));
            return employee;
        }).collect(Collectors.toList());
    }
}

2.5 Employee

package com.javadeveloperzone.model;
/**
 * Created by JavaDeveloperZone on 03-08-2017.
 */
public class Employee {
    private int employeeId;
    private String employeeName;
    private String employeeRole;
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeRole() {
        return employeeRole;
    }
    public void setEmployeeRole(String employeeRole) {
        this.employeeRole = employeeRole;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
}

2.6 Output

Let’s retrieve data  http://localhost:8080/getEmployeeList

Spring boot JNDI Datasource Example - Output

Spring boot JNDI Datasource Example – Output

3. Conclusion

In this article, We learned about how we can configure JNDI Datasource with spring boot application.

4. References

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *