Locale.getDefault() returns en always - java

Servers on unix machine are always using en as default locale.
Following is locale output
LANG=en_US
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=C
I just don't understand if LANG is set correctly then why servers starts with en locale.

In Linux/Unix/Mac, the settings LC_ALL and LANG can control the default locale for Java programs. In Windows, the locales are set from the Control Panel, under Regional and Language Options.
When the JVM starts in a *nix environment, it will do this:
Scan the environment for LC_ALL
If LC_ALL doesn't exist, scan the environment for LANG
If the JVM setting user.language is set, use that in place of the environment variables.
If nothing is set, default to en_US (I believe this is the final failure case)
In your environment, you have LC_ALL set to C, which is just the C locale. It's basically a traditional fallback to the days when locales weren't used.
You can change LC_ALL in your case, and restart your JVM, and you should get a new value for java.util.Locale.getDefault().
Example:
import java.util.Locale;
public class LocaleTest {
public static void main(String[] args) {
System.out.println(Locale.getDefault());
}
}
Here's running:
> LC_ALL=en_UK java LocaleTest
en_UK
> LC_ALL=ja_JP java LocaleTest
ja_JP
Also note that if you're running Java 1.7.0-b147, there is a bug with the JRE not recognizing environment settings for locale, and will always use the default system locale.
Bug report here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7073906

Related

Java NumberFormat seams to be stuck on / permanently overriden to english format

I am trying to parse a german number from a string. Here is a minimal example:
String stringValue = "1,00";
double value = NumberFormat.getInstance(Locale.GERMANY).parse(stringValue).doubleValue();
// value = 100.0 (locale machine from cmd, server jdk)
// value = 1.0 (locale machine from cmd, locale jdk)
Somehow the format is permanently stuck at an englisch formater. I debugged the line and had a look at the symbols.decimalSeperator and it is still a dot.
I must admit, that I can only reproduce this behaviour if I run the application with a JDK from a server in our company. Running it with my locale JDK everything works fine and as expected. So maybe the locale Locale on the server is englisch, but how can this override my hardcode Locale.GERMANY?
We are using Java 8.

Java TimeZone update

My system time zone is (UTC+02:00) Istanbul. When I run a simple java program to display time zone, it displays "America/Rio_Branco" (which is incorrect). But when I set to any other time zones it works correctly. Also I updated my jre using tzupdater.jar (I set my path to ..\jre\lib). What could be the reason?
My code is :
import java.util.*;
import java.text.*;
public class Time
{
public static void main(String[] args){
TimeZone timeZone = TimeZone.getDefault();
System.out.println("timeZone : "+timeZone);
}
}
I replaced tzmappings file with the one from jre8 and it solved my problem.
If you read the JavaDoc you'll see this:
Gets the default TimeZone for this host. The source of the default TimeZone may vary with implementation.
Thus reason you're getting "America/Rio_Branco" is because the JDK implementation for your host (operating system) thinks you are in Rio Branco's timezone. In the comments you mention you're running Windows 7, so it might be the case that Windows incorrectly has a timezone set somewhere. I think Java on Windows checks in the registry here:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/TimeZoneInformation
Maybe you can check that value?

DecimalFormatSymbols with Locale

For the code below I get a different result when I run it like this, and when I run it inside a Tomcat web app.
public static void main(String[] args)
{
System.out.println(System.getProperty("user.language"));
System.out.println(System.getProperty("user.country"));
System.out.println(Locale.getDefault(Category.DISPLAY));
System.out.println(Locale.getDefault(Category.FORMAT));
Locale l = new Locale("de", "DE");
System.out.println(l.getDisplayLanguage());
DecimalFormatSymbols dfs = new DecimalFormatSymbols(l);
System.out.println(dfs.getDecimalSeparator());
l = new Locale.Builder().setLanguage("de").setRegion("DE").build();
System.out.println(l.getDisplayLanguage());
dfs = new DecimalFormatSymbols(l);
System.out.println(dfs.getDecimalSeparator());
}
Standalone result (expected):
en
US
en_US
en_US
German
,
German
,
In Tomcat:
en
US
en_US
en_US
German
.
German
.
Can someone suggest what else influences DecimalFormatSymbols (and NumberFormat for that matter) that it doesn't use the locale provided.
I'm using JDK 1.8 with language level 1.7.
EDIT: This only happens when Tomcat runs in Eclipse. Eclipse/OSGi seems to interfere with the locale-based formatting, but only in a specific situation.
Tomcat our ENV setting might have an issue i see it from the post here.
Try starting the tomcat as suggested in the above post with the following params set as a batch file:
-Duser.timezone=Europe/Berlin
-Duser.country=DE
-Duser.language=de

Check java version during program load

I'm looking for a way to check which java version my software is running under.
I'd like to verify during load time my software is running on at least
To get the java version you can use any of these depending on the version you want:
java.specification.version
java.version
java.vm.version
java.runtime.version
However, note that java versions are not equivalent between operative systems. So Java 6 on OSX does not mean the same thing as Java 6 on Windows. So, I would recommend you to also get the OS where the application is running, if you wish to determine if a given feature is available:
System.getProperty("os.name")
As a general guideline, all of this stuff is in the System package. A trick I use is iterate through all the available fields to have an idea of what I can use:
import java.util.Map;
class ShowProperties {
public static void main(String[] args) {
for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
System.out.println(e);
}
}
}
Use java.version property to retrieve the jre version.
String javaVersion = System.getProperty("java.version");
if ((!javaVersion.startsWith("1.6")) && (!javaVersion.startsWith("1.7")) && (!javaVersion.startsWith("1.8")) && (!javaVersion.startsWith("1.9")))
{
// error
}
You can use System.getProperty:
System.out.println(System.getProperty("java.version"));
1.7.0_21
java.lang.System.getProperty("java.version")

How do I set the default locale in the JVM?

I want to set the default Locale for my JVM to fr_CA. What are the possible options to do this?
I know of only one option Locale.setDefault()
You can set it on the command line via JVM parameters:
java -Duser.country=CA -Duser.language=fr ... com.x.Main
For further information look at Internationalization: Understanding Locale in the Java Platform - Using Locale
From the Oracle Reference:
The default locale of your application is determined in three ways.
First, unless you have explicitly changed the default, the
Locale.getDefault() method returns the locale that was initially determined
by the Java Virtual Machine (JVM) when it first loaded. That is, the
JVM determines the default locale from the host environment. The host
environment's locale is determined by the host operating system and
the user preferences established on that system.
Second, 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.
Third, your application can call the Locale.setDefault(Locale)
method. The setDefault(Locale aLocale) method lets your application
set a systemwide (actually VM-wide) resource. After you set the default locale with this
method, subsequent calls to Locale.getDefault() will return the newly
set locale.
You can use JVM args
java -Duser.country=ES -Duser.language=es -Duser.variant=Traditional_WIN
In the answers here, up to now, we find two ways of changing the JRE locale setting:
Programatically, using Locale.setDefault() (which, in my case, was the solution, since I didn't want to require any action of the user):
Locale.setDefault(new Locale("pt", "BR"));
Via arguments to the JVM:
java -jar anApp.jar -Duser.language=pt-BR
But, just as reference, I want to note that, on Windows, there is one more way of changing the locale used by the JRE, as documented here: changing the system-wide language.
Note: You must be logged in with an account that has Administrative Privileges.
Click Start > Control Panel.
Windows 7 and Vista: Click Clock, Language and Region > Region and Language.
Windows XP: Double click the Regional and Language Options
icon.
The Regional and Language Options dialog box appears.
Windows 7: Click the Administrative tab.
Windows XP and Vista: Click the Advanced tab.
(If there is no Advanced tab, then you are not logged in with
administrative privileges.)
Under the Language for non-Unicode programs section, select the desired language from the drop down menu.
Click OK.
The system displays a dialog box asking whether to use existing
files or to install from the operating system CD. Ensure that you have
the CD ready.
Follow the guided instructions to install the files.
Restart the computer after the installation is complete.
Certainly on Linux the JRE also uses the system settings to determine which locale to use, but the instructions to set the system-wide language change from distro to distro.
There is another away if you don't like to change System locale but the JVM. you can setup a System (or user) Environment variable JAVA_TOOL_OPTIONS and set its value to -Duser.language=en-US or any other language-REGION you want.
You can do this:
And to capture locale. You can do this:
private static final String LOCALE = LocaleContextHolder.getLocale().getLanguage()
+ "-" + LocaleContextHolder.getLocale().getCountry();
You can enforce VM arguments for a JAR file with the following code:
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
public class JVMArgumentEnforcer
{
private String argument;
public JVMArgumentEnforcer(String argument)
{
this.argument = argument;
}
public static long getTotalPhysicalMemory()
{
com.sun.management.OperatingSystemMXBean bean =
(com.sun.management.OperatingSystemMXBean)
java.lang.management.ManagementFactory.getOperatingSystemMXBean();
return bean.getTotalPhysicalMemorySize();
}
public static boolean isUsing64BitJavaInstallation()
{
String bitVersion = System.getProperty("sun.arch.data.model");
return bitVersion.equals("64");
}
private boolean hasTargetArgument()
{
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> inputArguments = runtimeMXBean.getInputArguments();
return inputArguments.contains(argument);
}
public void forceArgument() throws Exception
{
if (!hasTargetArgument())
{
// This won't work from IDEs
if (JARUtilities.isRunningFromJARFile())
{
// Supply the desired argument
restartApplication();
} else
{
throw new IllegalStateException("Please supply the VM argument with your IDE: " + argument);
}
}
}
private void restartApplication() throws Exception
{
String javaBinary = getJavaBinaryPath();
ArrayList<String> command = new ArrayList<>();
command.add(javaBinary);
command.add("-jar");
command.add(argument);
String currentJARFilePath = JARUtilities.getCurrentJARFilePath();
command.add(currentJARFilePath);
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.start();
// Kill the current process
System.exit(0);
}
private String getJavaBinaryPath()
{
return System.getProperty("java.home")
+ File.separator + "bin"
+ File.separator + "java";
}
public static class JARUtilities
{
static boolean isRunningFromJARFile() throws URISyntaxException
{
File currentJarFile = getCurrentJARFile();
return currentJarFile.getName().endsWith(".jar");
}
static String getCurrentJARFilePath() throws URISyntaxException
{
File currentJarFile = getCurrentJARFile();
return currentJarFile.getPath();
}
private static File getCurrentJARFile() throws URISyntaxException
{
return new File(JVMArgumentEnforcer.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
}
}
It is used as follows:
JVMArgumentEnforcer jvmArgumentEnforcer = new JVMArgumentEnforcer("-Duser.language=pt-BR"); // For example
jvmArgumentEnforcer.forceArgument();

Categories

Resources