tacobot
tacobot

Reputation: 185

Setting locale only on local machine JVM

I need to change my Java locale to another language system-wide for work purposes, but there seems to be no easy way to do it by default. I do development for CJK applications, but changing my actual system locale to match also renames my home folders, meaning if my input method decides to stop working I would have to reboot my entire system.

I've tried setting JVM arguments (-Duser.language=ja -Duser.locale=JP) on

but none of them work. Pretty much at my wits end here.

To be clear I'm looking for a solution with the following criteria:

So basically some kind of environment variable.

Upvotes: 3

Views: 7057

Answers (6)

honeyp0t
honeyp0t

Reputation: 917

Posting a slightly related answer here because I ended up here when googling;

I've had some issues specifically when running test cases in IntelliJ. Finally figured out that you have to set -Duser.language=en in relevant "Run/Debug Configuration Template(s)"

Upvotes: 0

jmedwards
jmedwards

Reputation: 43

Your -Duser.locale=JP JVM argument should be -Duser.country=JP.

From Oracle technical resource on Locale:

... on some Java runtime implementations, the application user can override the host's default locale by providing this information on the command line by setting the user.language, user.country, and user.variant system properties.

(not a complete answer, but I don't have enough reputation to comment)

Upvotes: 2

tacobot
tacobot

Reputation: 185

The only way that I've found that works for me is setting LANG=ja_JP.UTF-8 as an actual system environment variable on my IDEs that kicks in after boot (both eclipse and intellij provide this under run configurations). But I really really dislike this approach.

Upvotes: 0

Yogesh Sanchihar
Yogesh Sanchihar

Reputation: 1118

You can try settig jvm parameters like (presudocode)

First way, you can do it like this-

java -Duser.country=CA -Duser.language=fr ........

Second way would be to call method

Locale.setDefault(Locale)

above method will set it jvm wise locale.

Third way, as per docs

Using an Explicit Locale

In some computing environments, applications use only a single locale throughout their life cycle. In other environments, applications use a global locale that can be changed. Those environments allow you to programmatically change the global locale preference, which remains in effect until you explicitly change it again. The Java application environment is unique, providing you with the ability to use a variety of locales throughout your application in any way you require.

Multinational companies have customers all around the globe. This means that both their customers and employees may speak different languages and have different expectations for how the company and its software should behave. Moreover, it is entirely possible, even common, to have a French employee handle a sales record for an Italian customer. In those situations, you will need absolute control over which locale your business and user interface objects use to manipulate and represent data. Your application may need to print sales receipts using Italian date and currency formats, yet sort customer lists for an English sales employee. The combinations are far too numerous to list, but Java technology provides you the flexibility to handle that complexity.

In order to get the most flexibility, you must explicitly request support for a target locale for each locale-sensitive class that you use. That means you must track the locale preferences for multiple aspects of the application or assign locale preferences to different users and customers.

If you have tracked the user's locale preference, you would create instances of locale-sensitive classes by explicitly providing a locale in a constructor or creation method. Imagine that a preferences object stores your customer's locale choice:

Locale userLocale = preferences.getLocale(); 
NumberFormat nf = NumberFormat.getInstance(userLocale);

So, in here, you can store your customer locale prefernce in this Preference object api, then do the required formatting operation etc.

What you can do is, set one global locale or leave one default locale. And whenever required, set explicitly the required "locale" in the method.

Kindly go throw the following links as well-

https://www.top-password.com/blog/tag/change-system-locale-windows-command-line/

https://www.oracle.com/technetwork/articles/javase/locale-140624.html#using

Upvotes: 1

Basil Bourque
Basil Bourque

Reputation: 338835

The JVM maintains its own current default locale. This behavior is required by the Java specifications.

Typically a JVM implementation detects the host OS default when the JVM starts up, and uses that as its own default. Later changing the host OS’ current default has no effect on the JVM. This behavior is not specified in the Java specs.

You can typically override that behavior by specifying a default locale on the command-line used to launch the JVM. You said you tried this, but did not explain why this is not a solution. This behavior is not specified in the Java specs.

Externally monitor & manipulate

You could externally monitor and manipulate the locale within Java by opening some communication path.

JMX springs to mind.

External look-up

When your app starts, it could look in an external source for an idea of what locale to use, then make that a singleton within your app.

An LDAP server is one such external place to hold such values. You would use JNDI in Java to access the server and retrieve the value.

Call Locale.setDefault

Calling Locale.setDefault immediately affects all code in all apps within the JVM. But this does not persist. You must call again when relaunching your app or JVM.

Any other code can call this as well as your code, making it unreliable. I do not recommend this approach.

You can hard-code the desired Locale by declaring a static class variable.

static final public Locale LOCALE = Locale.ITALY ;

In the lifecycle code called when your app launches, call Locale.setDefault( SomeClass.LOCALE ) ;.

Pass Locale object in your code

➥ I suggest always passing Locale explicitly as the optional argument in the various places you care about.

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
Locale locale = Locale.CANADA_FRENCH ;  // Pass explicitly your desired/expected `Locale`.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( locale ) ;
String output = today.format( f ) ;

mardi 11 juin 2019

Depending on the JVM’s current default locale is unreliable. As a programmer you are depending on externalities you cannot control.

  • The sysadmin or end-user may alter the default in deployment.
  • Any code in any thread of any app or library within the JVM calling Locale.setDefault immediately affects your code.

By the way, same goes for time zone, ZoneId. Better to always pass explicitly your desired/expected time zone.

Also, if the locale or time zone is crucial, best to confirm with the user.

Upvotes: 1

nortontgueno
nortontgueno

Reputation: 2801

You can include these properties on your application.properties or application.yaml:

spring.mvc.locale=pt_BR
spring.mvc.locale-resolver=fixed

Changing the locale to the one you need.

These properties are used to defined the locale when the WebMvcAutoConfiguration is being configured, through the following method:

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
    public LocaleResolver localeResolver() {
        if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
            return new FixedLocaleResolver(this.mvcProperties.getLocale());
        }
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
        return localeResolver;
    }

You can check also the source code here

Upvotes: 1

Related Questions