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:
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
<packaging>war</packaging>
- The main class of the Spring Boot should extends theĀ SpringBootServletInitializer abstract class and override the configure(SpringApplicationBuilder builder) method.
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.
<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
<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:
<?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.
spring.datasource.jndi-name=java:comp/env/jdbc/otp
Creating Item Repository:
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.
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.
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
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.
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-Examplemvn 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
Access the Application:
Happy Learning š