The tag fmt:message reads the property of a given key in a language that should be provided by the client. However, it seems to read the language from the request for the first request to this web application only. This bug was reproduced by a site containing: <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <fmt:setBundle basename="Resource"> ... <fmt:message key="language" /> There are two property files: Resource.properties containing: language=German Resource.properties_en containing: language=English For the test, two computers are used. One with a browser that is set to English and one that is set to German. The first browser that accesses the web application determines which resource bundle is used. Afterwards, all language information in the request seems to be ignored. A reload of the web application does not cause JSTL to listen again for the language requested by the client. A restart of Tomcat does. Instead of using a property file, a subclass of java.util.ResourceBundle was used. Its method were not called after the first client request. The tag bean:message from Struts does not seem to have this bug.
Johann, Could you run a test with the nightly binary of 'standard'. Many bugs related to "tag-pooling" behavior have been fixed since standard 1.0.2. If you still experience the same problem, please please reopen the bug and send us some sample code that we can then use to better investigate the problem.
Pierre, I would love to try a nightly snapshot. But all links for nightly builds on http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html and on http://jakarta.apache.org/taglibs/index.html point either to empty directories or result in a 404 error. By the way - I was using version 1.0.2 of JSTL, therefore I changed that field.
Download of the nigthly builds has been fixed.
Thank You Glenn, the current nightly build of JSTL (2003-02-03) does not seem to work with Tomcat 4.1.12. Unfortunately, the following stack trace of the root cause shows no hint about the class name that triggered the exception: java.lang.VerifyError: Cannot inherit from final class at java.lang.ClassLoader.defineClass0(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:509) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123) at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1664) at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:953) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1394) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1274) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:322) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.createContentDispatcher(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.(XMLDocumentFragmentScannerImpl.java:248) at org.apache.xerces.impl.XMLDocumentScannerImpl.(XMLDocumentScannerImpl.java:245) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.(Unknown Source) at org.apache.xerces.parsers.IntegratedParserConfiguration.createDocumentScanner(Unknown Source) at org.apache.xerces.parsers.DTDConfiguration.(DTDConfiguration.java:366) at org.apache.xerces.parsers.StandardParserConfiguration.(StandardParserConfiguration.java:197) at org.apache.xerces.parsers.IntegratedParserConfiguration.(Unknown Source) at org.apache.xerces.parsers.IntegratedParserConfiguration.(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:274) at java.lang.Class.newInstance0(Class.java:296) at java.lang.Class.newInstance(Class.java:249) at org.apache.xerces.util.ObjectFactory.newInstance(ObjectFactory.java:293) at org.apache.xerces.util.ObjectFactory.createObject(ObjectFactory.java:224) at org.apache.xerces.util.ObjectFactory.createObject(ObjectFactory.java:119) at org.apache.xerces.parsers.DOMParser.(DOMParser.java:153) at org.apache.xerces.parsers.DOMParser.(DOMParser.java:137) at org.apache.xerces.jaxp.DocumentBuilderImpl.(DocumentBuilderImpl.java:102) at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.newDocumentBuilder(DocumentBuilderFactoryImpl.java:88) at org.apache.jasper.xmlparser.ParserUtils.parseXMLDocument(ParserUtils.java:167) at org.apache.jasper.compiler.TldLocationsCache.processWebDotXml(TldLocationsCache.java:175) at org.apache.jasper.compiler.TldLocationsCache.init(TldLocationsCache.java:147) at org.apache.jasper.compiler.TldLocationsCache.getLocation(TldLocationsCache.java:318) at org.apache.jasper.JspCompilationContext.getTldLocation(JspCompilationContext.java:437) at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:353) [...]
Note: The tag library I18N shows the same behaviour. Maybe this bug is related to Bug #16932. Bug #16932 should be easier to reproduce than this one.
The nightly build from 2003-02-07 still shows the described behaviour. (only old xerces libraries where used in order to avoid the stack trace shown in my previous comment) Are there examples where the resource bundle selection works as intended?
Johan, Bug 16932 is related to the 'i18n' taglib, not 'standard'. Once again, please send us simple sample code that reproduces the problem and I'll then be able to look into it.
Pierre, with "related" I wanted to express that this type of bug might be common in several tag libs that do i18n. That does not mean that there must be a common code base. Sorry if that caused some confusion. Furthermore, I've got some more information which may be useful to reproduce the bug: The following code does NOT work as described in the specification: <fmt:setBundle basename="WebResource"/> <fmt:message key="title"/> Browser with English locale (en): Title Browser with German locale (de): Title <-- wrong, should be "Anrede" However, the following code DOES work: <fmt:setBundle basename="WebResource" var="lc" scope="page"/> <% javax.servlet.jsp.jstl.fmt.LocalizationContext locc = (javax.servlet.jsp.jstl.fmt.LocalizationContext)(pageContext.getAttribute("l c")); java.util.ResourceBundle rb = locc.getResourceBundle(); java.util.Locale locale = locc.getLocale(); %> <%= rb.getString("title") %> <%= locale.toString() %> Browser with English locale: Title en_US Browser with German locale: Anrede de I hope this helps to isolate the source of that bug. Please note that the following sequence is neccessary to reproduce the bug: - deployment of the test application - access with a browser with English locale setting - access with a browser with German locale setting The used resource bundle consists of two subclasses of java.util.ResourceBundle: - WebResource.java (returning German resources) - WebResource_de.java (returning English resources) Both override the following methods: - public java.util.Locale getLocale() - public Enumeration getKeys() - protected Object handleGetObject(String key) - private String lookup(String key) throws MissingResourceException Inserting log statements to those classes showed that the wrong resource bundle is used if the bug occurs. The classes reside in a jar-file in $TOMCAT_HOME/common/lib Is there somewhere an example war-file that uses fmt for i18n and can be downloaded in order to refer to it?
A new "demo" example has been added to standard-examples (in the category "I18N and Formatting"). It allows you to test the behavior of I18N and Formatting actions by letting you easily set the application-based locale as well as the fallback locale. Please give it a try. If you still find there is a problem with the tags, please re-open the bug.
The example "JSTL: Formatting/I18N Support -- ParametricReplacement" shows the behaviour described in this bug. When using it the first time, the browser locales where: de - en - en_US and it produced a German site (which is correct). When using it the second time, the browser locales where: en - en_US - de and it still showed a German site (which should have been in English). The example was tested with: - JSTL 1.0.3 (http://www.apache.org/dist/jakarta/taglibs/standard/binaries/jakarta-taglibs-standard-1.0.3.tar.gz) - Apache Tomcat/4.1.12 - Java Version: 1.4.0_01 (from Sun) It might be a bug in that specific Tomcat version. I was not able to figure that out.
Actually, the Parametric Replacement example is meant to only show German messages. Check the code (click on the screwdriver). How about this: - dowload the nigthly for standard 1.0 - run the standard-examples with Tomcat 4.1.24 - try the new demo example If you still find a problem, then I'll be happy to look at it with these known values.