Can't read properties file in JSP - java

The following JUnit test is working in my application:
#Test
public void testMessageResources(){
final InputStream stream = getClass().
getResourceAsStream("/com/service/MessageResources.properties");
Assert.assertNotNull(stream);
}
But in my JSP, I can't read the file using this code:
<%
final InputStream resourceAsStream = application.
getResourceAsStream("/com/service/MessageResources.properties");
%>
resourceAsStream is always null. I'm using JSP 2.1.
The MessageResources.properties file is on the classpath, but not inside the JSP directory. Is that a problem?

The JSP uses ServletContext.getResourceAsStream(), which doesn't do the same thing as Class.getResourceAsStream(). It doesn't search for the resources in the classpath. If you want to use Class.getResourceAsStream(), then use Class.getResourceAsStream(). It will also work in a Java EE context. Just make sure to use a class loaded from the same classloader as the one you want to use to load your properties file.
Such a method call shouldn't be done in a JSP, though, but in a Servlet or action which forxards to the JSP. JSPs should be used to generate markup.

The getClass().getResourceAsStream() searches the file in the classpath, while application.getResourceAsStream looks for the resource in your web application directly. So the directory 'com' should be inside your web application and not in the classpath.

Related

Where to put file resources in Dynamic Web Project Tomcat? [duplicate]

I've got a file in my war/WEB-INF folder of my app engine project. I read in the FAQs that you can read a file from there in a servlet context. I don't know how to form the path to the resource though:
/war/WEB-INF/test/foo.txt
How would I construct my path to that resource to use with File(), just as it looks above?
Thanks
There's a couple ways of doing this. As long as the WAR file is expanded (a set of files instead of one .war file), you can use this API:
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/test/foo.txt");
http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getRealPath(java.lang.String)
That will get you the full system path to the resource you are looking for. However, that won't work if the Servlet Container never expands the WAR file (like Tomcat). What will work is using the ServletContext's getResource methods.
ServletContext context = getContext();
URL resourceUrl = context.getResource("/WEB-INF/test/foo.txt");
or alternatively if you just want the input stream:
InputStream resourceContent = context.getResourceAsStream("/WEB-INF/test/foo.txt");
http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResource(java.lang.String)
The latter approach will work no matter what Servlet Container you use and where the application is installed. The former approach will only work if the WAR file is unzipped before deployment.
EDIT:
The getContext() method is obviously something you would have to implement. JSP pages make it available as the context field. In a servlet you get it from your ServletConfig which is passed into the servlet's init() method. If you store it at that time, you can get your ServletContext any time you want after that.
Now with Java EE 7 you can find the resource more easily with
InputStream resource = getServletContext().getResourceAsStream("/WEB-INF/my.json");
https://docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html#getServletContext--
I know this is late, but this is how I normally do it,
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream stream = classLoader.getResourceAsStream("../test/foo.txt");

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.

Load properties file in Servlet/JSP [duplicate]

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

How do I use a properties file with jax-rs?

I've just been getting started setting up a web service with jax-rs running on Tomcat. Is there a way to bundle a properties file with my java project (in eclipse) so that I can read properties out of it at runtime? Also if it's possible, where would be the best location to put it (so that it couldn't be seen via a url), WebContent, WEB-INF, etc?
Thanks.
Several options:
Option 1: You can put it under your classpath (in Eclipse put it under and source folder), so you can access it via the Classloader: MyClass.class.getResourceAsStream("myproperties.properites")
Pay attention that MyClass must also be in the same source folder (actually it's a bit more complex, it must be in the same classloader hierarchy, but any class from the same folder will do the job)
Option 2: Put it in WEB-INF folder. It's a preferred option, since you don't need to deal with the classpath. You'll need a ServletContext to access it: javax.servlet.ServletContext.getResourceAsStream("WEB-INF/myproperties.properites")
In jax-rs you can obtain the ServletContext using the #Context annotation in any registered resource or provider.
For GlassFish 3.1 users, I was able to get both of Tarlog's options working, but I had to use the file's absolute path. For Option 1 I put the file in the Source Packages folder in NetBeans, which I could then access via:
InputStream is = TestResource.class.getResourceAsStream("/test_model.js");
For Option 2 I put the file under WEB-INF and used:
#Context ServletContext servletContext;
InputStream is = servletContext.getResourceAsStream("/WEB-INF/test_model.js");
Without the leading slash the result was null. HTH

getResourceAsStream() is always returning null [duplicate]

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 have the following structure in a Java Web Application:
TheProject
-- [Web Pages]
-- -- [WEB-INF]
-- -- -- abc.txt
-- -- index.jsp
-- [Source Packages]
-- -- [wservices]
-- -- -- WS.java
In WS.java, I am using the following code in a Web Method:
InputStream fstream = this.getClass().getResourceAsStream("abc.txt");
But it is always returning a null. I need to read from that file, and I read that if you put the files in WEB-INF, you can access them with getResourceAsStream, yet the method is always returning a null.
Any ideas of what I may be doing wrong?
Btw, the strange thing is that this was working, but after I performed a Clean and Build on the Project, it suddenly stopped working :/
To my knowledge the file has to be right in the folder where the 'this' class resides, i.e. not in WEB-INF/classes but nested even deeper (unless you write in a default package):
net/domain/pkg1/MyClass.java
net/domain/pkg1/abc.txt
Putting the file in to your java sources should work, compiler copies that file together with class files.
A call to Class#getResourceAsStream(String) delegates to the class loader and the resource is searched in the class path. In other words, you current code won't work and you should put abc.txt in WEB-INF/classes, or in WEB-INF/lib if packaged in a jar file.
Or use ServletContext.getResourceAsStream(String) which allows servlet containers to make a resource available to a servlet from any location, without using a class loader. So use this from a Servlet:
this.getServletContext().getResourceAsStream("/WEB-INF/abc.txt") ;
But is there a way I can call getServletContext from my Web Service?
If you are using JAX-WS, then you can get a WebServiceContext injected:
#Resource
private WebServiceContext wsContext;
And then get the ServletContext from it:
ServletContext sContext= wsContext.getMessageContext()
.get(MessageContext.SERVLET_CONTEXT));
Instead of
InputStream fstream = this.getClass().getResourceAsStream("abc.txt");
use
InputStream fstream = this.getClass().getClassLoader().getResourceAsStream("abc.txt");
In this way it will look from the root, not from the path of the current invoking class
I think this way you can get the file from "anywhere" (including server locations) and you do not need to care about where to put it.
It's usually a bad practice having to care about such things.
Thread.currentThread().getContextClassLoader().getResourceAsStream("abc.properties");
I don't know if this applies to JAX-WS, but for JAX-RS I was able to access a file by injecting a ServletContext and then calling getResourceAsStream() on it:
#Context ServletContext servletContext;
...
InputStream is = servletContext.getResourceAsStream("/WEB-INF/test_model.js");
Note that, at least in GlassFish 3.1, the path had to be absolute, i.e., start with slash. More here: How do I use a properties file with jax-rs?
I had the same problem when I changed from Websphere 8.5 to WebSphere Liberty.
I utilized FileInputStream instead of getResourceAsStream(), because for some reason WebSphere Liberty can't locate the file in the WEB-INF folder.
The script was :
FileInputStream fis = new FileInputStream(getServletContext().getRealPath("/")
+ "\WEBINF\properties\myProperties.properties")
Note:
I used this script only for development.
I had a similar problem and I searched for the solution for quite a while:
It appears that the string parameter is case sensitive. So if your filename is abc.TXT but you search for abc.txt, eclipse will find it - the executable JAR file won't.

Categories