5
votes

There are two ways to load the properties file into JSF 2.0.

  1. Global Resource Bundle To load the properties file globally, so that all the jsf pages can access the messages. You can create a “faces-config.xml” file and declare the properties file explicitly.

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
     <application>
      <resource-bundle>
        <base-name>com.mkyong.messages</base-name>
        <var>msg</var>
       </resource-bundle>
     </application>
</faces-config>

Option 2: Local Resource Bundle To load the properties file locally, or for specified page only. Declare the <f:loadBundle /> tag in the page that need to access the message in the messages.properties.

Out of these two which one gives me better performance?

Lets say I going with 1st option, does it means all the bundles gets loaded during the application startup or is it lazy loading? (on demand)

If choose a 2nd option, does it potentially cause bundle to get loaded multiple time for each ViewRoot?

Is the Java ResourceBundle is factory class which provides singleton object within servlet container?

I mean getBundle method is factory method which creates singleton object for always?

ResourceBundle myResources =
      ResourceBundle.getBundle("MyResources", currentLocale);

Lets say I have a page abc.xhtml and I am using f:loadBundle, and there 1000 users accessing this page, does this mean there would 1000 resouceBundle object created? or is it only object which is being shared by all the page instances?

3

3 Answers

3
votes

Out of these two which one gives me better performance?

I wouldn't worry about the performance. The ResourceBundle already caches them internally.


Lets say I have a page abc.xhtml and I am using f:loadBundle, and there 1000 users accessing this page, does this mean there would 1000 resouceBundle object created? or is it only object which is being shared by all the page instances?

By default, only one is created. See also the ResourceBundle API documentation:

Cache Management

Resource bundle instances created by the getBundle factory methods are cached by default, and the factory methods return the same resource bundle instance multiple times if it has been cached. getBundle clients may clear the cache, manage the lifetime of cached resource bundle instances using time-to-live values, or specify not to cache resource bundle instances. Refer to the descriptions of the getBundle factory method, clearCache, ResourceBundle.Control.getTimeToLive, and ResourceBundle.Control.needsReload for details.

You can easily testify if yourself in debugger by looking at instance's hashcode.


The <application> declaration has by the way the additional benefit that the bundle is also injectable in a managed bean by @ManagedProperty("#{msg}"). See also among others this Q&A: Read resource bundle properties in a managed bean.

0
votes

You have seen from the answers that one global resource bundle suffices. On performance:

You have two kind of standard ResourceBundle instances:

  • PropertyResourceBundle - *[_LOCALE].properties files, and
  • ListResourceBundle, a java class (using package names with '.') - *[_LOCALE].class.

For ListResourceBundle:

Every locale java class creates an array of strings with shared (!) key and localized text. Sharing the key strings in the JVM is nice. Also all strings are loaded early.

So it might be worth delivering a ListResourceBundle.

For translation however, you then probably would have to maintain some non-java translation memory, tmx, xliff or so. And in the build process generate the java.

-1
votes

1st option - because it is application scoped and loads at start up