Newsletter

Spring Boot Configure DataSource Using JNDI with Example

Spring-Boot-Tutorials » on Aug 14, 2018 { 15 Comments } By Sivateja

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
Sivateja Kandula - 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

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

    Hello…
    is it possible to configure a javax.servlet.Filter in spring boot and that Filter should be executed before the request is reaching to DispatcherServlet?

  2. venkatesh says:

    please provide in java latest topics interview questions

  3. 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.

    • Mukesh Kumar says:

      Hi Swapna,

      I am also facing same issue. Did your issue got fixed? Please let me know too how you fixed this issue.

  4. Rachid says:

    Hallo Sivateja

    I added this to context.xml of extern tomcat.

    <Resource name="jdbc/myDB" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000"
    username="test" password="test" driverClassName="com.mysql.jdbc.Driver"
    removeAbandoned="true"
    validationQuery="Select 1"
    url="jdbc:mysql://localhost:3306/myDB?autoReconnect=true"/>

    And my application.propeties

    server.contextPath=/springboot-jndi-lookup
    spring.datasource.jndi-name=java:comp/env/jdbc/myDB
    server.port = 8090
    spring.data.rest.default-page-size=5

    And if I try to test it http://localhost:8090/get-cust-info

    I get this message: Ups, something went wrong! NetworkError when attempting to fetch resource.

    Could you please help to solve this problem?

  5. Java says:

    Nice Tuto……………

    • Nagendra says:

      Hi ,

      Hi I have created on RS web service using Liberty WAS server. where I ma using :
      @Resourse("JDBC/mydb")
      DataSource ds;

      and JNDI configuration are in Server.xml file.

      I am using ds.getConnection() ; means Java JDBC normal connection ;

      Now I Migrate the Web Service with Spring Boot Micro Service with using JersyConfig
      but JNDI configuration where need to chnage as embeeded container : I dont want to use default jdbctemplate because I have to change coding as well. Please can you provide any solution.

  6. Herny says:

    Hi, I want to know how to set lookuponstartUp property in a YML file. I'm not using tomcat embebed.Thank you.

  7. Ashok says:

    Excellent Article, Simple and Smart solution. Thank you.

  8. Sachin says:

    Hi,

    I had gone through this article and it is very nice article and explains in details for embedded tomcat also as to how to do a JNDI look up.I have similar requirement.Can you please guide me on what all necessary changes to do if I want to do this for XA datasource for DB2.

  9. Sachin says:

    Hi Sivateja,
    This is a very nice article.Thanks for writing such a good article.But can you please help me to do the same for DB2 xa datsource for embedded tomcat.
    I am actually struggling to do this and don't know what is the correct way to do this.

  10. sandeep says:

    Thanks a lot, bro!!

  11. Rupali says:

    Hi Sivteja,
    I followed your configuration steps for external Tomcat and it worked 🙂, but now same application I want to execute in STS with no change in code, Can you help me to understand how it will work?

  12. Dani says:

    Hi all,

    This class worked fine and I could create a JNDI datasource.

    But its failing when running my tests with "mvn test". The next error only appears when I have the configuration class "TomcatConfigs" as described in the tutorial:

    Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or in an application resource file: java.naming.factory.ini
    tial

    Anyone have executed Tests in these conditions?

    Thanks in advance.

  13. Ravi Ranjan says:

    Is there any way to do the same for the embedded netty server for spring webflux?

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 - 2024 Java4s - Get It Yourself.
The content is copyrighted to Sivateja Kandula and may not be reproduced on other websites.