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.

EnvPropFile
mykey=myvalue

2. Create URLFactory class which should implement ObjectFactory interface.

URLFactory.java
package com.xxx.example;

import java.net.URL;
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.

@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 fileRes = new ContextResource();
       fileRes.setName("url/EnvPropFile");
       fileRes.setType(URL.class.getName());
       fileRes.setProperty("factory","com.xxx.example.URLFactory.java");
       fileRes.setProperty("file","file:///C:/your-path/EnvPropFile");
       context.getNamingResources().addResource(evolutionEngineConfigResource);                                         
      }
   };
}

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 java.net.MalformedURLException;
import java.net.URL;

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;

@Configuration
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. 

@Component
public class MyService {
  
    @Autowired
    private URL envPropFile;

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

   }
}

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.

8 comments:

  1. Fantastic highlighted details. My spouse and i appreciate it about this. Without a doubt will probably be handy with regard to my personal potential tasks. Want to discover other sorts of articles for a passing fancy subject matter! windows tech support phone number canada

    ReplyDelete
  2. Fantastic! Relation as part of your docs, this recently been excellent. Relation just as before created for supplying your computer facts. Fluid Mechanics and Machines

    ReplyDelete
  3. Our knowledge of this subject comes through clearly in this article. I love to read this kind of articles, I hope you will update it. Thank you for sharing it with me. comforters

    ReplyDelete
  4. A specific thing definitely seems to be very amazing. Plus publish will allow most of us a number of facts. grow to be written content, My husband or wife and we all severely discovered very fantastic plus one of a kind tactics. Which may perhaps be helpful to anybody... Relation created for making this specific gratifying web site. advertising signs

    ReplyDelete
  5. Hi there! Many thanks for the fantastic details you have supplied! You have handled with important factors! The wholesale formula review

    ReplyDelete