Vernon,

> After more than three hours research and test, I haven't resolve the
> problem yet. If my understand is right, what you suggested is to
> have the following code frame in the JSP page:
>
> <fmt:bundle basename="org.apache.taglibs.standard.examples.i18n.Resources">   
<---- I had this line at the very 
> begining of the page
>  <fmt:message>
>   greetingMorning
>  </fmt:message>
> </fmt:bundle>   <----- at the bottom of the page
> 
> The problem doesn't go away with this change. 
> 
> In regarding of the number of resource files, the memory usage is
> around 70 m after the server is up if three files are there; compare
> to 20m if only two files. About 450 items are in each file.

Using either <fmt:bundle> or <fmt:setBundle>, as in

 <fmt:bundle basename="org.apache.taglibs.standard.examples.i18n.Resources">
   <%-- Nested <fmt:message> actions --%>
 </fmt:bundle> 

or

<fmt:setBundle basename="org.apache.taglibs.standard.examples.i18n.Resources"
     var="bundle"/>
<%-- Any number of <fmt:message bundle="${bundle}"> actions --%>

respectively, will reduce the number of resource bundles loaded, as
all the <fmt:message> actions will share the resource bundle of the
enclosing (as with <fmt:bundle>) or referenced (as with
<fmt:setBundle>) localization context.

The reason why all your available resources bundles ("default", "en",
and "zh") are still loaded must be related to JSTL's locale-matching algorithm
and the way java.util.ResourceBundle.getBundle() works.

Let's assume your preferred locales are "zh-TW" and "en-US", in this
order. <fmt:bundle> (or <fmt:setBundle) will make a call to
ResourceBundle.getBundle(), supplying "zh-TW" as the requested
locale. Since a language match (for "zh") is found, <fmt:bundle> will
store the associated resource bundle in its localization context. No
further preferred locales will be checked, since a match has already
been found for the first.

Let's assume your preferred locales are "fr-FR", "zh-TW", and "en-US",
in this order. <fmt:bundle> will call ResourceBundle.getBundle(),
passing in the first preferred locale
("fr-FR"). java.util.ResourceBundle.getBundle() will search the
following candidate bundles, assuming that your runtime's default
locale is "en-US" (o.a.t.s.e.i is an abbreviation of
org.apache.taglibs.standard.examples.i18n):

  o.a.t.s.e.i.Resources + "_" + "fr" + "_" + "FR"
  o.a.t.s.e.i.Resources + "_" + "fr"
  o.a.t.s.e.i.Resources + "_" + "en" + "_" + "US"
  o.a.t.s.e.i.Resources + "_" + "en"
  o.a.t.s.e.i.Resources

In this case, a resource bundle is found for 

  o.a.t.s.e.i.Resources + "_" + "en"

and loaded, but it won't be considered by JSTL, since it matches
neither the language nor the country component of the preferred locale
("fr-FR"). Therefore, JSTL will go ahead and make another call to
java.util.ResourceBundle(), passing in the second preferred locale
("zh-TW"). In this case, ResourceBundle.getBundle() will find a
resource bundle for "zh" and load it, which will be used by JSTL,
since it matches the language of the preferred locale.

In the second case, a "redundant" resource bundle
(o.a.t.s.e.i.Resources + "_" + "en") has been loaded.

One way to avoid loading a redundant resource bundle would be for JSTL
to check if a resource bundle for a preferred locale exists (by
calling Thread.currentThread().getContextClassLoader().getResource()),
and only if it does, call ResourceBundle.getBundle() for that locale.

So in the above example, JSTL would pass these resource names to
ClassLoader.getResource() when considering the first preferred locale:

  o/a/t/s/e/i/Resources_fr_FR.class
  o/a/t/s/e/i/Resources_fr_FR.properties
  o/a/t/s/e/i/Resources_fr.class
  o/a/t/s/e/i/Resources_fr.properties

and since none of these resource exist, JSTL would skip the first
preferred locale and move on to the second.

We could certainly implement this behaviour in JSTL, but we might run
into a problem where calling ClassLoader.getResource() will always
return null due to a lack of permissions. Note that
java.util.ResourceBundle loads resource bundle properties files inside
a java.security.AccessController.doPrivileged(), so as to have only
its own permissions considered and those of its callers ignored
(java.util.ResourceBundle is a system class and therefore has access
to any resources). However, if we load a resource from within JSTL, we
will have access to only those resources that JSTL is allowed to
read. This would be a problem.


Jan




--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to