Newsletter

Spring Boot Configure DataSource Using JNDI with Example

We already saw the default approach to configure datasource, in this article I am going to explain you how to configure datasources using JNDI lookup in spring boot applications.  Before you read this article, I highly recommend to read How to Deploy Spring Boot Applications on External Tomcat Server.

Spring Boot : Steps to Configure JNDI DataSource with External Tomcat

  • Add a dependency to pom.xml to give support to our Spring Boot application to run on external servers and also add packaging war (I will explain this later 🙂 )
  • Extend main class with SpringBootServletInitializer and override its configure method
  • Add a property spring.datasource.jndi-name in application.properties
  • Create new folder webapp/META-INF under main and add context.xml (will see this later)
  • Generate a WAR and deploy into the external Tomcat Server, that’s it you are good to go 😉

Before all these, make sure you have datasource information in your external server’s server.xml 🙂 this is very very important. Add the below line in between <GlobalNamingResources/> tag.

<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" 
                           maxActive="20" 
                           maxIdle="0" 
                           maxWait="10000" 
                           name="jdbc/j4s" 
                           password="java4s" 
                           username="java4s"
                           type="javax.sql.DataSource" 
                           url="jdbc:mysql://localhost/test"/>

I have given my local details, just change accordingly, mainly you need to change username, password and url.

pom.xml

<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>com.java4s</groupId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <artifactId>SpringBootDataSourceConfigJNDILookUp</artifactId>
  
  	<parent>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-parent</artifactId>
	    <version>1.5.6.RELEASE</version>
	</parent>
	
	<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>
        </dependency>    
		<dependency>
		    <groupId>mysql</groupId>
		    <artifactId>mysql-connector-java</artifactId>
		</dependency>		
		<dependency>
		   <groupId>org.springframework.boot</groupId>
		   <artifactId>spring-boot-starter-tomcat</artifactId>
		   <scope>provided</scope>
		</dependency>
	</dependencies>

	<properties>
	 	<java.version>1.8</java.version>
	</properties>
	
</project>

SpringBootApp.java

package com.java4s.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class SpringBootApp extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootApp.class, args);
	}
	
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(SpringBootApp.class);
	}
}

application.properties

spring.datasource.jndi-name=java:comp/env/jdbc/j4s

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<context>
	<ResourceLink auth="Container" name="jdbc/j4s" global="jdbc/j4s" type="javax.sql.DataSource" />
</context>

Make sure value in global attribute should match with the name attribute’s value in server.xml’s Resource tag (read again if you didn’t understand 🙂 ), I hope you know the basic JNDI concept.

lets see other supporting files that I have used in this example.

SpringJava4sController.java

package com.java4s.app.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.java4s.app.repository.SpringJava4sDAO;
import com.java4s.model.Customer;

@RestController
public class SpringJava4sController {
	
	@Autowired
	public SpringJava4sDAO dao;
	
	@RequestMapping("/get-cust-info")
	public List<Customer> customerInformation() {
		
		List<Customer> customers = dao.isData();		 
		
		return customers;
	}
}

SpringJava4sDAO.java

package com.java4s.app.repository;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.java4s.model.Customer;

@Repository
public class SpringJava4sDAO {
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	private static final String SQL = "select * from customers";
	
	public List<Customer> isData() {
		
		List<Customer> customers = new ArrayList<Customer>();

		List<Map<String, Object>> rows = jdbcTemplate.queryForList(SQL);
		
		for (Map<String, Object> row : rows) {
			Customer customer = new Customer();
			
			customer.setCustNo((int)row.get("Cust_id"));
			customer.setCustName((String)row.get("Cust_name"));
			customer.setCountry((String)row.get("Country"));
			
			customers.add(customer);
		}

		return customers;
		
	}
}

Customer.java

package com.java4s.model;

public class Customer {
	
	private int custNo;
	private String custName;
	private String country;
	
	public Customer() {		
	}
	
	public Customer(int custNumber, String custName, String country) {
		this.custNo = custNumber;
		this.custName = custName;
		this.country = country;
	}

	public int getCustNo() {
		return custNo;
	}

	public void setCustNo(int custNo) {
		this.custNo = custNo;
	}

	public String getCustName() {
		return custName;
	}

	public void setCustName(String custName) {
		this.custName = custName;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}	
}

Now just right click on the application > Run As > Maven install  ::. this will generate a WAR file in your applications target folder.  Now you can import that WAR and verify the changes.

Output

You can download and play with the code 🙂

 

Spring Boot : Steps to Configure JNDI DataSource with Embedded Tomcat

Lets compare the steps we have followed for the configuration done above for external tomcat server, for Embedded tomcat…

  • No need to add any external dependency
  • No need to extend main class with SpringBootServletInitializer
  • No need to add spring.datasource.jndi-name in application.properties
  • No need to create webapp/META-INF and context.xml
  • No need to generate WAR 

Rather just add one more java class which takes care of datasource and JNDI configuration 🙂 that’s it. Very easy with embedded tomcat.

TomcatConfigs.java

package com.java4s.app.configs;

import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.tomcat.util.descriptor.web.ContextResource;
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.Configuration;
import org.springframework.jndi.JndiObjectFactoryBean;

@Configuration
public class TomcatConfigs {
	
	 @Bean
	 public TomcatEmbeddedServletContainerFactory tomcatFactory() {
	        
		 return new TomcatEmbeddedServletContainerFactory() {
	          
	           @Override
	           protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) 
	           {
	                tomcat.enableNaming();
	                return super.getTomcatEmbeddedServletContainer(tomcat);
	            }
	        	
	            @Override
	            protected void postProcessContext(Context context) 
	            {
	                ContextResource resource = new ContextResource();

	                resource.setType(DataSource.class.getName());
	                resource.setName("j4s");
	                resource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
	                resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
	                resource.setProperty("url", "jdbc:mysql://localhost/test");
	                resource.setProperty("username", "java4s");
	                resource.setProperty("password", "java4s");
	                
	                context.getNamingResources().addResource(resource);
	            }
	        };
	    }
	 
	    @Bean
	    public DataSource jndiDataSource() throws IllegalArgumentException, NamingException 
	    {
	        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();    
	        bean.setJndiName("java:/comp/env/j4s");
	        bean.setProxyInterface(DataSource.class);
	        bean.setLookupOnStartup(false);
	        bean.afterPropertiesSet();
	        
	        return (DataSource) bean.getObject();
	    }
}

Output

Hope you enjoy the article and consider sharing this with your friends 🙂 BTW download the code and play with it.

​​

You Might Also Like

  ::. About the Author .::

Java4s_Author
- Java/J2EE Full Stack Developer
Founder of Java4s - Get It Yourself, A popular Java/J2EE Programming Blog, Love Java and UI frameworks.
You can sign-up for the Email Newsletter for your daily dose of Java tutorials.

Comments

2 Responses to “Spring Boot Configure DataSource Using JNDI with Example”
  1. venkatesh says:

    please provide in java latest topics interview questions

  2. swapna says:

    Hi Sivateja,

    I want develop spring boot 2.0.3 with spring boot jpa and DB is oracle that should be deploy in websphere 9.0.0.7.Normal DB url,un,pwd with these properties its deployed successfully into WAS. Now i want to use JNDI ,even i have created datasource also but its not binding to my JpaRepository extended classes( unable bean creation xxxRepositiry). How to use that data source into my repository classes. Please post a example for it.

Name*
Mail*
Website



By posting your answer, you agree to our comments policy.
Most Recent Posts from Top Categories
Spring Boot Hibernate Spring
Contact | About Us | Privacy Policy | Advertise With Us

© 2010 - 2018 Java4s - Get It Yourself.
The content is copyrighted to Sivateja Kandula and may not be reproduced on other websites.