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