Search code examples
springgrailsgrails-4

Grails 4.0.1 - MessageSource injection and using method get Message giving null pointer exception error


I am in the process of upgrading to Grails 4.0.1 and I'm having problems with internationalization. I keep getting a NullPointerException error java.lang.NullPointerException: Cannot invoke method getMessage() on null object. The line of code causing the error is:

  return messageSource.getMessage('dashboard.completed.label', 'Approved', LocaleContextHolder.getLocale())

When I println(messageSource), the value is null. I have tried adding

   spring: 
       messages:
           basename: grails-app/i8n/** 

to my application.yml, but I still get the same error. I thought maybe the problem is that a bean is missing from my resources.groovy, so I added the following messageSource bean to resources.groovy:

   beans = {
        messageSource(ReloadableResourceBundleMessageSource){
            basename = grails-app/i18n/messages
        }
   }

However, this produces the following error org.grails.core.exceptions.GrailsConfigurationException: Error loading spring/resources.groovy file: No such property: grails for class: grails.spring.BeanBuilder.

I then decided to try to place the bean in a resources.xml file instead of resources.groovy.

  <bean id="messageSource"
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
     <property name="basename" value="grails-app/i18n/" />
     <property name="defaultEncoding" value="UTF-8" />
 </bean>

But that too produces a NullPointerException. After scouring the internet, I found a resource that suggested a workaround by initializing messageSource inside bootstrap.groovy so I added the following to it:

  def messageSource

  def init = { servletContext ->
       messageSource.basenames = ['/grails-app/i18n/messages']
       messageSource.afterPropertiesSet()
  } 

That produces the same NullPointerException error.

This was working fine before I upgraded. If I println(messageSource) from inside the bootstrap.groovy, the program prints the array of basenames. However, doing println(messageSource) in my controller after injecting message source prints "null". Perhaps there is something that I missed in the upgrade process, but I am not sure what it is. Does anyone have any idea as to why I am getting the error and possible steps I could take to fix it?


Solution

  • See the project at https://github.com/jeffbrown/rookiecodermessagesource.

    https://github.com/jeffbrown/rookiecodermessagesource/blob/78d8760cd057b8eda25f72ddca05390463cbb68b/grails-app/init/rookiecodermessagesource/BootStrap.groovy

    package rookiecodermessagesource
    
    class BootStrap {
        def messageSource
    
        def init = { servletContext ->
            println messageSource
        }
        def destroy = {
        }
    }
    

    That works fine, as it should.