You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by André Warnier <aw...@ice-sa.com> on 2009/12/14 23:37:50 UTC
resource file location (was: Logo file location)
Hi.
On another thread, a discussion was started as to how to correctly
locate and specify some data file, part of the application, and which
needs to be read in by some code part of that same webapp.
Say that the application has a context path "/myapp".
The original idea is to locate the resource file for instance in a
subdirectory "logos" of the web application, and for some flexibility to
indicate this location to the webapp via an <init-param> in the webapp's
web.xml, like
<init-param>
<param-name>thelogo</param-name>
<param-value>path-to-mylogo.jpg</param-value>
</init-param>
"ctx" being the ServletContext, the webapp could then obtain an input
stream to this resource by a line like
InputStream logo_stream =
ctx.getResourceAsStream(ctx.getInitParameter('thelogo'));
Now the question is : how does this param-value need to be set in order
for the getResourceAsStream() to work correctly ?
According to the specification which I find here :
http://java.sun.com/products/servlet/2.5/docs/servlet-2_5-mr2/index.html
we have
java.io.InputStream getResourceAsStream(java.lang.String path)
Returns the resource located at the named path as an InputStream
object.
The trouble is, it does not really explain what is meant by a "path" in
that context, and some of the other method descriptions on the same page
introduce a slight doubt.
If it is a real absolute file path on the hosting system, and if on that
system CATALINA_BASE is "/srv/tomcat/", then supposedly the parameter
needs to be specified as
<init-param>
<param-name>thelogo</param-name>
<param-value>/srv/tomcat/webapps/myapp/logos/mylogo.jpg</param-value>
</init-param>
However, that is not very flexible. If this file is an integral part of
my webapp, then chances are that it is, relative to my webapp context,
always at the same place. But in absolute host path terms, it is not, if
my webapp is to be deployed on different hosts.
I would then have to change, inside of my webapp's web.xml file, the
value of the <param-value> in function of the target host, before I
create a war-file containing my webapp (and its web.xml), to deploy it
on that target host.
That seems to me in flagrant contradiction of the "encapsulation" ideal
of a webapp and even of Java.
So let's see if we can improve on that.
Maybe if we specify the parameter as follows
<init-param>
<param-name>thelogo</param-name>
<param-value>logos/mylogo.jpg</param-value>
</init-param>
and then used code like
InputStream logo_stream =
ctx.getResourceAsStream(ctx.getRealPath(ctx.getInitParameter('thelogo')));
then according to
java.lang.String getRealPath(java.lang.String path)
Returns a String containing the real path for a given virtual
path.
presumably we should get what we want (at least if "virtual path"
mentioned above has the meaning of "relative path under this webapp's
context path" but that is not very clear either).
However, it has many times been indicated on this list that
getRealPath() is not guaranteed to return anything.(*)
I can see still another way to possibly obtain an input stream on this
file, which would be to use the
java.lang.String getContextPath()
Returns the context path of the web application.
and then maybe add "/logos/mylogo.jpg" to it. But I am not quite sure
at this stage either what "path" means here (presumably just "/myapp"),
like when mentioned with the "path" attribute of a Context element.
So what is one to do, if one wants not to have to change the content of
one's war file for each target host, but still allow the webapp to find
and read the logo ?
(*) I understand that the path returned by this function could not be
used as a path to create a file, or write to one, because it is not
guaranteed to point to a writeable disk location. But considering that
this resource file is a part of my own application, which I supply
inside of my war file which is expanded by the servlet container, and
from which I only want to read, why can I not use this getRealPath()
successfully then ?
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
Re: resource file location (was: Logo file location)
Posted by André Warnier <aw...@ice-sa.com>.
Caldarale, Charles R wrote:
>> From: André Warnier [mailto:aw@ice-sa.com]
>> Subject: resource file location (was: Logo file location)
>>
>> The trouble is, it does not really explain what is meant by a "path" in
>> that context, and some of the other method descriptions on the same
>> page introduce a slight doubt.
>
> Sure it does:
>
> "The path must begin with a "/" and is interpreted as relative to the current context root.
>
> "This method allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.
>
> "The servlet container must implement the URL handlers and URLConnection objects that are necessary to access the resource."
>
> The path parameter is clearly a URL for any resource in the domain of the context. What the URL actually maps to depends on the configuration of the webapp and container.
>
>> If it is a real absolute file path on the hosting system
>
> There is no requirement and certainly no guarantee that the host even has a file system.
>
>> if on that system CATALINA_BASE is "/srv/tomcat/", then supposedly the
>> parameter needs to be specified as
>> <init-param>
>> <param-name>thelogo</param-name>
>> <param-value>/srv/tomcat/webapps/myapp/logos/mylogo.jpg</param-value>
>> </init-param>
>
> Nope. Read the API spec again: "interpreted as relative to the current context root." The proper setting is just <param-value>/logos/mylogo.jpg</param-value>.
>
>> That seems to me in flagrant contradiction of the "encapsulation" ideal
>> of a webapp and even of Java.
>
> It would be, which is why the spec doesn't do it that way.
>
>> and then used code like
>>
>> InputStream logo_stream =
>> ctx.getResourceAsStream(ctx.getRealPath(ctx.getInitParameter('thelogo')
>> ));
>
> Again, getRealPath() should NEVER (well, almost never) be used, since there's no requirement for it to return anything useful.
>
>> So what is one to do, if one wants not to have to change the content of
>> one's war file for each target host, but still allow the webapp to find
>> and read the logo ?
>
> You don't - you just have to read the spec correctly, and not ignore the definition of the parameter.
>
Chuck, Chris,
Ok, I get it now. I just read the Method Summary part of that page,
never scrolled down to the Method Detail descriptions, so I missed the
very clear definition of "path".
Mea culpa.
Thanks for showing me the errors of my ways.
And I swear that I'll never use getRealPath().
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
RE: resource file location (was: Logo file location)
Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: André Warnier [mailto:aw@ice-sa.com]
> Subject: resource file location (was: Logo file location)
>
> The trouble is, it does not really explain what is meant by a "path" in
> that context, and some of the other method descriptions on the same
> page introduce a slight doubt.
Sure it does:
"The path must begin with a "/" and is interpreted as relative to the current context root.
"This method allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.
"The servlet container must implement the URL handlers and URLConnection objects that are necessary to access the resource."
The path parameter is clearly a URL for any resource in the domain of the context. What the URL actually maps to depends on the configuration of the webapp and container.
> If it is a real absolute file path on the hosting system
There is no requirement and certainly no guarantee that the host even has a file system.
> if on that system CATALINA_BASE is "/srv/tomcat/", then supposedly the
> parameter needs to be specified as
> <init-param>
> <param-name>thelogo</param-name>
> <param-value>/srv/tomcat/webapps/myapp/logos/mylogo.jpg</param-value>
> </init-param>
Nope. Read the API spec again: "interpreted as relative to the current context root." The proper setting is just <param-value>/logos/mylogo.jpg</param-value>.
> That seems to me in flagrant contradiction of the "encapsulation" ideal
> of a webapp and even of Java.
It would be, which is why the spec doesn't do it that way.
> and then used code like
>
> InputStream logo_stream =
> ctx.getResourceAsStream(ctx.getRealPath(ctx.getInitParameter('thelogo')
> ));
Again, getRealPath() should NEVER (well, almost never) be used, since there's no requirement for it to return anything useful.
> So what is one to do, if one wants not to have to change the content of
> one's war file for each target host, but still allow the webapp to find
> and read the logo ?
You don't - you just have to read the spec correctly, and not ignore the definition of the parameter.
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.