1 2 Previous Next 29 Replies Latest reply on Oct 15, 2013 7:29 AM by pawo509 Go to original post
      • 15. Re: Seam looses internationalization capabilities
        gadeyne.bram

        I use an ear deployment.

         

        The server was running on JDK 1.6_13 I've updated it to JDK 1.6_34. We have the same application running on other locations and the problem does not occur over there. This morning I noticed the difference in these versions. Maybe there was a classloading problem in JDK 1.6_13.

         

        I'll keep you posted!

        • 16. Re: Seam looses internationalization capabilities
          gadeyne.bram

          Hi,

           

          I'm able to reproduce the problem!

           

          It seems that the problem occurs when the user changes its locale through the browser (currently IE 7).

           

          If the user logs on using "nl" as its locale and then changes it to "en" the problem occurs. The messages only contain 72 values from 2 internal properties files. Those are probably 16 messages from org.hibernate.validator.DefaulValidatorMessages and 56 messages from javax.faces.messages.properties.

           

          I've created a custom org.jboss.seam.international.messagesFactory component to debug this issue and to provide a workaround.

           

          Using the code below I do get the messages for "en" at that point.

           

          ResourceBundle rb=ResourceLoader.instance().loadBundle("messages");

           

          It seems like the cache in org.jboss.seam.core.SeamResourceBundle is somehow corrupt.

           

          As a workaround my messages component is session scoped and keeps a Map<String, Map<String,String>> with the messages as value and the locale as key to retrieve them if only 72 messages were resolved by the seem messages component.

          • 17. Re: Seam looses internationalization capabilities
            mkouba

            Hi,

            that's strange. What do you mean with "through the browser"? Does it mean through the application UI (e.g. using something like <h:commandButton action="#{localeSelector.selectLanguage('en')}" />) or configuring browser settings (HTTP Accept-Language header)? Anyways I did some basic tests and still cannot reproduce...

            • 18. Re: Seam looses internationalization capabilities
              gadeyne.bram

              Hi,

               

              I just change the locale in Internet Explorer using "internet properties" -> "languages" -> en-GB of nl-be. I think this changes HTTP header.

               

              It's realy very strange.

              • 19. Re: Seam looses internationalization capabilities
                mkouba

                Hm, that's really odd. I did some more tests (emulating browser and HTTP header settings) and the only way to get the message key (missing resource bundle) was to supply Accept-Language header with locale that was not listed in the supported locales in faces-config.xml (JSF falls back to the default locale of the server) and having no messages for the server default locale... However if I supply the default messages.properties file it logically works (if I remember correctly you have the default messages file, do you?). So I think we're stuck. At least you have the working workaround...

                • 20. Re: Seam looses internationalization capabilities
                  gadeyne.bram

                  Thanks Martin for the testing.

                   

                  Yes I have the default messages.properties file also.

                   

                  In my faces-config.xml I have:

                   

                  <locale-config>

                  <default-locale>nl</default-locale>

                  <supported-locale>en</supported-locale>

                  <supported-locale>nl</supported-locale>

                  </locale-config>

                   

                  In my components.xml i have

                   

                  <international:locale-config default-locale="nl" supported-locales="nl en" />

                   

                  I have these messages.properties files:

                  messages.properties

                  messages_nl.properties

                  messages_en.properties

                   

                  I've noticed that the cache also uses a HashMap value of some Init object. Could this cause the problem?

                  • 21. Re: Seam looses internationalization capabilities
                    mkouba

                    I have no idea. Init is a Seam component that holds configuration settings. I guess it might cause the problem if you have more than one web archives using Seam in your EAR...

                    • 22. Re: Seam looses internationalization capabilities
                      gadeyne.bram

                      Hi,

                       

                      Another update on this matter...

                       

                      The issue was resolved using my own implementation of the Messages component. However, a few days ago the problem reoccured. So now I've created my own implementation of the ResourceLoader component.

                       

                      I first try loading the message bundle using the Seam implementation and if the returned bundle is null I try the following.

                       

                      java.util.ResourceBundle.clearCache();

                      Locale current=org.jboss.seam.international.Locale.instance();

                      Locale l=new Locale(current.getLanguage());

                      java.util.ResourceBundle.getBundle("messages",locale);

                      //if bundle is null

                      java.util.ResourceBundle.getBundle("messages");

                       

                      The bundle is still null after some usages.

                       

                      Now I also found out this. The "in application" browser that causes this problem is JExplorer (version 2.2).

                      It's even stranger that:

                      -when I, after a clean server start, run the application from IE an then open it using JExplorer, everything works fine.

                      -when I, after a clean server start, run the application first in JExplorer and then in IE. The problem occurs for the JExplorer session but not in IE.

                       

                      Does anyone have any other idea's how to fix this problem?

                      • 23. Re: Seam looses internationalization capabilities
                        gadeyne.bram

                        I'm truly sorry for this but I completely forgot that the external application, using jexplorer, launches this seam application using some get parameters. In pages.xml there is also an action beiing called.

                         

                        So now I figured that using the same url as in jexplorer the same issue also occurs in IE.

                         

                        I've changed my code so that the client calls the page where the action method is executed. This action method then redirects the user to a new page where the messages are present.

                         

                        I've added some logging in this actionMethod and it seems that Messages.instance() does not include my messages bundle at that point. In this action method I also call identity.authenticate.

                         

                        Does anyone have any idea why the messages are empty in this action method?

                        • 24. Re: Seam looses internationalization capabilities
                          baddeley84

                          Hi Bram, did you ever get to the bottom of this?

                           

                          I have the same problem with Resource Bundle getting dropped when I change Locale manually (it just shows the message keys), no errors are thrown so I think it may be a config issue?

                           

                          Regards

                           

                          David

                          • 25. Re: Seam looses internationalization capabilities
                            gadeyne.bram

                            Hi David,

                             

                            The problem is not solved for me but I found a workaround.

                             

                            In my case the problem occurs when I do a login in a page load method. It seems like the session is then somehow cleared and the messages bundles are not there.

                             

                            I had this in my pages.xml file:

                             

                            <page view-id="/somepage.xhtml" action="#{someComponent.pageLoad}" />

                             

                            Then the pageLoad method looked like

                             

                            public void pageLoad(){

                                 //do some stuff

                                 identity.authenticate(); //I think this causes all my problems

                            }

                             

                            To solve this I added a dummy xhtml file that has some dummy content.

                             

                            A url now calls this dummy page instead of the real page:

                             

                            <page view-id="somedummypage.xhtml" action="#{someComponent.pageLoad}" />

                             

                            I've changed the pageLoad method like:

                             

                            public String pageLoad(){

                                 //do some stuff

                                 identity.authenticate(); //I think this causes all my problems

                                 return "someoutcome";

                            }

                             

                            I also added this in pages.xhtml:

                             

                            <rule if-outcome="someoutcome">

                                 <redirect view-id="/somepage.xhtml" />

                            </rule>

                             

                            All this does is performing a redirect after executing the pageLoad function instead of showing the page directly. It seems like the message bundles are then loaded correctly.

                             

                            Maybe you can try changing the locale and then redirecting the page?

                             

                            Regards

                            Bram

                            • 26. Re: Seam looses internationalization capabilities
                              baddeley84

                              Hi Bram,

                               

                              Thanks for the update, I have tried your method, doing a redirect after the localeSelector.select() action, but my problem still persists, its annoying that sometimes when I restart the server I can switch between message bundles ok, but on other times, when I change language it just loads the message keys

                               

                              I am trying to figure out a way to debug the ResourceBundle loader to see why the new bundle is not loading correctly, if you have any advice it would help!

                               

                              Regards

                               

                              David

                              • 27. Re: Seam looses internationalization capabilities
                                gadeyne.bram

                                Hi David,

                                 

                                I've uploaded 2 custom components . They extend 2 seam components that take care of resolving the messages bundles. Maybe you could use these to debug your problem. I'm using seam 2.2.2.Final so I hope they are compatible with your version. Otherwise you could create others the same way.

                                 

                                Kind regards Bram

                                • 28. Re: Seam looses internationalization capabilities
                                  baddeley84

                                  Thank you sir! Yes thats exactly what I needed (I am on 2.2.2.Final)

                                   

                                  After implementing your custom resource loader the problem has dissapeared. Funny because I was getting the MissingResourceException (even though the Message bundle did load) successfully)

                                   

                                  I did some experimenting and it looks like the...

                                  java.util.ResourceBundle.clearCache();

                                  ...is the silver bullet, as long as this is being called the new MessageBundle loads ok (I will test in production tomorrow)

                                   

                                  Im not sure if this is a bug in SEAM or I am doing something wrong, my change language method looks like this...

                                   

                                  @Override

                                  public String updateLanguage(String newLocaleString){

                                       String currentLanguage = localeSelector.getLocaleString();

                                       if(!newLocaleString.equalsIgnoreCase(currentLanguage)){

                                            localeSelector.setLocaleString(newLocaleString);

                                            localeSelector.select();

                                            messagePoster.postPopupInfoEntityMessage("entityUpdated","entity.language",1);

                                       }

                                       return Page.index.getPath();

                                  }

                                  • 29. Re: Seam looses internationalization capabilities
                                    pawo509

                                    Hi

                                    I have exactly the same problem as You (lost internationalization, keys displayed instead), and I can reproduce the problem under any browser.

                                     

                                    1. Environment

                                    Seam 2.2.0.GA with RichFaces 3.3.1.GA under JBoss 5.1.0.GA. Application is deployed as EAR file and uses stateless session beans (EJB3) internally.

                                     

                                    2. Description.

                                    I have a simple login page (login.xhtml) which displays login and password field and drop-down field with so called "departments" of the company where user is trying to log in. Departments are stored in database and mapped to the entity class named Department.java. A list of Departments is loaded from database by special SLSB (DictionaryService.java) and is used to create a list of SelectItem to display mentioned drop-down list on login.xhtml page. Loading is done when user enters the login.xhtml page with the help of Seam "page action" defined in pages.xml. Localized depratments names in the drop-down list are taken from messages.properties files (a key is stored in database and is returned in Department.java entity). Here is the complete code (trimmed for clarity):

                                     

                                    <?xml version="1.0" encoding="UTF-8"?>
                                    <pages ...>
                                      <page view-id="/login.xhtml" login-required="false" action="#{userContext.prepareDepartmentsToSelect}">
                                    </pages>
                                    
                                    
                                    

                                     

                                    <?xml version='1.0' encoding='UTF-8'?>
                                    <faces-config ...>
                                      <locale-config>
                                      <default-locale>pl</default-locale>
                                      <supported-locale>pl</supported-locale>
                                      <supported-locale>en</supported-locale>
                                      </locale-config>
                                    </faces-config>
                                    
                                    
                                    

                                     

                                    @Name(UserContext.NAME)
                                    @Scope(ScopeType.SESSION)
                                    public class UserContext {
                                        public static final String NAME = "userContext";
                                        @In (create = true)
                                        DictionaryService dictionaryService;
                                        private List<SelectItem> departmentsToSelect;
                                    
                                    
                                        public void prepareDepartmentsToSelect() {
                                            departmentsToSelect = new ArrayList<SelectItem>();
                                            List<Department> departments = dictionaryService.loadDepartments();
                                            for (Department dep: departments) {
                                                departmentsToSelect.add(new SelectItem(dep, dep.getNameToDisplay()));
                                            }
                                        }
                                    ...
                                    }
                                    
                                    
                                    
                                    @Local
                                    public interface DictionaryService {
                                      public static final String NAME = "dictionaryService";
                                        public List<Department> loadDepartments();
                                    }
                                    
                                    
                                    

                                     

                                    @Stateless
                                    @Name(DictionaryService.NAME)
                                    public class DictionaryServiceBean implements DictionaryService {
                                        @PersistenceContext
                                        private EntityManager em;
                                        @Override
                                        public List<Department> loadDepartments() {
                                            Query queryDep = em.createQuery("select dep from Department dep");
                                            List<Department> departments = queryDep.getResultList();
                                            // set name to be displayed on GUI
                                            SeamResourceBundle seamResourceBundle = (SeamResourceBundle) Component.getInstance("org.jboss.seam.core.resourceBundle");
                                            for (Department dep: departments) {
                                                try {
                                                    String localizedName = seamResourceBundle.getString(dep.getLocalizedNameKey());
                                                    dep.setNameToDisplay(localizedName);
                                                } catch (MissingResourceException mre) {
                                                    dep.setNameToDisplay("## "+dep.getLocalizedNameKey()+" ##");
                                                }
                                            }
                                            return departments;
                                        }
                                    }
                                    
                                    
                                    

                                     

                                    3. Error

                                    In the above method loadDepartments() I use Seam component for resources to obtain a real name for the key stored in Department entity (database). And now: if I start the server and I am trying to display the login page (login.xhtml), my internationalization is broken. I see keys instead of proper messages, not only on drop-down list but also on other login.xhtml page elements which uses internationalization, i.e. <h:commandButton value="#{messages['general.login']}" action="#{userContext.loginUser}" />. Other pages in the application are also broken. To be precise: MissingResourceException is thrown in the loadDepartments() method.

                                     

                                    4. Reason and workaround

                                    I figured out that the problemin my case is connected with using SeamResourceBundle inside SLSB as a first action in application after server startup. If I move code reposnsible for resolving localized named higher, into the UserContext component, then restart server and invoke login.xhtml, everything WORKS OK:

                                     

                                    @Name(UserContext.NAME)
                                    @Scope(ScopeType.SESSION)
                                    public class UserContext {
                                        public static final String NAME = "userContext";
                                        @In (create = true)
                                        DictionaryService dictionaryService;
                                        private List<SelectItem> departmentsToSelect;
                                        public void prepareDepartmentsToSelect() {
                                            departmentsToSelect = new ArrayList<SelectItem>();
                                            List<Department> departments = dictionaryService.loadDepartments();
                                            // resolving localized name moved from SLSB
                                            SeamResourceBundle seamResourceBundle = (SeamResourceBundle) Component.getInstance("org.jboss.seam.core.resourceBundle");
                                            for (Department dep: departments) {
                                                try {
                                                    String localizedName = seamResourceBundle.getString(dep.getLocalizedNameKey());
                                                    dep.setNameToDisplay(localizedName);
                                                } catch (MissingResourceException mre) {
                                                    dep.setNameToDisplay("## "+dep.getLocalizedNameKey()+" ##");
                                                }
                                                departmentsToSelect.add(new SelectItem(dep, dep.getNameToDisplay()));
                                            }
                                      }
                                    ...
                                    }
                                    
                                    
                                    

                                     

                                    Moreover, if I display some dummy page after the server startup, and this page displays dummy text from messages.properties (i.e. <h:outputText value="#{messages['some.key']}"/>) and as NEXT I will invoke login.xhtml, everything works OK regardless of a place where I use SeamResourceBundle (in UserContext or in SLSB)

                                     

                                    So a workaround will be displaying some dummy page or manually invoke SeamResourceBundle.getString() "higher" than in SLSB. The browser and its language setting has nothing to do with that (I tested it with Chrome, IE, FF). Hope this helps someone.

                                     

                                    Regards,

                                    Pawo509

                                    1 2 Previous Next