ErrorCode Map Initialization Needs To Be Thread Safe

Reworked deferred initialization of error message map to be thread safe

Change-Id: I78c0df172038bb1a97297837ff7c82b2727f8556
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1571
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: abdullah alamoudi <bamousaa@gmail.com>
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 517e243..8f859c7 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -165,21 +165,27 @@
     public static final int UTIL_LOCAL_FILE_SYSTEM_UTILS_PATH_NOT_FOUND = 3077;
     public static final int UTIL_HDFS_UTILS_CANNOT_OBTAIN_HDFS_SCHEDULER = 3078;
 
-    // Loads the map that maps error codes to error message templates.
-    private static Map<Integer, String> errorMessageMap = null;
-
     private ErrorCode() {
     }
 
-    public static String getErrorMessage(int errorCode) {
-        if (errorMessageMap == null) {
+    private static class Holder {
+        private static final Map<Integer, String> errorMessageMap;
+
+        static {
+            // Loads the map that maps error codes to error message templates.
             try (InputStream resourceStream = ErrorCode.class.getClassLoader().getResourceAsStream(RESOURCE_PATH)) {
                 errorMessageMap = ErrorMessageUtil.loadErrorMap(resourceStream);
             } catch (Exception e) {
                 throw new IllegalStateException(e);
             }
         }
-        String msg = errorMessageMap.get(errorCode);
+
+        private Holder() {
+        }
+    }
+
+    public static String getErrorMessage(int errorCode) {
+        String msg = Holder.errorMessageMap.get(errorCode);
         if (msg == null) {
             throw new IllegalStateException("Undefined error code: " + errorCode);
         }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
index 333b1df..401103b 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
@@ -64,21 +64,27 @@
     // Compilation error codes.
     public static final int RULECOLLECTION_NOT_INSTANCE_OF_LIST = 10001;
 
-    // Loads the map that maps error codes to error message templates.
-    private static Map<Integer, String> errorMessageMap = null;
+    private static class Holder {
+        private static final Map<Integer, String> errorMessageMap;
 
-    private ErrorCode() {
-    }
-
-    public static String getErrorMessage(int errorCode) {
-        if (errorMessageMap == null) {
+        static {
+            // Loads the map that maps error codes to error message templates.
             try (InputStream resourceStream = ErrorCode.class.getClassLoader().getResourceAsStream(RESOURCE_PATH)) {
                 errorMessageMap = ErrorMessageUtil.loadErrorMap(resourceStream);
             } catch (Exception e) {
                 throw new IllegalStateException(e);
             }
         }
-        String msg = errorMessageMap.get(errorCode);
+
+        private Holder() {
+        }
+    }
+
+    private ErrorCode() {
+    }
+
+    public static String getErrorMessage(int errorCode) {
+        String msg = Holder.errorMessageMap.get(errorCode);
         if (msg == null) {
             throw new IllegalStateException("Undefined error code: " + errorCode);
         }