Issue while reading a file from WAR file - java

I have a war file with the below structure.
--js
--sum.js
--WEB-INF
--classes
---com
-----test
-----MyTest.class
--home.html
I am trying to read the js file in my MyTest.class file,But I am getting exception while reading it. I tried most of the solutions already mentioned in the stack.
I have tried
1)
String path = Thread.currentThread().getContextClassLoader().getResource("js/sum.js").getPath();
File f = new File(path);
System.out.println(f.getAbsolutePath());
First line is throwing nullpointer exception
2)
InputStream in =MyNashHornTest.class.getClassLoader().getResourceAsStream("/js/sum.js");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
Second line is throwing null pointer exception
3)
InputStream in =MyNashHornTest.class.getClassLoader().getResourceAsStream("../../../../js/sum.js");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
Second line is throwing null pointer exception
Please help me to resolve this issue.

For war files, don’t use the servlet container’s classloader, but use the ServletContext instead.
This method allows servlet containers to make a resource available to a servlet from any location, without using a class loader.
ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream("/yourfilename.txt");
It is recommended to keep it under the /WEB-INF directory if you don’t want browers being able to access it.
The path must begin with a « / » and is interpreted as relative to the current context root. This method returns null if no resource exists at the specified path. For example ServletContext.getResourceAsStream(« WEB-INF/resources/yourfilename.cnf ») will return a nul exception, so be careful !
Why null pointer comes??
The path must begin with a "/" and is interpreted as relative to the current context root. This method returns null if no resource exists at the specified path. For example, using a path that doesn't start with a slash, You will get a null return value.
Details Description is given here: How to use ServletContext.getResourceAsStream(java.lang.String path)?
Resource Link:
HOW TO: Read a file from jar and war files (java and webapp archive) ?

You can get resources from the class path with ClassLoader.getResource or from the web root directory with ServletContext.getResource.
In a war, you use the former to access ressources stored under WEB-INF/classes, or in jars under WEB-INF/lib, and the former for what lies directly at the root of the web application.

Related

Relative to absolute path in java

I have have a file that I want to use in my project which is in the resources package
src.res
Following what was stated in this answer, I believe that my code is valid.
File fil = new File("/res/t2.nii");
// Prints C:\\res\\t2.nii
System.out.println(fil.getAbsolutePath());
The problem is that I that file is in my projects file not there, so I get an Exception.
How am I suppose to properly convert from relative path to absolute?
Try with directory first that will provide you absolute path of directory then use file.exists() method to check for file existence.
File fil = new File("res"); // no forward slash in the beginning
System.out.println(fil.getAbsolutePath()); // Absolute path of res folder
Find more variants of File Path & Operations
Must read Oracle Java Tutorial on What Is a Path? (And Other File System Facts)
A path is either relative or absolute.
An absolute path always contains the root element and the complete directory list required to locate the file.
For example, /res/images is an absolute path.
A relative path needs to be combined with another path in order to access a file.
For example, res/images is a relative path. Without more information, a program cannot reliably locate the res/images directory in the file system.
Since you are using a Java package, you must to use a class loader if you want to load a resource. e.g.:
URL url = ClassLoader.getSystemResource("res/t2.nii");
if (url != null) {
File file = new File(url.toURI());
System.out.println(file.getAbsolutePath());
}
You can notice that ClassLoader.getSystemResource("res/t2.nii") returns URL object for reading the resource, or null if the resource could not be found. The next line convertes the given URL into an abstract pathname.
See more in Preferred way of loading resources in Java.
validate with
if (fil.exists()) { }
before and check if it really exist. if not then you can get the current path with
System.getProperty("user.dir"));
to validate that you are starting fromt he proper path.
if you really want to access the path you shouldnt use absolut pathes / since it will as explained start from the root of your Harddisk.
you can get the absolut path of the res folder by using this what my poster was writte in the previous answer:
File fil = new File("res");
System.out.println(fil.getAbsolutePath());

Opening a resource file in a servlet on Openshift

I'm in troubles with opening file within my web-app. I tried it locally within Eclipse and it works fine but when I try to deploy it on Tomcat 6 on Openshift it doesn't find resource files for my web-app. There are some txt files in a ProjectFiles directory stored in WEB-INF directory; the code that locally opens file is
String nome_file = "C\:\\Users\\miKKo\\workspace\\fantacalcio_project\\WebContent\\WEB-INF\\ProjectFiles\\Risultati\\risultati_" + nome_lega + ".txt";
BufferedReader reader = new BufferedReader(new FileReader(nome_file));
I've pushed them within Git in the same repository (on server I renamed my project in "ROOT") and I've substituted string with this
String nome_file = this.getServletConfig().getServletContext().getContextPath()+"/WebContent/WEB-INF/ProjectFiles/Risultati/risultati_" + nome_lega + ".txt";
but it doesn't work. I've also tried with a context attribute
/var/lib/openshift/51c6178a5004467630000019/jbossews/work/Catalina/localhost/_/WEB-INF/ProjectFiles
but the thrown exception is always
java.io.FileNotFoundException: (#path) (No such file or directory)
What can I do for this?
Say your file is in the following location:
/WEB-INF/ProjectFiles/Risultati/risultat_text_file.txt
Then using:
String path = "/WEB-INF/ProjectFiles/Risultati/risultat_text_file.txt";
InputStream inputStream = new FileInputStream(this.getServletConfig().getServletContext().getRealPath(path));
Should work for you. Note that, ServletContext.getRealPath() return the real OS path corresponding to the given virtual path.
Edit:
If this doesn't work for your case, you really need to revisit your virtual path. You can manually check that does this file exist in the expected directory in the war file or you can log the output of the getRealPath() method to examine what's really going on! If necessary you can put "/" in your getRealPath() method and examine what is your application's root path.
Since I don't get application's root realpath, I resolved in this way:
String path="/WEB-INF/ProjectFiles/Risultati/risultati_test.txt";
InputStream inputStream = this.getServletConfig().getServletContext().getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
and now it works. By the way, I also found useful informations here
getResourceAsStream() vs FileInputStream

Google App Engine Java: Reading in an html file problems

I'm trying to read in an html file as a string using InputStream but no matter what I try I keep getting a null pointer exception. The File I am trying to read is at "/war/index.html" and the code to read it in looks like this:
File f = new File(path);
ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream(f.getAbsolutePath());
int data = is.read();
As soon as I call is.read() it gives me a NullPointerException. Any help is appreciated thanks!
Here seems to be 2 issues combined:
by default when you create file with relative path, working directory in this case is java.dir, which in most cases is not the same, as webapps folder of web-container
you seem to have extra war indicator in your path.
Please check how ServletContext resolves files.
So you simply need to use:
ServletContext context = getServletContext();
InputStream is = context.getResourceAsStream("/index.html");

Reading from src/main/resources gives NullPointerException

In my Maven project, I have a xls file in src/main/resources.
When I read it like this:
InputStream in = new
FileInputStream("src/main/resources/WBU_template.xls");
everything is ok.
However I want to read it as InputStream with getResourceAsStream. When I do this, with or without the slash I always get a NPE.
private static final String TEMPLATEFILE = "/WBU_template.xls";
InputStream in = this.getClass.getResourceAsStream(TEMPLATEFILE);
No matter if the slash is there or not, or if I make use of the getClassLoader() method, I still get a NullPointer.
I also have tried this :
URL u = this.getClass().getResource(TEMPLATEFILE);
System.out.println(u.getPath());
the console says.../target/classes/WBU_template.xls
and then get my NullPointer.
What am I doing wrong ?
FileInputStream will load a the file path you pass to the constructor as relative from the working directory of the Java process.
getResourceAsStream() will load a file path relative from your application's classpath.
When you use .getClass().getResource(fileName) it considers the location of the fileName is the same location of the of the calling class.
When you use .getClass().getClassLoader().getResource(fileName)
it considers the location of the fileName is the root - in other words bin folder.
The file should be located in src/main/resources when loading using Class loader
In short, you have to use .getClass().getClassLoader().getResource(fileName) to load the file in your case.
I usually load files from WEB-INF like this
session.getServletContext().getResourceAsStream("/WEB-INF/WBU_template.xls")

get File from JAR

I'm using Spring's Resource abstraction to work with resources (files) in the filesystem. One of the resources is a file inside a JAR file. According to the following code, it appears the reference is valid
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
// The path to the resource from the root of the JAR file
Resource fileInJar = resourcePatternResolver.getResources("/META-INF/foo/file.txt");
templateResource.exists(); // returns true
templateResource.isReadable(); // returns true
At this point, all is well, but then when I try to convert the Resource to a File
templateResource.getFile();
I get the exception
java.io.FileNotFoundException: class path resource [META-INF/foo/file.txt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/D:/m2repo/uic-3.2.6-0.jar!/META-INF/foo/file.txt
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:198)
at org.springframework.core.io.ClassPathResource.getFile(ClassPathResource.java:174)
What is the correct way to get a File reference to a Resource that exists inside a JAR file?
What is the correct way to get a File
reference to a Resource that exists
inside a JAR file?
The correct way is not doing that at all because it's impossible. A File represents an actual file on a file system, which a JAR entry is not, unless you have a special file system for that.
If you just need the data, use getInputStream(). If you have to satisfy an API that demands a File object, then I'm afraid the only thing you can do is to create a temp file and copy the data from the input stream to it.
If you want to read it, just call resource.getInputStream()
The exception message is pretty clear - the file does not reside on the file-system, so you can't have a File instance. Besides - what will do do with that File, apart from reading its content?
A quick look at the link you provided for Resource documentation, says the following:
Throws: IOException if the resource cannot be resolved as absolute file path,
i.e. if the resource is not available in a file system
Maybe the text file is inside a jar? In that case you will have to use getInputStream() to read its contents.
Just adding an example to the answers here. If you need a File (and not just the contents of it) from within your JAR, you need to create a temporary file from the resource first. (The below is written in Groovy):
InputStream inputStream = resourceLoader.getResource('/META-INF/foo/file.txt').inputStream
File tempFile = new File('file.txt')
OutputStream outputStream = new FileOutputStream(tempFile)
try {
IOUtils.copy(inputStream, outputStream)
} catch (IOException e) {
// Handle exception
} finally {
outputStream.close()
}

Categories