Load properties file in Servlet/JSP [duplicate] - java

This question already has answers here:
Where to place and how to read configuration resource files in servlet based application?
(6 answers)
Closed 6 years ago.
I've created a jar from my Java project and wanted to use the same jar in a JSP Servlet Project. I'm trying to load a property file let say sample.properties from my JSP Servlet Project kept in WEB/properties/sample.properties which should be read by a class in the jar.I'm using the following code wriiten in a class of jar to access it.
Properties prop=new Properties();
prop.load(/WEB-INF/properties/sample.properties);
But each time I'm getting fileNotFound exception.
Please suggest me the solution.
Here is the structure
WEB-INF
|
lib
|
myproject.jar
|
myclass (This class needs to read sample.properties)
|
properties
|sample.properties

The /WEB-INF folder is not part of the classpath. So any answer here which is thoughtless suggesting ClassLoader#getResourceAsStream() will never work. It would only work if the properties file is placed in /WEB-INF/classes which is indeed part of the classpath (in an IDE like Eclipse, just placing it in Java source folder root ought to be sufficient).
Provided that the properties file is really there where you'd like to keep it, then you should be getting it as web content resource by ServletContext#getResourceAsStream() instead.
Assuming that you're inside a HttpServlet, this should do:
properties.load(getServletContext().getResourceAsStream("/WEB-INF/properties/sample.properties"));
(the getServletContext() is inherited from the servlet superclass, you don't need to implement it yourself; so the code is as-is)
But if the class is by itself not a HttpServlet at all, then you'd really need to move the properties file into the classpath.
See also:
Where to place and how to read configuration resource files in servlet based application?

Try to put sample.properties under src folder, and then
Properties prop = new Properties();
prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("myprop.properties"));

Move your properties files under WEB-INF/classes. Then load it as following:
prop.load(getClass().getResourceAsStream("sample.properties"));
You can put it into sub-directory under classes as well. In this case change the call to getResourceAsStream() accordingly.
To be safer in multi-classloader system you can use Thread.getContextClassLoader().getResourceAsStream() instead.
To make the properties file to arrive to classes folder of your war file you have to put it under resources folder in your project (if you are using maven) or just under src folder if you do not use maven-like directory structure.

Try this,
InputStream inStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("/WEB-INF/properties/sample.properties");
Then, load(InputStream) it into a Properties object:
Properties props = new Properties();
props.load(inStream);

it may not work If you are try to load the properties from jsp/servlet. Write a utility class to read properties and package along with jar file. copy the properties file into same package as of utility.
Class Utility{
Properties properties=null;
public void load() throws IOException{
properties.load(getClass().getResourceAsStream("sample.properties"));
}
public Object get(String key) throws IOException{
if (properties==null){
load();
}
return properties.get(key);
}
}
Now use this utility class from servlet to read the property values. May be you can define the class as singleton for better practice
Cheers
Satheesh

Related

Reading application.properties file in ResourceBundle class [duplicate]

In my web application I have to send email to set of predefined users like finance#xyz.example, so I wish to add that to a .properties file and access it when required. Is this a correct procedure, if so then where should I place this file? I am using Netbeans IDE which is having two separate folders for source and JSP files.
It's your choice. There are basically three ways in a Java web application archive (WAR):
1. Put it in classpath
So that you can load it by ClassLoader#getResourceAsStream() with a classpath-relative path:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Here foo.properties is supposed to be placed in one of the roots which are covered by the default classpath of a webapp, e.g. webapp's /WEB-INF/lib and /WEB-INF/classes, server's /lib, or JDK/JRE's /lib. If the propertiesfile is webapp-specific, best is to place it in /WEB-INF/classes. If you're developing a standard WAR project in an IDE, drop it in src folder (the project's source folder). If you're using a Maven project, drop it in /main/resources folder.
You can alternatively also put it somewhere outside the default classpath and add its path to the classpath of the appserver. In for example Tomcat you can configure it as shared.loader property of Tomcat/conf/catalina.properties.
If you have placed the foo.properties it in a Java package structure like com.example, then you need to load it as below
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Note that this path of a context class loader should not start with a /. Only when you're using a "relative" class loader such as SomeClass.class.getClassLoader(), then you indeed need to start it with a /.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
However, the visibility of the properties file depends then on the class loader in question. It's only visible to the same class loader as the one which loaded the class. So, if the class is loaded by e.g. server common classloader instead of webapp classloader, and the properties file is inside webapp itself, then it's invisible. The context class loader is your safest bet so you can place the properties file "everywhere" in the classpath and/or you intend to be able to override a server-provided one from the webapp on.
2. Put it in webcontent
So that you can load it by ServletContext#getResourceAsStream() with a webcontent-relative path:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Note that I have demonstrated to place the file in /WEB-INF folder, otherwise it would have been public accessible by any webbrowser. Also note that the ServletContext is in any HttpServlet class just accessible by the inherited GenericServlet#getServletContext() and in Filter by FilterConfig#getServletContext(). In case you're not in a servlet class, it's usually just injectable via #Inject.
3. Put it in local disk file system
So that you can load it the usual java.io way with an absolute local disk file system path:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Note the importance of using an absolute path. Relative local disk file system paths are an absolute no-go in a Java EE web application. See also the first "See also" link below.
Which to choose?
Just weigh the advantages/disadvantages in your own opinion of maintainability.
If the properties files are "static" and never needs to change during runtime, then you could keep them in the WAR.
If you prefer being able to edit properties files from outside the web application without the need to rebuild and redeploy the WAR every time, then put it in the classpath outside the project (if necessary add the directory to the classpath).
If you prefer being able to edit properties files programmatically from inside the web application using Properties#store() method, put it outside the web application. As the Properties#store() requires a Writer, you can't go around using a disk file system path. That path can in turn be passed to the web application as a VM argument or system property. As a precaution, never use getRealPath(). All changes in deploy folder will get lost on a redeploy for the simple reason that the changes are not reflected back in original WAR file.
See also:
getResourceAsStream() vs FileInputStream
Adding a directory to tomcat classpath
Accessing properties file in a JSF application programmatically
Word of warning: if you put config files in your WEB-INF/classes folder, and your IDE, say Eclipse, does a clean/rebuild, it will nuke your conf files unless they were in the Java source directory. BalusC's great answer alludes to that in option 1 but I wanted to add emphasis.
I learned the hard way that if you "copy" a web project in Eclipse, it does a clean/rebuild from any source folders. In my case I had added a "linked source dir" from our POJO java library, it would compile to the WEB-INF/classes folder. Doing a clean/rebuild in that project (not the web app project) caused the same problem.
I thought about putting my confs in the POJO src folder, but these confs are all for 3rd party libs (like Quartz or URLRewrite) that are in the WEB-INF/lib folder, so that didn't make sense. I plan to test putting it in the web projects "src" folder when i get around to it, but that folder is currently empty and having conf files in it seems inelegant.
So I vote for putting conf files in WEB-INF/commonConfFolder/filename.properties, next to the classes folder, which is Balus option 2.
Ex: In web.xml file the tag
<context-param>
<param-name>chatpropertyfile</param-name>
<!-- Name of the chat properties file. It contains the name and description of rooms.-->
<param-value>chat.properties</param-value>
</context-param>
And chat.properties you can declare your properties like this
For Ex :
Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.
It just needs to be in the classpath (aka make sure it ends up under /WEB-INF/classes in the .war as part of the build).
You can you with your source folder so whenever you build, those files are automatically copied to the classes directory.
Instead of using properties file, use XML file.
If the data is too small, you can even use web.xml for accessing the properties.
Please note that any of these approach will require app server restart for changes to be reflected.
Assume your code is looking for the file say app.properties. Copy this file to any dir and add this dir to classpath, by creating a setenv.sh in the bin dir of tomcat.
In your setenv.sh of tomcat( if this file is not existing, create one , tomcat will load this setenv.sh file.
#!/bin/sh
CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"
You should not have your properties files in ./webapps//WEB-INF/classes/app.properties
Tomcat class loader will override the with the one from WEB-INF/classes/
A good read:
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Java Listener Exception regarding dealing with file [duplicate]

In my web application I have to send email to set of predefined users like finance#xyz.example, so I wish to add that to a .properties file and access it when required. Is this a correct procedure, if so then where should I place this file? I am using Netbeans IDE which is having two separate folders for source and JSP files.
It's your choice. There are basically three ways in a Java web application archive (WAR):
1. Put it in classpath
So that you can load it by ClassLoader#getResourceAsStream() with a classpath-relative path:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Here foo.properties is supposed to be placed in one of the roots which are covered by the default classpath of a webapp, e.g. webapp's /WEB-INF/lib and /WEB-INF/classes, server's /lib, or JDK/JRE's /lib. If the propertiesfile is webapp-specific, best is to place it in /WEB-INF/classes. If you're developing a standard WAR project in an IDE, drop it in src folder (the project's source folder). If you're using a Maven project, drop it in /main/resources folder.
You can alternatively also put it somewhere outside the default classpath and add its path to the classpath of the appserver. In for example Tomcat you can configure it as shared.loader property of Tomcat/conf/catalina.properties.
If you have placed the foo.properties it in a Java package structure like com.example, then you need to load it as below
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Note that this path of a context class loader should not start with a /. Only when you're using a "relative" class loader such as SomeClass.class.getClassLoader(), then you indeed need to start it with a /.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
However, the visibility of the properties file depends then on the class loader in question. It's only visible to the same class loader as the one which loaded the class. So, if the class is loaded by e.g. server common classloader instead of webapp classloader, and the properties file is inside webapp itself, then it's invisible. The context class loader is your safest bet so you can place the properties file "everywhere" in the classpath and/or you intend to be able to override a server-provided one from the webapp on.
2. Put it in webcontent
So that you can load it by ServletContext#getResourceAsStream() with a webcontent-relative path:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Note that I have demonstrated to place the file in /WEB-INF folder, otherwise it would have been public accessible by any webbrowser. Also note that the ServletContext is in any HttpServlet class just accessible by the inherited GenericServlet#getServletContext() and in Filter by FilterConfig#getServletContext(). In case you're not in a servlet class, it's usually just injectable via #Inject.
3. Put it in local disk file system
So that you can load it the usual java.io way with an absolute local disk file system path:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Note the importance of using an absolute path. Relative local disk file system paths are an absolute no-go in a Java EE web application. See also the first "See also" link below.
Which to choose?
Just weigh the advantages/disadvantages in your own opinion of maintainability.
If the properties files are "static" and never needs to change during runtime, then you could keep them in the WAR.
If you prefer being able to edit properties files from outside the web application without the need to rebuild and redeploy the WAR every time, then put it in the classpath outside the project (if necessary add the directory to the classpath).
If you prefer being able to edit properties files programmatically from inside the web application using Properties#store() method, put it outside the web application. As the Properties#store() requires a Writer, you can't go around using a disk file system path. That path can in turn be passed to the web application as a VM argument or system property. As a precaution, never use getRealPath(). All changes in deploy folder will get lost on a redeploy for the simple reason that the changes are not reflected back in original WAR file.
See also:
getResourceAsStream() vs FileInputStream
Adding a directory to tomcat classpath
Accessing properties file in a JSF application programmatically
Word of warning: if you put config files in your WEB-INF/classes folder, and your IDE, say Eclipse, does a clean/rebuild, it will nuke your conf files unless they were in the Java source directory. BalusC's great answer alludes to that in option 1 but I wanted to add emphasis.
I learned the hard way that if you "copy" a web project in Eclipse, it does a clean/rebuild from any source folders. In my case I had added a "linked source dir" from our POJO java library, it would compile to the WEB-INF/classes folder. Doing a clean/rebuild in that project (not the web app project) caused the same problem.
I thought about putting my confs in the POJO src folder, but these confs are all for 3rd party libs (like Quartz or URLRewrite) that are in the WEB-INF/lib folder, so that didn't make sense. I plan to test putting it in the web projects "src" folder when i get around to it, but that folder is currently empty and having conf files in it seems inelegant.
So I vote for putting conf files in WEB-INF/commonConfFolder/filename.properties, next to the classes folder, which is Balus option 2.
Ex: In web.xml file the tag
<context-param>
<param-name>chatpropertyfile</param-name>
<!-- Name of the chat properties file. It contains the name and description of rooms.-->
<param-value>chat.properties</param-value>
</context-param>
And chat.properties you can declare your properties like this
For Ex :
Jsp = Discussion about JSP can be made here.
Java = Talk about java and related technologies like J2EE.
ASP = Discuss about Active Server Pages related technologies like VBScript and JScript etc.
Web_Designing = Any discussion related to HTML, JavaScript, DHTML etc.
StartUp = Startup chat room. Chatter is added to this after he logs in.
It just needs to be in the classpath (aka make sure it ends up under /WEB-INF/classes in the .war as part of the build).
You can you with your source folder so whenever you build, those files are automatically copied to the classes directory.
Instead of using properties file, use XML file.
If the data is too small, you can even use web.xml for accessing the properties.
Please note that any of these approach will require app server restart for changes to be reflected.
Assume your code is looking for the file say app.properties. Copy this file to any dir and add this dir to classpath, by creating a setenv.sh in the bin dir of tomcat.
In your setenv.sh of tomcat( if this file is not existing, create one , tomcat will load this setenv.sh file.
#!/bin/sh
CLASSPATH="$CLASSPATH:/home/user/config_my_prod/"
You should not have your properties files in ./webapps//WEB-INF/classes/app.properties
Tomcat class loader will override the with the one from WEB-INF/classes/
A good read:
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

How to reference a file in the source dir from any Java code?

Suppose I had a directory containing resource files stored somewhere within the "src" source directory, containing things like templates, config files, etc.
I'm aware that from a Servlet I can access files by name like:
File file = new File(ServletContact.getResource("some/namespace/filename.txt").getPath());
And from a non-Servlet I can do:
File file = new File(Object.class.getResource("some/namespace/filename.txt").getPath());
But the problem is that I have code that needs to access these resource files and can be run independent of the runtime environment. e.g. Some code uses templates from within a servlet (under Tomcat 7). Other code runs as a Quartz background job and works with templates. If I try the Object.class.getResource() method in a Tomcat servlet, it returns null.
How can I access resources files in a safe way regardless of runtime environment, app engine, etc.?
To read file from classpath you can use:
getClass().getClassLoader().getResourceAsStream("path/to/resource");
Also there is simple and useful Spring utility ClassPathResource class:
Resource resource = new ClassPathResource("path/to/resource");
I would use any class (e.g. domain class) from your project, use getClassLoader() or getContextClassloader() and provide the path to your resource. Should work.

How to load files/properties from WEB-INF directory?

It seems that in my Tapestry app, I can't load ini files nor properties file from WEB-INF directory or class path.
I tried several different methods which should load my file but non of them worked.
ex
realm.setResourcePath("/WEB-INF/auth.properties");
ex
realm.setResourcePath("classpath:wip/pages/auth.properties");
I need to load properties/ini file in order to use tapestry-security module which is based on Shiro.
Thanks for help !
Try ServletContext.getResourceAsStream("/WEB-INF/auth.properties") or ServletContext.getResourceAsStream("WEB-INF/auth.properties")
ServletContext has to be use from servlet, servletListener etc.
The root of the classpath is the way to go.
Put your file in src/main/resources/auth.properties then set your resourcePath using
realm.setResourcePath("classpath:auth.properties");
Check the ExtendedPropertiesRealm and the tapestry-security testapp for an example
http://svn.codehaus.org/tynamo/trunk/tapestry-security/src/test/java/org/tynamo/security/testapp/services/AppModule.java
http://svn.codehaus.org/tynamo/trunk/tapestry-security/src/test/resources/shiro-users.properties
Try
Properties props = new Properties();
props.load(new FileInputStream(new File(req.getServletContext().getRealPath("/WEB-INF/fileName.properties"))));
System.out.println(props);
I found the easiest way was to
put file in src/main/resources/config.properties. This will be put in /WEB-INF/classes/config.properties when the project is compiled by maven into WAR
read the file from a servlet with the following
InputStreaminputStream = getClass().getClassLoader().getResourceAsStream("config.properties");
https://crunchify.com/java-properties-file-how-to-read-config-properties-values-in-java/

How to Specify Path for Properties file

I am using Config. properties file for passing parameters to my methods Now i am loading file from
Properties Config= new Properties();
Config.load(new FileInputStream("C:\\Config. properties "));
As i don't want to keep it hard coded how can i set it with package level. or within application.
Thanks in Advance.
Make use of ResourceBundle Class. You just need to specify the properties file name. It will take the file from any path,provided the path should be in the classpath.
Example:
// abc.properties is the properties file,which is placed in the class path.You just need to
// specify its name and the properties file gets loaded.
ResourceBundle s=ResourceBundle.getBundle("abc");
s.getString("key"); //any key from properties file...
I was also just going to suggest that but you can also pass in the full path to the config file via a command line argument for example:
java YourApp -config C:\\config.properties
A properties file packaged with the application should not be loaded using the file system, but using the class loader. Indeed, the properties file, once the application is packaged, will be embedded inside a jar file, with the .class files.
If the config.properties file is in the package com.foo.bar, then you should load it using
InputStream in = SomeClass.class.getResourceAsStream("/com/foo/bar/config.properties");
Or with
InputStream in = SomeClass.class.getClassLoader().getResourceAsStream("com/foo/bar/config.properties");
You may also load it with a relative path. If SomeClass is also in the package com.foo.bar, then you may load it with.
InputStream in = SomeClass.class.getResourceAsStream("config.properties");
Note that Java variables should always start with a lowercase letter: config and not Config.
If it's just the path you're worried about then you can use a relative path:
Config.load(new FileInputStream("Config.properties"));
This will look in the current working directory. The upsdie: dead simple. The downside: it's not that robust. If you start your application from somewhere else without changing the working directory before, the file won't be found.
Put the config file in the classpath (where your .class files are), and access it using
getClass().getClassLoader().getResourceAsStream(_path_to_config_file);
There are two ways to get the path of the config files at runtime.
a) Getting it from database.
b) Getting it from custom properties of JVM configured at server level
Best process is "b" , you can change the properties of JVM at any time if path is changed and just restart the server.

Categories