

Table of Contents
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
2.1 pom.xml
- spring-boot-starter-jdbccontains JDBC related class of spring.
- mysql-connector-javais 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 TomcatEmbeddedServletContainerFactoryand define JNDI database configuration inContextResource.If want to deploy .war file inside tomcat then create define JNDI properties inside tomcat XML configurations.
- DataSourcebean 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-nameconfiguration that we can write inapplication.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
3. Conclusion
In this article, We learned about how we can configure JNDI Datasource with spring boot application.

 
  
 