IGNITE-10732 Force -Dfile.encoding=UTF-8 when not specified otherwise - Fixes #5725.
authorIlya Kasnacheev <ilya.kasnacheev@gmail.com>
Thu, 10 Jan 2019 13:38:00 +0000 (16:38 +0300)
committerIlya Kasnacheev <ilya.kasnacheev@gmail.com>
Thu, 10 Jan 2019 13:38:00 +0000 (16:38 +0300)
Signed-off-by: Ilya Kasnacheev <ilya.kasnacheev@gmail.com>
bin/include/parseargs.sh
modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
modules/core/src/main/java/org/apache/ignite/startup/cmdline/CommandLineTransformer.java
modules/core/src/test/java/org/apache/ignite/startup/cmdline/GridCommandLineTransformerSelfTest.java
modules/platforms/cpp/core/src/ignition.cpp
modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteManager.cs

index 3ab255e..1efb48e 100755 (executable)
@@ -51,3 +51,13 @@ do
     esac
     shift
 done
+
+#
+# Set 'file.encoding' to UTF-8 default if not specified otherwise
+#
+case "${JVM_OPTS}" in
+    *-Dfile.encoding=*)
+        ;;
+    *)
+        JVM_OPTS="${JVM_OPTS} -Dfile.encoding=UTF-8";;
+esac
index 3a3af8e..9633f89 100644 (file)
@@ -29,6 +29,7 @@ import java.io.Serializable;
 import java.lang.management.ManagementFactory;
 import java.lang.management.RuntimeMXBean;
 import java.lang.reflect.Constructor;
+import java.nio.charset.Charset;
 import java.text.DateFormat;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
@@ -40,6 +41,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -1077,6 +1079,9 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
                 gw.writeUnlock();
             }
 
+            // Check whether UTF-8 is the default character encoding.
+            checkFileEncoding();
+
             // Check whether physical RAM is not exceeded.
             checkPhysicalRam();
 
@@ -1406,6 +1411,20 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
     }
 
     /**
+     * Check whether UTF-8 is the default character encoding.
+     * Differing character encodings across cluster may lead to erratic behavior.
+     */
+    private void checkFileEncoding() {
+        String encodingDisplayName = Charset.defaultCharset().displayName(Locale.ENGLISH);
+
+        if (!"UTF-8".equals(encodingDisplayName)) {
+            U.quietAndWarn(log, "Default character encoding is " + encodingDisplayName +
+                ". Specify UTF-8 character encoding by setting -Dfile.encoding=UTF-8 JVM parameter. " +
+                "Differing character encodings across cluster may lead to erratic behavior.");
+        }
+    }
+
+    /**
      * Checks whether physical RAM is not exceeded.
      */
     @SuppressWarnings("ConstantConditions")
index f4aad17..e449bfa 100644 (file)
@@ -204,10 +204,15 @@ public class CommandLineTransformer {
      * @param args Collection of unknown (from JCommander point of view) arguments.
      */
     private void parseJvmOptionsAndSpringConfig(Iterable<String> args) {
+        boolean hadFileEncoding = false;
+
         for (String arg : args) {
             if (arg.startsWith(JVM_OPTION_PREFIX)) {
                 String jvmOpt = arg.substring(JVM_OPTION_PREFIX.length());
 
+                if (jvmOpt.startsWith("-Dfile.encoding="))
+                    hadFileEncoding = true;
+
                 if (!checkJVMOptionIsSupported(jvmOpt))
                     throw new RuntimeException(JVM_OPTION_PREFIX + " JVM parameters for Ignite batch scripts " +
                         "with double quotes are not supported. " +
@@ -222,6 +227,9 @@ public class CommandLineTransformer {
                     throw new RuntimeException("Unrecognised parameter has been found: " + arg);
             }
         }
+
+        if (!hadFileEncoding)
+            jvmOptions = (jvmOptions.isEmpty() ? "" : (jvmOptions + " ")) + "-Dfile.encoding=UTF-8";
     }
 
     /**
@@ -234,4 +242,4 @@ public class CommandLineTransformer {
     private boolean checkJVMOptionIsSupported(String jvmOpt) {
         return !(jvmOpt.contains("-XX:OnError") || jvmOpt.contains("-XX:OnOutOfMemoryError"));
     }
-}
\ No newline at end of file
+}
index d08ed6b..fbcb547 100644 (file)
@@ -36,7 +36,7 @@ public class GridCommandLineTransformerSelfTest extends GridCommonAbstractTest {
     public void testTransformIfNoArguments() throws Exception {
         assertEquals(
             "\"INTERACTIVE=0\" \"QUIET=-DIGNITE_QUIET=true\" \"NO_PAUSE=0\" " +
-                "\"NO_JMX=0\" \"JVM_XOPTS=\" \"CONFIG=\"",
+                "\"NO_JMX=0\" \"JVM_XOPTS=-Dfile.encoding=UTF-8\" \"CONFIG=\"",
             CommandLineTransformer.transform());
     }
 
@@ -111,7 +111,7 @@ public class GridCommandLineTransformerSelfTest extends GridCommonAbstractTest {
     public void testTransformIfOnlyPathToConfigSpecified() throws Exception {
         assertEquals(
             "\"INTERACTIVE=0\" \"QUIET=-DIGNITE_QUIET=true\" \"NO_PAUSE=0\" \"NO_JMX=0\" " +
-            "\"JVM_XOPTS=\" \"CONFIG=c:\\qw.xml\"",
+            "\"JVM_XOPTS=-Dfile.encoding=UTF-8\" \"CONFIG=c:\\qw.xml\"",
             CommandLineTransformer.transform("c:\\qw.xml"));
     }
 
@@ -122,7 +122,7 @@ public class GridCommandLineTransformerSelfTest extends GridCommonAbstractTest {
     public void testTransformIfAllSupportedArguments() throws Exception {
         assertEquals(
             "\"INTERACTIVE=1\" \"QUIET=-DIGNITE_QUIET=false\" \"NO_PAUSE=1\" \"NO_JMX=1\" " +
-                "\"JVM_XOPTS=-Xmx1g -Xms1m\" " +
+                "\"JVM_XOPTS=-Xmx1g -Xms1m -Dfile.encoding=UTF-8\" " +
                 "\"CONFIG=\"c:\\path to\\русский каталог\"\"",
             CommandLineTransformer.transform("-i", "-np", "-v", "-J-Xmx1g", "-J-Xms1m", "-nojmx",
                 "\"c:\\path to\\русский каталог\""));
index 7d90a52..3891be1 100644 (file)
@@ -111,6 +111,10 @@ namespace ignite
 
             int idx = 0;
 
+            std::string fileEncParam = "-Dfile.encoding=";
+
+            bool hadFileEnc = false;
+
             // 1. Set classpath.
             std::string cpFull = "-Djava.class.path=" + cp;
 
@@ -131,8 +135,19 @@ namespace ignite
             opts[idx++] = CopyChars(xmxStr.c_str());
 
             // 4. Set the rest options.
-            for (std::list<std::string>::const_iterator i = cfg.jvmOpts.begin(); i != cfg.jvmOpts.end(); ++i)
+            for (std::list<std::string>::const_iterator i = cfg.jvmOpts.begin(); i != cfg.jvmOpts.end(); ++i) {
+                if (i->find(fileEncParam) != std::string::npos)
+                    hadFileEnc = true;
+
                 opts[idx++] = CopyChars(i->c_str());
+            }
+
+            // 5. Set file.encoding.
+            if (!hadFileEnc) {
+                std::string fileEncFull = fileEncParam + "UTF-8";
+
+                opts[idx++] = CopyChars(fileEncFull.c_str());
+            }
         }
 
         /**
index 47260a7..e2a4b9f 100644 (file)
@@ -40,6 +40,9 @@ namespace Apache.Ignite.Core.Impl
         /** Java Command line argument: Xmx. Case sensitive. */
         private const string CmdJvmMaxMemJava = "-Xmx";
 
+        /** Java Command line argument: file.encoding. Case sensitive. */
+        private const string CmdJvmFileEncoding = "-Dfile.encoding=";
+
         /** Monitor for DLL load synchronization. */
         private static readonly object SyncRoot = new object();
 
@@ -93,7 +96,7 @@ namespace Apache.Ignite.Core.Impl
                 return cbs;
             }
         }
-        
+
         /// <summary>
         /// Memory manager attached to currently running JVM.
         /// </summary>
@@ -141,6 +144,9 @@ namespace Apache.Ignite.Core.Impl
                 cfg.JvmMaxMemoryMb != IgniteConfiguration.DefaultJvmMaxMem)
                 jvmOpts.Add(string.Format(CultureInfo.InvariantCulture, "{0}{1}m", CmdJvmMaxMemJava, cfg.JvmMaxMemoryMb));
 
+            if (!jvmOpts.Any(opt => opt.StartsWith(CmdJvmFileEncoding, StringComparison.Ordinal)))
+                jvmOpts.Add(string.Format(CultureInfo.InvariantCulture, "{0}UTF-8", CmdJvmFileEncoding));
+
             return jvmOpts;
         }