get path to a file

Hi,

   I have a file which resides under WebContent folder in my web application.
   Path: WebContent/pdf/filename.pdf

   I need to supply the path of this file to a java class under JavaSource in my project.
   I know a way to do it in Servlet using ServletContext.getRealPath(), but how do I do this in
   a regular java class?

Thanks
LVL 4
t3chAsked:
Who is Participating?
 
Gurvinder Pal SinghConnect With a Mentor Commented:
<<so "../" is nothing but web-content?>>
No, i tried it just now, it didn't worked for me

try this
            URL dirUrl = MyClass.class.getResource("./");
            System.out.println(dirUrl.getPath());

this should give you the path to current class, from where you can get the relative path to your webcontent (this you have to hardcode)
URL fileUrl = new URL(dirUrl, "../../data.txt");
0
 
Gurvinder Pal SinghCommented:
the path will be relative to WEB-INF inside the web-content only.

../pdf/filename.pdf
0
 
HegemonCommented:
If your web application is deployed exploded and you can work out the actual path, you can do just that.
Otherwise, if it is a .war file or it is not possible to determine the physical path, try the following:

Thread.currentThread.getContextClassLoader().getResourceAsStream ("WebContent/pfd/filename.pdf")
0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
t3chAuthor Commented:
Hi Gurvinder,

                  so "../" is nothing but web-content?
0
 
t3chAuthor Commented:
HI Hegemon,

                   The content is in a war file which eventually goes into an EAR file.
0
 
HegemonCommented:
So that's the only way to get the content of the file then (I think so)
0
 
t3chAuthor Commented:
Hi Gurvinder,

                     so once I do URL myURL =  MyClass.class.getResource("./")  "Is it ./ or ../"?
                     I'll have the path to my current class?

                    so for my PDF file I can do:
             
                    myURL + "webcontent/pdf/"????

                    Can I define this path in properties file as well?
0
 
Gurvinder Pal SinghCommented:
I would suggest that you keep any such resource out of your war file. It will be much easier for you to maintain it, as you do not need to open your war file, if you wish to change the pdf.
0
 
t3chAuthor Commented:
Hi Gurvinder,

              I tried running the first line of code that you gave and this is what it printed for the Class where I need to access the path value:

URL value: file:/C:/WorkSpace/PROJECTNAME/WebContent/WEB-INF/classes/com/companyname/module/business/report/

so what would be the relative path to the pdf folder if we consider
 the structure:

 WebContent/pdf/pdf_file
0
 
Gurvinder Pal SinghCommented:
../../../../../../../pdf/pdf_file

but i would still recommend that you keep it outside the war file
0
 
t3chAuthor Commented:
Hi Gurvinder,
 
                  Thanks for the suggestion, actually with current architecture files already exist outside the war, but for some strange reason when we added this file under the same directory, its throwing File not found exception, hence we decided to move this one inside the war.

The relative path you suggested, isnt that pointing to the class where I am referencing the path of the pdf, instead of the pdf path itself?

Is the below path correct? Please correct me if I am thinking something completely different.

 (for project name) ../ (WebContent) ../ (pdf) ../ pdf_file
0
 
Gurvinder Pal SinghCommented:
path might be correct, but you wont be able to access the file from this path, from any class.
You need to use the path that i have replied in my last reply
0
 
t3chAuthor Commented:
Thanks Gurvinder, I will try it out and post results.
0
 
objectsCommented:
afaik you need to use getRealPath() anything else is not going to be reliable
0
 
t3chAuthor Commented:
Hi Objects,

                 How to go about it? I tried Gurvinders solution and My code isnt picking up the file.
                 How do I use getRealPath? Its not a servlet, just a regular java class
0
 
objectsCommented:
you need to pass the servlet context to it (or find the path from somewhere that has access to the context and pass the path to your class)

Alternative would be to put the file in the classes directory, then you could access it from the class loader.
0
 
t3chAuthor Commented:
Not sure, How I would use Servlet Context but If I put the file in classes directory, How do I access it using Class loader?
0
 
rrzCommented:
I agree with objects. You should put file into your web app's classes folder(which puts it into the classpath).
Please try something like this.
String resource = "filename.pdf";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource(resource);
String filePath = url.getFile();
0
 
t3chAuthor Commented:
Thanks Objects.

Thanks rrz, will try it soon and post the results back.
0
 
t3chAuthor Commented:
Hi Objects, rrz, gurvinder,

            I tried the Class loader way and I am able to get the path of the file, still have to see if it will pick it up correctly. I am facing another problem now, I kept the file in classes folder under WEB-INF, but anytime I clean the project, this file gets cleaned up too (Deleted from the classes folder.) How do I persist the file at this location?
0
 
HegemonCommented:
The file should be initially anywhere else, i.e. if you want to keep it under classes, the original should be under src. Alternatively, it does not have to be under classes, you can keep it in any other folder with your build making process placing it where necessary.
0
 
t3chAuthor Commented:
Hi Hegemon,

          I am trying to run the application locally at the moment, so I am not making use of the ant build file. I have some other properties files which are under a package called com.prop.files. So I kept this new file in the same package as well, all the properties files are visible under classes folder except for this new one.
0
 
HegemonCommented:
That's strange, check your IDE settings for whether there is a filter copying only certain file types to classes as it compiles the application.
0
 
t3chAuthor Commented:
Hi Hegemon,

               so I just tried running it, heres the scenario.

1. When I keep the file in classes folder(not inside a specific pacakage folder), it works.
2. When I keep the file in some package, the same file is reflected under the same package sturcture under classes. For example, if I keep my file in package com.abc.xyz, I can see the file under,
WEB-INF->classes->com->abc->xyz
 
   but in this scenario, the pdf is not generating.
0
 
HegemonConnect With a Mentor Commented:
Well, to summarise:

If your application is deployed as a .war file and you need to READ the file, unless you can store the file externally, you put into classpath. Then you load it as a resource, streaming or not, by supplying the correct path using classLoader.getResource() / getResourceAsStream(), as in my earlier post.

How you put the resource into the archive/classpath is another matter. Either you can do it straight away by simply placing the file under the "src" hierarchy, with your IDE copying it to "classes" during compilation; or, for cleaner separation, you put it into a separate resources folder, in which you will need either to tune your IDE to include specific resources into the .WAR, or use a building tool, such as ant.

If the file is made available by placing it into classpath, it does not mean that your generated files will go to classpath as well. On the contrary, it is fine to read a file off classpath, but any generated files should be placed elsewhere. If an app generates files storing them somewhere, it is a common practice to either pass the location of the target directory as a command line parameter, or specify the directory in an OS environment variable.
0
 
t3chAuthor Commented:
Hi Hegemon,

                    Thanks for the detailed reply. I eventually got it to work and it works fine on my local machine. As soon as I deploy on remote WAS 6.1, it never works. Do this depend on machine to machine?
0
 
rrzCommented:
>Do this depend on machine to machine?
Ideally, "Write once, run anywhere" (Sun slogan).
Please show us your current code and file location. Maybe someone can help you.
0
 
HegemonCommented:
- Do this depend on machine to machine?

If you pack all resources you need into a .WAR and read the file off classpath, it will work on any servlet container on any machine.

I guess you are currently running it from your IDE. Make sure the WAR is packed correctly and try locally without the IDE as well.
0
 
t3chAuthor Commented:
>> Please show us your current code and file location

   String fileName = "abc.xsl";
          
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL fileURL = loader.getResource(fileName);

      This is my current code.

      Is there any difference between getResource and getResourceAsStream?

      Current structure of code:

      JavaSource:
         com.package1
         com.package2
         com.package3
         abc.xsl
      WebContent:
       images
       jsp
       html
       js
       WEB_INF
0
 
rrzCommented:
>Is there any difference between getResource and getResourceAsStream?
Yes. The first gives a URL. The second gives a stream. You should tell us what you are trying to do here. What do you want to do with the file and it's content ?  
>Current structure of code:  
It looks like you are giving us the structure in your IDE. As Hegemon requested, we are interested in the war file that you are deploying to your remote server. Using a zip utility(rename it to .zip if necessary), unzip it and see where your file is located. Alternatively from the command line, you can use
jar tvf your.war
0
 
t3chAuthor Commented:
Hi rrz@871311,

          Thanks for the reply. Wont be possible to supply war file, its a huge one (close to 88 mb).

Heres the scenario what I trying to do:

Trying to generate a pdf through an XSL file. and this is the file that my class needs to access in order to generate the PDF.
0
 
rrzCommented:
>Wont be possible to supply war file
We don't want the file. You can open it up and see where XSL file is located.  
>this is the file that my class needs to access in order to generate the PDF.
What does the method of that class expect as a parameter ?  
0
 
HegemonCommented:
If InputSource is used, then it probably needs an InputStream as a parameter. I am not clear why t3ch mentioned

" Path: WebContent/pdf/filename.pdf"

in the original question, since he needs to read the XSL, not PDF.
0
 
t3chAuthor Commented:
Hi Hegemon,

           I apologize, I just replace xsl with pdf (because in the beginning I thought the task is just to get to that file)
0
 
t3chAuthor Commented:
@rrz,

           The file resides under JavaSource. This is the path I am getting with getResource:

xslFilePath file:/C:/Workspace/projectName/WebContent/WEB-INF/classes/abc.xsl
0
 
t3chAuthor Commented:
I saw another difference in my code then what rrz suggested.
 At the very last line of his code, to get filepath, he did
String filepath = url.getFile();

I didnt do that, instead I used String filepath = url.toString();

Do you think this can be the cause of it?
0
 
objectsCommented:
you can't get the file path from a url. What do you need the path for?
0
 
t3chAuthor Commented:
Hi Objects,

              The code looks for an XSL file, populates all the attributes and eventually prints a PDF. I just added this new XSL file with some different attributes just like the previous XSL files that are already present in this application. The only difference is all those files reside outside the WAR file in a folder on the same unix box which holds the EAR deployment, but when we added this new file, we always got file not found exception, so eventually decided to move it in the EAR.
0
 
objectsCommented:
you can't access it as a file, only as a url (or stream from the url)
0
 
t3chAuthor Commented:
ohk. So whats the way to Access it as a file Objects? considering I dont have access to ServletContext.
0
 
objectsConnect With a Mentor Commented:
you shouldn't be accessing it as a File object, and from what you've said you don't need to.
0
 
rrzConnect With a Mentor Commented:
>this is the file that my class needs to access in order to generate the PDF.  
What is the signature of the method in that class ? Does it accept a file path or what ?  

objects>you can't get the file path from a url.  
It works in Tomcat. I ran my code from a unpack war. On my machine it returned the following.
filePath is  /C:/Tomcat/work/Catalina/localhost/testApp/WEB-INF/classes/test.txt

I can't test WAS 6.1  (which is what t3ch is deploying to)
0
 
objectsConnect With a Mentor Commented:
> filePath is  /C:/Tomcat/work/Catalina/localhost/testApp/WEB-INF/classes/test.txt

strictly speaking thats not actually a file path
you can derive a path when using an unpacked war, its just not necessary
And it will fail if the war is not unpacked.
0
 
HegemonCommented:
To repeat, if you are using XSL to to generate PDF, you are likely to need a Stream, not a File. Anyway, you cannot access a File in a packed .war. If you do need a file, you will have to create a temporary one, streaming the content from the original file using a stream.
0
 
t3chAuthor Commented:
>> It works in Tomcat. I ran my code from a unpack war. On my machine it returned the following.

 Hi rrz, it prints the file path on WAS6.1 as well.
0
 
rrzCommented:
Where do we stand now ?  You got the path to the file. Are you able to use it to do what you want ?
0
 
Gurvinder Pal SinghCommented:
@t3ch: Is your problem resolved?
0
 
t3chAuthor Commented:
folks, eventually the problem got solved. There was an extra white space in the path written under the properties file :)
 I will assign points to all of you. You all really helped a lot.
0
 
t3chAuthor Commented:
Thanks folks.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.