This tutorial helps you to configure JNDI in Spring Boot application with external Apache Tomcat server.

Spring Boot JNDI Configuration:

A complete guide for Spring Boot JNDI with Apache Tomcat 9 server configuration.

Technologies:

  • Spring Boot 1.5.16.BUILD-SNAPSHOT
  • Spring JDBC
  • MySQL
  • Apache Tomcat 9.0.8
  • Java 8
  • Maven
  • IntelliJ

Application Structure:

Spring Boot JNDI Configuration

Preparing Application to be deployable on External Tomcat:

  • As we are going to deploy our application on an external tomcat instance, we should generate the war file out of it. To make it happen we need to declare packaging as a war in pom.xml
pom.xml
<packaging>war</packaging>
  • The main class of the Spring Boot should extends theĀ  SpringBootServletInitializer abstract class and override the configure(SpringApplicationBuilder builder) method.
Application.java
public class Application extends SpringBootServletInitializer {
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

    return application.sources(Application.class);

  }
}

Configuring JNDI on Tomcat Server:

Step1:

Open server.xml file under /conf folder and add the below configuration under the <GlobalNamingResources> tag.

tomcat/conf/server.xml
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" 
                           maxActive="20" 
               global="jdbc/otp"
                           maxIdle="0" 
                           maxWait="10000" 
                           name="jdbc/otp" 
                           password="Chandu@123" 
                           username="root"
                           type="javax.sql.DataSource" 
                           url="jdbc:mysql://localhost:3306/otp"/>

The above Resource tag allows you to give all configuration details about your database. As I am going to connect with the MySQL database, I gave the driverClassName as com.mysql.jdbc.Driver, if you are using Oracle database, you have to give appropriate oracle driver name.

Here the name attribute represents the JNDI name and the username, password, URL, and type are self-explanatory.

Step2:

Open context.xml file under the same /conf folder and add the below

tomcat/conf/context.xml
<ResourceLink name="jdbc/otp"
              global="jdbc/otp"
              auth="Container" type="javax.sql.DataSource" />

Note: The global attribute value should be equal to the name of the JNDI defined in the server.xml file.

Complete Spring Boot JNDI Example:

pom.xml
<?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>com.onlinetutorialspoint</groupId>
  <artifactId>SpringBoot-JNDIConfig-Example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>SpringBoot-JNDIConfig-Example</name>
  <description>Demo project for Spring Boot</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.16.BUILD-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </pluginRepository>
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </pluginRepository>
  </pluginRepositories>
</project>

Configuring JNDI resource name (defined in server.xml file) in application.properties file.

application.properties
spring.datasource.jndi-name=java:comp/env/jdbc/otp

Creating Item Repository:

ItemRepository.java
package com.onlinetutorialspoint.repo;

import com.onlinetutorialspoint.model.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class ItemRepository {

    @Autowired
    JdbcTemplate template;

    /*Getting all Items from table*/
    public List<Item> getAllItems(){
        List<Item> items = template.query("select id, name,category from item",(result,rowNum)->new Item(result.getInt("id"),
                result.getString("name"),result.getString("category")));
        return items;
    }
    /*Getting a specific item by item id from table*/
    public Item getItem(int itemId){
        Item item = null;
        String query = "SELECT * FROM ITEM WHERE ID=?";
        try{
            item = template.queryForObject(query,new Object[]{itemId},new BeanPropertyRowMapper<>(Item.class));
        }catch(Exception e){
            e.printStackTrace();
        }
        return item;
    }
}

Creating a Model class.

Item.java
package com.onlinetutorialspoint.model;

public class Item {
    private int id;
    private String name;
    private String category;

    public Item() {
    }

    public Item(int id, String name, String category) {
        this.id = id;
        this.name = name;
        this.category = category;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }
}

Creating Controller.

ItemController.java
package com.onlinetutorialspoint.controller;

import com.onlinetutorialspoint.model.Item;
import com.onlinetutorialspoint.repo.ItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.List;

@RestController
public class ItemController {
    @Autowired
    ItemRepository itemRepo;

    @RequestMapping("/getAllItems")
    @ResponseBody
    public ResponseEntity<List<Item>> getAllItems(){
        List<Item> items =  itemRepo.getAllItems();
        return new ResponseEntity<List<Item>>(items, HttpStatus.OK);
    }

    @GetMapping("/item/{itemId}")
    @ResponseBody
    public ResponseEntity<Item> getItem(@PathVariable int itemId){
        if(itemId <= 0){
            System.out.println("Invalid ItemId");
            return null;
        }
        Item item = itemRepo.getItem(itemId);
        return new ResponseEntity<Item>(item, HttpStatus.OK);
    }

}

Application.java

Application.java
package com.onlinetutorialspoint;

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

@SpringBootApplication
@PropertySource("classpath:application.properties")
public class Application extends SpringBootServletInitializer {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(Application.class);
  }
}

Build Application:

It will generate the war file and placed under the application’s /target folder.

Terminal
mvn clean install

[INFO] Assembling webapp [SpringBoot-JNDIConfig-Example] in [E:\work\JNDI\SpringBoot-JNDIConfig-Example\target\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Webapp assembled in [532 msecs]
[INFO] Building war: E:\work\JNDI\SpringBoot-JNDIConfig-Example\target\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.16.BUILD-SNAPSHOT:repackage (default) @ SpringBoot-JNDIConfig-Example ---
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ SpringBoot-JNDIConfig-Example ---
[INFO] Installing E:\work\JNDI\SpringBoot-JNDIConfig-Example\target\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war to C:\Users\Lenovo\.m2\repository\com\onlinetutorialspoint\Spring
Boot-JNDIConfig-Example
mvn clean install
[INFO] Assembling webapp [SpringBoot-JNDIConfig-Example] in [E:\work\JNDI\SpringBoot-JNDIConfig-Example\target\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Webapp assembled in [532 msecs]
[INFO] Building war: E:\work\JNDI\SpringBoot-JNDIConfig-Example\target\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.16.BUILD-SNAPSHOT:repackage (default) @ SpringBoot-JNDIConfig-Example ---
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ SpringBoot-JNDIConfig-Example ---
[INFO] Installing E:\work\JNDI\SpringBoot-JNDIConfig-Example\target\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war to C:\Users\Lenovo\.m2\repository\com\onlinetutorialspoint\Spring
Boot-JNDIConfig-Example\0.0.1-SNAPSHOT\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war
.0.1-SNAPSHOT\SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war

Deploying war file into Tomcat:

Move/Copy the generated SpringBoot-JNDIConfig-Example-0.0.1-SNAPSHOT.war from /target folder to Tomcat’s deployment directory i.e tomcat/webapps folder and run the tomcat.

/tomcat/bin/startup.bat (or) startup.sh

Spring Boot JNDI Configuration 2

Access the Application:

Spring Boot JNDI Configuration 3

Happy Learning šŸ™‚

Download Example