Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

  • maven command line arguments (really not what I want but tried out of desperation)
  • {$project_dir}/.mvn/jvm.config (not ideal)
  • environment JAVA_ARGS (under /etc/environment)
  • maven JVM arguments in eclipse/intellij
  • MAVEN_OPTS

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:

  • Not project specific
  • Doesn't require project source modification (e.g. project properties files) outside of .mvn
  • Doesn't involve changing my actual system locale (en_US)
  • Doesn't require constant maintenance (e.g. constantly add command line arguments)

So basically some kind of environment variable.

like image 903
tacobot Avatar asked Jan 01 '26 03:01

tacobot


1 Answers

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.

like image 114
Basil Bourque Avatar answered Jan 02 '26 15:01

Basil Bourque