changeset 7727:af7c2b5cd307

7172176: test/sun/tools/jconsole/ImmutableResourceTest.sh failing Reviewed-by: mchung, mfang
author egahlin
date Thu, 27 Nov 2014 04:24:07 +0100
parents 4728d748209d
children b2a3cf632477
files test/ProblemList.txt test/sun/tools/jconsole/ResourceCheckTest.java test/sun/tools/jconsole/ResourceCheckTest.sh
diffstat 3 files changed, 118 insertions(+), 364 deletions(-) [+]
line wrap: on
line diff
--- a/test/ProblemList.txt	Wed Nov 26 20:47:26 2014 +0300
+++ b/test/ProblemList.txt	Thu Nov 27 04:24:07 2014 +0100
@@ -387,9 +387,6 @@
 # Filed 6986875
 sun/tools/jps/jps-Vvml.sh                                       generic-all
 
-# Filed 6979016
-sun/tools/jconsole/ResourceCheckTest.sh                         generic-all
-
 # 7132203
 sun/jvmstat/monitor/MonitoredVm/CR6672135.java                  generic-all
 
--- a/test/sun/tools/jconsole/ResourceCheckTest.java	Wed Nov 26 20:47:26 2014 +0300
+++ b/test/sun/tools/jconsole/ResourceCheckTest.java	Thu Nov 27 04:24:07 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,377 +27,134 @@
  *  This isn't the test case: ResourceCheckTest.sh is.
  *  Refer to ResourceCheckTest.sh when running this test.
  *
- *  @bug 5008856 5023573 5024917 5062569
+ *  @bug 5008856 5023573 5024917 5062569 7172176
  *  @summary 'missing resource key' error for key = "Operating system"
  */
 
-import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
 
+import sun.tools.jconsole.Messages;
 import sun.tools.jconsole.Resources;
 
+/*
+ * Ensures that there is a one-to-one mapping between constants in the
+ * Message class and the keys in the sun.tools.jconsole.resources.messages
+ * bundle.
+ *
+ * An error will be thrown if there is a:
+ *
+ * - key in the resource bundle that doesn't have a public static field with
+ *   the same name in the Message class.
+ *
+ * - public static field in the Message class that doesn't have a key with
+ *   the same name in the resource bundle.
+ *
+ * - message with a mnemonic identifier(&) for which a mnemonic can't
+ *   be looked up using Resources#getMnemonicInt().
+ *
+ */
 public class ResourceCheckTest {
+    private static final String MISSING_RESOURCE_KEY_PREFIX = "missing message for";
+    private static final String RESOURCE_BUNDLE = "sun.tools.jconsole.resources.messages";
+    private static final String NEW_LINE = String.format("%n");
 
-    public static void main(String[] args){
-        Object [][] testData = {
-            {"<", "", "", "", ""},
-            {"<<", "", "", "", ""},
-            {">", "", "", "", ""},
-            {" 1 day", "", "", "", ""},
-            {" 1 hour", "", "", "", ""},
-            {" 1 min", "", "", "", ""},
-            {" 1 month", "", "", "", ""},
-            {" 1 year", "", "", "", ""},
-            {" 2 hours", "", "", "", ""},
-            {" 3 hours", "", "", "", ""},
-            {" 3 months", "", "", "", ""},
-            {" 5 min", "", "", "", ""},
-            {" 6 hours", "", "", "", ""},
-            {" 6 months", "", "", "", ""},
-            {" 7 days", "", "", "", ""},
-            {"10 min", "", "", "", ""},
-            {"12 hours", "", "", "", ""},
-            {"30 min", "", "", "", ""},
-            {"ACTION", "", "", "", ""},
-            {"ACTION_INFO", "", "", "", ""},
-            {"All", "", "", "", ""},
-            {"Architecture", "", "", "", ""},
-            {"Attribute", "", "", "", ""},
-            {"Attribute value", "", "", "", ""},
-            {"Attribute values", "", "", "", ""},
-            {"Attributes", "", "", "", ""},
-            {"Blank", "", "", "", ""},
-            {"BlockedCount WaitedCount", "BlockedCount", "WaitedCount", "", ""},
-            {"Boot class path", "", "", "", ""},
-            {"BorderedComponent.moreOrLessButton.toolTip", "", "", "", ""},
-            {"Close", "", "", "", ""},
-            {"CPU Usage", "", "", "", ""},
-            {"CPUUsageFormat","PhonyPercentage", "", "", ""},
-            {"Cancel", "", "", "", ""},
-            {"Cascade", "", "", "", ""},
-            {"Cascade.mnemonic", "", "", "", ""},
-            {"Chart:", "", "", "", ""},
-            {"Chart:.mnemonic", "", "", "", ""},
-            {"ClassTab.infoLabelFormat", "LoadedCount", "UnloadedCount", "TotalCount", ""},
-            {"ClassTab.loadedClassesPlotter.accessibleName", "", "", "", ""},
-            {"Class path", "", "", "", ""},
-            {"Classes", "", "", "", ""},
-            {"ClassName", "", "", "", ""},
-            {"Column.Name", "", "", "", ""},
-            {"Column.PID", "", "", "", ""},
-            {"Committed", "", "", "", ""},
-            {"Committed memory", "", "", "", ""},
-            {"Committed virtual memory", "", "", "", ""},
-            {"Compiler", "", "", "", ""},
-            {"Connect...", "", "", "", ""},
-            {"Connect", "", "", "", ""},
-            {"Connect.mnemonic", "", "", "", ""},
-            {"ConnectDialog.connectButton.toolTip", "", "", "", ""},
-            {"ConnectDialog.accessibleDescription", "", "", "", ""},
-            {"ConnectDialog.masthead.accessibleName", "", "", "", ""},
-            {"ConnectDialog.masthead.title", "", "", "", ""},
-            {"ConnectDialog.statusBar.accessibleName", "", "", "", ""},
-            {"ConnectDialog.title", "", "", "", ""},
-            {"Connected. Click to disconnect.", "", "", "", ""},
-            {"connectingTo1", "PhonyConnectionName", "", "", ""},
-            {"connectingTo2", "PhonyConnectionName", "", "", ""},
-            {"connectionFailed1", "", "", "", ""},
-            {"connectionFailed2", "PhonyConnectionName", "", "", ""},
-            {"connectionLost1", "", "", "", ""},
-            {"connectionLost2", "PhonyConnectionName", "", "", ""},
-            {"Connection failed", "", "", "", ""},
-            {"Connection", "", "", "", ""},
-            {"Connection.mnemonic", "", "", "", ""},
-            {"Connection name", "", "", "", ""},
-            {"ConnectionName (disconnected)", "Phony", "Phony", "", ""},
-            {"Constructor", "", "", "", ""},
-            {"Create", "Phony", "Phony", "", ""},
-            {"Current classes loaded", "", "", "", ""},
-            {"Current heap size", "", "", "", ""},
-            {"Current value", "PhonyValue", "", "", ""},
-            {"Daemon threads", "", "", "", ""},
-            {"deadlockAllTab", "", "", "", ""},
-            {"deadlockTab", "", "", "", ""},
-            {"deadlockTabN", "PhonyInt", "", "", ""},
-            {"Description", "", "", "", ""},
-            {"Descriptor", "", "", "", ""},
-            {"Details", "", "", "", ""},
-            {"Detect Deadlock", "", "", "", ""},
-            {"Detect Deadlock.mnemonic", "", "", "", ""},
-            {"Detect Deadlock.toolTip", "", "", "", ""},
-            {"Dimension is not supported:", "", "", "", ""},
-            {"Discard chart", "", "", "", ""},
-            {"Disconnected. Click to connect.", "", "", "", ""},
-            {"Double click to expand/collapse", "", "", "", ""},
-            {"Double click to visualize", "", "", "", ""},
-            {"DurationDaysHoursMinutes", 0, 13, 54, ""},
-            {"DurationDaysHoursMinutes", 1, 13, 54, ""},
-            {"DurationDaysHoursMinutes", 2, 13, 54, ""},
-            {"DurationDaysHoursMinutes", 1024, 13, 45, ""},
-            {"DurationHoursMinutes", 0, 13, "", ""},
-            {"DurationHoursMinutes", 1, 0, "", ""},
-            {"DurationHoursMinutes", 1, 1, "", ""},
-            {"DurationHoursMinutes", 2, 42, "", ""},
-            {"DurationMinutes", 0, "", "", ""},
-            {"DurationMinutes", 1, "", "", ""},
-            {"DurationMinutes", 2, "", "", ""},
-            {"DurationSeconds", 0, "", "", ""},
-            {"DurationSeconds", 1, "", "", ""},
-            {"DurationSeconds", 2, "", "", ""},
-            {"Empty array", "", "", "", ""},
-            {"Error", "", "", "", ""},
-            {"Error: MBeans already exist", "", "", "", ""},
-            {"Error: MBeans do not exist", "", "", "", ""},
-            {"Event", "", "", "", ""},
-            {"Exit", "", "", "", ""},
-            {"Exit.mnemonic", "", "", "", ""},
-            {"expand", "", "", "", ""},
-            {"Fail to load plugin", "", "", "", ""},
-            {"FileChooser.fileExists.cancelOption", "", "", "", ""},
-            {"FileChooser.fileExists.message", "PhonyFileName", "", "", ""},
-            {"FileChooser.fileExists.okOption", "", "", "", ""},
-            {"FileChooser.fileExists.title", "", "", "", ""},
-            {"FileChooser.savedFile", "PhonyFilePath", "PhonyFileSize", "", ""},
-            {"FileChooser.saveFailed.message", "PhonyFilePath", "PhonyMessage", "", ""},
-            {"FileChooser.saveFailed.title", "", "", "", ""},
-            {"Free physical memory", "", "", "", ""},
-            {"Free swap space", "", "", "", ""},
-            {"Garbage collector", "", "", "", ""},
-            {"GC time", "", "", "", ""},
-            {"GC time details", 54, "Phony", 11, ""},
-            {"GcInfo", "Phony", -1, 768, ""},
-            {"GcInfo", "Phony", 0, 768, ""},
-            {"GcInfo", "Phony", 1, 768, ""},
-            {"Heap", "", "", "", ""},
-            {"Heap Memory Usage", "", "", "", ""},
-            {"Help.AboutDialog.accessibleDescription", "", "", "", ""},
-            {"Help.AboutDialog.jConsoleVersion", "DummyVersion", "", "", ""},
-            {"Help.AboutDialog.javaVersion", "DummyVersion", "", "", ""},
-            {"Help.AboutDialog.masthead.accessibleName", "", "", "", ""},
-            {"Help.AboutDialog.masthead.title", "", "", "", ""},
-            {"Help.AboutDialog.title", "", "", "", ""},
-            {"Help.AboutDialog.userGuideLink", "DummyMessage", "", "", ""},
-            {"Help.AboutDialog.userGuideLink.mnemonic", "", "", "", ""},
-            {"Help.AboutDialog.userGuideLink.url", "DummyURL", "", "", ""},
-            {"HelpMenu.About.title", "", "", "", ""},
-            {"HelpMenu.About.title.mnemonic", "", "", "", ""},
-            {"HelpMenu.UserGuide.title", "", "", "", ""},
-            {"HelpMenu.UserGuide.title.mnemonic", "", "", "", ""},
-            {"HelpMenu.title", "", "", "", ""},
-            {"HelpMenu.title.mnemonic", "", "", "", ""},
-            {"Hotspot MBeans...", "", "", "", ""},
-            {"Hotspot MBeans....mnemonic", "", "", "", ""},
-            {"Hotspot MBeans.dialog.accessibleDescription", "", "", "", ""},
-            {"Impact", "", "", "", ""},
-            {"Info", "", "", "", ""},
-            {"INFO", "", "", "", ""},
-            {"Invalid plugin path", "", "", "", ""},
-            {"Invalid URL", "", "", "", ""},
-            {"Is", "", "", "", ""},
-            {"Java Monitoring & Management Console", "", "", "", ""},
-            {"Java Virtual Machine", "", "", "", ""},
-            {"JConsole: ", "", "", "", ""},
-            {"JConsole.accessibleDescription", "", "", "", ""},
-            {"JConsole version", "PhonyVersion", "", "", ""},
-            {"JIT compiler", "", "", "", ""},
-            {"Library path", "", "", "", ""},
-            {"Live Threads", "", "", "", ""},
-            {"Loaded", "", "", "", ""},
-            {"Local Process:", "", "", "", ""},
-            {"Local Process:.mnemonic", "", "", "", ""},
-            {"Manage Hotspot MBeans in: ", "", "", "", ""},
-            {"Management Not Enabled", "", "", "", ""},
-            {"Management Will Be Enabled", "", "", "", ""},
-            {"Masthead.font", "", "", "", ""},
-            {"Max", "", "", "", ""},
-            {"Max", "", "", "", ""},
-            {"Maximum heap size", "", "", "", ""},
-            {"MBeanAttributeInfo", "", "", "", ""},
-            {"MBeanInfo", "", "", "", ""},
-            {"MBeanNotificationInfo", "", "", "", ""},
-            {"MBeanOperationInfo", "", "", "", ""},
-            {"MBeans", "", "", "", ""},
-            {"MBeansTab.clearNotificationsButton", "", "", "", ""},
-            {"MBeansTab.clearNotificationsButton.mnemonic", "", "", "", ""},
-            {"MBeansTab.clearNotificationsButton.toolTip", "", "", "", ""},
-            {"MBeansTab.compositeNavigationMultiple", 0, 0, "", ""},
-            {"MBeansTab.compositeNavigationSingle", "", "", "", ""},
-            {"MBeansTab.refreshAttributesButton", "", "", "", ""},
-            {"MBeansTab.refreshAttributesButton.mnemonic", "", "", "", ""},
-            {"MBeansTab.refreshAttributesButton.toolTip", "", "", "", ""},
-            {"MBeansTab.subscribeNotificationsButton", "", "", "", ""},
-            {"MBeansTab.subscribeNotificationsButton.mnemonic", "", "", "", ""},
-            {"MBeansTab.subscribeNotificationsButton.toolTip", "", "", "", ""},
-            {"MBeansTab.tabularNavigationMultiple", 0, 0, "", ""},
-            {"MBeansTab.tabularNavigationSingle", "", "", "", ""},
-            {"MBeansTab.unsubscribeNotificationsButton", "", "", "", ""},
-            {"MBeansTab.unsubscribeNotificationsButton.mnemonic", "", "", "", ""},
-            {"MBeansTab.unsubscribeNotificationsButton.toolTip", "", "", "", ""},
-            {"Memory", "", "", "", ""},
-            {"MemoryPoolLabel", "PhonyMemoryPool", "", "", ""},
-            {"MemoryTab.heapPlotter.accessibleName", "", "", "", ""},
-            {"MemoryTab.infoLabelFormat", "UsedCount", "CommittedCount", "MaxCount", ""},
-            {"MemoryTab.nonHeapPlotter.accessibleName", "", "", "", ""},
-            {"MemoryTab.poolChart.aboveThreshold", "Threshold", "", "", ""},
-            {"MemoryTab.poolChart.accessibleName", "", "", "", ""},
-            {"MemoryTab.poolChart.belowThreshold", "Threshold", "", "", ""},
-            {"MemoryTab.poolPlotter.accessibleName", "PhonyMemoryPool", "", "", ""},
-            {"Message", "", "", "", ""},
-            {"Method successfully invoked", "", "", "", ""},
-            {"Monitor locked", "", "", "", ""},
-            {"Minimize All", "", "", "", ""},
-            {"Minimize All.mnemonic", "", "", "", ""},
-            {"Name", "", "", "", ""},
-            {"Name and Build", "PhonyName", "PhonyBuild", "", ""},
-            {"Name Build and Mode", "PhonyName", "PhonyBuild", "PhonyMode", ""},
-            {"Name State", "PhonyName", "PhonyState", "", ""},
-            {"Name State LockName", "PhonyName", "PhonyState", "PhonyLock", ""},
-            {"Name State LockName LockOwner", "PhonyName", "PhonyState", "PhonyLock", "PhonyOwner"},
-            {"New Connection...", "", "", "", ""},
-            {"New Connection....mnemonic", "", "", "", ""},
-            {"No deadlock detected", "", "", "", ""},
-            {"Non-Heap", "", "", "", ""},
-            {"Non-Heap Memory Usage", "", "", "", ""},
-            {"Notification", "", "", "", ""},
-            {"Notification buffer", "", "", "", ""},
-            {"Notifications", "", "", "", ""},
-            {"NotifTypes", "", "", "", ""},
-            {"Number of Loaded Classes", "", "", "", ""},
-            {"Number of processors", "", "", "", ""},
-            {"Number of Threads", "", "", "", ""},
-            {"ObjectName", "", "", "", ""},
-            {"Operating System", "", "", "", ""},
-            {"Operation", "", "", "", ""},
-            {"Operation invocation", "", "", "", ""},
-            {"Operation return value", "", "", "", ""},
-            {"Operations", "", "", "", ""},
-            {"Overview", "", "", "", ""},
-            {"OverviewPanel.plotter.accessibleName", "PhonyPlotter", "", "", ""},
-            {"Parameter", "", "", "", ""},
-            {"Password: ", "", "", "", ""},
-            {"Password: .mnemonic", "", "", "", ""},
-            {"Password.accessibleName", "", "", "", ""},
-            {"Peak", "", "", "", ""},
-            {"Perform GC", "", "", "", ""},
-            {"Perform GC.mnemonic", "", "", "", ""},
-            {"Perform GC.toolTip", "", "", "", ""},
-            {"Plotter.accessibleName", "", "", "", ""},
-            {"Plotter.accessibleName.keyAndValue", "Key", "Value", "", ""},
-            {"Plotter.accessibleName.noData", "", "", "", ""},
-            {"Plotter.saveAsMenuItem", "", "", "", ""},
-            {"Plotter.saveAsMenuItem.mnemonic", "", "", "", ""},
-            {"Plotter.timeRangeMenu", "", "", "", ""},
-            {"Plotter.timeRangeMenu.mnemonic", "", "", "", ""},
-            {"plot", "", "", "", ""},
-            {"Problem adding listener", "", "", "", ""},
-            {"Problem displaying MBean", "", "", "", ""},
-            {"Problem invoking", "", "", "", ""},
-            {"Problem removing listener", "", "", "", ""},
-            {"Problem setting attribute", "", "", "", ""},
-            {"Process CPU time", "", "", "", ""},
-            {"Readable", "", "", "", ""},
-            {"Reconnect", "", "", "", ""},
-            {"Remote Process:", "", "", "", ""},
-            {"Remote Process:.mnemonic", "", "", "", ""},
-            {"Remote Process.textField.accessibleName", "", "", "", ""},
-            {"remoteTF.usage", "", "", "", ""},
-            {"Restore All", "", "", "", ""},
-            {"Restore All.mnemonic", "", "", "", ""},
-            {"ReturnType", "", "", "", ""},
-            {"SeqNum", "", "", "", ""},
-            {"Size Bytes", 512, "", "", ""},
-            {"Size Gb", 512, "", "", ""},
-            {"Size Kb", 512, "", "", ""},
-            {"Size Mb", 512, "", "", ""},
-            {"Source", "", "", "", ""},
-            {"Stack trace", "", "", "", ""},
-            {"SummaryTab.headerDateTimeFormat", "", "", "", ""},
-            {"SummaryTab.pendingFinalization.label", "", "", "", ""},
-            {"SummaryTab.pendingFinalization.value", "ObjectCount", "", "", ""},
-            {"SummaryTab.tabName", "", "", "", ""},
-            {"SummaryTab.vmVersion",  "VMName", "VMVersion", "", ""},
-            {"ThreadTab.infoLabelFormat", "LiveCount", "PeakCount", "TotalCount", ""},
-            {"ThreadTab.threadInfo.accessibleName", "", "", "", ""},
-            {"ThreadTab.threadPlotter.accessibleName", "", "", "", ""},
-            {"Threads", "", "", "", ""},
-            {"Threshold", "", "", "", ""},
-            {"Tile", "", "", "", ""},
-            {"Tile.mnemonic", "", "", "", ""},
-            {"Time", "", "", "", ""},
-            {"Time Range:", "", "", "", ""},
-            {"Time Range:.mnemonic", "", "", "", ""},
-            {"TimeStamp", "", "", "", ""},
-            {"Total classes loaded", "", "", "", ""},
-            {"Total classes unloaded", "", "", "", ""},
-            {"Total compile time", "", "", "", ""},
-            {"Total Loaded", "", "", "", ""},
-            {"Total physical memory", "", "", "", ""},
-            {"Total swap space", "", "", "", ""},
-            {"Total threads started", "", "", "", ""},
-            {"Type", "", "", "", ""},
-            {"Unavailable", "", "", "", ""},
-            {"UNKNOWN", "", "", "", ""},
-            {"Unregister", "", "", "", ""},
-            {"Uptime", "", "", "", ""},
-            {"Usage Threshold", "", "", "", ""},
-            {"Used", "", "", "", ""},
-            {"Username: ", "", "", "", ""},
-            {"Username: .mnemonic", "", "", "", ""},
-            {"Username.accessibleName", "", "", "", ""},
-            {"UserData", "", "", "", ""},
-            {"Value", "", "", "", ""},
-            {"Vendor", "", "", "", ""},
-            {"Verbose Output", "", "", "", ""},
-            {"Verbose Output.toolTip", "", "", "", ""},
-            {"visualize", "", "", "", ""},
-            {"VM", "", "", "", ""},
-            {"VMInternalFrame.accessibleDescription", "", "", "", ""},
-            {"VM arguments", "", "", "", ""},
-            {"Virtual Machine", "", "", "", ""},
-            {"Window", "", "", "", ""},
-            {"Window.mnemonic", "", "", "", ""},
-            {"Writable", "", "", "", ""},
-            {"zz usage text", "PhonyName", "", "", ""},
-        };
-        //boolean verbose = false;
-        boolean verbose = true;
-
-        long badLookups = 0;
-        System.out.println("Start...");
-        for (int ii = 0; ii < testData.length; ii++) {
-            String key = (String)testData[ii][0];
-
-            if (key.endsWith(".mnemonic")) {
-                String baseKey = key.substring(0, key.length() - ".mnemonic".length());
-                int mnemonic = Resources.getMnemonicInt(baseKey);
-                if (mnemonic == 0) {
-                    badLookups++;
-                    System.out.println("****lookup failed for key = " + key);
+    public static void main(String... args) {
+        List<String> errors = new ArrayList<>();
+        // Ensure that all Message fields have a corresponding key/value
+        // in the resource bundle and that mnemonics can be looked
+        // up where applicable.
+        ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+        for (Field field : Messages.class.getFields()) {
+            if (isResourceKeyField(field)) {
+                String resourceKey = field.getName();
+                String message = readField(field);
+                if (message.startsWith(MISSING_RESOURCE_KEY_PREFIX)) {
+                    errors.add("Can't find message (and perhaps mnemonic) for "
+                            + Messages.class.getSimpleName() + "."
+                            + resourceKey + " in resource bundle.");
                 } else {
-                    if (verbose) {
-                        System.out.println("    mnemonic: " + KeyEvent.getKeyText(mnemonic));
+                    String resourceMessage = rb.getString(resourceKey);
+                    if (hasMnemonicIdentifier(resourceMessage)) {
+                        int mi = Resources.getMnemonicInt(message);
+                        if (mi == 0) {
+                            errors.add("Could not look up mnemonic for message '"
+                                    + message + "'.");
+                        }
                     }
                 }
-                continue;
-            }
-
-            String ss = Resources.getText(key,
-                                          testData[ii][1],
-                                          testData[ii][2],
-                                          testData[ii][3],
-                                          testData[ii][4]);
-            if (ss.startsWith("missing resource key")) {
-                badLookups++;
-                System.out.println("****lookup failed for key = " + key);
-            } else {
-                if (verbose) {
-                    System.out.println("  " + ss);
-                }
             }
         }
-        if (badLookups > 0) {
-            throw new Error ("Resource lookup failed " + badLookups +
-                             " time(s); Test failed");
+
+        // Ensure that there is Message class field for every resource key.
+        for (String key : Collections.list(rb.getKeys())) {
+            try {
+                Messages.class.getField(key);
+            } catch (NoSuchFieldException nfe) {
+                errors.add("Can't find static field ("
+                        + Messages.class.getSimpleName() + "." + key
+                        + ") matching '" + key
+                        + "' in resource bundle. Unused message?");
+            }
         }
-        System.out.println("...Finished.");
+
+        if (errors.size() > 0) {
+            throwError(errors);
+        }
+    }
+
+    private static String readField(Field field) {
+        try {
+            return (String) field.get(null);
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new Error("Could not access field " + field.getName()
+                    + " when trying to read resource message.");
+        }
+    }
+
+    private static boolean isResourceKeyField(Field field) {
+        int modifiers = field.getModifiers();
+        return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers);
+    }
+
+    private static boolean hasMnemonicIdentifier(String s) {
+        for (int i = 0; i < s.length() - 1; i++) {
+            if (s.charAt(i) == '&') {
+                if (s.charAt(i + 1) != '&') {
+                    return true;
+                } else {
+                    i++;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static void throwError(List<String> errors) {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("Found ");
+        buffer.append(errors.size());
+        buffer.append(" error(s) when checking one-to-one mapping ");
+        buffer.append("between Message and resource bundle keys in ");
+        buffer.append(RESOURCE_BUNDLE);
+        buffer.append(" with ");
+        buffer.append(Locale.getDefault());
+        buffer.append(" locale.");
+        buffer.append(NEW_LINE);
+        int errorIndex = 1;
+        for (String error : errors) {
+            buffer.append("Error ");
+            buffer.append(errorIndex);
+            buffer.append(": ");
+            buffer.append(error);
+            buffer.append(NEW_LINE);
+            errorIndex++;
+        }
+        throw new Error(buffer.toString());
     }
 }
--- a/test/sun/tools/jconsole/ResourceCheckTest.sh	Wed Nov 26 20:47:26 2014 +0300
+++ b/test/sun/tools/jconsole/ResourceCheckTest.sh	Thu Nov 27 04:24:07 2014 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@
 
 OS=`uname -s`
 case "$OS" in
-   SunOS | Linux )
+   SunOS | Linux | Darwin)
       PATHSEP=":"
       ;;