• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Localization. How to indicate where resource bundle property files are located?

 
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:
I am using IntelliJ and here is the location of my Resource bundle and property files (see screenshot).
When I run this code, I get a MissingResourceException.








javaranch0.png
resource bundle screenshot
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:
I needed to specify the package also. This fixed the error.



Trying to solve the question, I don't understand why the property file for es wasn't found.
es_MX is the default locale.

The output is

violette generic



I expected

violette lujoso



The question is:


tb864615.OCPJAVASE17PT.c14.046
Given the following three property files, what does the following method output?

toothbrush.properties
color=purple
type=generic

toothbrush_es.properties
color=morado
type=lujoso

toothbrush_fr.properties
color=violette





 
Saloon Keeper
Posts: 27865
196
  • Number of slices to send:
    Optional 'thank-you' note:


stacktrace wrote:
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name toothbrush, locale fr


So as I read it, you're attempting to read from toothbrush_fr.properties with default values coming from toothbrush.properties. You are overriding the Locale, so the fact that you set the default locale to es_MX shouldn't matter here.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Tim Holloway wrote: default values coming from toothbrush.properties. You are overriding the Locale, so the fact that you set the default locale to es_MX shouldn't matter here.


I am finding it hard to understand this. If default locale is set to es_MX then shouldn't it take type from there?

P.S. the exception is not related to this - it was from my not specifying the package.
 
Tim Holloway
Saloon Keeper
Posts: 27865
196
  • Number of slices to send:
    Optional 'thank-you' note:
I have not read the docs in a long time, but no, I'm pretty sure that the arrangement is that you can set up a chain of locales to search, but the master bundle that is referenced when a key cannot be found in any other bundle in the chin is simply "basename.properties" and not a local-specific "basename_xx_YY..properties".

The thing I wonder about more is that your bundle name is "boyarsky_ch11_exceptions_localization.toothbrush". Because I was pretty sure that bundle paths were done the same way as other Java package resources, so a more likely bundle specification would be "boyarsky.ch11.exceptions.localization.toothbrush".
 
Marshal
Posts: 28262
95
  • Number of slices to send:
    Optional 'thank-you' note:
I haven't looked at the docs for a very very long time either, neither have I had to deal with a complex setup like that, but the posted code looks very much like the example in Baeldung's ResourceBundle tutorial. In which case I think Anil is correct.

I'm assuming that the code at the beginning does set the default locale... Oops! I just looked at it for the fifth or sixth time. It does indeed set the default locale. Just not to es_MX, that is. That explains the book's answer, which is correct.
 
Paul Clapham
Marshal
Posts: 28262
95
  • Number of slices to send:
    Optional 'thank-you' note:
No, wait a minute, I'm still confused by Locale terminology. The Locale.Builder documentation talks about "language" and "region" and Locale talks about "language" and "country". For example there's a Locale called CANADA_FRENCH whose name is "fr-CA". The meaning of the thing is "French as used in Canada". Likewise "es-MX" is "Spanish as used in Mexico" and "es" is "Spanish default usage".

So the code from the book does actually produce the "es-MX" Locale which should work the way that Anil says it should work. That's my opinion so far. Waiting for somebody else to explain why we're wrong.

... (later) ... After spending a while to figure out where to put the property files, I ran the code and got the same output as Anil.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Paul Clapham wrote:
So the code from the book does actually produce the "es-MX" Locale



Here is the output showing the default locale set

violette generic
Locale.getDefault: es_MX



From my understanding, it should go to the default locale if it cannot find the exact-match property file.
So I don't know why it doesn't.
 
Paul Clapham
Marshal
Posts: 28262
95
  • Number of slices to send:
    Optional 'thank-you' note:

Anil Philip wrote:From my understanding, it should go to the default locale if it cannot find the exact-match property file.


That's what the tutorial I linked to says too. (I'm pretty sure it says that.)

So I don't know why it doesn't.


Me neither. Although I've never written code where the default locale is involved in the decision process.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Paul Clapham wrote:That's what the tutorial I linked to says too. (I'm pretty sure it says that.)



Here is what Boyarsky-Selikoff says are the steps followed:

1) Look for the resource bundle for the requested locale, followed by the one for the default locale.
2) For each locale, check the language/country, followed by just the language.
3) Use the default resource bundle if no matching locale can be found.

 
Tim Holloway
Saloon Keeper
Posts: 27865
196
  • Number of slices to send:
    Optional 'thank-you' note:
Item #1: Yes, Baeldung seems to confirm it's "package.path.toothbbrush.properties", not "package_path.toothbrush.properties".

Item #2. The Locale definition in the example sets the default Locale for the entire JVM, not just the Bundle. So, if I'm correct, an unqualified getBundle("package.path.toothbbrush.properties") would concatenate package.path.toothbrush_es_MX.properties, package.path.toothbrush_es.properties and finally package.path.toothbrush.properties, searching them in that order until the named property is resolved (fallback resources).

HOEVER, since Locale "fr" was given on the getBundle, the DEFAULT language/region is overridden by the SPECIFIED language/region, giving us a concatenation of package.path.toothbrush_fr.properties and package.path.toothbrush.properties.
 
Tim Holloway
Saloon Keeper
Posts: 27865
196
  • Number of slices to send:
    Optional 'thank-you' note:
Final note: Don't confuse the default locale with the default bundle. The default bundle is the one with no locale qualifiers in its filename.
 
Paul Clapham
Marshal
Posts: 28262
95
  • Number of slices to send:
    Optional 'thank-you' note:

Anil Philip wrote:1) Look for the resource bundle for the requested locale, followed by the one for the default locale.


Is it possible that because there isn't a property file for "es-MX", which is the default locale, therefore the "es" property file isn't looked at?

You could test that by adding an es-MX property file to your setup.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Paul Clapham wrote:You could test that by adding an es-MX property file to your setup.


The output remains the same. See screenshot.

violette generic
Locale.getDefault: es_MX



toothbrush_es_MX.properties


color=dazzle
type=bling



javaranch0.png
 
Paul Clapham
Marshal
Posts: 28262
95
  • Number of slices to send:
    Optional 'thank-you' note:

Anil Philip wrote:The output remains the same. See screenshot.


As I mostly expected.

If I was you I'd leave this one for now and move on. It could be errata, after all. Or it could be some picky thing that we haven't noticed.
 
Saloon Keeper
Posts: 15620
366
  • 2
  • Number of slices to send:
    Optional 'thank-you' note:
You seem confused what "default locale" really means.

"Default locale" does NOT mean "Use this locale if you can't find a resource for the explicitly specified locale".

"Default locale" means "Use this locale if you don't explicitly specify a locale".

You explicitly specified a locale for your resource bundle ("fr"), so the default locale is no longer relevant.

You're asking toothbrush_fr for the "color" and "type" strings. It contains one for "color", so it returns "violette". It does NOT contain a string for "type", so it returns the value from its parent bundle (which is the root bundle): "generic".

The parent bundle of toothbrush_es_MX is indeed toothbrush_es, but you never asked toothbrush_es_MX for a string, because you explicitly specified the locale "fr".
 
author & internet detective
Posts: 41911
909
  • Number of slices to send:
    Optional 'thank-you' note:

Paul Clapham wrote:No, wait a minute, I'm still confused by Locale terminology. The Locale.Builder documentation talks about "language" and "region" and Locale talks about "language" and "country". For example there's a Locale called CANADA_FRENCH whose name is "fr-CA". The meaning of the thing is "French as used in Canada". Likewise "es-MX" is "Spanish as used in Mexico" and "es" is "Spanish default usage".


Region and country should be treated interchanably in the docs. Per the Locale doc

country (region)
ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code. You can find a full list of valid country and region codes in the IANA Language Subtag Registry (search for "Type: region"). The country (region) field is case insensitive, but Locale always canonicalizes to upper case.
Well-formed country/region values have the form [a-zA-Z]{2} | [0-9]{3}
Example: "US" (United States), "FR" (France), "029" (Caribbean)


Region is more generic so my guess is they started using region after writing the original code. A region could be something that isn't a country (like the two examples you gave)
 
Jeanne Boyarsky
author & internet detective
Posts: 41911
909
  • Number of slices to send:
    Optional 'thank-you' note:
The output of "violette generic" is correct.

Here's the explanation in the book

Java starts out by looking for a properties file with the requested locale. In this case, the
requested locale is the fr language, which it finds with toothbrush_fr.properties.
For this reason, the default locale of es_MX is ignored, and the first value for color printed
is violette. Next, it looks for a value for type property. Since it doesn’t find it in the first
properties file, it checks the default toothbrush.properties, where it does find it, and
prints generic. For these reasons, option B is correct.



And to use different words since Anil is confused, there's two concepts at play and this question tests both.

Concept 1 - Finding the locale to use
The locale search order is what you quoted. Look for the requested locale followed by the one for the default with language/region and then just language, falling thru to default. This results in finding toothbrush_fr.properties since the requested local is "fr" (French.)

At this point, you remember toothbrush_fr.properties and stop thinking about the locales. They aren't used anymore

Concept 2 - Getting properties
Once you have the property file, Java only looks in it (and more generic) ones. Since "color" is found in the fr file, violette is printed. For "type", it is not found in the fr file. So Java looks up the hierarchy and uses "generic" from the default/parent.

The "parent" relationship is dropping the region/country if present and then dropping the language if present. In concept 2, it does not look at alternate locales because it found one. This makes sense as  you wouldn't want your user documentation to be a mix of French and Spanish!
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Stephan van Hulst wrote:You seem confused what "default locale" really means.


Well, then consider what Boyarsky-Selikoff are saying. Look at step 3:

Java handles the logic of picking the best available resource bundle for a given key. It tries to find the most specific value. Table 11.11 shows what Java goes through when asked for resource bundle Zoo with the locale new Locale("fr", "FR") when the default locale is U.S. English.

TABLE 11.11 Picking a resource bundle for French/France with default locale English/US

see screenshot

As another way of remembering the order of Table 11.11, learn these steps:

Look for the resource bundle for the requested locale, followed by the one for the default locale.
For each locale, check the language/country, followed by just the language.
Use the default resource bundle if no matching locale can be found.

javaranch0.png
TABLE 11.11 Picking a resource bundle for French/France with default locale English/US
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Jeanne Boyarsky wrote:
And to use different words since Anil is confused,


Please see the screenshot of the table from the book. Step 2 and Step 3.
It looks for fr and then goes to the default en_US.
 
Stephan van Hulst
Saloon Keeper
Posts: 15620
366
  • Number of slices to send:
    Optional 'thank-you' note:
I see. Yes, that's incorrect.

Either steps 1, 2, 5, 6 are taken if you explicitly specify a locale, or steps 3, 4, 5, 6 are taken if you don't explicitly specify a locale.
 
Jeanne Boyarsky
author & internet detective
Posts: 41911
909
  • Number of slices to send:
    Optional 'thank-you' note:

Anil Philip wrote:

Jeanne Boyarsky wrote:
And to use different words since Anil is confused,


Please see the screenshot of the table from the book. Step 2 and Step 3.
It looks for fr and then goes to the default en_US.


I don't see how it is incorrect. We are talking about the "Finding the Locale to use step". If fr isn't found, it goes on looking. But in the question we are discussing in this thread, fr is used. So it doesn't go on any further looking up a locale. If found the fr one so now knows to use that.
 
Jeanne Boyarsky
author & internet detective
Posts: 41911
909
  • Number of slices to send:
    Optional 'thank-you' note:

Stephan van Hulst wrote:I see. Yes, that's incorrect.

Either steps 1, 2, 5, 6 are taken if you explicitly specify a locale, or steps 3, 4, 5, 6 are taken if you don't explicitly specify a locale.


I still think the table is correct. Try deleting the "fr" file from your file system and running the same example. It finds the spanish one.

The locale is specified but there are no matching files so Java goes on to the default locale.
 
Stephan van Hulst
Saloon Keeper
Posts: 15620
366
  • 1
  • Number of slices to send:
    Optional 'thank-you' note:
I double checked it, you're correct.

That's extremely disappointing behavior. I can't really think of a good use case to switch to a different locale (even if it IS the default locale) if my resource bundle can't be found. Just use the root bundle instead.

That just makes me want to set the default locale to some obscure locale that I know will never be used in my application.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Jeanne Boyarsky wrote:The locale is specified but there are no matching files so Java goes on to the default locale.


Jeanne Boyarsky wrote:Next, it looks for a value for type property. Since it doesn’t find it in the first
properties file, it checks the default toothbrush.properties, where it does find it, and
prints generic. For these reasons, option B is correct.



But the book does not say that now it starts looking for properties, and it just shoots up to the generic toothbrush.properties.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Stephan van Hulst wrote:I double checked it, you're correct.

That's extremely disappointing behavior.

That just makes me want to set the default locale to some obscure locale that I know will never be used in my application.


I see that Anil wasn't the only one who was confused!
 
Jeanne Boyarsky
author & internet detective
Posts: 41911
909
  • Number of slices to send:
    Optional 'thank-you' note:

Anil Philip wrote:

Jeanne Boyarsky wrote:The locale is specified but there are no matching files so Java goes on to the default locale.


Jeanne Boyarsky wrote:Next, it looks for a value for type property. Since it doesn’t find it in the first
properties file, it checks the default toothbrush.properties, where it does find it, and
prints generic. For these reasons, option B is correct.



But the book does not say that now it starts looking for properties, and it just shoots up to the generic toothbrush.properties.


The toothbrush thing is an explanation for a question though. It's providing a summary of the reasons, not explaining as if the study guide hasn't been read. The chapter part does explain it more thoroughly (ex: the table)
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Jeanne Boyarsky wrote:The chapter part does explain it more thoroughly (ex: the table)



In the explanation of the following table 11.12


The JVM will provide data from en_US only if there is no matching fr_FR or fr resource bundle. If it finds a fr_FR or fr resource bundle, then only those bundles, along with the default bundle, will be used.



what does "along with the default bundle" mean? I thought the default bundle is excluded since fr has been found.
 
Stephan van Hulst
Saloon Keeper
Posts: 15620
366
  • 2
  • Number of slices to send:
    Optional 'thank-you' note:
No. You are once again confusing "default bundle" and "default locale". To avoid confusion, I prefer to say "root bundle" instead of "default bundle".

There are two separate phases that you need to consider in isolation from each other. Phase one is getting the resource bundle. Phase two is getting a string from the found resource bundle.

First, we get a resource bundle. This works according to the steps in table from the screenshot. Let's say you've explicitly specified the locale "fr-FR", so the application starts by looking for "toothbrush_fr_FR.properties". If that file doesn't exist, then it continues by looking for "toothbrush_fr.properties". If that file doesn't exist either, it continues by looking for the file that matches the default locale, which would be "toothbrush_es_MX.properties" (using your original example). If that file doesn't exist, it continues by looking for "toothbrush_es.properties". Finally, if that file doesn't exist either, it falls back on the root bundle "toothbrush.properties".

Let's assume that the file "toothbrush_fr.properties" exists and has been found by the call to ResourceBundle.getBundle(). You are now completely done with the default locale and can erase it from your mind. However, you must not forget about the root bundle, because it is still used in phase two!

We are now in phase two: getting a string from the resource bundle.

If a string can't be found in a resource bundle, the call is delegated to the bundle's parent bundle. The parent bundle of toothbrush_fr.properties is the root bundle "toothbrush.properties". Once again, the default locale plays absolutely no role in this phase. If "toothbrush_fr.properties" exists, then it will NEVER delegate to "toothbrush_es.properties", even if the default locale is "es-MX".
 
Paul Clapham
Marshal
Posts: 28262
95
  • Number of slices to send:
    Optional 'thank-you' note:

Stephan van Hulst wrote:No. You are once again confusing "default bundle" and "default locale". To avoid confusion, I prefer to say "root bundle" instead of "default bundle".


Which is what many of us have done. Looking at the Baeldung tutorial, they do use the correct terminology but then steer us directly into this confusion.

It's the same with Table 11.11, posted earlier. It describes the actual process correctly but it very easily leads the incautious reader into incorrect assumptions.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Stephan van Hulst wrote:
There are two separate phases that you need to consider in isolation from each other. Phase one is getting the resource bundle. Phase two is getting a string from the found resource bundle.



Clear explanation. Thank you!
@Jeanne Can you please include this explanation in your book?
After Table 11.11 example showing how to get the Resource Bundle for the Locale, you also listed the steps to get it. This was phase 1 or concept 1 (to use your term).
It will be good to also list the steps showing how to get the key from the property files. This was missing for phase 2 or concept 2.
 
Tim Holloway
Saloon Keeper
Posts: 27865
196
  • Number of slices to send:
    Optional 'thank-you' note:
Couple of remarks here. The language/region think isn't unique or new to bundles. You also use it, for example, to indicate keyboard classes when installing Linux for distros that set up locale at install time. There's actually an RFC for those designators, I believe.

It's not technically correct to talk about Bundle "phases". If memory serves, Bundles are based on Properties, and Properties are chainable. So "getBundle" is actually loading in the applicable property files all at once and realizing each file's contents as a loaded Properties object chained to the next property until you get down to the base property, which chains to nothing. When you do a "get" on a Property, the property table is searched first, then, if the key isn't found there, the chained Property is searched, and so forth.

The Bundle Properties are not magic, so it's also perfectly legal to front them with additional layers of Properties inside the app if you find it useful to do so.

The Bundle property loading runs from most specific to least specific, so "en_US" is the top Property object, followed by "en", followed by default. And again, "default" means ROOT, not default locale. If you ask for a Bundle with specific Locale, that overrides the default locale.

It is not required to have a region-specific Bundle property. You could have a "toothbrush_en" and a "toothbrush" (root) and the English could bloody well learn how to spell "aluminum" instead of supplying an "en_GB" layer.
 
Jeanne Boyarsky
author & internet detective
Posts: 41911
909
  • Number of slices to send:
    Optional 'thank-you' note:
I've made a note to see if we want to change anything next time we look at it.
 
Ranch Hand
Posts: 67
1
  • 1
  • Number of slices to send:
    Optional 'thank-you' note:
Here is a javadoc page for the default Resource Bundle Search and Loading Strategy.
 
Anil Philip
Ranch Foreman
Posts: 626
3
  • Number of slices to send:
    Optional 'thank-you' note:

Ira Go wrote:Here is a javadoc page for the default Resource Bundle Search and Loading Strategy.


Thank you
reply
    Bookmark Topic Watch Topic
  • New Topic
vceplus-200-125    | boson-200-125    | training-cissp    | actualtests-cissp    | techexams-cissp    | gratisexams-300-075    | pearsonitcertification-210-260    | examsboost-210-260    | examsforall-210-260    | dumps4free-210-260    | reddit-210-260    | cisexams-352-001    | itexamfox-352-001    | passguaranteed-352-001    | passeasily-352-001    | freeccnastudyguide-200-120    | gocertify-200-120    | passcerty-200-120    | certifyguide-70-980    | dumpscollection-70-980    | examcollection-70-534    | cbtnuggets-210-065    | examfiles-400-051    | passitdump-400-051    | pearsonitcertification-70-462    | anderseide-70-347    | thomas-70-533    | research-1V0-605    | topix-102-400    | certdepot-EX200    | pearsonit-640-916    | itproguru-70-533    | reddit-100-105    | channel9-70-346    | anderseide-70-346    | theiia-IIA-CIA-PART3    | certificationHP-hp0-s41    | pearsonitcertification-640-916    | anderMicrosoft-70-534    | cathMicrosoft-70-462    | examcollection-cca-500    | techexams-gcih    | mslearn-70-346    | measureup-70-486    | pass4sure-hp0-s41    | iiba-640-916    | itsecurity-sscp    | cbtnuggets-300-320    | blogged-70-486    | pass4sure-IIA-CIA-PART1    | cbtnuggets-100-101    | developerhandbook-70-486    | lpicisco-101    | mylearn-1V0-605    | tomsitpro-cism    | gnosis-101    | channel9Mic-70-534    | ipass-IIA-CIA-PART1    | forcerts-70-417    | tests-sy0-401    | ipasstheciaexam-IIA-CIA-PART3    | mostcisco-300-135    | buildazure-70-533    | cloudera-cca-500    | pdf4cert-2v0-621    | f5cisco-101    | gocertify-1z0-062    | quora-640-916    | micrcosoft-70-480    | brain2pass-70-417    | examcompass-sy0-401    | global-EX200    | iassc-ICGB    | vceplus-300-115    | quizlet-810-403    | cbtnuggets-70-697    | educationOracle-1Z0-434    | channel9-70-534    | officialcerts-400-051    | examsboost-IIA-CIA-PART1    | networktut-300-135    | teststarter-300-206    | pluralsight-70-486    | coding-70-486    | freeccna-100-101    | digitaltut-300-101    | iiba-CBAP    | virtuallymikebrown-640-916    | isaca-cism    | whizlabs-pmp    | techexams-70-980    | ciscopress-300-115    | techtarget-cism    | pearsonitcertification-300-070    | testking-2v0-621    | isacaNew-cism    | simplilearn-pmi-rmp    | simplilearn-pmp    | educationOracle-1z0-809    | education-1z0-809    | teachertube-1Z0-434    | villanovau-CBAP    | quora-300-206    | certifyguide-300-208    | cbtnuggets-100-105    | flydumps-70-417    | gratisexams-1V0-605    | ituonline-1z0-062    | techexams-cas-002    | simplilearn-70-534    | pluralsight-70-697    | theiia-IIA-CIA-PART1    | itexamtips-400-051    | pearsonitcertification-EX200    | pluralsight-70-480    | learn-hp0-s42    | giac-gpen    | mindhub-102-400    | coursesmsu-CBAP    | examsforall-2v0-621    | developerhandbook-70-487    | root-EX200    | coderanch-1z0-809    | getfreedumps-1z0-062    | comptia-cas-002    | quora-1z0-809    | boson-300-135    | killtest-2v0-621    | learncia-IIA-CIA-PART3    | computer-gcih    | universitycloudera-cca-500    | itexamrun-70-410    | certificationHPv2-hp0-s41    | certskills-100-105    | skipitnow-70-417    | gocertify-sy0-401    | prep4sure-70-417    | simplilearn-cisa    |
http://www.pmsas.pr.gov.br/wp-content/    | http://www.pmsas.pr.gov.br/wp-content/    |