5

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?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Chetan
  • 1,507
  • 7
  • 30
  • 43

3 Answers3

3

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.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

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.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
-1

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

TheWhiteRabbit
  • 15,480
  • 4
  • 33
  • 57
  • 1
    Are you saying if I go for the first option, it would load the bundle everytime I have the page accessed? Lets say I have a page abc.xhtml and I am using f:loadBundle, and there 1000 users accessing this page, does that mean there would 1000 resouceBundle object created? – Chetan Jan 16 '13 at 13:38
  • This is not true. It's loaded and injected in every request. Think once again, how would the endusers ever end up getting the bundle in different languages if there would be only one instance in the application scope? The OP is merely asking if it's worth the effort to get it injected in **every request/view** instead of explicitly declaring yourself by `` on a per-view basis. – BalusC Jan 16 '13 at 13:44
  • Well, It is not the case, For a given locale and Basename, ResourceBundle returns the same object each time you request for it. In JSF resource bundle is created per Application class loader. check:com.sun.faces.facelets.tag.jsf.core.LoadBundleHandler – Chetan Jan 16 '13 at 14:01
  • JSF does not store it in application scope. It merely calls `ResourceBundle.getBundle()` on every request. It's the `ResourceBundle` itself who is caching them. See also my answer. The `#{msg}` is request scoped not application scoped. – BalusC Jan 16 '13 at 14:02