Announcement Announcement Module
Collapse
No announcement yet.
ReloadableResourceBundle finds values first time only Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ReloadableResourceBundle finds values first time only

    I am trying to use the ReloadableResourceBundleMessageSource to retrieve key-value pairs from multiple files. I have a class that is used widely within our application that I want to rewrite to use standard resource bundles instead of the current custom implementation. I change the existing class to implement MessageSourceAware and it successfully returns the values when the application first starts and when the first JSP is loaded. However, if I refresh the JSP page, a NoMessageException is thrown.

    Could it have anything to do with the fact that the implementing class uses static methods to get at the property values?

    In applicationContext.xml:
    Code:
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
         <property name="basenames">
            <list>
              <value>/WEB-INF/messages</value>
              <value>/WEB-INF/sql</value>
              <value>/WEB-INF/errors</value>
              <value>/WEB-INF/images</value>
            </list>
            </property>
    	<property name="cacheSeconds" value="1" />
    	<property name="useCodeAsDefaultMessage" value="false"/>
        </bean>
    
    <bean id="appInfo" class="com.xxx.AppInfo">
            <description>Wrapper class for resource bundle meant to replace the original implementation that used a Properties object</description>
            <property name="messageSource" ref="messageSource" />
        </bean>
    Existing class has static methods:
    Code:
    public class AppInfo implements MessageSourceAware {
        
        public void setMessageSource(MessageSource messageSource) {
           this.messageSource = messageSource;
        }
        
        private static MessageSource messageSource;
        
        
        public static String getProperty(String thePropKey)
        {
    
            return messageSource.getMessage(thePropKey, null, Locale.getDefault());
        }
    
       
        public static String getFormattedProperty(String key, String param) {
            return getFormattedProperty(key, new Object[] { param });
        }
    
        public static String getFormattedProperty(String key, Object... params) {
            return MessageFormat.format(getProperty(key), params);
        }
    }
    Last edited by wufpack00; Jan 30th, 2008, 04:26 PM. Reason: meant to include the bean config for appinfo class

  • #2
    There is something else you are missing. . . hard to say from what you have posted. It shouldn't behave like that (i can't replicate it).

    You might also want to clean up some of your code.
    1. Why do you set the static variable from the instance method?
    2.
    Code:
    <property name="messageSource" ref="messageSource" />
    - defining this property is not necessary. Your AppInfo class already implements MessageSourceAware which means ApplicationContext will inject it in there for you.

    Comment


    • #3
      Fixed by using non-reloadable version of ResourceBundleMessageSource

      Thanks for the response!

      Yes, I agree, the code is not the prettiest I've seen...so I'm trying to make the necessary changes w/o having to modify every file in the project. (There are over 15K references to the static method AppInfo.getProperty(String) in both .java and .jsp files.)

      You are correct about not needing to specify the reference to the messageSource bean in the XML file since the class implements MessageSourceAware. I noticed that and changed it shortly after creating this thread. (That's a nice feature of MessageSourceAware, btw)

      I was finally able to resolve the problem by using the plain ResourceBundleMessageSource instead of the reloadable version. As a result of making that change, I moved all the .properties files into /WEB-INF/classes. This isn't exactly what I wanted, but it does move the code closer to Spring than it was before.

      The final code is:
      Code:
      <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
           <property name="basenames">
              <list>
                <value>messages</value>
                <value>sql</value>
                <value>errors</value>
                <value>images</value>
                <value>appResources</value>
              </list>
              </property>
          </bean>
      
          <bean id="appInfo" class="com.xxx.AppInfo" />
      Code:
      public class AppInfo implements MessageSourceAware {
          
          private static MessageSourceAccessor messageSourceAccessor = null;
      
          public void setMessageSource(MessageSource messageSource) {
              this.messageSourceAccessor = new MessageSourceAccessor(messageSource);
          }
      
          public static MessageSourceAccessor getMessageSource() {
              return messageSourceAccessor;
          }
          
          public static String getProperty(String thePropKey)
          {
              return getMessageSource().getMessage(thePropKey);
          }
      
        ...
      }

      Comment

      Working...
      X