Solved

get path to a file

Posted on 2010-09-09
50
721 Views
Last Modified: 2012-06-27
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
0
Comment
Question by:t3ch
  • 23
  • 8
  • 7
  • +2
50 Comments
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33639284
the path will be relative to WEB-INF inside the web-content only.

../pdf/filename.pdf
0
 
LVL 10

Expert Comment

by:Hegemon
ID: 33639364
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
 
LVL 4

Author Comment

by:t3ch
ID: 33639739
Hi Gurvinder,

                  so "../" is nothing but web-content?
0
 
LVL 4

Author Comment

by:t3ch
ID: 33639753
HI Hegemon,

                   The content is in a war file which eventually goes into an EAR file.
0
 
LVL 10

Expert Comment

by:Hegemon
ID: 33640122
So that's the only way to get the content of the file then (I think so)
0
 
LVL 40

Accepted Solution

by:
gurvinder372 earned 100 total points
ID: 33640188
<<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
 
LVL 4

Author Comment

by:t3ch
ID: 33640972
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
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33641183
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
 
LVL 4

Author Comment

by:t3ch
ID: 33641569
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
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33641669
../../../../../../../pdf/pdf_file

but i would still recommend that you keep it outside the war file
0
 
LVL 4

Author Comment

by:t3ch
ID: 33641825
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
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33641866
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
 
LVL 4

Author Comment

by:t3ch
ID: 33641924
Thanks Gurvinder, I will try it out and post results.
0
 
LVL 92

Expert Comment

by:objects
ID: 33642449
afaik you need to use getRealPath() anything else is not going to be reliable
0
 
LVL 4

Author Comment

by:t3ch
ID: 33643137
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
 
LVL 92

Expert Comment

by:objects
ID: 33643158
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
 
LVL 4

Author Comment

by:t3ch
ID: 33643195
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
 
LVL 92

Expert Comment

by:objects
ID: 33643226
0
 
LVL 27

Expert Comment

by:rrz
ID: 33643235
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
 
LVL 4

Author Comment

by:t3ch
ID: 33646417
Thanks Objects.

Thanks rrz, will try it soon and post the results back.
0
 
LVL 4

Author Comment

by:t3ch
ID: 33647691
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
 
LVL 10

Expert Comment

by:Hegemon
ID: 33647857
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
 
LVL 4

Author Comment

by:t3ch
ID: 33647929
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
 
LVL 10

Expert Comment

by:Hegemon
ID: 33647957
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
 
LVL 4

Author Comment

by:t3ch
ID: 33648640
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 10

Assisted Solution

by:Hegemon
Hegemon earned 100 total points
ID: 33650169
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
 
LVL 4

Author Comment

by:t3ch
ID: 33650917
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
 
LVL 27

Expert Comment

by:rrz
ID: 33651728
>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
 
LVL 10

Expert Comment

by:Hegemon
ID: 33652514
- 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
 
LVL 4

Author Comment

by:t3ch
ID: 33662968
>> 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
 
LVL 27

Expert Comment

by:rrz
ID: 33663458
>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
 
LVL 4

Author Comment

by:t3ch
ID: 33663682
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
 
LVL 27

Expert Comment

by:rrz
ID: 33663828
>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
 
LVL 10

Expert Comment

by:Hegemon
ID: 33663882
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
 
LVL 4

Author Comment

by:t3ch
ID: 33664183
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
 
LVL 4

Author Comment

by:t3ch
ID: 33664207
@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
 
LVL 4

Author Comment

by:t3ch
ID: 33666119
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
 
LVL 92

Expert Comment

by:objects
ID: 33667439
you can't get the file path from a url. What do you need the path for?
0
 
LVL 4

Author Comment

by:t3ch
ID: 33668426
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
 
LVL 92

Expert Comment

by:objects
ID: 33668458
you can't access it as a file, only as a url (or stream from the url)
0
 
LVL 4

Author Comment

by:t3ch
ID: 33668510
ohk. So whats the way to Access it as a file Objects? considering I dont have access to ServletContext.
0
 
LVL 92

Assisted Solution

by:objects
objects earned 200 total points
ID: 33668520
you shouldn't be accessing it as a File object, and from what you've said you don't need to.
0
 
LVL 27

Assisted Solution

by:rrz
rrz earned 100 total points
ID: 33668818
>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
 
LVL 92

Assisted Solution

by:objects
objects earned 200 total points
ID: 33668866
> 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
 
LVL 10

Expert Comment

by:Hegemon
ID: 33670043
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
 
LVL 4

Author Comment

by:t3ch
ID: 33674814
>> 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
 
LVL 27

Expert Comment

by:rrz
ID: 33677868
Where do we stand now ?  You got the path to the file. Are you able to use it to do what you want ?
0
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33690058
@t3ch: Is your problem resolved?
0
 
LVL 4

Author Comment

by:t3ch
ID: 33730681
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
 
LVL 4

Author Closing Comment

by:t3ch
ID: 34243407
Thanks folks.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now