This week's giveaway is in the EJB and other Java EE Technologies forum.
We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line!
See this thread for details.
The moose likes Tomcat and the fly likes Where to place non java files in a WAR archive? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Products » Tomcat
Bookmark "Where to place non java files in a WAR archive?" Watch "Where to place non java files in a WAR archive?" New topic
Author

Where to place non java files in a WAR archive?

Andrei Miclaus
Greenhorn

Joined: Mar 08, 2011
Posts: 6
What is the best practice to place non java files(like a XML file with domain specific information) in a WAR.

I want to deploy my web-app on Tomcat 7.0.

As far as I found out, I have the option to place the files:
- in the root directory of the web-app, where they are visible to everyone
or
- in the WEB-INF/classes folder where they are visible only to the application

I wish to place the my XML encoded files somewhere hidden from users but I don't believe that placing them together with the java class files is that good...

Here is a description about the Tomcat classloader, it seems it only looks in the root and under WEB-INF/classes and WEB-INF/lib:
http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html

I use
to get the location of the xml file.

It works if the file is in the above mentioned folders(root and WEB-INF/classes), but not if it is in any other folder.

I am sorry if this question was already answered but i did not find any information on the web.
Many Thanks,
Andrei
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15632
    
  15

Welcome to the JavaRanch, Andrei!

First, just to make one thing clear: you should NEVER write files to a WAR. It not only violates the Java standards, it can cause serious pain and suffering. So any files in a WAR should be read-only.

If you want a file to be inaccessible from URL (client) requests, you have to put it somewhere under WEB-INF, because that's the only place that resources are invisible to clients. Anywhere outside of there could be secured, but it would still be visible, so it's better if you just put it under WEB-INF. Come to think of it, META-INF might work, but I don't recommend it. Use WEB-INF.

WEB-INF is a general directory and only the "classes" and "lib" subdirectories under it are actually class resources unless you have customized classloading. If you created a file named /WEB-INF/data/POIList.xml, the classloader wouldn't be able to find it. However, an HttpServeletRequest . getResourceAsStream("/WEB-INF/data/POIList") would work wonderfully as a feed to your favorite XML parser. The Request getResource methods can access any resource in a WAR, not just classpath resources.


Customer surveys are for companies who didn't pay proper attention to begin with.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 60049
    
  65

Andrei Miclaus wrote:but I don't believe that placing them together with the java class files is that good...

Why not? This is a common practice when the file is be made available via the classloader. Message files for example.

As Tim pointed out, if the classloader will not be used, anywhere else under WEB-INF will do.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Andrei Miclaus
Greenhorn

Joined: Mar 08, 2011
Posts: 6
Hello and thanks a lot for the answers

Unfortunately I could not call
because there is no such method. Only through

but then the classloader is called and it doesn't work.
The same with


But, I am victorious!

Thanks to your tips and chapter "Accessing Passive Server Resources" from novocode (http://www.novocode.com/doc/servlet-essentials/chapter3.html#ch_3_3) I managed to get my XML file with the Servlet Context

My POIList.xml file is now under WEB-INF/data/POIList.xml, it works and i feel happy.

Thanks a lot Tim Holloway and Bear Bibeault
Glad to be on JavaRanch
Best wishes
Andrei
Andrei Miclaus
Greenhorn

Joined: Mar 08, 2011
Posts: 6
One more question
First, just to make one thing clear: you should NEVER write files to a WAR. It not only violates the Java standards, it can cause serious pain and suffering. So any files in a WAR should be read-only.

If one should never write to a WAR where would I store files I write during execution of the web-app(for example log files or usage statistics).
Should all go into a database?

Thanks
Andrei
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18120
    
    8

You should store them somewhere outside the web application, and in fact somewhere entirely outside the application server.

Create a directory somewhere, make sure the permissions are correct, and write your data there.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15632
    
  15

Your getResourceAsStream failed because it's an instance method, not a class method. You need the actual HttpServletRequest object, not its class.

If you need to upload or otherwise maintain mutable files related to a web application, you should designate an external location outside of the web application (and the Tomcat server) to hold them. A database may or may not be useful here, depending on your needs.

Conventionally in Linux, you would store file like that in a directory named something like /var/lib/myapp/uploads. In Windows, there's no convention, so just make a directory somewhere. I always make the directory location a variable (resource-reference) so that it isn't hard-coded into the webapp.
Andrei Miclaus
Greenhorn

Joined: Mar 08, 2011
Posts: 6
Tim Holloway wrote:Your getResourceAsStream failed because it's an instance method, not a class method. You need the actual HttpServletRequest object, not its class.

I forgot to mention that one

The HttpServletRequest Object "request" that is passed to the Servlet in the doGet, for example, does not have a getResource or getResourcesAsStream method. Only If one calls getClass() but that goes over the classLoader so this does not work

Am I missing something?

And thanks to the other repliers, will keep the tips in mind
Andrei
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15632
    
  15

Are you missing something? Only that I'm too lazy to RTFM.

It's on the ServletContext, not the HttpServletRequest. I'm fairly sure there's a path from one to the other, but I can't recall what it is at the moment. In any event, the Servlet itself has a getServletContext() method that can be used to get there.
Andrei Miclaus
Greenhorn

Joined: Mar 08, 2011
Posts: 6
Andrei Miclaus wrote:
Thanks to your tips and chapter "Accessing Passive Server Resources" from novocode (http://www.novocode.com/doc/servlet-essentials/chapter3.html#ch_3_3) I managed to get my XML file with the Servlet Context

My POIList.xml file is now under WEB-INF/data/POIList.xml, it works and i feel happy.


This settles it

Thanks again
Andrei
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Where to place non java files in a WAR archive?
 
Similar Threads
we can deploy a folder instead of jar or war what is the difference
sax java.io.FileNotFoundException
getServletContext() getRealPath() problem in packaged J2EE application
JasperException
ant not deploying on Tomcat 7