Sunday, 28 January 2018

How To + SpringBoot + Embedded Tomcat + JNDI + URL + File Resources

If you are building your application in SpringBoot with Embedded Tomcat and looking for reading property files using JNDI, this post may help you.

Let say you have an environment property file which you want to keep out of your web package  and it should be referred/read in your application using JNDI URL resource. You can follow below steps to achieve same.

1. Create the property file which you want to read using JNDI URL resource.


2. Create URLFactory class which should implement ObjectFactory interface.

import java.util.Hashtable;
import javax.naming.*;
import javax.naming.spi.ObjectFactory;

public class URLFactory implements ObjectFactory {
    public Object getObjectInstance(Object obj, Name name,
       Context nameCtx, Hashtable environment) throws Exception {
       Reference ref = (Reference) obj;
       String urlString = (String) ref.get("file").getContent();
       return new URL(urlString);

3. Add below code in your spring boot application class that should initialize TomcatEmbeddedServletContainerFactory bean. Here in this bean, under postProcessContext() method, you can define JNDI file resources as mentioned below.  Factory class should be same that you created in step #2.

public TomcatEmbeddedServletContainerFactory tomcatFactory() {
  return new TomcatEmbeddedServletContainerFactory() {

     protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                             Tomcat tomcat) {
         return super.getTomcatEmbeddedServletContainer(tomcat);

     protected void postProcessContext(Context context) {
       ContextResource fileRes = new ContextResource();

4. Define the URL bean which should return URL using resource name lookup. Keep 'java:comp/env' as it is and add your resource name as mentioned above.


import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;

public class ConfigFileConfiguration {

 @Bean(name="envPropFile", destroyMethod = "")
  public URL envPropFile() throws MalformedURLException, NamingException{
                              InitialContext context = new InitialContext();
                              return (URL) context.lookup("java:comp/env/url/EnvPropFile");

5. Now autowire this URL bean in other spring component where you want to access the properties. Note that, in actual production code, file initialization should happen only once. 

public class MyService {
    private URL envPropFile;

    public   void pringEnvPropFileKey() throws Exception{
      Properties configHolder = new Properties();
      final URLConnection conn = envPropFile.openConnection();
      final InputStream inputStream = conn.getInputStream();
      String value = configHolder.getProperty("mykey"); // This is the key mentioned in prop file


I think that's pretty much what you need to do to read file using JNDI in spring boot embedded tomcat application.To get more detail specific to tomcat and it's JNDI resources you can refer this link.