From 5f8e39900cd0c35d623b41bc0f35d82019809562 Mon Sep 17 00:00:00 2001
From: Erik Joelsson <erikj@openjdk.org>
Date: Tue, 24 Nov 2015 15:40:03 +0100
Subject: [PATCH 01/62] 8143895: Fix LDFLAGS issues after JDK-8056925

Reviewed-by: ihse
---
 jdk/make/launcher/Launcher-jdk.accessibility.gmk | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/jdk/make/launcher/Launcher-jdk.accessibility.gmk b/jdk/make/launcher/Launcher-jdk.accessibility.gmk
index 0fa486377f1..eba521c469a 100644
--- a/jdk/make/launcher/Launcher-jdk.accessibility.gmk
+++ b/jdk/make/launcher/Launcher-jdk.accessibility.gmk
@@ -73,8 +73,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
     $$(eval $$(call SetupNativeCompilation, BUILD_JACCESSINSPECTOR$1, \
       SRC := $(TOPDIR)/jaccessinspector $(TOPDIR)/common \
           $(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \
-      CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \
-      LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib User32.lib, \
+      CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
+      LDFLAGS := $$(LDFLAGS_JDKEXE) -stack:655360, \
+      LIBS := advapi32.lib user32.lib, \
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccessinspector$1, \
       OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
       PROGRAM := jaccessinspector$1, \
@@ -100,8 +101,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
     $$(eval $$(call SetupNativeCompilation,BUILD_JACCESSWALKER$1, \
       SRC := $(TOPDIR)/jaccesswalker $(TOPDIR)/common \
           $(TOPDIR)/toolscommon $(TOPDIR)/include/bridge, \
-      CFLAGS :== $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 /EHsc, \
-      LDFLAGS := $$(LDFLAGS_JDKEXE) /STACK:655360 Advapi32.lib Comctl32.lib Gdi32.lib User32.lib, \
+      CFLAGS := $$(CFLAGS_JDKEXE) $(TOOLS_CFLAGS) -DACCESSBRIDGE_ARCH_$2 -EHsc, \
+      LDFLAGS := $$(LDFLAGS_JDKEXE) -stack:655360, \
+      LIBS := advapi32.lib comctl32.lib gdi32.lib user32.lib, \
       OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/jdk.accessibility/jaccesswalker$1, \
       OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/jdk.accessibility, \
       PROGRAM := jaccesswalker$1, \

From 3c1af171595aaf96cc34750bd5e54433d55ffd9e Mon Sep 17 00:00:00 2001
From: Steven Loomis <srl@openjdk.org>
Date: Tue, 24 Nov 2015 13:36:12 -0800
Subject: [PATCH 02/62] 8068619: remove unused internal function in layout

No functional change. Removes unused code. Makes JDK's layout engine have the same signature as ICU HarfBuzz's wrapper. Reviewed: http://mail.openjdk.java.net/pipermail/2d-dev/2015-March/005156.html

Reviewed-by: prr
---
 .../libfontmanager/FontInstanceAdapter.cpp    |  6 -----
 .../libfontmanager/FontInstanceAdapter.h      |  1 -
 .../libfontmanager/layout/LEFontInstance.h    | 24 +------------------
 3 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp
index 8c8c47593fb..3d133952d4d 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp
+++ b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.cpp
@@ -67,12 +67,6 @@ FontInstanceAdapter::FontInstanceAdapter(JNIEnv *theEnv,
 };
 
 
-const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
-{
-  size_t ignored = 0;
-  return getFontTable(tableTag, ignored);
-}
-
 static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = {
   GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG
 };
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h
index 8d2ee3073a0..0d8322dddbe 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h
+++ b/jdk/src/java.desktop/share/native/libfontmanager/FontInstanceAdapter.h
@@ -85,7 +85,6 @@ public:
 
     // tables are cached with the native font scaler data
     // only supports gsub, gpos, gdef, mort tables at present
-    virtual const void *getFontTable(LETag tableTag) const;
     virtual const void *getFontTable(LETag tableTag, size_t &len) const;
 
     virtual void *getKernPairs() const {
diff --git a/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h b/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h
index 2baf2d6c85e..3ac687906fa 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LEFontInstance.h
@@ -172,28 +172,6 @@ public:
     // Font file access
     //
 
-    /**
-     * This method reads a table from the font. Note that in general,
-     * it only makes sense to call this method on an <code>LEFontInstance</code>
-     * which represents a physical font - i.e. one which has been returned by
-     * <code>getSubFont()</code>. This is because each subfont in a composite font
-     * will have different tables, and there's no way to know which subfont to access.
-     *
-     * Subclasses which represent composite fonts should always return <code>NULL</code>.
-     *
-     * Note that implementing this function does not allow for range checking.
-     * Subclasses that desire the safety of range checking must implement the
-     * variation which has a length parameter.
-     *
-     * @param tableTag - the four byte table tag. (e.g. 'cmap')
-     *
-     * @return the address of the table in memory, or <code>NULL</code>
-     *         if the table doesn't exist.
-     *
-     * @stable ICU 2.8
-     */
-    virtual const void *getFontTable(LETag tableTag) const = 0;
-
     /**
      * This method reads a table from the font. Note that in general,
      * it only makes sense to call this method on an <code>LEFontInstance</code>
@@ -213,7 +191,7 @@ public:
      *         if the table doesn't exist.
      * @internal
      */
-    virtual const void* getFontTable(LETag tableTag, size_t &length) const { length=-1; return getFontTable(tableTag); }  /* -1 = unknown length */
+    virtual const void* getFontTable(LETag tableTag, size_t &length) const = 0;
 
     virtual void *getKernPairs() const = 0;
     virtual void  setKernPairs(void *pairs) const = 0;

From 69b04049b56d38ae5811850c9d44a997fa6bd1d1 Mon Sep 17 00:00:00 2001
From: Prasanta Sadhukhan <psadhukhan@openjdk.org>
Date: Wed, 25 Nov 2015 14:44:29 +0300
Subject: [PATCH 03/62] 7063986: Wrong JNi method call in font scaler

Reviewed-by: prr, rchamyal
---
 .../java.desktop/share/native/libfontmanager/freetypeScaler.c   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c b/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
index 5fe5372be2f..c2a294f91b7 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
+++ b/jdk/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
@@ -258,7 +258,7 @@ Java_sun_font_FreetypeFontScaler_initNativeScaler(
                                               scalerInfo->fontData,
                                               scalerInfo->fontDataLength);
             if (bBuffer != NULL) {
-                (*env)->CallObjectMethod(env, font2D,
+                (*env)->CallVoidMethod(env, font2D,
                                    sunFontIDs.readFileMID, bBuffer);
 
                 error = FT_New_Memory_Face(scalerInfo->library,

From bcb678575580e78beb157c5706c10b4ea521250a Mon Sep 17 00:00:00 2001
From: Ambarish Rapte <arapte@openjdk.org>
Date: Thu, 26 Nov 2015 19:12:28 +0400
Subject: [PATCH 04/62] 8055197: TextField deletes multiline strings

Reviewed-by: serb, alexsch
---
 .../share/classes/java/awt/TextField.java     |  21 +-
 .../java/awt/TextField/EOLTest/EOLTest.java   | 202 ++++++++++++++++++
 2 files changed, 221 insertions(+), 2 deletions(-)
 create mode 100644 jdk/test/java/awt/TextField/EOLTest/EOLTest.java

diff --git a/jdk/src/java.desktop/share/classes/java/awt/TextField.java b/jdk/src/java.desktop/share/classes/java/awt/TextField.java
index de6b5cda6d4..2dfd19c4128 100644
--- a/jdk/src/java.desktop/share/classes/java/awt/TextField.java
+++ b/jdk/src/java.desktop/share/classes/java/awt/TextField.java
@@ -198,7 +198,7 @@ public class TextField extends TextComponent {
      * @see java.awt.GraphicsEnvironment#isHeadless
      */
     public TextField(String text, int columns) throws HeadlessException {
-        super(text);
+        super(replaceEOL(text));
         this.columns = (columns >= 0) ? columns : 0;
     }
 
@@ -297,12 +297,28 @@ public class TextField extends TextComponent {
      * @see         java.awt.TextComponent#getText
      */
     public void setText(String t) {
-        super.setText(t);
+        super.setText(replaceEOL(t));
 
         // This could change the preferred size of the Component.
         invalidateIfValid();
     }
 
+    /**
+     * Replaces EOL characters from the text variable with a space character.
+     * @param       text   the new text.
+     * @return      Returns text after replacing EOL characters.
+     */
+    private static String replaceEOL(String text) {
+        String[] strEOLs = {System.lineSeparator(), "\n"};
+        for (String eol : strEOLs) {
+            if (text.contains(eol)) {
+                text = text.replace(eol, " ");
+            }
+        }
+        return text;
+    }
+
+
     /**
      * Indicates whether or not this text field has a
      * character set for echoing.
@@ -704,6 +720,7 @@ public class TextField extends TextComponent {
     {
         // HeadlessException will be thrown by TextComponent's readObject
         s.defaultReadObject();
+        text = replaceEOL(text);
 
         // Make sure the state we just read in for columns has legal values
         if (columns < 0) {
diff --git a/jdk/test/java/awt/TextField/EOLTest/EOLTest.java b/jdk/test/java/awt/TextField/EOLTest/EOLTest.java
new file mode 100644
index 00000000000..a9ab7b0941d
--- /dev/null
+++ b/jdk/test/java/awt/TextField/EOLTest/EOLTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8055197 7186036
+ @summary TextField should replace EOL character with space character
+ @run main EOLTest
+ */
+
+import java.awt.Frame;
+import java.awt.TextField;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+
+public class EOLTest {
+
+    private Frame mainFrame;
+    private TextField textField;
+    private String testStrEOL;
+    private boolean isTestFail;
+    private int testFailCount;
+    StringBuilder testFailMessage;
+    private String expectedString = "Row1 Row2 Row3";
+
+    public EOLTest() {
+        mainFrame = new Frame();
+        mainFrame.setSize(200, 200);
+        mainFrame.setVisible(true);
+        testFailMessage = new StringBuilder();
+        testStrEOL = "Row1" + System.lineSeparator() + "Row2\nRow3";
+    }
+
+    private void testConstructor1() {
+        textField = new TextField(testStrEOL);
+        textField.setSize(200, 100);
+        mainFrame.add(textField);
+        checkTest();
+        mainFrame.remove(textField);
+    }
+
+    private void testConstructor2() {
+        textField = new TextField(30);
+        textField.setSize(200, 100);
+        mainFrame.add(textField);
+        textField.setText(testStrEOL);
+        checkTest();
+        mainFrame.remove(textField);
+    }
+
+    private void testConstructor3() {
+        textField = new TextField(testStrEOL, 30);
+        textField.setSize(200, 100);
+        mainFrame.add(textField);
+        checkTest();
+        mainFrame.remove(textField);
+    }
+
+    private void testSetText() {
+        textField = new TextField();
+        textField.setSize(200, 100);
+        textField.setText(testStrEOL);
+        mainFrame.add(textField);
+        checkTest();
+        mainFrame.remove(textField);
+    }
+
+    private void testDeserialization() {
+        TextField textFieldToSerialize = new TextField(testStrEOL);
+        textFieldToSerialize.setSize(200, 100);
+        mainFrame.add(textFieldToSerialize);
+        try {
+            // Serialize TextField object "textFieldToSerialize".
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutput outStream = new ObjectOutputStream(baos);
+            outStream.writeObject(textFieldToSerialize);
+
+            // Search the text variable data through serialized object stream.
+            byte[] streamedBytes = baos.toByteArray();
+            int foundLoc = 0;
+            for (int i = 0; i < streamedBytes.length; ++i) {
+                if (streamedBytes[i] == expectedString.charAt(0)) {
+                    foundLoc = i;
+                    int j = 1;
+                    for (; j < expectedString.length(); ++j) {
+                        if (streamedBytes[i+j] != expectedString.charAt(j)) {
+                            break;
+                        }
+                    }
+                    if (j == expectedString.length()) {
+                        break;
+                    }
+                }
+                foundLoc = -1;
+            }
+
+            if (foundLoc == -1) {
+                // Could not find text data in serialized object stream.
+                throw new Exception("Could not find text data in serialized "
+                    + "object stream.");
+            }
+            // Replace space character from serialized stream with
+            // EOL character for testing de-serialization.
+            String EOLChar = System.lineSeparator();
+            String newExpectedString = "";
+            for (int i = foundLoc, j = 0; j < expectedString.length(); ++i, ++j) {
+                newExpectedString += (char)(streamedBytes[i]);
+                if (streamedBytes[i] == ' ') {
+                    int k = 0;
+                    for (; k < EOLChar.length(); ++k) {
+                        streamedBytes[i + k] = (byte) EOLChar.charAt(k);
+                    }
+                    i += k-1;
+                    j += k-1;
+                }
+            }
+            // New line character varies with platform,
+            // ex. For windows '\r\n', for linux '\n'.
+            // While replacing space from serialized object stream, the length
+            // of EOL character will affect the expected string as well.
+            expectedString = newExpectedString;
+
+            // De-serialize TextField object stream.
+            ByteArrayInputStream bais = new ByteArrayInputStream(streamedBytes);
+            ObjectInput inStream = new ObjectInputStream(bais);
+            textField = (TextField) inStream.readObject();
+        } catch (Exception ex) {
+            // Serialization or De-serialization failed.
+            // Create textField with empty string to show failure.
+            ex.printStackTrace();
+            textField = new TextField();
+        }
+
+        checkTest();
+        mainFrame.remove(textFieldToSerialize);
+    }
+
+    private void checkTest() {
+        if (!textField.getText().equals(expectedString)) {
+            testFailMessage.append("TestFail line : ");
+            testFailMessage.append(Thread.currentThread().getStackTrace()[2].
+                    getLineNumber());
+            testFailMessage.append(" TextField.getText() : \"");
+            testFailMessage.append(textField.getText());
+            testFailMessage.append("\" does not match expected string : \"");
+            testFailMessage.append(expectedString).append("\"");
+            testFailMessage.append(System.getProperty("line.separator"));
+            testFailCount++;
+            isTestFail = true;
+        }
+    }
+
+    private void checkFailures() {
+        if (isTestFail) {
+            testFailMessage.insert(0, "Test Fail count : " + testFailCount
+                    + System.getProperty("line.separator"));
+            dispose();
+            throw new RuntimeException(testFailMessage.toString());
+        }
+    }
+
+    private void dispose() {
+        if (mainFrame != null) {
+            mainFrame.dispose();
+        }
+    }
+
+    public static void main(String[] args) {
+        EOLTest testEOL = new EOLTest();
+        testEOL.testConstructor1();
+        testEOL.testConstructor2();
+        testEOL.testConstructor3();
+        testEOL.testSetText();
+        testEOL.testDeserialization();
+        testEOL.checkFailures();
+        testEOL.dispose();
+    }
+}
\ No newline at end of file

From 39ce42b41e470034869b79d8ab1fdcde1456477b Mon Sep 17 00:00:00 2001
From: Semyon Sadetsky <ssadetsky@openjdk.org>
Date: Tue, 1 Dec 2015 19:02:50 +0300
Subject: [PATCH 05/62] 8081457: TrayIcon tests fail in OEL 7 only

Reviewed-by: alexsch, serb, azvegint
---
 .../classes/sun/awt/X11/XTrayIconPeer.java    |  1 +
 .../TrayIcon/ActionCommand/ActionCommand.java |  7 +-
 .../ActionEventMask/ActionEventMask.java      |  6 +-
 .../TrayIcon/ModalityTest/ModalityTest.java   | 66 ++++++++++++------
 .../MouseEventMask/MouseEventMaskTest.java    |  4 +-
 .../MouseMovedTest/MouseMovedTest.java        | 12 +++-
 .../FunctionalityCheck.java                   | 69 ++++++++++++-------
 .../FunctionalityCheck/tray.policy            |  2 +
 .../awt/TrayIcon/SystemTrayIconHelper.java    | 42 ++++++++++-
 .../TrayIconEventModifiersTest.java           |  8 ++-
 .../TrayIconEvents/TrayIconEventsTest.java    | 67 ++++++++++++------
 .../TrayIconMouseTest/TrayIconMouseTest.java  | 10 ++-
 .../TrayIconPopup/TrayIconPopupTest.java      |  4 +-
 13 files changed, 217 insertions(+), 81 deletions(-)

diff --git a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java
index eba30a7e2af..20b7a9d7899 100644
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java
@@ -413,6 +413,7 @@ public class XTrayIconPeer implements TrayIconPeer,
     void addListeners() {
         canvas.addMouseListener(eventProxy);
         canvas.addMouseMotionListener(eventProxy);
+        eframe.addMouseListener(eventProxy);
     }
 
     long getWindow() {
diff --git a/jdk/test/java/awt/TrayIcon/ActionCommand/ActionCommand.java b/jdk/test/java/awt/TrayIcon/ActionCommand/ActionCommand.java
index 5c5a17e0dbc..ce5495e3585 100644
--- a/jdk/test/java/awt/TrayIcon/ActionCommand/ActionCommand.java
+++ b/jdk/test/java/awt/TrayIcon/ActionCommand/ActionCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -59,8 +59,11 @@ public class ActionCommand {
                         "and rerun test.");
             } else  if (System.getProperty("os.name").toLowerCase().startsWith("mac")){
                 isMacOS = true;
+            } else if (SystemTrayIconHelper.isOel7()) {
+                System.out.println("OEL 7 doesn't support double click in " +
+                        "systray. Skipped");
+                return;
             }
-
             new ActionCommand().doTest();
         }
     }
diff --git a/jdk/test/java/awt/TrayIcon/ActionEventMask/ActionEventMask.java b/jdk/test/java/awt/TrayIcon/ActionEventMask/ActionEventMask.java
index fb95874eadc..ebafe40e282 100644
--- a/jdk/test/java/awt/TrayIcon/ActionEventMask/ActionEventMask.java
+++ b/jdk/test/java/awt/TrayIcon/ActionEventMask/ActionEventMask.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -66,6 +66,10 @@ public class ActionEventMask {
         } else {
             if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
                 isMacOS = true;
+            } else if (SystemTrayIconHelper.isOel7()) {
+                System.out.println("OEL 7 doesn't support double click in " +
+                        "systray. Skipped");
+                return;
             }
             new ActionEventMask().doTest();
         }
diff --git a/jdk/test/java/awt/TrayIcon/ModalityTest/ModalityTest.java b/jdk/test/java/awt/TrayIcon/ModalityTest/ModalityTest.java
index 2118457ee79..4c0bb1d3c4a 100644
--- a/jdk/test/java/awt/TrayIcon/ModalityTest/ModalityTest.java
+++ b/jdk/test/java/awt/TrayIcon/ModalityTest/ModalityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -35,6 +35,7 @@ import java.awt.image.BufferedImage;
  */
 public class ModalityTest {
 
+    private static boolean isOEL7;
     TrayIcon icon;
     ExtendedRobot robot;
     Dialog d;
@@ -80,7 +81,7 @@ public class ModalityTest {
                         "\"Always show all icons and notifications on the taskbar\" true " +
                         "to avoid this problem. Or change behavior only for Java SE tray " +
                         "icon and rerun test.");
-
+            isOEL7 = SystemTrayIconHelper.isOel7();
             new ModalityTest().doTest();
         }
     }
@@ -225,6 +226,12 @@ public class ModalityTest {
         Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
         if (iconPosition == null)
             throw new RuntimeException("Unable to find the icon location!");
+        if (isOEL7) {
+            // close tray
+            robot.mouseMove(100,100);
+            robot.click(InputEvent.BUTTON1_MASK);
+            robot.waitForIdle(2000);
+        }
 
         if (! d.isVisible())
             throw new RuntimeException("FAIL: The modal dialog is not yet visible");
@@ -232,27 +239,35 @@ public class ModalityTest {
         robot.mouseMove(iconPosition.x, iconPosition.y);
         robot.waitForIdle(2000);
 
-        SystemTrayIconHelper.doubleClick(robot);
+        if(!isOEL7) {
+            SystemTrayIconHelper.doubleClick(robot);
 
-        if (! actionPerformed) {
-            synchronized (actionLock) {
-                try {
-                    actionLock.wait(3000);
-                } catch (Exception e) {
+            if (!actionPerformed) {
+                synchronized (actionLock) {
+                    try {
+                        actionLock.wait(3000);
+                    } catch (Exception e) {
+                    }
                 }
             }
+            if (!actionPerformed)
+                throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
         }
-        if (! actionPerformed)
-            throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
 
         for (int i = 0; i < buttonTypes.length; i++) {
             mousePressed = false;
-            robot.mousePress(buttonTypes[i]);
+            if(isOEL7) {
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+                robot.mouseMove(iconPosition.x, iconPosition.y);
+                robot.click(buttonTypes[i]);
+            } else {
+                robot.mousePress(buttonTypes[i]);
+            }
 
             if (! mousePressed) {
                 synchronized (pressLock) {
                     try {
-                        pressLock.wait(3000);
+                        pressLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -264,12 +279,18 @@ public class ModalityTest {
 
             mouseReleased = false;
             mouseClicked = false;
-            robot.mouseRelease(buttonTypes[i]);
+            if(isOEL7) {
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+                robot.mouseMove(iconPosition.x, iconPosition.y);
+                robot.click(buttonTypes[i]);
+            } else {
+                robot.mouseRelease(buttonTypes[i]);
+            }
 
             if (! mouseReleased) {
                 synchronized (releaseLock) {
                     try {
-                        releaseLock.wait(3000);
+                        releaseLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -281,7 +302,7 @@ public class ModalityTest {
             if (! mouseClicked) {
                 synchronized (clickLock) {
                     try {
-                        clickLock.wait(3000);
+                        clickLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -290,13 +311,14 @@ public class ModalityTest {
                 throw new RuntimeException("FAIL: mouseClicked not triggered when " +
                         buttonNames[i] + " pressed & released");
         }
+        if (!isOEL7) {
+            mouseMoved = false;
+            robot.mouseMove(iconPosition.x, iconPosition.y);
+            robot.glide(iconPosition.x + 100, iconPosition.y);
 
-        mouseMoved = false;
-        robot.mouseMove(iconPosition.x, iconPosition.y);
-        robot.glide(iconPosition.x + 100, iconPosition.y);
-
-        if (! mouseMoved)
-            if (! SystemTrayIconHelper.skip(0) )
-                throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
+            if (!mouseMoved)
+                if (!SystemTrayIconHelper.skip(0))
+                    throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
+        }
     }
 }
diff --git a/jdk/test/java/awt/TrayIcon/MouseEventMask/MouseEventMaskTest.java b/jdk/test/java/awt/TrayIcon/MouseEventMask/MouseEventMaskTest.java
index e6c194ec69c..113ec7e9d71 100644
--- a/jdk/test/java/awt/TrayIcon/MouseEventMask/MouseEventMaskTest.java
+++ b/jdk/test/java/awt/TrayIcon/MouseEventMask/MouseEventMaskTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -71,6 +71,8 @@ public class MouseEventMaskTest {
                         "\"Always show all icons and notifications on the taskbar\" true " +
                         "to avoid this problem. Or change behavior only for Java SE tray " +
                         "icon and rerun test.");
+            } else if (SystemTrayIconHelper.isOel7()) {
+                return;
             }
             new MouseEventMaskTest().doTest();
         }
diff --git a/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java b/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java
index 04d91f23859..d6e6d760f79 100644
--- a/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java
+++ b/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -31,7 +31,7 @@ import java.awt.image.BufferedImage;
  * @summary Check for mouseMoved event for java.awt.TrayIcon
  * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
  * @library ../../../../lib/testlibrary
- * @build ExtendedRobot
+ * @build ExtendedRobot SystemTrayIconHelper
  * @run main MouseMovedTest
  */
 
@@ -39,6 +39,14 @@ public class MouseMovedTest {
     static volatile boolean moved;
 
     public static void main(String[] args) throws Exception {
+        if (!SystemTray.isSupported()) {
+            return;
+        }
+
+        if (SystemTrayIconHelper.isOel7()) {
+            return;
+        }
+
         moved = false;
 
         TrayIcon icon = new TrayIcon(new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB), "Test icon");
diff --git a/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/FunctionalityCheck.java b/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/FunctionalityCheck.java
index 5918ac3dfc0..c9d2eade8c3 100644
--- a/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/FunctionalityCheck.java
+++ b/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/FunctionalityCheck.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -51,6 +51,7 @@ public class FunctionalityCheck {
     boolean mouseReleased = false;
     boolean mouseClicked = false;
     boolean mouseMoved = false;
+    static boolean isOEL7;
 
     static final int[] buttonTypes = {
         InputEvent.BUTTON1_MASK,
@@ -69,6 +70,7 @@ public class FunctionalityCheck {
             System.out.println("SystemTray not supported on the platform under test. " +
                                "Marking the test passed");
         } else {
+            isOEL7 = SystemTrayIconHelper.isOel7();
             new FunctionalityCheck().doTest();
         }
     }
@@ -188,31 +190,44 @@ public class FunctionalityCheck {
         Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
         if (iconPosition == null)
             throw new RuntimeException("Unable to find the icon location!");
+        if (isOEL7) {
+            // close tray
+            robot.mouseMove(100,100);
+            robot.click(InputEvent.BUTTON1_MASK);
+            robot.waitForIdle(2000);
+        }
 
         robot.mouseMove(iconPosition.x, iconPosition.y);
-        robot.waitForIdle(2000);
+        robot.waitForIdle();
+        if(!isOEL7) {
+            SystemTrayIconHelper.doubleClick(robot);
 
-        SystemTrayIconHelper.doubleClick(robot);
-
-        if (! actionPerformed) {
-            synchronized (actionLock) {
-                try {
-                    actionLock.wait(3000);
-                } catch (Exception e) {
+            if (!actionPerformed) {
+                synchronized (actionLock) {
+                    try {
+                        actionLock.wait(3000);
+                    } catch (Exception e) {
+                    }
                 }
             }
+            if (!actionPerformed)
+                throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
         }
-        if (! actionPerformed)
-            throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
 
         for (int i = 0; i < buttonTypes.length; i++) {
             mousePressed = false;
-            robot.mousePress(buttonTypes[i]);
+            if(isOEL7) {
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+                robot.mouseMove(iconPosition.x, iconPosition.y);
+                robot.click(buttonTypes[i]);
+            } else {
+                robot.mousePress(buttonTypes[i]);
+            }
 
             if (! mousePressed) {
                 synchronized (pressLock) {
                     try {
-                        pressLock.wait(3000);
+                        pressLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -224,12 +239,17 @@ public class FunctionalityCheck {
 
             mouseReleased = false;
             mouseClicked = false;
-            robot.mouseRelease(buttonTypes[i]);
-
+            if(isOEL7) {
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+                robot.mouseMove(iconPosition.x, iconPosition.y);
+                robot.click(buttonTypes[i]);
+            } else {
+                robot.mouseRelease(buttonTypes[i]);
+            }
             if (! mouseReleased) {
                 synchronized (releaseLock) {
                     try {
-                        releaseLock.wait(3000);
+                        releaseLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -242,7 +262,7 @@ public class FunctionalityCheck {
             if (! mouseClicked) {
                 synchronized (clickLock) {
                     try {
-                        clickLock.wait(3000);
+                        clickLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -251,13 +271,14 @@ public class FunctionalityCheck {
                 throw new RuntimeException("FAIL: mouseClicked not triggered when " +
                         buttonNames[i] + " pressed & released");
         }
+        if(!isOEL7) {
+            mouseMoved = false;
+            robot.mouseMove(iconPosition.x + 100, iconPosition.y);
+            robot.glide(iconPosition.x, iconPosition.y);
 
-        mouseMoved = false;
-        robot.mouseMove(iconPosition.x + 100, iconPosition.y);
-        robot.glide(iconPosition.x, iconPosition.y);
-
-        if (! mouseMoved)
-            if (! SystemTrayIconHelper.skip(0) )
-                throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
+            if (!mouseMoved)
+                if (!SystemTrayIconHelper.skip(0))
+                    throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
+        }
     }
 }
diff --git a/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/tray.policy b/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/tray.policy
index 845bfb8d80b..c2c76434cd3 100644
--- a/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/tray.policy
+++ b/jdk/test/java/awt/TrayIcon/SecurityCheck/FunctionalityCheck/tray.policy
@@ -5,6 +5,7 @@ grant {
   permission java.util.PropertyPermission "resultsDir", "read";
   permission java.util.PropertyPermission "user.home", "read";
   permission java.util.PropertyPermission "os.name", "read";
+  permission java.util.PropertyPermission "os.version", "read";
   permission java.awt.AWTPermission "accessEventQueue";
   permission java.lang.RuntimePermission "setIO";
   permission java.lang.RuntimePermission "accessDeclaredMembers";
@@ -17,5 +18,6 @@ grant {
   permission java.util.PropertyPermission "java.class.path", "read";
   permission java.awt.AWTPermission "readDisplayPixels";
   permission java.awt.AWTPermission "watchMousePointer";
+
 };
 
diff --git a/jdk/test/java/awt/TrayIcon/SystemTrayIconHelper.java b/jdk/test/java/awt/TrayIcon/SystemTrayIconHelper.java
index a8f6e2f7cf5..cb36b8fdba3 100644
--- a/jdk/test/java/awt/TrayIcon/SystemTrayIconHelper.java
+++ b/jdk/test/java/awt/TrayIcon/SystemTrayIconHelper.java
@@ -66,7 +66,9 @@ public class SystemTrayIconHelper {
                 for (int x = (int) (screenSize.getWidth()-width); x > 0; x--) {
                     for (int y = (int) (screenSize.getHeight()-height); y > (screenSize.getHeight()-50); y--) {
                         if (imagesEquals(((BufferedImage)icon.getImage()).getSubimage(0, 0, width, height), screen.getSubimage(x, y, width, height))) {
-                            return new Point(x+5, y+5);
+                            Point point = new Point(x + 5, y + 5);
+                            System.out.println("Icon location " + point);
+                            return point;
                         }
                     }
                 }
@@ -91,6 +93,7 @@ public class SystemTrayIconHelper {
                 point2d = (Point2D)m_getLocation.invoke(peer, new Object[]{model});
                 Point po = new Point((int)(point2d.getX()), (int)(point2d.getY()));
                 po.translate(10, -5);
+                System.out.println("Icon location " + po);
                 return po;
             }catch(Exception e) {
                 e.printStackTrace();
@@ -101,12 +104,15 @@ public class SystemTrayIconHelper {
                 // sun.awt.X11.XTrayIconPeer
                 Field f_peer = getField(java.awt.TrayIcon.class, "peer");
 
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+
                 Object peer = f_peer.get(icon);
                 Method m_getLOS = peer.getClass().getDeclaredMethod(
                         "getLocationOnScreen", new Class[]{});
                 m_getLOS.setAccessible(true);
                 Point point = (Point)m_getLOS.invoke(peer, new Object[]{});
                 point.translate(5, 5);
+                System.out.println("Icon location " + point);
                 return point;
             } catch (Exception e) {
                 e.printStackTrace();
@@ -169,4 +175,38 @@ public class SystemTrayIconHelper {
         }
         return false;
     }
+
+    public static boolean openTrayIfNeeded(Robot robot) {
+        String sysv = System.getProperty("os.version");
+        System.out.println("System version is " + sysv);
+        //Additional step to raise the system try in Gnome 3 in OEL 7
+        if(isOel7()) {
+            System.out.println("OEL 7 detected");
+            GraphicsConfiguration gc = GraphicsEnvironment.
+                    getLocalGraphicsEnvironment().getDefaultScreenDevice().
+                    getDefaultConfiguration();
+            Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
+            if(insets.bottom > 0) {
+                Dimension screenSize = Toolkit.getDefaultToolkit()
+                        .getScreenSize();
+                robot.mouseMove(screenSize.width - insets.bottom / 2,
+                        screenSize.height - insets.bottom / 2);
+                robot.delay(50);
+                robot.mousePress(InputEvent.BUTTON1_MASK);
+                robot.delay(50);
+                robot.mouseRelease(InputEvent.BUTTON1_MASK);
+                robot.waitForIdle();
+                robot.delay(1000);
+                System.out.println("Tray is opened");
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isOel7() {
+        return System.getProperty("os.name").toLowerCase()
+                .contains("linux") && System.getProperty("os.version")
+                .toLowerCase().contains("el7");
+    }
 }
diff --git a/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java b/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java
index 9cdce634a92..b80db75b510 100644
--- a/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java
+++ b/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -121,6 +121,12 @@ public class TrayIconEventModifiersTest {
                 };
             }
 
+            if (SystemTrayIconHelper.isOel7()) {
+                System.out.println("OEL 7 doesn't support click modifiers in " +
+                        "systray. Skipped");
+                return;
+            }
+
             new TrayIconEventModifiersTest().doTest();
         }
     }
diff --git a/jdk/test/java/awt/TrayIcon/TrayIconEvents/TrayIconEventsTest.java b/jdk/test/java/awt/TrayIcon/TrayIconEvents/TrayIconEventsTest.java
index c7c79ea6570..275e51065ca 100644
--- a/jdk/test/java/awt/TrayIcon/TrayIconEvents/TrayIconEventsTest.java
+++ b/jdk/test/java/awt/TrayIcon/TrayIconEvents/TrayIconEventsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -37,6 +37,7 @@ import java.awt.image.BufferedImage;
 
 public class TrayIconEventsTest {
 
+    private static boolean isOEL7;
     TrayIcon icon;
     ExtendedRobot robot;
 
@@ -77,6 +78,7 @@ public class TrayIconEventsTest {
                         "\"Always show all icons and notifications on the taskbar\" true " +
                         "to avoid this problem. Or change behavior only for Java SE " +
                         "tray icon.");
+            isOEL7 = SystemTrayIconHelper.isOel7();
             new TrayIconEventsTest().doTest();
         }
     }
@@ -195,31 +197,44 @@ public class TrayIconEventsTest {
         Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
         if (iconPosition == null)
             throw new RuntimeException("Unable to find the icon location!");
+        if (isOEL7) {
+            // close tray
+            robot.mouseMove(100,100);
+            robot.click(InputEvent.BUTTON1_MASK);
+            robot.waitForIdle(2000);
+        }
 
         robot.mouseMove(iconPosition.x, iconPosition.y);
-        robot.waitForIdle(2000);
+        robot.waitForIdle();
+        if(!isOEL7) {
+            SystemTrayIconHelper.doubleClick(robot);
 
-        SystemTrayIconHelper.doubleClick(robot);
-
-        if (! actionPerformed) {
-            synchronized (actionLock) {
-                try {
-                    actionLock.wait(10000);
-                } catch (Exception e) {
+            if (!actionPerformed) {
+                synchronized (actionLock) {
+                    try {
+                        actionLock.wait(10000);
+                    } catch (Exception e) {
+                    }
                 }
             }
+            if (!actionPerformed)
+                throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
         }
-        if (! actionPerformed)
-            throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
 
         for (int i = 0; i < buttonTypes.length; i++) {
             mousePressed = false;
-            robot.mousePress(buttonTypes[i]);
+            if(isOEL7) {
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+                robot.mouseMove(iconPosition.x, iconPosition.y);
+                robot.click(buttonTypes[i]);
+            } else {
+                robot.mousePress(buttonTypes[i]);
+            }
 
             if (! mousePressed) {
                 synchronized (pressLock) {
                     try {
-                        pressLock.wait(3000);
+                        pressLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -231,12 +246,18 @@ public class TrayIconEventsTest {
 
             mouseReleased = false;
             mouseClicked = false;
-            robot.mouseRelease(buttonTypes[i]);
+            if(isOEL7) {
+                SystemTrayIconHelper.openTrayIfNeeded(robot);
+                robot.mouseMove(iconPosition.x, iconPosition.y);
+                robot.click(buttonTypes[i]);
+            } else {
+                robot.mouseRelease(buttonTypes[i]);
+            }
 
             if (! mouseReleased) {
                 synchronized (releaseLock) {
                     try {
-                        releaseLock.wait(3000);
+                        releaseLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -248,7 +269,7 @@ public class TrayIconEventsTest {
             if (! mouseClicked) {
                 synchronized (clickLock) {
                     try {
-                        clickLock.wait(3000);
+                        clickLock.wait(6000);
                     } catch (Exception e) {
                     }
                 }
@@ -258,12 +279,14 @@ public class TrayIconEventsTest {
                         buttonNames[i] + " pressed & released");
         }
 
-        mouseMoved = false;
-        robot.mouseMove(iconPosition.x + 100, iconPosition.y);
-        robot.glide(iconPosition.x, iconPosition.y);
+        if (!isOEL7) {
+            mouseMoved = false;
+            robot.mouseMove(iconPosition.x + 100, iconPosition.y);
+            robot.glide(iconPosition.x, iconPosition.y);
 
-        if (! mouseMoved)
-            if (! SystemTrayIconHelper.skip(0) )
-                throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
+            if (!mouseMoved)
+                if (!SystemTrayIconHelper.skip(0))
+                    throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
+        }
     }
 }
diff --git a/jdk/test/java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java b/jdk/test/java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java
index 124ceba5399..b8f6a69d30c 100644
--- a/jdk/test/java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java
+++ b/jdk/test/java/awt/TrayIcon/TrayIconMouseTest/TrayIconMouseTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -66,6 +66,10 @@ public class TrayIconMouseTest {
         } else {
             if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
                 isMacOS = true;
+            } else if (SystemTrayIconHelper.isOel7()) {
+                System.out.println("OEL 7 doesn't support double click in " +
+                        "systray. Skipped");
+                return;
             }
             new TrayIconMouseTest().doTest();
         }
@@ -108,7 +112,7 @@ public class TrayIconMouseTest {
         for (int i = 0; i < buttonTypes.length; i++) {
             actionPerformed = false;
             robot.click(buttonTypes[i]);
-            robot.waitForIdle(2000);
+            robot.waitForIdle(6000);
 
             if (isMacOS && actionPerformed && i == 2) {
 
@@ -155,7 +159,7 @@ public class TrayIconMouseTest {
                     if (! actionPerformed) {
                         synchronized (actionLock) {
                             try {
-                                actionLock.wait(3000);
+                                actionLock.wait(6000);
                             } catch (Exception e) {
                             }
                         }
diff --git a/jdk/test/java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java b/jdk/test/java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java
index f866cc18aa0..a81e516bd0e 100644
--- a/jdk/test/java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java
+++ b/jdk/test/java/awt/TrayIcon/TrayIconPopup/TrayIconPopupTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -127,7 +127,7 @@ public class TrayIconPopupTest {
         robot.mousePress(InputEvent.BUTTON3_MASK);
         robot.delay(50);
         robot.mouseRelease(InputEvent.BUTTON3_MASK);
-        robot.delay(1000);
+        robot.delay(6000);
 
         robot.mouseMove(window.getLocation().x + 10, window.getLocation().y + 10);
         robot.mousePress(InputEvent.BUTTON3_MASK);

From afabb1b2c0e38ad2f124489faab54456d85b9c96 Mon Sep 17 00:00:00 2001
From: Semyon Sadetsky <ssadetsky@openjdk.org>
Date: Tue, 1 Dec 2015 19:07:45 +0300
Subject: [PATCH 06/62] 8068228: Test
 closed/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest fails with
 GTKLookAndFeel

Reviewed-by: ssadetsky, arapte
---
 .../MaximizedFrameTest.html                   |  42 ----
 .../MaximizedFrameTest.java                   | 200 +++++++++++-------
 2 files changed, 129 insertions(+), 113 deletions(-)
 delete mode 100644 jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.html

diff --git a/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.html b/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.html
deleted file mode 100644
index 97781dc7643..00000000000
--- a/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.html
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-<!--
-  @test
-  @bug 6176814
-  @summary Metalworks frame maximizes after the move
-  @author Andrei.Dmitriev.Com area=Event
-  @run applet MaximizedFrameTest.html
-  -->
-<head>
-<title>  </title>
-</head>
-<body>
-
-<h1>bug 6176814<br>Bug ID:  6176814 </h1>
-
-<p> This is an AUTOMATIC test, simply wait for completion </p>
-
-<APPLET CODE="MaximizedFrameTest.class" WIDTH=200 HEIGHT=200></APPLET>
-</body>
-</html>
diff --git a/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.java b/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.java
index c2ee806bb19..e519d3dad19 100644
--- a/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.java
+++ b/jdk/test/java/awt/Mouse/MaximizedFrameTest/MaximizedFrameTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015 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
@@ -22,91 +22,149 @@
  */
 
 /*
-  test
-  @bug 6176814
-  @summary  Metalworks frame maximizes after the move
-  @author Andrei.Dmitriev area=Event
-  @run applet MaximizedFrameTest.html
-*/
+ @test
+ @bug 6176814 8132766
+ @summary Metalworks frame maximizes after the move
+ @run main MaximizedFrameTest
+ */
 
-import java.applet.Applet;
-import javax.swing.*;
-import java.awt.event.*;
-import java.awt.*;
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
 
-public class MaximizedFrameTest extends Applet
-{
-    final int ITERATIONS_COUNT = 20;
-    Robot robot;
-    Point framePosition;
-    Point newFrameLocation;
-    JFrame  frame;
-    Rectangle gcBounds;
-    public static Object LOCK = new Object();
+public class MaximizedFrameTest {
 
-    public void init()
-    {
-        String[] instructions =
-        {
-            "This is an AUTOMATIC test",
-            "simply wait until it is done"
-        };
+    final static int ITERATIONS_COUNT = 5;
+    private static JFrame frame;
+    private static Point tempMousePosition;
+    private static Component titleComponent;
+
+    public void init() {
         JFrame.setDefaultLookAndFeelDecorated(true);
+
+        try {
+            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+        } catch (ClassNotFoundException | InstantiationException |
+                IllegalAccessException | UnsupportedLookAndFeelException ex) {
+            throw new RuntimeException("Test Failed. MetalLookAndFeel not set "
+                    + "for frame");
+        }
+
         frame = new JFrame("JFrame Maximization Test");
         frame.pack();
         frame.setSize(450, 260);
-    }//End  init()
-
-    public void start ()
-    {
         frame.setVisible(true);
-        validate();
-        JLayeredPane lPane = frame.getLayeredPane();
-        //        System.out.println("JFrame's LayeredPane " + lPane );
-        Component titleComponent = null;
-        boolean titleFound = false;
-        for (int j=0; j < lPane.getComponentsInLayer(JLayeredPane.FRAME_CONTENT_LAYER.intValue()).length; j++){
-            titleComponent = lPane.getComponentsInLayer(JLayeredPane.FRAME_CONTENT_LAYER.intValue())[j];
-            if (titleComponent.getClass().getName().equals("javax.swing.plaf.metal.MetalTitlePane")){
-                titleFound = true;
-                break;
+    }
+
+    public void getTitleComponent() throws Exception {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                JLayeredPane lPane = frame.getLayeredPane();
+                boolean titleFound = false;
+
+                for (int j = 0; j < lPane.getComponentsInLayer(
+                    JLayeredPane.FRAME_CONTENT_LAYER.intValue()).length; j++) {
+
+                    titleComponent = lPane.getComponentsInLayer(
+                    JLayeredPane.FRAME_CONTENT_LAYER.intValue())[j];
+
+                    if (titleComponent.getClass().getName().equals(
+                        "javax.swing.plaf.metal.MetalTitlePane")) {
+
+                        titleFound = true;
+                        break;
+                    }
+                }
+
+                if (!titleFound) {
+                    try {
+                        dispose();
+                    } catch (Exception ex) {
+                        Logger.getLogger(MaximizedFrameTest.class.getName())
+                                .log(Level.SEVERE, null, ex);
+                    }
+                    throw new RuntimeException("Test Failed. Unable to "
+                            + "determine title component");
+                }
             }
-        }
-        if ( !titleFound ){
-            throw new RuntimeException("Test Failed. Unable to determine title's size.");
-        }
-        //--------------------------------
-        // it is sufficient to get maximized Frame only once.
-        Point tempMousePosition;
-        framePosition = frame.getLocationOnScreen();
+        });
+    }
+
+    public void doMaximizeFrameTest() throws Exception {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                Point framePosition = frame.getLocationOnScreen();
+
+                tempMousePosition = new Point(framePosition.x
+                        + frame.getWidth() / 2, framePosition.y
+                                + titleComponent.getHeight() / 2);
+            }
+        });
+
         try {
-            robot = new Robot();
-            tempMousePosition = new Point(framePosition.x +
-                                          frame.getWidth()/2,
-                                          framePosition.y +
-                                          titleComponent.getHeight()/2);
+            Robot robot = new Robot();
             robot.mouseMove(tempMousePosition.x, tempMousePosition.y);
-            for (int iteration=0; iteration < ITERATIONS_COUNT; iteration++){
+            robot.waitForIdle();
+
+            for (int iteration = 0; iteration < ITERATIONS_COUNT; iteration++) {
                 robot.mousePress(InputEvent.BUTTON1_MASK);
-                gcBounds =
-                    GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getConfigurations()[0].getBounds();
-                //Moving a mouse pointer less than a few pixels
-                //leads to rising a double click event.
-                //We have to use exceeded the AWT_MULTICLICK_SMUDGE
-                //const value (which is 4 by default on GNOME) to test that.
+                robot.waitForIdle();
+
+                // Moving a mouse pointer less than a few pixels
+                // leads to rising a double click event.
+                // We have to use exceeded the AWT_MULTICLICK_SMUDGE
+                // const value (which is 4 by default on GNOME) to test that.
                 tempMousePosition.x += 5;
                 robot.mouseMove(tempMousePosition.x, tempMousePosition.y);
-                robot.delay(70);
+                robot.waitForIdle();
                 robot.mouseRelease(InputEvent.BUTTON1_MASK);
-                if ( frame.getExtendedState() != 0 ){
-                    throw new RuntimeException ("Test failed. JFrame was maximized. ExtendedState is : "+frame.getExtendedState());
-                }
-                robot.delay(500);
-            } //for iteration
+                robot.waitForIdle();
 
-            }catch(AWTException e) {
-                throw new RuntimeException("Test Failed. AWTException thrown.");
+                if (frame.getExtendedState() != 0) {
+                    dispose();
+                    throw new RuntimeException("Test failed. JFrame was "
+                            + "maximized. ExtendedState is : "
+                            + frame.getExtendedState());
+                }
             }
+        } catch (AWTException e) {
+            dispose();
+            throw new RuntimeException("Test Failed. AWTException thrown.");
+        }
         System.out.println("Test passed.");
-    }// start()
-}// class
+    }
+
+    private void dispose() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                if (null != frame) {
+                    frame.dispose();
+                }
+            }
+        });
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        MaximizedFrameTest maximizedFrameTest = new MaximizedFrameTest();
+        maximizedFrameTest.init();
+        maximizedFrameTest.getTitleComponent();
+        maximizedFrameTest.doMaximizeFrameTest();
+        maximizedFrameTest.dispose();
+    }
+}

From 39b6389c6da36985bead96afefc1c68a5fcd2690 Mon Sep 17 00:00:00 2001
From: Semyon Sadetsky <ssadetsky@openjdk.org>
Date: Tue, 1 Dec 2015 19:21:40 +0300
Subject: [PATCH 07/62] 8030702: Deadlock between subclass of AbstractDocument
 and UndoManager

Reviewed-by: alexsch, azvegint
---
 .../javax/swing/text/AbstractDocument.java    |  88 +++++++++++++
 .../classes/javax/swing/undo/UndoManager.java | 119 +++++++++++++----
 .../swing/text/UndoableEditLockSupport.java   |  43 ++++++
 .../AbstractDocumentUndoConcurrentTest.java   | 122 ++++++++++++++++++
 4 files changed, 346 insertions(+), 26 deletions(-)
 create mode 100644 jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java
 create mode 100644 jdk/test/javax/swing/undo/UndoManager/AbstractDocumentUndoConcurrentTest.java

diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java
index 2b87618abd9..b965ccfcbc0 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractDocument.java
@@ -36,6 +36,7 @@ import javax.swing.tree.TreeNode;
 
 import sun.font.BidiUtils;
 import sun.swing.SwingUtilities2;
+import sun.swing.text.UndoableEditLockSupport;
 
 /**
  * An implementation of the document interface to serve as a
@@ -275,6 +276,11 @@ public abstract class AbstractDocument implements Document, Serializable {
      * @see EventListenerList
      */
     protected void fireUndoableEditUpdate(UndoableEditEvent e) {
+        if (e.getEdit() instanceof DefaultDocumentEvent) {
+            e = new UndoableEditEvent(e.getSource(),
+                    new DefaultDocumentEventUndoableWrapper(
+                            (DefaultDocumentEvent)e.getEdit()));
+        }
         // Guaranteed to return a non-null array
         Object[] listeners = listenerList.getListenerList();
         // Process the listeners last to first, notifying
@@ -2952,6 +2958,88 @@ public abstract class AbstractDocument implements Document, Serializable {
 
     }
 
+    static class DefaultDocumentEventUndoableWrapper implements
+            UndoableEdit, UndoableEditLockSupport
+    {
+        final DefaultDocumentEvent dde;
+        public DefaultDocumentEventUndoableWrapper(DefaultDocumentEvent dde) {
+            this.dde = dde;
+        }
+
+        @Override
+        public void undo() throws CannotUndoException {
+            dde.undo();
+        }
+
+        @Override
+        public boolean canUndo() {
+            return dde.canUndo();
+        }
+
+        @Override
+        public void redo() throws CannotRedoException {
+            dde.redo();
+        }
+
+        @Override
+        public boolean canRedo() {
+            return dde.canRedo();
+        }
+
+        @Override
+        public void die() {
+            dde.die();
+        }
+
+        @Override
+        public boolean addEdit(UndoableEdit anEdit) {
+            return dde.addEdit(anEdit);
+        }
+
+        @Override
+        public boolean replaceEdit(UndoableEdit anEdit) {
+            return dde.replaceEdit(anEdit);
+        }
+
+        @Override
+        public boolean isSignificant() {
+            return dde.isSignificant();
+        }
+
+        @Override
+        public String getPresentationName() {
+            return dde.getPresentationName();
+        }
+
+        @Override
+        public String getUndoPresentationName() {
+            return dde.getUndoPresentationName();
+        }
+
+        @Override
+        public String getRedoPresentationName() {
+            return dde.getRedoPresentationName();
+        }
+
+        /**
+         * {@inheritDoc}
+         * @since 1.9
+         */
+        @Override
+        public void lockEdit() {
+            ((AbstractDocument)dde.getDocument()).writeLock();
+        }
+
+        /**
+         * {@inheritDoc}
+         * @since 1.9
+         */
+        @Override
+        public void unlockEdit() {
+            ((AbstractDocument)dde.getDocument()).writeUnlock();
+        }
+    }
+
     /**
      * This event used when firing document changes while Undo/Redo
      * operations. It just wraps DefaultDocumentEvent and delegates
diff --git a/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java b/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java
index 782dd3b3356..cb85826e611 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/undo/UndoManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -28,6 +28,7 @@ package javax.swing.undo;
 import javax.swing.event.*;
 import javax.swing.UIManager;
 import java.util.*;
+import sun.swing.text.UndoableEditLockSupport;
 
 /**
  * {@code UndoManager} manages a list of {@code UndoableEdits},
@@ -134,6 +135,11 @@ import java.util.*;
  */
 @SuppressWarnings("serial") // Same-version serialization only
 public class UndoManager extends CompoundEdit implements UndoableEditListener {
+    private enum Action {
+        UNDO,
+        REDO,
+        ANY
+    }
     int indexOfNextAdd;
     int limit;
 
@@ -369,13 +375,8 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener {
      * @throws CannotRedoException if one of the edits throws
      *         <code>CannotRedoException</code>
      */
-    public synchronized void undoOrRedo() throws CannotRedoException,
-        CannotUndoException {
-        if (indexOfNextAdd == edits.size()) {
-            undo();
-        } else {
-            redo();
-        }
+    public void undoOrRedo() throws CannotRedoException, CannotUndoException {
+        tryUndoOrRedo(Action.ANY);
     }
 
     /**
@@ -407,16 +408,8 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener {
      * @see #canUndo
      * @see #editToBeUndone
      */
-    public synchronized void undo() throws CannotUndoException {
-        if (inProgress) {
-            UndoableEdit edit = editToBeUndone();
-            if (edit == null) {
-                throw new CannotUndoException();
-            }
-            undoTo(edit);
-        } else {
-            super.undo();
-        }
+    public void undo() throws CannotUndoException {
+        tryUndoOrRedo(Action.UNDO);
     }
 
     /**
@@ -452,16 +445,90 @@ public class UndoManager extends CompoundEdit implements UndoableEditListener {
      * @see #canRedo
      * @see #editToBeRedone
      */
-    public synchronized void redo() throws CannotRedoException {
-        if (inProgress) {
-            UndoableEdit edit = editToBeRedone();
-            if (edit == null) {
-                throw new CannotRedoException();
+    public void redo() throws CannotRedoException {
+        tryUndoOrRedo(Action.REDO);
+    }
+
+    private void tryUndoOrRedo(Action action) {
+        UndoableEditLockSupport lockSupport = null;
+        boolean undo;
+        synchronized (this) {
+            if (action == Action.ANY) {
+                undo = indexOfNextAdd == edits.size();
+            } else {
+                undo = action == Action.UNDO;
+            }
+            if (inProgress) {
+                UndoableEdit edit = undo ? editToBeUndone() : editToBeRedone();
+                if (edit == null) {
+                    throw undo ? new CannotUndoException() :
+                            new CannotRedoException();
+                }
+                lockSupport = getEditLockSupport(edit);
+                if (lockSupport == null) {
+                    if (undo) {
+                        undoTo(edit);
+                    } else {
+                        redoTo(edit);
+                    }
+                    return;
+                }
+            } else {
+                if (undo) {
+                    super.undo();
+                } else {
+                    super.redo();
+                }
+                return;
             }
-            redoTo(edit);
-        } else {
-            super.redo();
         }
+        // the edit synchronization is required
+        while (true) {
+            lockSupport.lockEdit();
+            UndoableEditLockSupport editLockSupport = null;
+            try {
+                synchronized (this) {
+                    if (action == Action.ANY) {
+                        undo = indexOfNextAdd == edits.size();
+                    }
+                    if (inProgress) {
+                        UndoableEdit edit = undo ? editToBeUndone() :
+                                editToBeRedone();
+                        if (edit == null) {
+                            throw undo ? new CannotUndoException() :
+                                    new CannotRedoException();
+                        }
+                        editLockSupport = getEditLockSupport(edit);
+                        if (editLockSupport == null ||
+                                editLockSupport == lockSupport) {
+                            if (undo) {
+                                undoTo(edit);
+                            } else {
+                                redoTo(edit);
+                            }
+                            return;
+                        }
+                    } else {
+                        if (undo) {
+                            super.undo();
+                        } else {
+                            super.redo();
+                        }
+                        return;
+                    }
+                }
+            } finally {
+                if (lockSupport != null) {
+                    lockSupport.unlockEdit();
+                }
+                lockSupport = editLockSupport;
+            }
+        }
+    }
+
+    private UndoableEditLockSupport getEditLockSupport(UndoableEdit anEdit) {
+        return anEdit instanceof UndoableEditLockSupport ?
+                (UndoableEditLockSupport)anEdit : null;
     }
 
     /**
diff --git a/jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java b/jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java
new file mode 100644
index 00000000000..43440da0dc8
--- /dev/null
+++ b/jdk/src/java.desktop/share/classes/sun/swing/text/UndoableEditLockSupport.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.swing.text;
+
+import javax.swing.undo.UndoableEdit;
+
+/**
+ * UndoableEdit support for undo/redo actions synchronization
+ * @since 1.9
+ */
+public interface UndoableEditLockSupport extends UndoableEdit {
+    /**
+     * lock the UndoableEdit for threadsafe undo/redo
+     */
+    void lockEdit();
+
+    /**
+     * unlock the UndoableEdit
+     */
+    void unlockEdit();
+}
diff --git a/jdk/test/javax/swing/undo/UndoManager/AbstractDocumentUndoConcurrentTest.java b/jdk/test/javax/swing/undo/UndoManager/AbstractDocumentUndoConcurrentTest.java
new file mode 100644
index 00000000000..30c48df47f8
--- /dev/null
+++ b/jdk/test/javax/swing/undo/UndoManager/AbstractDocumentUndoConcurrentTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+   @bug 8030702
+   @summary Deadlock between subclass of AbstractDocument and UndoManager
+   @author Semyon Sadetsky
+  */
+
+import javax.swing.text.PlainDocument;
+import javax.swing.text.StringContent;
+import javax.swing.undo.UndoManager;
+import java.text.DecimalFormat;
+import java.text.Format;
+import java.util.concurrent.CyclicBarrier;
+
+public class AbstractDocumentUndoConcurrentTest {
+    static  CyclicBarrier barrier = new CyclicBarrier(3);
+
+    private static PlainDocument doc1;
+    private static PlainDocument doc2;
+    private static Format format1 = new DecimalFormat("<Test1 0000>");
+    private static Format format2 = new DecimalFormat("<Test22 0000>");
+
+    public static void main(String[] args) throws Exception {
+        test();
+        System.out.println(doc1.getText(0, doc1.getLength()));
+        System.out.println(doc2.getText(0, doc2.getLength()));
+        System.out.println("ok");
+    }
+
+    private static void test() throws Exception {
+        doc1 = new PlainDocument(new StringContent());
+        final UndoManager undoManager = new UndoManager();
+
+        doc1.addUndoableEditListener(undoManager);
+        doc1.insertString(0, "<Test1 XXXX>", null);
+
+        doc2 = new PlainDocument(new StringContent());
+
+        doc2.addUndoableEditListener(undoManager);
+        doc2.insertString(0, "<Test22 XXXX>", null);
+
+        Thread t1 = new Thread("Thread doc1") {
+            @Override
+            public void run() {
+                try {
+                    barrier.await();
+                    for (int i = 0; i < 1000; i++) {
+                        doc1.insertString(0, format1.format(i), null);
+                        if(doc1.getLength() > 100) doc1.remove(0, 12);
+                    }
+
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                System.out.println("t1 done");
+            }
+        };
+
+        Thread t2 = new Thread("Thread doc2") {
+            @Override
+            public void run() {
+                try {
+                    barrier.await();
+                    for (int i = 0; i < 1000; i++) {
+                        doc2.insertString(0, format2.format(i), null);
+                        if(doc2.getLength() > 100) doc2.remove(0, 13);
+                    }
+
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                System.out.println("t2 done");
+            }
+        };
+
+        Thread t3 = new Thread("Undo/Redo Thread") {
+            @Override
+            public void run() {
+                try {
+                    barrier.await();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                for (int i = 0; i < 1000; i++) {
+                    undoManager.undoOrRedo();
+                    undoManager.undo();
+                }
+                System.out.println("t3 done");
+            }
+        };
+
+        t1.start();
+        t2.start();
+        t3.start();
+
+        t1.join();
+        t2.join();
+        t3.join();
+    }
+}

From e300345cc8e854f9ad7fe5347d4fe07ec93cfc9c Mon Sep 17 00:00:00 2001
From: Jayathirth D V <jdv@openjdk.org>
Date: Wed, 2 Dec 2015 00:34:35 +0530
Subject: [PATCH 08/62] 8074967: [macosx] JPEGImageReader incorrectly
 identifies YCbCr JPEGs as RGB in standard metadata

Reviewed-by: prr, psadhukhan
---
 .../imageio/plugins/jpeg/JPEGMetadata.java    |  12 +--
 .../jpeg/JpegMetadataColorSpaceTest.java      |  69 ++++++++++++++++++
 .../javax/imageio/plugins/jpeg/nomarkers.jpg  | Bin 0 -> 548 bytes
 3 files changed, 75 insertions(+), 6 deletions(-)
 create mode 100644 jdk/test/javax/imageio/plugins/jpeg/JpegMetadataColorSpaceTest.java
 create mode 100644 jdk/test/javax/imageio/plugins/jpeg/nomarkers.jpg

diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
index f25863955ec..7975efda580 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGMetadata.java
@@ -874,13 +874,13 @@ public class JPEGMetadata extends IIOMetadata implements Cloneable {
             return chroma;
         }
 
-        boolean idsAreJFIF = true;
+        boolean idsAreJFIF = false;
 
-        for (int i = 0; i < sof.componentSpecs.length; i++) {
-            int id = sof.componentSpecs[i].componentId;
-            if ((id < 1) || (id >= sof.componentSpecs.length)) {
-                idsAreJFIF = false;
-            }
+        int cid0 = sof.componentSpecs[0].componentId;
+        int cid1 = sof.componentSpecs[1].componentId;
+        int cid2 = sof.componentSpecs[2].componentId;
+        if ((cid0 == 1) && (cid1 == 2) && (cid2 == 3)) {
+            idsAreJFIF = true;
         }
 
         if (idsAreJFIF) {
diff --git a/jdk/test/javax/imageio/plugins/jpeg/JpegMetadataColorSpaceTest.java b/jdk/test/javax/imageio/plugins/jpeg/JpegMetadataColorSpaceTest.java
new file mode 100644
index 00000000000..dbe54f553e2
--- /dev/null
+++ b/jdk/test/javax/imageio/plugins/jpeg/JpegMetadataColorSpaceTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug     8074967
+ * @summary Test verifies if there is no JFIF & EXIF header
+ *          and sampling factor is same of JPEG image, then
+ *          JPEG colorspace should not be RGB.
+ * @run     main JpegMetadataColorSpaceTest
+ */
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.metadata.IIOMetadataNode;
+import javax.imageio.stream.ImageInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+
+public class JpegMetadataColorSpaceTest {
+    public static void main(String[] args) throws IOException {
+        String fileName = "nomarkers.jpg";
+        String sep = System.getProperty("file.separator");
+        String dir = System.getProperty("test.src", ".");
+        String filePath = dir+sep+fileName;
+        System.out.println("Test file: " + filePath);
+        File file = new File(filePath);
+        ImageInputStream stream = ImageIO.createImageInputStream(file);
+        Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
+
+        if(readers.hasNext()) {
+            ImageReader reader = readers.next();
+            reader.setInput(stream);
+            IIOMetadata metadata = reader.getImageMetadata(0);
+
+            IIOMetadataNode standardTree = (IIOMetadataNode)
+                metadata.getAsTree
+                (IIOMetadataFormatImpl.standardMetadataFormatName);
+            IIOMetadataNode colorSpaceType = (IIOMetadataNode)
+                standardTree.getElementsByTagName("ColorSpaceType").item(0);
+            String colorSpaceName = colorSpaceType.getAttribute("name");
+            if(colorSpaceName.equals("RGB"))
+                throw new RuntimeException("Identified incorrect ColorSpace");
+        }
+    }
+}
diff --git a/jdk/test/javax/imageio/plugins/jpeg/nomarkers.jpg b/jdk/test/javax/imageio/plugins/jpeg/nomarkers.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3b08cdd3b02b159411cd54e30c2683be6d8ca6b0
GIT binary patch
literal 548
zcmb79+YN#+6uq~lP-wvxTjbZoJs|PRE!@N%9K$h;L--h`wjq+BJmSgu>CJi7-Q5fJ
zKnV%-h&&l*EQ(l`Br%tnlp+%%FG`gcx)4HDO0SKzR<1U6W$Myc6GD)BPsCEjQj?3^
z{0(;n&7p;sq6VUoYIHZSfCxiye>Oi?a8HmFfhei~@X`)V{p%Fm>O1r3-P~s)Bcavk
saREhaa85va!DL0;bQO~VY_|CM3{XE@oe#TFE-Y0`OFO~L5HEPV0ZWiZasU7T

literal 0
HcmV?d00001


From 3a2b32b7076804276dbe02c4f9d11ee20bcc981e Mon Sep 17 00:00:00 2001
From: Jayathirth D V <jdv@openjdk.org>
Date: Wed, 2 Dec 2015 00:47:36 +0530
Subject: [PATCH 09/62] 6967419: IndexOutOfBoundsException when drawing PNGs

Reviewed-by: prr, psadhukhan
---
 .../imageio/plugins/png/PNGImageWriter.java   | 12 ++-
 .../plugins/png/PngForceStopWritingTest.java  | 76 +++++++++++++++++++
 2 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 jdk/test/javax/imageio/plugins/png/PngForceStopWritingTest.java

diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
index 0004904aa99..278882e5385 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
@@ -193,7 +193,17 @@ final class IDATOutputStream extends ImageOutputStreamImpl {
 
         // Return to end of chunk and flush to minimize buffering
         stream.seek(pos);
-        stream.flushBefore(pos);
+        try {
+            stream.flushBefore(pos);
+        } catch (IOException e) {
+            /*
+             * If flushBefore() fails we try to access startPos in finally
+             * block of write_IDAT(). We should update startPos to avoid
+             * IndexOutOfBoundException while seek() is happening.
+             */
+            this.startPos = stream.getStreamPosition();
+            throw e;
+        }
     }
 
     public int read() throws IOException {
diff --git a/jdk/test/javax/imageio/plugins/png/PngForceStopWritingTest.java b/jdk/test/javax/imageio/plugins/png/PngForceStopWritingTest.java
new file mode 100644
index 00000000000..b2da248787c
--- /dev/null
+++ b/jdk/test/javax/imageio/plugins/png/PngForceStopWritingTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug     6967419
+ * @summary Test verifies that when we force stop PNG writing to
+ *          ImageOutputStream, it should not cause IndexOutOfBoundException.
+ * @run     main PngForceStopWritingTest
+ */
+
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
+
+public class PngForceStopWritingTest {
+
+    public static void main(String[] args) throws IOException {
+
+        OutputStream outputStream = new NullOutputStream();
+        ImageOutputStream imageOutputStream =
+            ImageIO.createImageOutputStream(outputStream);
+        try {
+            ImageIO.write(createImage(2048),"PNG", imageOutputStream);
+        } catch (IOException e) {
+            imageOutputStream.close();
+        }
+    }
+
+    private static BufferedImage createImage(int size) {
+
+        BufferedImage image = new
+            BufferedImage(size, size, BufferedImage.TYPE_3BYTE_BGR);
+        Graphics2D g = image.createGraphics();
+        g.setPaint(new GradientPaint(0, 0, Color.blue, size, size, Color.red));
+        g.fillRect(0, 0, size, size);
+        g.dispose();
+        return image;
+    }
+
+    static class NullOutputStream extends OutputStream {
+        long count = 0;
+        @Override
+        public void write(int b) throws IOException {
+            count++;
+            if (count > 30000L) {
+                throw new IOException("Force stop image writing");
+            }
+        }
+    }
+}

From 2b89c8529ddb210492786b533435521fa9eef559 Mon Sep 17 00:00:00 2001
From: Jayathirth D V <jdv@openjdk.org>
Date: Wed, 2 Dec 2015 00:52:49 +0530
Subject: [PATCH 10/62] 8041501: ImageIO reader is not capable of reading JPEGs
 without JFIF header

Reviewed-by: prr, psadhukhan
---
 .../share/native/libjavajpeg/imageioJPEG.c    | 30 ++++----
 .../plugins/jpeg/JpegImageColorSpaceTest.java | 69 +++++++++++++++++++
 2 files changed, 86 insertions(+), 13 deletions(-)
 create mode 100644 jdk/test/javax/imageio/plugins/jpeg/JpegImageColorSpaceTest.java

diff --git a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
index f0d5c019a8d..81fe9117d04 100644
--- a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
+++ b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
@@ -1610,6 +1610,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
     int ret;
     int h_samp0, h_samp1, h_samp2;
     int v_samp0, v_samp1, v_samp2;
+    int cid0, cid1, cid2;
     jboolean retval = JNI_FALSE;
     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_decompress_ptr cinfo;
@@ -1711,17 +1712,15 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
                 }
             } else if (!cinfo->saw_JFIF_marker && !IS_EXIF(cinfo)) {
                 /*
-                 * IJG assumes all unidentified 3-channels are YCbCr.
-                 * We assume that only if the second two channels are
-                 * subsampled (either horizontally or vertically).  If not,
-                 * we assume RGB.
-                 *
-                 * 4776576: Some digital cameras output YCbCr JPEG images
-                 * that do not contain a JFIF APP0 marker but are only
-                 * vertically subsampled (no horizontal subsampling).
-                 * We should only assume this is RGB data if the subsampling
-                 * factors for the second two channels are the same as the
-                 * first (check both horizontal and vertical factors).
+                 * In the absence of certain markers, IJG has interpreted
+                 * component id's of [1,2,3] as meaning YCbCr.We follow that
+                 * interpretation, which is additionally described in the Image
+                 * I/O JPEG metadata spec.If that condition is not met here the
+                 * next step will be to examine the subsampling factors, if
+                 * there is any difference in subsampling factors we also assume
+                 * YCbCr, only if both horizontal and vertical subsampling
+                 * is same we assume JPEG color space as RGB.
+                 * This is also described in the Image I/O JPEG metadata spec.
                  */
                 h_samp0 = cinfo->comp_info[0].h_samp_factor;
                 h_samp1 = cinfo->comp_info[1].h_samp_factor;
@@ -1731,8 +1730,13 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader
                 v_samp1 = cinfo->comp_info[1].v_samp_factor;
                 v_samp2 = cinfo->comp_info[2].v_samp_factor;
 
-                if ((h_samp1 == h_samp0) && (h_samp2 == h_samp0) &&
-                    (v_samp1 == v_samp0) && (v_samp2 == v_samp0))
+                cid0 = cinfo->comp_info[0].component_id;
+                cid1 = cinfo->comp_info[1].component_id;
+                cid2 = cinfo->comp_info[2].component_id;
+
+                if ((!(cid0 == 1 && cid1 == 2 && cid2 == 3)) &&
+                    ((h_samp1 == h_samp0) && (h_samp2 == h_samp0) &&
+                    (v_samp1 == v_samp0) && (v_samp2 == v_samp0)))
                 {
                     cinfo->jpeg_color_space = JCS_RGB;
                     /* output is already RGB, so it stays the same */
diff --git a/jdk/test/javax/imageio/plugins/jpeg/JpegImageColorSpaceTest.java b/jdk/test/javax/imageio/plugins/jpeg/JpegImageColorSpaceTest.java
new file mode 100644
index 00000000000..c18b8216120
--- /dev/null
+++ b/jdk/test/javax/imageio/plugins/jpeg/JpegImageColorSpaceTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug     8041501
+ * @summary Test verifies if there is no JFIF & EXIF header
+ *          and sampling factor is same of JPEG image, then
+ *          imageIO should not override colorspace determined
+ *          in IJG library.
+ * @run     main JpegImageColorSpaceTest
+ */
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import javax.imageio.ImageIO;
+
+public class JpegImageColorSpaceTest {
+
+    public static void main(String args[]) throws Exception {
+
+        String fileName = "nomarkers.jpg";
+        String sep = System.getProperty("file.separator");
+        String dir = System.getProperty("test.src", ".");
+        String filePath = dir+sep+fileName;
+        System.out.println("Test file: " + filePath);
+        File imageFile = new File(filePath);
+
+        BufferedImage bufferedImage = ImageIO.read(imageFile);
+        int imageWidth = bufferedImage.getWidth();
+        int imageHeight = bufferedImage.getHeight();
+
+        for (int i = 0; i < imageWidth; i++) {
+            for(int j = 0; j < imageHeight; j++) {
+                /*
+                * Since image is white we check individual pixel values from
+                * BufferedImage to verify if ImageIO.read() is done with proper
+                * color space or not.
+                */
+                if (bufferedImage.getRGB(i, j) != Color.white.getRGB()) {
+                    // color space is not proper
+                    throw new RuntimeException("ColorSpace is not determined "
+                            + "properly by ImageIO");
+               }
+            }
+        }
+    }
+}

From 854c76518636eacf0496f971fc4fd75a7eed8e9f Mon Sep 17 00:00:00 2001
From: Jiri Vanek <jvanek@redhat.com>
Date: Wed, 2 Dec 2015 21:23:59 +0000
Subject: [PATCH 11/62] 8144071: ImageIO does not reset stream if an exception
 is thrown

Reset the I/O stream in a finally block

Reviewed-by: andrew
---
 .../share/classes/javax/imageio/ImageIO.java  |   9 +-
 .../imageio/spi/MarkTryFinallyReproducer.java | 367 ++++++++++++++++++
 2 files changed, 373 insertions(+), 3 deletions(-)
 create mode 100644 jdk/test/javax/imageio/spi/MarkTryFinallyReproducer.java

diff --git a/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java
index 7beea7b77a6..b56975ba15b 100644
--- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageIO.java
@@ -564,9 +564,12 @@ public final class ImageIO {
                 if (stream != null) {
                     stream.mark();
                 }
-                canDecode = spi.canDecodeInput(input);
-                if (stream != null) {
-                    stream.reset();
+                try {
+                    canDecode = spi.canDecodeInput(input);
+                } finally {
+                    if (stream != null) {
+                        stream.reset();
+                    }
                 }
 
                 return canDecode;
diff --git a/jdk/test/javax/imageio/spi/MarkTryFinallyReproducer.java b/jdk/test/javax/imageio/spi/MarkTryFinallyReproducer.java
new file mode 100644
index 00000000000..7efd06a62f4
--- /dev/null
+++ b/jdk/test/javax/imageio/spi/MarkTryFinallyReproducer.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright 2015 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8144071
+ * @run main/othervm MarkTryFinallyReproducer
+ * @summary Test that call to canDecodeInput in ImageIO don't corrupt
+ *           mark/reset stack in ImageInputStream
+ * @author Jiri Vanek
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.ByteOrder;
+import java.util.Locale;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.IIOByteBuffer;
+import javax.imageio.stream.ImageInputStream;
+
+
+public class MarkTryFinallyReproducer {
+
+    private static final byte[] bmp = new byte[]{
+        127,127, 66, 77, -86, 0, 0, 0, 0, 0, 0, 0,
+        122, 0, 0, 0, 108, 0, 0, 0, 4, 0, 0, 0, 4,
+        0, 0, 0, 1, 0, 24, 0, 0, 0, 0, 0, 48, 0, 0,
+        0, 19, 11, 0, 0, 19, 11, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 66, 71, 82, 115, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, -1,
+        -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 0, 0, 0, -17,
+        0, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1,
+        -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 0, -1
+    };
+    //first two are evil, we are skipping them later. Others are normal BMP
+
+    private static class NotClosingImageInputStream implements ImageInputStream {
+
+        private final ImageInputStream src;
+
+        private NotClosingImageInputStream(ImageInputStream createImageInputStream) {
+            this.src = createImageInputStream;
+        }
+
+        @Override
+        public void setByteOrder(ByteOrder byteOrder) {
+            src.setByteOrder(byteOrder);
+        }
+
+        @Override
+        public ByteOrder getByteOrder() {
+            return src.getByteOrder();
+        }
+
+        @Override
+        public int read() throws IOException {
+            return src.read();
+        }
+
+        @Override
+        public int read(byte[] b) throws IOException {
+            return src.read(b);
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            return src.read(b, off, len);
+        }
+
+        @Override
+        public void readBytes(IIOByteBuffer buf, int len) throws IOException {
+            src.readBytes(buf, len);
+        }
+
+        @Override
+        public boolean readBoolean() throws IOException {
+            return src.readBoolean();
+        }
+
+        @Override
+        public byte readByte() throws IOException {
+            return src.readByte();
+        }
+
+        @Override
+        public int readUnsignedByte() throws IOException {
+            return src.readUnsignedByte();
+        }
+
+        @Override
+        public short readShort() throws IOException {
+            return src.readShort();
+        }
+
+        @Override
+        public int readUnsignedShort() throws IOException {
+            return src.readUnsignedShort();
+        }
+
+        @Override
+        public char readChar() throws IOException {
+            return src.readChar();
+        }
+
+        @Override
+        public int readInt() throws IOException {
+            return src.readInt();
+        }
+
+        @Override
+        public long readUnsignedInt() throws IOException {
+            return src.readUnsignedInt();
+        }
+
+        @Override
+        public long readLong() throws IOException {
+            return src.readLong();
+        }
+
+        @Override
+        public float readFloat() throws IOException {
+            return src.readFloat();
+        }
+
+        @Override
+        public double readDouble() throws IOException {
+            return src.readDouble();
+        }
+
+        @Override
+        public String readLine() throws IOException {
+            return src.readLine();
+        }
+
+        @Override
+        public String readUTF() throws IOException {
+            return src.readUTF();
+        }
+
+        @Override
+        public void readFully(byte[] b, int off, int len) throws IOException {
+            src.readFully(b, off, len);
+        }
+
+        @Override
+        public void readFully(byte[] b) throws IOException {
+            src.readFully(b);
+        }
+
+        @Override
+        public void readFully(short[] s, int off, int len) throws IOException {
+            src.readFully(s, off, len);
+        }
+
+        @Override
+        public void readFully(char[] c, int off, int len) throws IOException {
+            src.readFully(c, off, len);
+        }
+
+        @Override
+        public void readFully(int[] i, int off, int len) throws IOException {
+            src.readFully(i, off, len);
+        }
+
+        @Override
+        public void readFully(long[] l, int off, int len) throws IOException {
+            src.readFully(l, off, len);
+        }
+
+        @Override
+        public void readFully(float[] f, int off, int len) throws IOException {
+            src.readFully(f, off, len);
+        }
+
+        @Override
+        public void readFully(double[] d, int off, int len) throws IOException {
+            src.readFully(d, off, len);
+        }
+
+        @Override
+        public long getStreamPosition() throws IOException {
+            return src.getStreamPosition();
+        }
+
+        @Override
+        public int getBitOffset() throws IOException {
+            return src.getBitOffset();
+        }
+
+        @Override
+        public void setBitOffset(int bitOffset) throws IOException {
+            src.setBitOffset(bitOffset);
+        }
+
+        @Override
+        public int readBit() throws IOException {
+            return src.readBit();
+        }
+
+        @Override
+        public long readBits(int numBits) throws IOException {
+            return src.readBits(numBits);
+        }
+
+        @Override
+        public long length() throws IOException {
+            return src.length();
+        }
+
+        @Override
+        public int skipBytes(int n) throws IOException {
+            return src.skipBytes(n);
+        }
+
+        @Override
+        public long skipBytes(long n) throws IOException {
+            return src.skipBytes(n);
+        }
+
+        @Override
+        public void seek(long pos) throws IOException {
+            src.seek(pos);
+        }
+
+        @Override
+        public void mark() {
+            src.mark();
+        }
+
+        @Override
+        public void reset() throws IOException {
+            src.reset();
+        }
+
+        @Override
+        public void flushBefore(long pos) throws IOException {
+            src.flushBefore(pos);
+        }
+
+        @Override
+        public void flush() throws IOException {
+            src.flush();
+        }
+
+        @Override
+        public long getFlushedPosition() {
+            return src.getFlushedPosition();
+        }
+
+        @Override
+        public boolean isCached() {
+            return src.isCached();
+        }
+
+        @Override
+        public boolean isCachedMemory() {
+            return src.isCachedMemory();
+        }
+
+        @Override
+        public boolean isCachedFile() {
+            return src.isCachedFile();
+        }
+
+        @Override
+        public void close() throws IOException {
+            //the only important one. nothing
+        }
+    }
+
+    static final String readerClassName
+            = MarkTryFinallyReproducerSpi.class.getName();
+    static final String[] localNames = {"myNames"};
+    static final String[] localSuffixes = {"mySuffixes"};
+    static final String[] localMIMETypes = {"myMimes"};
+
+    public static class MarkTryFinallyReproducerSpi extends ImageReaderSpi {
+
+        public MarkTryFinallyReproducerSpi() {
+            super("MarkTryFinallyReproducerSpi",
+                    "1.0",
+                    localNames,
+                    localSuffixes,
+                    localMIMETypes,
+                    readerClassName,
+                    new Class[]{ImageInputStream.class},
+                    new String[0],
+                    false,
+                    null,
+                    null,
+                    new String[0],
+                    new String[0],
+                    false,
+                    null,
+                    null,
+                    new String[0],
+                    new String[0]);
+        }
+
+        @Override
+        public String getDescription(Locale locale) {
+            return "";
+        }
+
+        @Override
+        public boolean canDecodeInput(Object input) throws IOException {
+            throw new IOException("Bad luck");
+        }
+
+        @Override
+        public ImageReader createReaderInstance(Object extension) {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) throws IOException {
+        MarkTryFinallyReproducerSpi spi = new MarkTryFinallyReproducerSpi();
+        IIORegistry.getDefaultInstance().registerServiceProvider(spi);
+
+        ImageInputStream iis1 =
+          new NotClosingImageInputStream(ImageIO.createImageInputStream(new ByteArrayInputStream(bmp)));
+        iis1.readByte();
+        iis1.mark();
+        long p1 = iis1.getStreamPosition();
+        iis1.readByte();
+        iis1.mark();
+        long p2 = iis1.getStreamPosition();
+        BufferedImage bi1 = ImageIO.read(iis1);
+        iis1.reset();
+        long pn2 = iis1.getStreamPosition();
+        iis1.reset();
+        long pn1 = iis1.getStreamPosition();
+        if (p1 != pn1 || p2!= pn2) {
+            throw new RuntimeException("Exception from call to canDecodeInput in ImageIO. " +
+                                       "Corrupted stack in ImageInputStream");
+        }
+
+    }
+
+}

From 59accc606b6d79a8dba0a86d11fa92fa7e52cb23 Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov <serb@openjdk.org>
Date: Thu, 3 Dec 2015 12:27:02 +0530
Subject: [PATCH 12/62] 8131754: AquaTreeUI.getCollapsedIcon() issue reported
 in java beans tests with a modular build

Reviewed-by: malenkov, alexsch
---
 .../share/classes/javax/swing/JComponent.java |  1 +
 .../XMLEncoder/javax_swing_JComponent.java    | 77 +++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100644 jdk/test/java/beans/XMLEncoder/javax_swing_JComponent.java

diff --git a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
index 3276d534a48..b6fa1b7bd81 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java
@@ -618,6 +618,7 @@ public abstract class JComponent extends Container implements Serializable,
      * @return the {@code ComponentUI} object that renders this component
      * @since 1.9
      */
+    @Transient
     public ComponentUI getUI() {
         return ui;
     }
diff --git a/jdk/test/java/beans/XMLEncoder/javax_swing_JComponent.java b/jdk/test/java/beans/XMLEncoder/javax_swing_JComponent.java
new file mode 100644
index 00000000000..9ca11f9954a
--- /dev/null
+++ b/jdk/test/java/beans/XMLEncoder/javax_swing_JComponent.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+
+/*
+ * @test
+ * @bug 8131754
+ * @summary Tests JComponent encoding
+ */
+public final class javax_swing_JComponent extends AbstractTest<JComponent> {
+
+    public static void main(final String[] args) {
+        new javax_swing_JComponent().test(true);
+    }
+
+    protected JComponent getObject() {
+        return new SimpleJComponent();
+    }
+
+    protected JComponent getAnotherObject() {
+        return new CustomJComponent();
+    }
+
+    public static final class SimpleJComponent extends JComponent {
+
+    }
+
+    public static final class CustomJComponent extends JComponent {
+
+        public CustomJComponent() {
+            ui = new CustomUI();
+        }
+
+        @Override
+        public ComponentUI getUI() {
+            return ui;
+        }
+
+        @Override
+        public void setUI(final ComponentUI newUI) {
+            ui = newUI;
+        }
+    }
+
+    public static final class CustomUI extends ComponentUI {
+
+        public boolean getFlag() {
+            throw new Error();
+        }
+
+        public void setFlag(final boolean flag) {
+            throw new Error();
+        }
+    }
+}

From 6ffba3b398f03d29ed0778e5ca6534540c1d89a3 Mon Sep 17 00:00:00 2001
From: Alexey Ivanov <aivanov@openjdk.org>
Date: Thu, 3 Dec 2015 15:22:31 +0300
Subject: [PATCH 13/62] 8134152: Public API for java 8 DataFlavor fields do not
 have @since tag

Reviewed-by: ssadetsky, alexsch
---
 .../share/classes/java/awt/datatransfer/DataFlavor.java     | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
index 5f05177be39..becfd0563ba 100644
--- a/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
@@ -289,6 +289,8 @@ public class DataFlavor implements Externalizable, Cloneable {
      *     representationClass = String
      *     mimeType           = "text/html"
      * </pre>
+     *
+     * @since 1.8
      */
     public static DataFlavor selectionHtmlFlavor = initHtmlDataFlavor("selection");
 
@@ -301,6 +303,8 @@ public class DataFlavor implements Externalizable, Cloneable {
      *     representationClass = String
      *     mimeType           = "text/html"
      * </pre>
+     *
+     * @since 1.8
      */
     public static DataFlavor fragmentHtmlFlavor = initHtmlDataFlavor("fragment");
 
@@ -314,6 +318,8 @@ public class DataFlavor implements Externalizable, Cloneable {
      *     representationClass = String
      *     mimeType           = "text/html"
      * </pre>
+     *
+     * @since 1.8
      */
     public static  DataFlavor allHtmlFlavor = initHtmlDataFlavor("all");
 

From 3096b2cc2f538b50b73971d8996c2c90a60da380 Mon Sep 17 00:00:00 2001
From: Rajeev Chamyal <rchamyal@openjdk.org>
Date: Fri, 4 Dec 2015 09:56:50 +0400
Subject: [PATCH 14/62] 8067660: JFileChooser create new folder fails silently

Reviewed-by: alexsch, psadhukhan
---
 .../swing/filechooser/FileSystemView.java     |  13 +-
 .../JFileChooser/8067660/FileChooserTest.java | 250 ++++++++++++++++++
 2 files changed, 259 insertions(+), 4 deletions(-)
 create mode 100644 jdk/test/javax/swing/JFileChooser/8067660/FileChooserTest.java

diff --git a/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java b/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
index 54cd7c037d4..bbc35bf9c1d 100644
--- a/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
+++ b/jdk/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java
@@ -663,7 +663,9 @@ class UnixFileSystemView extends FileSystemView {
         if(newFolder.exists()) {
             throw new IOException("Directory already exists:" + newFolder.getAbsolutePath());
         } else {
-            newFolder.mkdirs();
+            if(!newFolder.mkdirs()) {
+                throw new IOException(newFolder.getAbsolutePath());
+            }
         }
 
         return newFolder;
@@ -773,7 +775,9 @@ class WindowsFileSystemView extends FileSystemView {
         if(newFolder.exists()) {
             throw new IOException("Directory already exists:" + newFolder.getAbsolutePath());
         } else {
-            newFolder.mkdirs();
+            if(!newFolder.mkdirs()) {
+                throw new IOException(newFolder.getAbsolutePath());
+            }
         }
 
         return newFolder;
@@ -842,9 +846,10 @@ class GenericFileSystemView extends FileSystemView {
         if(newFolder.exists()) {
             throw new IOException("Directory already exists:" + newFolder.getAbsolutePath());
         } else {
-            newFolder.mkdirs();
+            if(!newFolder.mkdirs()) {
+                throw new IOException(newFolder.getAbsolutePath());
+            }
         }
-
         return newFolder;
     }
 
diff --git a/jdk/test/javax/swing/JFileChooser/8067660/FileChooserTest.java b/jdk/test/javax/swing/JFileChooser/8067660/FileChooserTest.java
new file mode 100644
index 00000000000..acd49add15f
--- /dev/null
+++ b/jdk/test/javax/swing/JFileChooser/8067660/FileChooserTest.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8067660
+ * @summary JFileChooser create new folder fails silently
+ * @requires (os.family == "windows")
+ * @run main/manual FileChooserTest
+ */
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+public class FileChooserTest {
+
+    private static boolean theTestPassed;
+    private static boolean testGeneratedInterrupt;
+    private static Thread mainThread;
+    private static int sleepTime = 30000;
+    public static  JFileChooser fileChooser;
+
+    private static void init() throws Exception {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                String[] instructions
+                        = {
+                            "1) Create a folder with read only permissions",
+                            "2) Click on run test button.It will open a open dialog"
+                            + " Navigate to the newly created read only folder",
+                            "3) Click on the create new folder button in open dialog",
+                            "4) If an error message does not pops up"
+                            + "test failed otherwise passed.",
+                            "5) Pressing Pass/Fail button will mark test as "
+                            + "pass/fail and will shutdown JVM"};
+
+                Sysout.createDialogWithInstructions(instructions);
+                Sysout.printInstructions(instructions);
+            }
+        });
+    }
+
+    /**
+     * ***************************************************
+     * Standard Test Machinery Section DO NOT modify anything in this section --
+     * it's a standard chunk of code which has all of the synchronisation
+     * necessary for the test harness. By keeping it the same in all tests, it
+     * is easier to read and understand someone else's test, as well as insuring
+     * that all tests behave correctly with the test harness. There is a section
+     * following this for test-defined classes
+     */
+    public static void main(String args[]) throws Exception {
+
+        mainThread = Thread.currentThread();
+        try {
+            init();
+        } catch (Exception ex) {
+            return;
+        }
+        try {
+            mainThread.sleep(sleepTime);
+        } catch (InterruptedException ex) {
+            Sysout.dispose();
+            if (!theTestPassed && testGeneratedInterrupt) {
+                throw new RuntimeException("Test Failed");
+            }
+        }
+        if (!testGeneratedInterrupt) {
+            Sysout.dispose();
+            throw new RuntimeException("Test Failed");
+        }
+    }
+
+    public static synchronized void pass() {
+        theTestPassed = true;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+
+    public static synchronized void fail() {
+        theTestPassed = false;
+        testGeneratedInterrupt = true;
+        mainThread.interrupt();
+    }
+}
+
+/**
+ * This is part of the standard test machinery. It creates a dialog (with the
+ * instructions), and is the interface for sending text messages to the user. To
+ * print the instructions, send an array of strings to Sysout.createDialog
+ * WithInstructions method. Put one line of instructions per array entry. To
+ * display a message for the tester to see, simply call Sysout.println with the
+ * string to be displayed. This mimics System.out.println but works within the
+ * test harness as well as standalone.
+ */
+class Sysout {
+
+    private static TestDialog dialog;
+    private static JFrame frame;
+
+    public static void createDialogWithInstructions(String[] instructions) {
+        frame = new JFrame();
+        dialog = new TestDialog(frame, "Instructions");
+        dialog.printInstructions(instructions);
+        dialog.setVisible(true);
+        println("Any messages for the tester will display here.");
+    }
+
+    public static void printInstructions(String[] instructions) {
+        dialog.printInstructions(instructions);
+    }
+
+    public static void println(String messageIn) {
+        dialog.displayMessage(messageIn);
+    }
+
+    public static void dispose() {
+        Sysout.println("Shutting down the Java process..");
+        if(FileChooserTest.fileChooser != null) {
+            FileChooserTest.fileChooser.cancelSelection();
+        }
+        frame.dispose();
+        dialog.dispose();
+    }
+}
+
+/**
+ * This is part of the standard test machinery. It provides a place for the test
+ * instructions to be displayed, and a place for interactive messages to the
+ * user to be displayed. To have the test instructions displayed, see Sysout. To
+ * have a message to the user be displayed, see Sysout. Do not call anything in
+ * this dialog directly.
+ */
+class TestDialog extends JDialog {
+
+    private TextArea instructionsText;
+    private TextArea messageText;
+    private int maxStringLength = 80;
+    private Panel buttonP = new Panel();
+    private JButton run = new JButton("Run");
+    private JButton passB = new JButton("Pass");
+    private JButton failB = new JButton("Fail");
+
+    public TestDialog(JFrame frame, String name) {
+        super(frame, name);
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        int scrollBoth = TextArea.SCROLLBARS_BOTH;
+        instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
+        add("North", instructionsText);
+
+        messageText = new TextArea("", 5, maxStringLength, scrollBoth);
+        add("Center", messageText);
+
+        buttonP.add("East", run);
+        buttonP.add("East", passB);
+        buttonP.add("West", failB);
+        passB.setEnabled(false);
+        failB.setEnabled(false);
+        add("South", buttonP);
+
+        run.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                FileChooserTest.fileChooser = new JFileChooser();
+                FileChooserTest.fileChooser.showOpenDialog(null);
+                passB.setEnabled(true);
+                failB.setEnabled(true);
+            }
+        });
+
+        passB.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                FileChooserTest.pass();
+            }
+        });
+
+        failB.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                FileChooserTest.fail();
+            }
+        });
+        pack();
+
+        setVisible(true);
+    }
+
+    public void printInstructions(String[] instructions) {
+        instructionsText.setText("");
+
+        String printStr, remainingStr;
+        for (String instruction : instructions) {
+            remainingStr = instruction;
+            while (remainingStr.length() > 0) {
+                if (remainingStr.length() >= maxStringLength) {
+                    int posOfSpace = remainingStr.
+                            lastIndexOf(' ', maxStringLength - 1);
+
+                    if (posOfSpace <= 0) {
+                        posOfSpace = maxStringLength - 1;
+                    }
+
+                    printStr = remainingStr.substring(0, posOfSpace + 1);
+                    remainingStr = remainingStr.substring(posOfSpace + 1);
+                } else {
+                    printStr = remainingStr;
+                    remainingStr = "";
+                }
+                instructionsText.append(printStr + "\n");
+            }
+        }
+
+    }
+
+    public void displayMessage(String messageIn) {
+        messageText.append(messageIn + "\n");
+    }
+}

From 9c2dc1edf517c9e025972c167453594127db9a01 Mon Sep 17 00:00:00 2001
From: Prasanta Sadhukhan <psadhukhan@openjdk.org>
Date: Fri, 4 Dec 2015 13:52:21 +0300
Subject: [PATCH 15/62] 8140530: Creating a VolatileImage with size 0, 0
 results in no longer working g2d.drawStri

Reviewed-by: flar, serb
---
 .../sun/awt/image/SunVolatileImage.java       |  4 ++
 .../native/common/java2d/x11/X11SurfaceData.c |  9 ++++
 .../image/VolatileImage/VolatileImageBug.java | 52 +++++++++++++++++++
 3 files changed, 65 insertions(+)
 create mode 100644 jdk/test/java/awt/image/VolatileImage/VolatileImageBug.java

diff --git a/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java b/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java
index 00c8911f696..1ee5c4019f1 100644
--- a/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java
+++ b/jdk/src/java.desktop/share/classes/sun/awt/image/SunVolatileImage.java
@@ -70,6 +70,10 @@ public class SunVolatileImage extends VolatileImage
     {
         this.comp = comp;
         this.graphicsConfig = graphicsConfig;
+        if (width <= 0 || height <= 0) {
+            throw new IllegalArgumentException("Width (" + width + ")" +
+                              " and height (" + height + ") cannot be <= 0");
+        }
         this.width = width;
         this.height = height;
         this.forcedAccelSurfaceType = accType;
diff --git a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
index d9af8ddf6e1..e6597a4723c 100644
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
@@ -438,6 +438,15 @@ jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width
         xsdo->drawable = drawable;
         xsdo->isPixmap = JNI_FALSE;
     } else {
+        /*
+         * width , height must be nonzero otherwise XCreatePixmap
+         * generates BadValue in error_handler
+         */
+        if (width <= 0 || height <= 0) {
+            JNU_ThrowOutOfMemoryError(env,
+                                  "Can't create offscreen surface");
+            return JNI_FALSE;
+        }
         xsdo->isPixmap = JNI_TRUE;
         /* REMIND: workaround for bug 4420220 on pgx32 boards:
            don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
diff --git a/jdk/test/java/awt/image/VolatileImage/VolatileImageBug.java b/jdk/test/java/awt/image/VolatileImage/VolatileImageBug.java
new file mode 100644
index 00000000000..70ca2b00840
--- /dev/null
+++ b/jdk/test/java/awt/image/VolatileImage/VolatileImageBug.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.VolatileImage;
+
+/**
+ * @test
+ * @bug 8140530
+ * @run main VolatileImageBug
+ * @summary Creating volatileimage(0,0) should throw IAE
+ */
+public class VolatileImageBug {
+    public static void main(String[] args) {
+
+        boolean iaeThrown = false;
+        GraphicsEnvironment ge = GraphicsEnvironment.
+                                      getLocalGraphicsEnvironment();
+        GraphicsConfiguration gc = ge.getDefaultScreenDevice().
+                                           getDefaultConfiguration();
+        try {
+            VolatileImage volatileImage = gc.createCompatibleVolatileImage(0, 0);
+        } catch (IllegalArgumentException iae) {
+            iaeThrown = true;
+        }
+        if (!iaeThrown) {
+            throw new RuntimeException ("IllegalArgumentException not thrown " +
+                                        "for createCompatibleVolatileImage(0,0)");
+        }
+    }
+}
+

From cdb4a75a00102ecf64d363b495b28499f7c3588c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20Bourg=C3=A8s?= <lbourges@openjdk.org>
Date: Sat, 5 Dec 2015 09:48:43 -0800
Subject: [PATCH 16/62] 8144630: Use PrivilegedAction to create Thread in
 Marlin RendererStats

Reviewed-by: prr, flar
---
 .../sun/java2d/marlin/RendererStats.java      | 42 ++++++++++++-------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
index 6ddb5253372..4588bf270b3 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java
@@ -25,6 +25,8 @@
 
 package sun.java2d.marlin;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -32,6 +34,7 @@ import static sun.java2d.marlin.MarlinUtils.logInfo;
 import sun.java2d.marlin.stats.Histogram;
 import sun.java2d.marlin.stats.Monitor;
 import sun.java2d.marlin.stats.StatLong;
+import sun.awt.util.ThreadGroupUtils;
 
 /**
  * This class gathers global rendering statistics for debugging purposes only
@@ -237,22 +240,33 @@ public final class RendererStats implements MarlinConst {
     private RendererStats() {
         super();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                dump();
-            }
-        });
+        AccessController.doPrivileged(
+            (PrivilegedAction<Void>) () -> {
+                final Thread hook = new Thread(
+                    ThreadGroupUtils.getRootThreadGroup(),
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            dump();
+                        }
+                    },
+                    "MarlinStatsHook"
+                );
+                hook.setContextClassLoader(null);
+                Runtime.getRuntime().addShutdownHook(hook);
 
-        if (useDumpThread) {
-            final Timer statTimer = new Timer("RendererStats");
-            statTimer.scheduleAtFixedRate(new TimerTask() {
-                @Override
-                public void run() {
-                    dump();
+                if (useDumpThread) {
+                    final Timer statTimer = new Timer("RendererStats");
+                    statTimer.scheduleAtFixedRate(new TimerTask() {
+                        @Override
+                        public void run() {
+                            dump();
+                        }
+                    }, statDump, statDump);
                 }
-            }, statDump, statDump);
-        }
+                return null;
+            }
+        );
     }
 
     void dump() {

From 4faa0ee15c1a16d6cbe6cef90c89640013510050 Mon Sep 17 00:00:00 2001
From: Joe Darcy <darcy@openjdk.org>
Date: Mon, 7 Dec 2015 14:12:58 -0800
Subject: [PATCH 17/62] 8144880: Instrument intermittently failing test
 ConfigChanges.java

Reviewed-by: lancea, martin
---
 jdk/test/TEST.groups                                      | 2 ++
 .../util/concurrent/ThreadPoolExecutor/ConfigChanges.java | 8 ++++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups
index 0600a4c8345..769d3f91e30 100644
--- a/jdk/test/TEST.groups
+++ b/jdk/test/TEST.groups
@@ -32,6 +32,7 @@ tier1 = \
     :jdk_util \
     -java/util/WeakHashMap/GCDuringIteration.java \
     -java/util/concurrent/Phaser/Basic.java \
+    -java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java
     sun/nio/cs/ISO8859x.java \
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
@@ -42,6 +43,7 @@ tier2 = \
     java/util/zip/TestLocalTime.java \
     java/util/concurrent/Phaser/Basic.java \
     java/util/WeakHashMap/GCDuringIteration.java \
+    java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
     :jdk_io \
     :jdk_nio \
     -sun/nio/cs/ISO8859x.java \
diff --git a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java
index 2418acc18c5..a7ff015bc77 100644
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -25,7 +25,10 @@
  * @test
  * @bug 6450200
  * @summary Test proper handling of pool state changes
+ * @library /lib/testlibrary/
+ * @build jdk.testlibrary.RandomFactory
  * @run main/othervm ConfigChanges
+ * @key randomness intermittent
  * @author Martin Buchholz
  */
 
@@ -42,11 +45,12 @@ import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.atomic.AtomicInteger;
+import jdk.testlibrary.RandomFactory;
 
 public class ConfigChanges {
     static final ThreadGroup tg = new ThreadGroup("pool");
 
-    static final Random rnd = new Random();
+    static final Random rnd = RandomFactory.getRandom();
 
     static void report(ThreadPoolExecutor tpe) {
         try {

From 307b9775e8e3ec16f085d3f37466584aa43780e9 Mon Sep 17 00:00:00 2001
From: Xue-Lei Andrew Fan <xuelei@openjdk.org>
Date: Tue, 8 Dec 2015 03:49:12 +0000
Subject: [PATCH 18/62] 8144890: Add the intermittent keyword test
 B6216082.java

Reviewed-by: mullan
---
 .../protocol/https/HttpsURLConnection/B6216082.java | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
index 33af848f466..72bae7e4ed5 100644
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -21,15 +21,20 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6216082
  * @summary  Redirect problem with HttpsURLConnection using a proxy
- *     SunJSSE does not support dynamic system properties, no way to re-use
- *     system properties in samevm/agentvm mode.
  * @modules java.base/sun.net.www
  * @library ..
- * @build HttpCallback TestHttpsServer ClosedChannelList HttpTransaction TunnelProxy
+ * @build HttpCallback TestHttpsServer ClosedChannelList
+ *        HttpTransaction TunnelProxy
+ * @key intermittent
  * @run main/othervm B6216082
  */
 

From 4d646ce63350d2c0e29069159adc93c95736aa69 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan <sundar@openjdk.org>
Date: Tue, 8 Dec 2015 10:13:57 +0530
Subject: [PATCH 19/62] 8143404: Remove apple script engine code in jdk
 repository

Reviewed-by: alanb, mchung
---
 jdk/make/lib/Lib-jdk.deploy.osx.gmk           |  26 -
 .../apple/applescript/AppleScriptEngine.java  | 389 ---------
 .../applescript/AppleScriptEngineFactory.java | 244 ------
 .../AS_NS_ConversionUtils.h                   |  38 -
 .../AS_NS_ConversionUtils.m                   | 793 ------------------
 .../libapplescriptengine/AppleScriptEngine.m  | 199 -----
 .../AppleScriptExecutionContext.h             |  46 -
 .../AppleScriptExecutionContext.m             | 165 ----
 .../NS_Java_ConversionUtils.h                 |  33 -
 .../NS_Java_ConversionUtils.m                 | 145 ----
 10 files changed, 2078 deletions(-)
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngine.java
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngineFactory.java
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.h
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.m
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.h
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.m
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.h
 delete mode 100644 jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.m

diff --git a/jdk/make/lib/Lib-jdk.deploy.osx.gmk b/jdk/make/lib/Lib-jdk.deploy.osx.gmk
index a5c0eb1d41f..08125ce9d23 100644
--- a/jdk/make/lib/Lib-jdk.deploy.osx.gmk
+++ b/jdk/make/lib/Lib-jdk.deploy.osx.gmk
@@ -29,32 +29,6 @@ ifeq ($(OPENJDK_TARGET_OS), macosx)
 
   ################################################################################
 
-  LIBAPPLESCRIPTENGINE_SRC := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libapplescriptengine
-
-  $(eval $(call SetupNativeCompilation,BUILD_LIBAPPLESCRIPTENGINE, \
-      LIBRARY := AppleScriptEngine, \
-      OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
-      SRC := $(LIBAPPLESCRIPTENGINE_SRC), \
-      OPTIMIZATION := LOW, \
-      CFLAGS := $(CFLAGS_JDKLIB) \
-          -I$(LIBAPPLESCRIPTENGINE_SRC) \
-          -I$(SUPPORT_OUTPUTDIR)/headers/jdk.deploy.osx, \
-      DISABLED_WARNINGS_clang := implicit-function-declaration format, \
-      LDFLAGS := $(LDFLAGS_JDKLIB) \
-          $(call SET_SHARED_LIBRARY_ORIGIN), \
-      LIBS := -framework Cocoa \
-          -framework Carbon \
-          -framework JavaNativeFoundation \
-          $(JDKLIB_LIBS), \
-      OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libAppleScriptEngine, \
-      DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
-
-  $(BUILD_LIBAPPLESCRIPTENGINE): $(call FindLib, java.base, java)
-
-  TARGETS += $(BUILD_LIBAPPLESCRIPTENGINE)
-
-  ################################################################################
-
   LIBOSX_DIRS := $(JDK_TOPDIR)/src/jdk.deploy.osx/macosx/native/libosx
   LIBOSX_CFLAGS := -I$(LIBOSX_DIRS) \
       -I$(JDK_TOPDIR)/src/java.desktop/macosx/native/libosxapp \
diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngine.java b/jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngine.java
deleted file mode 100644
index 8ef8116e744..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngine.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package apple.applescript;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.util.*;
-import java.util.Map.Entry;
-
-import javax.script.*;
-
-/**
- * AppleScriptEngine implements JSR 223 for AppleScript on Mac OS X
- */
-public class AppleScriptEngine implements ScriptEngine {
-    private static native void initNative();
-
-    private static native long createContextFrom(final Object object);
-    private static native Object createObjectFrom(final long context);
-    private static native void disposeContext(final long context);
-
-    private static native long evalScript(final String script, long contextptr);
-    private static native long evalScriptFromURL(final String filename, long contextptr);
-
-    static {
-        System.loadLibrary("AppleScriptEngine");
-        initNative();
-        TRACE("<static-init>");
-    }
-
-    static void checkSecurity() {
-        final SecurityManager securityManager = System.getSecurityManager();
-        if (securityManager != null) securityManager.checkExec("/usr/bin/osascript");
-    }
-
-    static void TRACE(final String str) {
-//        System.out.println(AppleScriptEngine.class.getName() + "." + str);
-    }
-
-    /**
-     * Accessor for the ScriptEngine's long name variable
-     * @return the long name of the ScriptEngine
-     */
-    protected static String getEngine() {
-        TRACE("getEngine()");
-        return AppleScriptEngineFactory.ENGINE_NAME;
-    }
-
-    /**
-     * Accessor for the ScriptEngine's version
-     * @return the version of the ScriptEngine
-     */
-    protected static String getEngineVersion() {
-        TRACE("getEngineVersion()");
-        return AppleScriptEngineFactory.ENGINE_VERSION;
-    }
-
-    /**
-     * Accessor for the ScriptEngine's short name
-     * @return the short name of the ScriptEngine
-     */
-    protected static String getName() {
-        TRACE("getName()");
-        return AppleScriptEngineFactory.ENGINE_SHORT_NAME;
-    }
-
-    /**
-     * Accessor for the ScriptEngine's supported language name
-     * @return the language the ScriptEngine supports
-     */
-    protected static String getLanguage() {
-        TRACE("getLanguage()");
-        return AppleScriptEngineFactory.LANGUAGE;
-    }
-
-    /**
-     * The no argument constructor sets up the object with default members,
-     * a factory for the engine and a fresh context.
-     * @see com.apple.applescript.AppleScriptEngine#init()
-     */
-    public AppleScriptEngine() {
-        TRACE("<ctor>()");
-        // set our parent factory to be a new factory
-        factory = AppleScriptEngineFactory.getFactory();
-
-        // set up our noarg bindings
-        setContext(new SimpleScriptContext());
-        put(ARGV, "");
-
-        init();
-    }
-
-    /**
-     * All AppleScriptEngines share the same ScriptEngineFactory
-     */
-    private final ScriptEngineFactory factory;
-
-    /**
-     * The local context for the AppleScriptEngine
-     */
-    private ScriptContext context;
-
-    /**
-     * The constructor taking a factory as an argument sets the parent factory for
-     * this engine to be the passed factory, and sets up the engine with a fresh context
-     * @param factory
-     * @see com.apple.applescript.AppleScriptEngine#init()
-     */
-    public AppleScriptEngine(final ScriptEngineFactory factory) {
-        // inherit the factory passed to us
-        this.factory = factory;
-
-        // set up our noarg bindings
-        setContext(new SimpleScriptContext());
-        put(ARGV, "");
-
-        init();
-    }
-
-    /**
-     * The initializer populates the local context with some useful predefined variables:
-     * <ul><li><code>javax_script_language_version</code> - the version of AppleScript that the AppleScriptEngine supports.</li>
-     * <li><code>javax_script_language</code> - "AppleScript" -- the language supported by the AppleScriptEngine.</li>
-     * <li><code>javax_script_engine</code> - "AppleScriptEngine" -- the name of the ScriptEngine.</li>
-     * <li><code>javax_script_engine_version</code> - the version of the AppleScriptEngine</li>
-     * <li><code>javax_script_argv</code> - "" -- AppleScript does not take arguments from the command line</li>
-     * <li><code>javax_script_filename</code> - "" -- the currently executing filename</li>
-     * <li><code>javax_script_name</code> - "AppleScriptEngine" -- the short name of the AppleScriptEngine</li>
-     * <li><code>THREADING</code> - null -- the AppleScriptEngine does not support concurrency, you will have to implement thread-safeness yourself.</li></ul>
-     */
-    private void init() {
-        TRACE("init()");
-        // set up our context
-/* TODO -- name of current executable?  bad java documentation at:
- * http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */
-        put(ScriptEngine.FILENAME, "");
-        put(ScriptEngine.ENGINE, getEngine());
-        put(ScriptEngine.ENGINE_VERSION, getEngineVersion());
-        put(ScriptEngine.NAME, getName());
-        put(ScriptEngine.LANGUAGE, getLanguage());
-        put(ScriptEngine.LANGUAGE_VERSION, getLanguageVersion());
-
-        // TODO -- for now, err on the side of caution and say that we are NOT thread-safe
-        put("THREADING", null);
-    }
-
-    /**
-     * Uses the AppleScriptEngine to get the local AppleScript version
-     * @return the version of AppleScript running on the system
-     */
-    protected String getLanguageVersion() {
-        TRACE("AppleScriptEngine.getLanguageVersion()");
-        try {
-            final Object result = eval("get the version of AppleScript");
-            if (result instanceof String) return (String)result;
-        } catch (final ScriptException e) { e.printStackTrace(); }
-        return "unknown";
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Returns the factory parent of this AppleScriptEngine
-     */
-    public ScriptEngineFactory getFactory() {
-        return factory;
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Return the engine's context
-     * @return this ScriptEngine's context
-     */
-    public ScriptContext getContext() {
-        return context;
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Set a new context for the engine
-     * @param context the new context to install in the engine
-     */
-    public void setContext(final ScriptContext context) {
-        this.context = context;
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Create and return a new set of simple bindings.
-     * @return a new and empty set of bindings
-     */
-    public Bindings createBindings() {
-        return new SimpleBindings();
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Return the engines bindings for the context indicated by the argument.
-     * @param scope contextual scope to return.
-     * @return the bindings in the engine for the scope indicated by the parameter
-     */
-    public Bindings getBindings(final int scope) {
-        return context.getBindings(scope);
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Sets the bindings for the indicated scope
-     * @param bindings a set of bindings to assign to the engine
-     * @param scope the scope that the passed bindings should be assigned to
-     */
-    public void setBindings(final Bindings bindings, final int scope) {
-        context.setBindings(bindings, scope);
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Insert a key and value into the engine's bindings (scope: engine)
-     * @param key the key of the pair
-     * @param value the value of the pair
-     */
-    public void put(final String key, final Object value) {
-        getBindings(ScriptContext.ENGINE_SCOPE).put(key, value);
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Get a value from the engine's bindings using a key (scope: engine)
-     * @param key the key of the pair
-     * @return the value of the pair
-     */
-    public Object get(final String key) {
-        return getBindings(ScriptContext.ENGINE_SCOPE).get(key);
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Passes the Reader argument, as well as the engine's context to a lower evaluation function.<br />
-     * Prefers FileReader or BufferedReader wrapping FileReader as argument.
-     * @param reader a Reader to AppleScript source or compiled AppleScript
-     * @return an Object corresponding to the return value of the script
-     * @see com.apple.applescript.AppleScriptEngine#eval(Reader, ScriptContext)
-     */
-    public Object eval(final Reader reader) throws ScriptException {
-        return eval(reader, getContext());
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Uses the passed bindings as the context for executing the passed script.
-     * @param reader a stream to AppleScript source or compiled AppleScript
-     * @param bindings a Bindings object representing the contexts to execute inside
-     * @return the return value of the script
-     * @see com.apple.applescript.AppleScriptEngine#eval(Reader, ScriptContext)
-     */
-    public Object eval(final Reader reader, final Bindings bindings) throws ScriptException {
-        final Bindings tmp = getContext().getBindings(ScriptContext.ENGINE_SCOPE);
-        getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE);
-        final Object retval = eval(reader);
-        getContext().setBindings(tmp, ScriptContext.ENGINE_SCOPE);
-        return retval;
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * This function can execute either AppleScript source or compiled AppleScript and functions by writing the
-     * contents of the Reader to a temporary file and then executing it with the engine's context.
-     * @param reader
-     * @param scriptContext
-     * @return an Object corresponding to the return value of the script
-     */
-    public Object eval(final Reader reader, final ScriptContext context) throws ScriptException {
-        checkSecurity();
-
-        // write our passed reader to a temporary file
-        File tmpfile;
-        FileWriter tmpwrite;
-        try {
-            tmpfile = Files.createTempFile("AppleScriptEngine.", ".scpt").toFile();
-            tmpwrite = new FileWriter(tmpfile);
-
-            // read in our input and write directly to tmpfile
-            /* TODO -- this may or may not be avoidable for certain Readers,
-             * if a filename can be grabbed, it would be faster to get that and
-             * use the underlying file than writing a temp file.
-             */
-            int data;
-            while ((data = reader.read()) != -1) {
-                tmpwrite.write(data);
-            }
-            tmpwrite.close();
-
-            // set up our context business
-            final long contextptr = scriptContextToNSDictionary(context);
-            try {
-                final long retCtx = evalScriptFromURL("file://" + tmpfile.getCanonicalPath(), contextptr);
-                Object retVal = (retCtx == 0) ? null : createObjectFrom(retCtx);
-                disposeContext(retCtx);
-                return retVal;
-            } finally {
-                disposeContext(contextptr);
-                tmpfile.delete();
-            }
-        } catch (final IOException e) {
-            throw new ScriptException(e);
-        }
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Evaluate an AppleScript script passed as a source string. Using the engine's built in context.
-     * @param script the string to execute.
-     * @return an Object representing the return value of the script
-     * @see com.apple.applescript.AppleScriptEngine#eval(String, ScriptContext)
-     */
-    public Object eval(final String script) throws ScriptException {
-        return eval(script, getContext());
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent<br />
-     * Evaluate an AppleScript script passed as a source string with a custom ScriptContext.
-     * @param script the AppleScript source to compile and execute.
-     * @param scriptContext the context to execute the script under
-     * @see com.apple.applescript.AppleScriptEngine#eval(String, ScriptContext)
-     */
-    public Object eval(final String script, final Bindings bindings) throws ScriptException {
-        final Bindings tmp = getContext().getBindings(ScriptContext.ENGINE_SCOPE);
-        getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE);
-
-        final Object retval = eval(script);
-        getContext().setBindings(tmp, ScriptContext.ENGINE_SCOPE);
-
-        return retval;
-    }
-
-    /**
-     * Implementation required by ScriptEngine parent
-     * @param script
-     * @param scriptContext
-     */
-    public Object eval(final String script, final ScriptContext context) throws ScriptException {
-        checkSecurity();
-        final long ctxPtr = scriptContextToNSDictionary(context);
-        try {
-            final long retCtx = evalScript(script, ctxPtr);
-            Object retVal = (retCtx == 0) ? null : createObjectFrom(retCtx);
-            disposeContext(retCtx);
-            return retVal;
-        } finally {
-            disposeContext(ctxPtr);
-        }
-    }
-
-    /**
-     * Converts a ScriptContext into an NSDictionary
-     * @param context ScriptContext for the engine
-     * @return a pointer to an NSDictionary
-     */
-    private long scriptContextToNSDictionary(final ScriptContext context) throws ScriptException {
-        final Map<String, Object> contextAsMap = new HashMap<String, Object>();
-        for (final Entry<String, Object> e : context.getBindings(ScriptContext.ENGINE_SCOPE).entrySet()) {
-            contextAsMap.put(e.getKey().replaceAll("\\.", "_"), e.getValue());
-        }
-        return createContextFrom(contextAsMap);
-    }
-}
diff --git a/jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngineFactory.java b/jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngineFactory.java
deleted file mode 100644
index 8c50b9d9301..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/classes/apple/applescript/AppleScriptEngineFactory.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package apple.applescript;
-
-import java.security.*;
-import java.util.*;
-import javax.script.*;
-
-public class AppleScriptEngineFactory implements ScriptEngineFactory {
-    private static volatile boolean initialized = false;
-
-    private static native void initNative();
-
-    static void TRACE(final String str) {
-//        System.out.println(AppleScriptEngineFactory.class.getName() + "." + str);
-    }
-
-    /**
-     * The name of this ScriptEngine
-     */
-    static final String ENGINE_NAME = "AppleScriptEngine";
-
-    /**
-     * The version of this ScriptEngine
-     */
-    static final String ENGINE_VERSION = "1.1";
-
-    /**
-     * The name of this ScriptEngine (yes, again)
-     */
-    static final String ENGINE_SHORT_NAME = ENGINE_NAME;
-
-    /**
-     * The name of the language supported by this ScriptEngine
-     */
-    static final String LANGUAGE = "AppleScript";
-
-    static ScriptEngineFactory getFactory() {
-        TRACE("getFactory()");
-        return new AppleScriptEngineFactory();
-    }
-
-    /**
-     * Initialize a new AppleScriptEngineFactory, replete with a member AppleScriptEngine
-     */
-    public AppleScriptEngineFactory() {
-        TRACE("<ctor>()");
-    }
-
-    /**
-     * Returns the full name of the ScriptEngine.
-     *
-     * @return full name of the ScriptEngine
-     */
-    @Override
-    public String getEngineName() {
-        TRACE("getEngineName()");
-        return ENGINE_NAME;
-    }
-
-    /**
-     * Returns the version of the ScriptEngine.
-     *
-     * @return version of the ScriptEngine
-     */
-    @Override
-    public String getEngineVersion() {
-        TRACE("getEngineVersion()");
-        return ENGINE_VERSION;
-    }
-
-    /**
-     * Returns the name of the scripting language supported by this ScriptEngine.
-     *
-     * @return name of the language supported by the ScriptEngine(Factory)
-     */
-    @Override
-    public String getLanguageName() {
-        TRACE("getLanguageName()");
-        return LANGUAGE;
-    }
-
-    /**
-     * Returns the version of the scripting language supported by this ScriptEngine(Factory).
-     *
-     * @return language version supported by the ScriptEngine(Factory)
-     */
-    @Override
-    public String getLanguageVersion() {
-        TRACE("getLanguageVersion()");
-        return AccessController.doPrivileged(new PrivilegedAction<String>() {
-            public String run() {
-                final AppleScriptEngine engine = getScriptEngine();
-                return engine.getLanguageVersion();
-            }
-        });
-    }
-
-    /**
-     * Returns an immutable list of filename extensions, which generally identify
-     * scripts written in the language supported by this ScriptEngine.
-     *
-     * @return ArrayList of file extensions AppleScript associates with
-     */
-    @Override
-    public List<String> getExtensions() {
-        TRACE("getExtensions()");
-        return Arrays.asList("scpt", "applescript", "app");
-    }
-
-    /**
-     * Returns an immutable list of mimetypes, associated with scripts
-     * that can be executed by the engine.
-     *
-     * @return ArrayList of mimetypes that AppleScript associates with
-     */
-    @Override
-    public List<String> getMimeTypes() {
-        TRACE("getMimeTypes()");
-        return Arrays.asList("application/x-applescript", "text/plain", "text/applescript");
-    }
-
-    /**
-     * Returns an immutable list of short names for the ScriptEngine,
-     * which may be used to identify the ScriptEngine by the ScriptEngineManager.
-     *
-     * @return
-     */
-    @Override
-    public List<String> getNames() {
-        TRACE("getNames()");
-        return Arrays.asList("AppleScriptEngine", "AppleScript", "OSA");
-    }
-
-    /**
-     * Returns a String which can be used to invoke a method of a Java
-     * object using the syntax of the supported scripting language.
-     *
-     * @param obj
-     *            unused -- AppleScript does not support objects
-     * @param m
-     *            function name
-     * @param args
-     *            arguments to the function
-     * @return the AppleScript string calling the method
-     */
-    @Override
-    public String getMethodCallSyntax(final String obj, final String fname, final String ... args) {
-//        StringBuilder builder = new StringBuilder();
-//        builder.append("my " + fname + "(");
-//        // TODO -- do
-//        builder.append(")\n");
-//        return builder.toString();
-
-        return null;
-    }
-
-    /**
-     * Returns a String that can be used as a statement to display the specified String using the syntax of the supported scripting language.
-     *
-     * @param toDisplay
-     * @return
-     */
-    @Override
-    public String getOutputStatement(final String toDisplay) {
-        // TODO -- this might even be good enough? XD
-        return getMethodCallSyntax(null, "print", toDisplay);
-    }
-
-    /**
-     * Returns the value of an attribute whose meaning may be implementation-specific.
-     *
-     * @param key
-     *            the key to look up
-     * @return the static preseeded value for the key in the ScriptEngine, if it exists, otherwise <code>null</code>
-     */
-    @Override
-    public Object getParameter(final String key) {
-        final AppleScriptEngine engine = getScriptEngine();
-        if (!engine.getBindings(ScriptContext.ENGINE_SCOPE).containsKey(key)) return null;
-        return engine.getBindings(ScriptContext.ENGINE_SCOPE).get(key);
-    }
-
-    /**
-     * Returns A valid scripting language executable program with given statements.
-     *
-     * @param statements
-     * @return
-     */
-    @Override
-    public String getProgram(final String ... statements) {
-        final StringBuilder program = new StringBuilder();
-        for (final String statement : statements) {
-            program.append(statement + "\n");
-        }
-        return program.toString();
-    }
-
-    /**
-     * Returns an instance of the ScriptEngine associated with this ScriptEngineFactory.
-     *
-     * @return new AppleScriptEngine with this factory as it's parent
-     */
-    @Override
-    public AppleScriptEngine getScriptEngine() {
-        AppleScriptEngine.checkSecurity();
-        ensureInitialized();
-
-        return new AppleScriptEngine(this);
-    }
-
-    private static synchronized void ensureInitialized() {
-        if (!initialized) {
-            initialized = true;
-
-            java.awt.Toolkit.getDefaultToolkit();
-            System.loadLibrary("AppleScriptEngine");
-            initNative();
-        }
-    }
-}
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.h b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.h
deleted file mode 100644
index 3b428d222d7..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#import <Foundation/Foundation.h>
-
-
-// A 'collection' (responds to -objectEnumerator) is translated to an AS list.
-// For any other object obj, this returns [[obj description] aeDescriptorValue], mainly
-// intended for debugging purposes.
-@interface NSObject (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *) aeDescriptorValue;
-@end
-
-@interface NSAppleEventDescriptor (JavaAppleScriptEngineAdditions)
-- (id) objCObjectValue;
-@end
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.m b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.m
deleted file mode 100644
index 42c0da59d5e..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AS_NS_ConversionUtils.m
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-//
-//    Most of this is adapted from Ken Ferry's KFAppleScript Additions, contributed with permission
-//    http://homepage.mac.com/kenferry/software.html
-//
-
-#import "AS_NS_ConversionUtils.h"
-
-#import <Cocoa/Cocoa.h>
-#import <Carbon/Carbon.h>
-
-
-@interface NSAppleEventDescriptor (JavaAppleScriptEngineAdditionsPrivate)
-
-// just returns self.  This means that you can pass custom descriptors
-// to -[NSAppleScript executeHandler:error:withParameters:].
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-
-// working with primitive descriptor types
-+ (id)descriptorWithInt16:(SInt16)val;
-- (SInt16)int16Value;
-+ (id)descriptorWithUnsignedInt32:(UInt32)val;
-- (UInt32)unsignedInt32Value;
-+ (id)descriptorWithFloat32:(Float32)val;
-- (Float32)float32Value;
-+ (id)descriptorWithFloat64:(Float64)val;
-- (Float64)float64Value;
-+ (id)descriptorWithLongDateTime:(LongDateTime)val;
-- (LongDateTime)longDateTimeValue;
-
-
-// These are the methods for converting AS objects to objective-C objects.
-// -[NSAppleEventDescriptor objCObjectValue] is the general method for converting
-// AS objects to ObjC objects, and is called by -[NSAppleScript executeHandler:error:withParameters:].
-// It does no work itself.  It finds a handler based on the type of the descriptor and lets that
-// handler object do the work.  If there is no handler type registered for a the type of a descriptor,
-// the raw descriptor is returned.
-//
-// You can designate a handlers for descriptor types with
-// +[NSAppleEventDescriptor registerConversionHandler:selector:forDescriptorTypes:].  Please note
-// that this method does _not_ retain the handler object (for now anyway).  The selector should
-// take a single argument, a descriptor to translate, and should return an object.  An example such
-// selector is @selector(dictionaryWithAEDesc:), for which the handler object would be [NSDictionary class].
-//
-// A number of handlers are designated by default.  The methods and objects can be easily inferred (or check
-// the implementation), but the automatically handled types are
-//    typeUnicodeText,
-//    typeText,
-//    typeUTF8Text,
-//    typeCString,
-//    typeChar,
-//    typeBoolean,
-//    typeTrue,
-//    typeFalse,
-//    typeSInt16,
-//    typeSInt32,
-//    typeUInt32,
-//    typeSInt64,
-//    typeIEEE32BitFloatingPoint,
-//    typeIEEE64BitFloatingPoint,
-//    type128BitFloatingPoint,
-//    typeAEList,
-//    typeAERecord,
-//    typeLongDateTime,
-//    typeNull.
-+ (void)registerConversionHandler:(id)anObject selector:(SEL)aSelector forDescriptorTypes:(DescType)firstType, ...;
-+ (void) jaseSetUpHandlerDict;
-@end
-
-// wrap the NSAppleEventDescriptor string methods
-@interface NSString (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-+ (NSString *)stringWithAEDesc:(NSAppleEventDescriptor *)desc;
-@end
-
-// wrap the NSAppleEventDescriptor longDateTime methods
-@interface NSDate (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-+ (NSDate *)dateWithAEDesc:(NSAppleEventDescriptor *)desc;
-@end
-
-// these are fairly complicated methods, due to having to try to match up the various
-// AS number types (see NSAppleEventDescriptor for the primitive number methods)
-// with NSNumber variants.  For complete behavior it's best to look at the implementation.
-// Some notes:
-//    NSNumbers created with numberWithBool should be correctly translated to AS booleans and vice versa.
-//    NSNumbers created with large integer types may have to be translated to AS doubles,
-//      so be careful if checking equality (you may have to check equality within epsilon).
-//    Since NSNumbers can't remember if they were created with an unsigned value,
-//      [[NSNumber numberWithUnsignedChar:255] aeDescriptorValue] is going to get you an AS integer
-//      with value -1.  If you really need a descriptor with an unsigned value, you'll need to do it
-//      manually using the primitive methods on NSAppleEventDescriptor.  The resulting descriptor
-//      can still be passed to AS with -[NSAppleScript executeHandler:error:withParameters:].
-@interface NSNumber (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-+ (id)numberWithAEDesc:(NSAppleEventDescriptor *)desc;
-@end
-
-// Here we're following the behavior described in the CocoaScripting release note.
-//
-// NSPoint -> list of two numbers: {x, y}
-// NSRange -> list of two numbers: {begin offset, end offset}
-// NSRect  -> list of four numbers: {left, bottom, right, top}
-// NSSize  -> list of two numbers: {width, height}
-@interface NSValue (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-@end
-
-// No need for ObjC -> AS conversion here, we fall through to NSObject as a collection.
-// For AS -> ObjC conversion, we build an array using the primitive list methods on
-// NSAppleEventDescriptor.
-@interface NSArray (JavaAppleScriptEngineAdditions)
-+ (NSArray *)arrayWithAEDesc:(NSAppleEventDescriptor *)desc;
-@end
-
-
-// Please see the CocoaScripting release note for behavior.  It's kind of complicated.
-//
-// methods wrap the primitive record methods on NSAppleEventDescriptor.
-@interface NSDictionary (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-+ (NSDictionary *)dictionaryWithAEDesc:(NSAppleEventDescriptor *)desc;
-@end
-
-// be aware that a null descriptor does not correspond to the 'null' keyword in
-// AppleScript - it's more like nothing at all.  For example, the return
-// from an empty handler.
-@interface NSNull (JavaAppleScriptEngineAdditions)
-- (NSAppleEventDescriptor *)aeDescriptorValue;
-+ (NSNull *)nullWithAEDesc:(NSAppleEventDescriptor *)desc;
-@end
-
-
-@interface NSNumber (JavaAppleScriptEngineAdditionsPrivate)
-+ (id) jaseNumberWithSignedIntP:(void *)int_p byteCount:(int)bytes;
-+ (id) jaseNumberWithUnsignedIntP:(void *)int_p byteCount:(int)bytes;
-+ (id) jaseNumberWithFloatP:(void *)float_p byteCount:(int)bytes;
-@end
-
-
-@implementation NSObject (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    // collections go to lists
-    if (![self respondsToSelector:@selector(objectEnumerator)]) {
-        // encode the description as a fallback - this is pretty useless, only helpful for debugging
-        return [[self description] aeDescriptorValue];
-    }
-
-    NSAppleEventDescriptor *resultDesc = [NSAppleEventDescriptor listDescriptor];
-    NSEnumerator *objectEnumerator = [(id)self objectEnumerator];
-
-    unsigned int i = 1; // apple event descriptors are 1-indexed
-    id currentObject;
-    while((currentObject = [objectEnumerator nextObject]) != nil) {
-        [resultDesc insertDescriptor:[currentObject aeDescriptorValue] atIndex:i++];
-    }
-
-    return resultDesc;
-}
-
-@end
-
-
-@implementation NSArray (JavaAppleScriptEngineAdditions)
-
-// don't need to override aeDescriptorValue, the NSObject will treat the array as a collection
-+ (NSArray *)arrayWithAEDesc:(NSAppleEventDescriptor *)desc {
-    NSAppleEventDescriptor *listDesc = [desc coerceToDescriptorType:typeAEList];
-    NSMutableArray *resultArray = [NSMutableArray array];
-
-    // apple event descriptors are 1-indexed
-    unsigned int listCount = [listDesc numberOfItems];
-    unsigned int i;
-    for (i = 1; i <= listCount; i++) {
-        [resultArray addObject:[[listDesc descriptorAtIndex:i] objCObjectValue]];
-    }
-
-    return resultArray;
-}
-
-@end
-
-
-@implementation NSDictionary (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    NSAppleEventDescriptor *resultDesc = [NSAppleEventDescriptor recordDescriptor];
-    NSMutableArray *userFields = [NSMutableArray array];
-    NSArray *keys = [self allKeys];
-
-    unsigned int keyCount = [keys count];
-    unsigned int i;
-    for (i = 0; i < keyCount; i++) {
-        id key = [keys objectAtIndex:i];
-
-        if ([key isKindOfClass:[NSNumber class]]) {
-            [resultDesc setDescriptor:[[self objectForKey:key] aeDescriptorValue] forKeyword:[(NSNumber *)key intValue]];
-        } else if ([key isKindOfClass:[NSString class]]) {
-            [userFields addObject:key];
-            [userFields addObject:[self objectForKey:key]];
-        }
-    }
-
-    if ([userFields count] > 0) {
-        [resultDesc setDescriptor:[userFields aeDescriptorValue] forKeyword:keyASUserRecordFields];
-    }
-
-    return resultDesc;
-}
-
-+ (NSDictionary *)dictionaryWithAEDesc:(NSAppleEventDescriptor *)desc {
-    NSAppleEventDescriptor *recDescriptor = [desc coerceToDescriptorType:typeAERecord];
-    NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
-
-    // NSAppleEventDescriptor uses 1 indexing
-    unsigned int recordCount = [recDescriptor numberOfItems];
-    unsigned int recordIndex;
-    for (recordIndex = 1; recordIndex <= recordCount; recordIndex++) {
-        AEKeyword keyword = [recDescriptor keywordForDescriptorAtIndex:recordIndex];
-
-        if(keyword == keyASUserRecordFields) {
-            NSAppleEventDescriptor *listDescriptor = [recDescriptor descriptorAtIndex:recordIndex];
-
-            // NSAppleEventDescriptor uses 1 indexing
-            unsigned int listCount = [listDescriptor numberOfItems];
-            unsigned int listIndex;
-            for (listIndex = 1; listIndex <= listCount; listIndex += 2) {
-                id keyObj = [[listDescriptor descriptorAtIndex:listIndex] objCObjectValue];
-                id valObj = [[listDescriptor descriptorAtIndex:listIndex+1] objCObjectValue];
-
-                [resultDict setObject:valObj forKey:keyObj];
-            }
-        } else {
-            id keyObj = [NSNumber numberWithInt:keyword];
-            id valObj = [[recDescriptor descriptorAtIndex:recordIndex] objCObjectValue];
-
-            [resultDict setObject:valObj forKey:keyObj];
-        }
-    }
-
-    return resultDict;
-}
-
-@end
-
-
-@implementation NSString (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    return [NSAppleEventDescriptor descriptorWithString:self];
-}
-
-+ (NSString *)stringWithAEDesc:(NSAppleEventDescriptor *)desc {
-    return [desc stringValue];
-}
-
-+ (NSString *)versionWithAEDesc:(NSAppleEventDescriptor *)desc {
-    const AEDesc *aeDesc = [desc aeDesc];
-    VersRec v;
-    AEGetDescData(aeDesc, &v, sizeof(v));
-    return [[[NSString alloc] initWithBytes:&v.shortVersion[1] length:StrLength(v.shortVersion) encoding:NSUTF8StringEncoding] autorelease];
-}
-
-@end
-
-
-@implementation NSNull (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    return [NSAppleEventDescriptor nullDescriptor];
-}
-
-+ (NSNull *)nullWithAEDesc:(NSAppleEventDescriptor *)desc {
-    return [NSNull null];
-}
-
-@end
-
-
-@implementation NSDate (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    LongDateTime ldt;
-    UCConvertCFAbsoluteTimeToLongDateTime(CFDateGetAbsoluteTime((CFDateRef)self), &ldt);
-    return [NSAppleEventDescriptor descriptorWithLongDateTime:ldt];
-}
-
-+ (NSDate *)dateWithAEDesc:(NSAppleEventDescriptor *)desc {
-    CFAbsoluteTime absTime;
-    UCConvertLongDateTimeToCFAbsoluteTime([desc longDateTimeValue], &absTime);
-    NSDate *resultDate = (NSDate *)CFDateCreate(NULL, absTime);
-    return [resultDate autorelease];
-}
-
-@end
-
-
-
-static inline int areEqualEncodings(const char *enc1, const char *enc2) {
-    return (strcmp(enc1, enc2) == 0);
-}
-
-@implementation NSNumber (JavaAppleScriptEngineAdditions)
-
--(id)jaseDescriptorValueWithFloatP:(void *)float_p byteCount:(int)bytes {
-    float floatVal;
-    if (bytes < sizeof(Float32)) {
-        floatVal = [self floatValue];
-        float_p = &floatVal;
-        bytes = sizeof(floatVal);
-    }
-
-    double doubleVal;
-    if (bytes > sizeof(Float64)) {
-        doubleVal = [self doubleValue];
-        float_p = &doubleVal;
-        bytes = sizeof(doubleVal);
-    }
-
-    if (bytes == sizeof(Float32)) {
-        return [NSAppleEventDescriptor descriptorWithFloat32:*(Float32 *)float_p];
-    }
-
-    if (bytes == sizeof(Float64)) {
-        return [NSAppleEventDescriptor descriptorWithFloat64:*(Float64 *)float_p];
-    }
-
-    [NSException raise:NSInvalidArgumentException
-                format:@"Cannot create an NSAppleEventDescriptor for float with %d bytes of data.",  bytes];
-
-    return nil;
-}
-
--(id)jaseDescriptorValueWithSignedIntP:(void *)int_p byteCount:(int)bytes {
-    int intVal;
-
-    if (bytes < sizeof(SInt16)) {
-        intVal = [self intValue];
-        int_p = &intVal;
-        bytes = sizeof(intVal);
-    }
-
-    if (bytes == sizeof(SInt16)) {
-        return [NSAppleEventDescriptor descriptorWithInt16:*(SInt16 *)int_p];
-    }
-
-    if (bytes == sizeof(SInt32)) {
-        return [NSAppleEventDescriptor descriptorWithInt32:*(SInt32 *)int_p];
-    }
-
-    double val = [self doubleValue];
-    return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
-}
-
--(id)jaseDescriptorValueWithUnsignedIntP:(void *)int_p byteCount:(int)bytes {
-    unsigned int uIntVal;
-
-    if (bytes < sizeof(UInt32)) {
-        uIntVal = [self unsignedIntValue];
-        int_p = &uIntVal;
-        bytes = sizeof(uIntVal);
-    }
-
-    if (bytes == sizeof(UInt32)) {
-        return [NSAppleEventDescriptor descriptorWithUnsignedInt32:*(UInt32 *)int_p];
-    }
-
-    double val = (double)[self unsignedLongLongValue];
-    return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
-}
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    // NSNumber is unfortunately complicated, because the applescript
-    // type we should use depends on the c type that our NSNumber corresponds to
-
-    const char *type = [self objCType];
-
-    // convert
-    if (areEqualEncodings(type, @encode(BOOL))) {
-        return [NSAppleEventDescriptor descriptorWithBoolean:[self boolValue]];
-    }
-
-    if (areEqualEncodings(type, @encode(char))) {
-        char val = [self charValue];
-        return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(short))) {
-        short val = [self shortValue];
-        return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(int))) {
-        int val = [self intValue];
-        return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(long))) {
-        long val = [self longValue];
-        return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(long long))) {
-        long long val = [self longLongValue];
-        return [self jaseDescriptorValueWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(unsigned char))) {
-        unsigned char val = [self unsignedCharValue];
-        return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(unsigned short))) {
-        unsigned short val = [self unsignedShortValue];
-        return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(unsigned int))) {
-        unsigned int val = [self unsignedIntValue];
-        return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(unsigned long))) {
-        unsigned long val = [self unsignedLongValue];
-        return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(unsigned long long))) {
-        unsigned long long val = [self unsignedLongLongValue];
-        return [self jaseDescriptorValueWithUnsignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(float))) {
-        float val = [self floatValue];
-        return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
-    }
-
-    if (areEqualEncodings(type, @encode(double))) {
-        double val = [self doubleValue];
-        return [self jaseDescriptorValueWithFloatP:&val byteCount:sizeof(val)];
-    }
-
-    [NSException raise:@"jaseUnsupportedAEDescriptorConversion"
-                format:@"JavaAppleScriptEngineAdditions: conversion of an NSNumber with objCType '%s' to an aeDescriptor is not supported.", type];
-
-    return nil;
-}
-
-+ (id)numberWithAEDesc:(NSAppleEventDescriptor *)desc {
-    DescType type = [desc descriptorType];
-
-    if ((type == typeTrue) || (type == typeFalse) || (type == typeBoolean)) {
-        return [NSNumber numberWithBool:[desc booleanValue]];
-    }
-
-    if (type == typeSInt16) {
-        SInt16 val = [desc int16Value];
-        return [NSNumber jaseNumberWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (type == typeSInt32) {
-        SInt32 val = [desc int32Value];
-        return [NSNumber jaseNumberWithSignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (type == typeUInt32) {
-        UInt32 val = [desc unsignedInt32Value];
-        return [NSNumber jaseNumberWithUnsignedIntP:&val byteCount:sizeof(val)];
-    }
-
-    if (type == typeIEEE32BitFloatingPoint) {
-        Float32 val = [desc float32Value];
-        return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
-    }
-
-    if (type == typeIEEE64BitFloatingPoint) {
-        Float64 val = [desc float64Value];
-        return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
-    }
-
-    // try to coerce to 64bit floating point
-    desc = [desc coerceToDescriptorType:typeIEEE64BitFloatingPoint];
-    if (desc != nil) {
-        Float64 val = [desc float64Value];
-        return [NSNumber jaseNumberWithFloatP:&val byteCount:sizeof(val)];
-    }
-
-    [NSException raise:@"jaseUnsupportedAEDescriptorConversion"
-                format:@"JavaAppleScriptEngineAdditions: conversion of an NSAppleEventDescriptor with objCType '%s' to an aeDescriptor is not supported.", type];
-
-    return nil;
-}
-
-+ (id) jaseNumberWithSignedIntP:(void *)int_p byteCount:(int)bytes {
-    if (bytes == sizeof(char)) {
-        return [NSNumber numberWithChar:*(char *)int_p];
-    }
-
-    if (bytes == sizeof(short)) {
-        return [NSNumber numberWithShort:*(short *)int_p];
-    }
-
-    if (bytes == sizeof(int)) {
-        return [NSNumber numberWithInt:*(int *)int_p];
-    }
-
-    if (bytes == sizeof(long)) {
-        return [NSNumber numberWithLong:*(long *)int_p];
-    }
-
-    if (bytes == sizeof(long long)) {
-        return [NSNumber numberWithLongLong:*(long long *)int_p];
-    }
-
-    [NSException raise:NSInvalidArgumentException
-                format:@"NSNumber jaseNumberWithSignedIntP:byteCount: number with %i bytes not supported.", bytes];
-
-    return nil;
-}
-
-+ (id) jaseNumberWithUnsignedIntP:(void *)int_p byteCount:(int)bytes {
-    if (bytes == sizeof(unsigned char)) {
-        return [NSNumber numberWithUnsignedChar:*(unsigned char *)int_p];
-    }
-
-    if (bytes == sizeof(unsigned short)) {
-        return [NSNumber numberWithUnsignedShort:*(unsigned short *)int_p];
-    }
-
-    if (bytes == sizeof(unsigned int)) {
-        return [NSNumber numberWithUnsignedInt:*(unsigned int *)int_p];
-    }
-
-    if (bytes == sizeof(unsigned long)) {
-        return [NSNumber numberWithUnsignedLong:*(unsigned long *)int_p];
-    }
-
-    if (bytes == sizeof(unsigned long long)) {
-        return [NSNumber numberWithUnsignedLongLong:*(unsigned long long *)int_p];
-    }
-
-    [NSException raise:NSInvalidArgumentException
-                format:@"NSNumber numberWithUnsignedInt:byteCount: number with %i bytes not supported.", bytes];
-
-    return nil;
-}
-
-+ (id) jaseNumberWithFloatP:(void *)float_p byteCount:(int)bytes {
-    if (bytes == sizeof(float)) {
-        return [NSNumber numberWithFloat:*(float *)float_p];
-    }
-
-    if (bytes == sizeof(double)) {
-        return [NSNumber numberWithFloat:*(double *)float_p];
-    }
-
-    [NSException raise:NSInvalidArgumentException
-                format:@"NSNumber numberWithFloat:byteCount: floating point number with %i bytes not supported.", bytes];
-
-    return nil;
-}
-
-@end
-
-@implementation NSValue (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    const char *type = [self objCType];
-
-    if (areEqualEncodings(type, @encode(NSSize))) {
-        NSSize size = [self sizeValue];
-        return [[NSArray arrayWithObjects:
-                 [NSNumber numberWithFloat:size.width],
-                 [NSNumber numberWithFloat:size.height], nil] aeDescriptorValue];
-    }
-
-    if (areEqualEncodings(type, @encode(NSPoint))) {
-        NSPoint point = [self pointValue];
-        return [[NSArray arrayWithObjects:
-                 [NSNumber numberWithFloat:point.x],
-                 [NSNumber numberWithFloat:point.y], nil] aeDescriptorValue];
-    }
-
-    if (areEqualEncodings(type, @encode(NSRange))) {
-        NSRange range = [self rangeValue];
-        return [[NSArray arrayWithObjects:
-                 [NSNumber numberWithUnsignedInt:range.location],
-                 [NSNumber numberWithUnsignedInt:range.location + range.length], nil] aeDescriptorValue];
-    }
-
-    if (areEqualEncodings(type, @encode(NSRect))) {
-        NSRect rect = [self rectValue];
-        return [[NSArray arrayWithObjects:
-                 [NSNumber numberWithFloat:rect.origin.x],
-                 [NSNumber numberWithFloat:rect.origin.y],
-                 [NSNumber numberWithFloat:rect.origin.x + rect.size.width],
-                 [NSNumber numberWithFloat:rect.origin.y + rect.size.height], nil] aeDescriptorValue];
-    }
-
-    [NSException raise:@"jaseUnsupportedAEDescriptorConversion"
-                format:@"JavaAppleScriptEngineAdditions: conversion of an NSNumber with objCType '%s' to an aeDescriptor is not supported.", type];
-
-    return nil;
-}
-
-@end
-
-
-@implementation NSImage (JavaAppleScriptEngineAdditions)
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    NSData *data = [self TIFFRepresentation];
-    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeTIFF data:data];
-}
-
-+ (NSImage *)imageWithAEDesc:(NSAppleEventDescriptor *)desc {
-    const AEDesc *d = [desc aeDesc];
-    NSMutableData *data = [NSMutableData dataWithLength:AEGetDescDataSize(d)];
-    AEGetDescData(d, [data mutableBytes], [data length]);
-    return [[[NSImage alloc] initWithData:data] autorelease];
-}
-
-@end
-
-
-
-@implementation NSAppleEventDescriptor (JavaAppleScriptEngineAdditions)
-
-// we're going to leak this.  It doesn't matter much for running apps, but
-// for developers it might be nice to try to dispose of it (so it would not clutter the
-// output when testing for leaks)
-static NSMutableDictionary *handlerDict = nil;
-
-- (id)objCObjectValue {
-    if (handlerDict == nil) [NSAppleEventDescriptor jaseSetUpHandlerDict];
-
-    id returnObj;
-    DescType type = [self descriptorType];
-    NSInvocation *handlerInvocation = [handlerDict objectForKey:[NSValue valueWithBytes:&type objCType:@encode(DescType)]];
-    if (handlerInvocation == nil) {
-        if (type == typeType) {
-            DescType subType;
-            AEGetDescData([self aeDesc], &subType, sizeof(subType));
-            if (subType == typeNull) return [NSNull null];
-        }
-        // return raw apple event descriptor if no handler is registered
-        returnObj = self;
-    } else {
-        [handlerInvocation setArgument:&self atIndex:2];
-        [handlerInvocation invoke];
-        [handlerInvocation getReturnValue:&returnObj];
-    }
-
-    return returnObj;
-}
-
-// FIXME - error checking, non nil handler
-+ (void)registerConversionHandler:(id)anObject selector:(SEL)aSelector forDescriptorTypes:(DescType)firstType, ... {
-    if (handlerDict == nil) [NSAppleEventDescriptor jaseSetUpHandlerDict];
-
-    NSInvocation *handlerInvocation = [NSInvocation invocationWithMethodSignature:[anObject methodSignatureForSelector:aSelector]];
-    [handlerInvocation setTarget:anObject];
-    [handlerInvocation setSelector:aSelector];
-
-    DescType aType = firstType;
-    va_list typesList;
-    va_start(typesList, firstType);
-    do {
-        NSValue *type = [NSValue valueWithBytes:&aType objCType:@encode(DescType)];
-        [handlerDict setObject:handlerInvocation forKey:type];
-    } while((aType = va_arg(typesList, DescType)) != 0);
-    va_end(typesList);
-}
-
-
-- (NSAppleEventDescriptor *)aeDescriptorValue {
-    return self;
-}
-
-+ (id)descriptorWithInt16:(SInt16)val {
-    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeSInt16 bytes:&val length:sizeof(val)];
-}
-
-- (SInt16)int16Value {
-    SInt16 retValue;
-    [[[self coerceToDescriptorType:typeSInt16] data] getBytes:&retValue];
-    return retValue;
-}
-
-+ (id)descriptorWithUnsignedInt32:(UInt32)val {
-    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeUInt32 bytes:&val length:sizeof(val)];
-}
-
-- (UInt32)unsignedInt32Value {
-    UInt32 retValue;
-    [[[self coerceToDescriptorType:typeUInt32] data] getBytes:&retValue];
-    return retValue;
-}
-
-
-+ (id)descriptorWithFloat32:(Float32)val {
-    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE32BitFloatingPoint bytes:&val length:sizeof(val)];
-}
-
-- (Float32)float32Value {
-    Float32 retValue;
-    [[[self coerceToDescriptorType:typeIEEE32BitFloatingPoint] data] getBytes:&retValue];
-    return retValue;
-}
-
-
-+ (id)descriptorWithFloat64:(Float64)val {
-    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&val length:sizeof(val)];
-}
-
-- (Float64)float64Value {
-    Float64 retValue;
-    [[[self coerceToDescriptorType:typeIEEE64BitFloatingPoint] data] getBytes:&retValue];
-    return retValue;
-}
-
-+ (id)descriptorWithLongDateTime:(LongDateTime)val {
-    return [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&val length:sizeof(val)];
-}
-
-- (LongDateTime)longDateTimeValue {
-    LongDateTime retValue;
-    [[[self coerceToDescriptorType:typeLongDateTime] data] getBytes:&retValue];
-    return retValue;
-}
-
-+ (void)jaseSetUpHandlerDict {
-    handlerDict = [[NSMutableDictionary alloc] init];
-
-    // register default handlers
-    // types are culled from AEDataModel.h and AERegistry.h
-
-    // string -> NSStrings
-    [NSAppleEventDescriptor registerConversionHandler:[NSString class] selector:@selector(stringWithAEDesc:) forDescriptorTypes:
-     typeUnicodeText, typeText, typeUTF8Text, typeCString, typeChar, nil];
-
-    // number/bool -> NSNumber
-    [NSAppleEventDescriptor registerConversionHandler:[NSNumber class] selector:@selector(numberWithAEDesc:) forDescriptorTypes:
-     typeBoolean, typeTrue, typeFalse,
-     typeSInt16, typeSInt32, typeUInt32, typeSInt64,
-     typeIEEE32BitFloatingPoint, typeIEEE64BitFloatingPoint, type128BitFloatingPoint, nil];
-
-    // list -> NSArray
-    [NSAppleEventDescriptor registerConversionHandler:[NSArray class] selector:@selector(arrayWithAEDesc:) forDescriptorTypes:typeAEList, nil];
-
-    // record -> NSDictionary
-    [NSAppleEventDescriptor registerConversionHandler:[NSDictionary class] selector:@selector(dictionaryWithAEDesc:) forDescriptorTypes:typeAERecord, nil];
-
-    // date -> NSDate
-    [NSAppleEventDescriptor registerConversionHandler:[NSDate class] selector:@selector(dateWithAEDesc:) forDescriptorTypes:typeLongDateTime, nil];
-
-    // images -> NSImage
-    [NSAppleEventDescriptor registerConversionHandler:[NSImage class] selector:@selector(imageWithAEDesc:) forDescriptorTypes:
-     typeTIFF, typeJPEG, typeGIF, typePict, typeIconFamily, typeIconAndMask, nil];
-
-    // vers -> NSString
-    [NSAppleEventDescriptor registerConversionHandler:[NSString class] selector:@selector(versionWithAEDesc:) forDescriptorTypes:typeVersion, nil];
-
-    // null -> NSNull
-    [NSAppleEventDescriptor registerConversionHandler:[NSNull class] selector:@selector(nullWithAEDesc:) forDescriptorTypes:typeNull, nil];
-}
-
-@end
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m
deleted file mode 100644
index 33c8cdc379b..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#import "apple_applescript_AppleScriptEngine.h"
-#import "apple_applescript_AppleScriptEngineFactory.h"
-
-// Must include this before JavaNativeFoundation.h to get jni.h from build
-#include "jni.h"
-#include "jni_util.h"
-
-#import <JavaNativeFoundation/JavaNativeFoundation.h>
-
-#import "NS_Java_ConversionUtils.h"
-#import "AppleScriptExecutionContext.h"
-
-//#define DEBUG 1
-
-/*
- * Declare library specific JNI_Onload entry if static build
- */
-DEF_STATIC_JNI_OnLoad
-
-/*
- * Class:     apple_applescript_AppleScriptEngineFactory
- * Method:    initNative
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_apple_applescript_AppleScriptEngineFactory_initNative
-(JNIEnv *env, jclass clazz)
-{
-    return;
-}
-
-
-/*
- * Class:     apple_applescript_AppleScriptEngine
- * Method:    initNative
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_apple_applescript_AppleScriptEngine_initNative
-(JNIEnv *env, jclass clazz)
-{
-    return;
-}
-
-
-/*
- * Class:     apple_applescript_AppleScriptEngine
- * Method:    createContextFrom
- * Signature: (Ljava/lang/Object;)J
- */
-JNIEXPORT jlong JNICALL Java_apple_applescript_AppleScriptEngine_createContextFrom
-(JNIEnv *env, jclass clazz, jobject javaContext)
-{
-    NSObject *obj = nil;
-
-JNF_COCOA_ENTER(env);
-
-    obj = [[JavaAppleScriptEngineCoercion coercer] coerceJavaObject:javaContext withEnv:env];
-
-#ifdef DEBUG
-    NSLog(@"converted context: %@", obj);
-#endif
-
-    CFRetain(obj);
-
-JNF_COCOA_EXIT(env);
-
-    return ptr_to_jlong(obj);
-}
-
-
-/*
- * Class:     apple_applescript_AppleScriptEngine
- * Method:    createObjectFrom
- * Signature: (J)Ljava/lang/Object;
- */
-JNIEXPORT jobject JNICALL Java_apple_applescript_AppleScriptEngine_createObjectFrom
-(JNIEnv *env, jclass clazz, jlong nativeContext)
-{
-    jobject obj = NULL;
-
-JNF_COCOA_ENTER(env);
-
-    obj = [[JavaAppleScriptEngineCoercion coercer] coerceNSObject:(id)jlong_to_ptr(nativeContext) withEnv:env];
-
-JNF_COCOA_EXIT(env);
-
-    return obj;
-}
-
-
-/*
- * Class:     apple_applescript_AppleScriptEngine
- * Method:    disposeContext
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_apple_applescript_AppleScriptEngine_disposeContext
-(JNIEnv *env, jclass clazz, jlong nativeContext)
-{
-
-JNF_COCOA_ENTER(env);
-
-    id obj = (id)jlong_to_ptr(nativeContext);
-    if (obj != nil) CFRelease(obj);
-
-JNF_COCOA_EXIT(env);
-
-}
-
-
-/*
- * Class:     apple_applescript_AppleScriptEngine
- * Method:    evalScript
- * Signature: (Ljava/lang/String;J)J
- */
-JNIEXPORT jlong JNICALL Java_apple_applescript_AppleScriptEngine_evalScript
-(JNIEnv *env, jclass clazz, jstring ascript, jlong contextptr)
-{
-    id retval = nil;
-
-JNF_COCOA_ENTER(env);
-
-    NSDictionary *ncontext = jlong_to_ptr(contextptr);
-    NSString *source = JNFJavaToNSString(env, ascript);
-
-#ifdef DEBUG
-    NSLog(@"evalScript(source:\"%@\" context: %@)", source, ncontext);
-#endif
-
-    AppleScriptExecutionContext *scriptInvocationCtx = [[[AppleScriptExecutionContext alloc] initWithSource:source context:ncontext] autorelease];
-    retval = [scriptInvocationCtx invokeWithEnv:env];
-
-#ifdef DEBUG
-    NSLog(@"returning: %@", retval);
-#endif
-
-    if (retval) CFRetain(retval);
-
-JNF_COCOA_EXIT(env);
-
-    return ptr_to_jlong(retval);
-}
-
-
-/*
- * Class:     apple_applescript_AppleScriptEngine
- * Method:    evalScriptFromURL
- * Signature: (Ljava/lang/String;J)J
- */
-JNIEXPORT jlong JNICALL Java_apple_applescript_AppleScriptEngine_evalScriptFromURL
-(JNIEnv *env, jclass clazz, jstring afilename, jlong contextptr)
-{
-    id retval = nil;
-
-JNF_COCOA_ENTER(env);
-
-    NSDictionary *ncontext = jlong_to_ptr(contextptr);
-    NSString *filename = JNFJavaToNSString(env, afilename);
-
-#ifdef DEBUG
-    NSLog(@"evalScript(filename:\"%@\" context: %@)", filename, ncontext);
-#endif
-
-    AppleScriptExecutionContext *scriptInvocationCtx = [[[AppleScriptExecutionContext alloc] initWithFile:filename context:ncontext] autorelease];
-    retval = [scriptInvocationCtx invokeWithEnv:env];
-
-#ifdef DEBUG
-    NSLog(@"returning: %@", retval);
-#endif
-
-    if (retval) CFRetain(retval);
-
-JNF_COCOA_EXIT(env);
-
-    return ptr_to_jlong(retval);
-}
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.h b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.h
deleted file mode 100644
index 863d0a711a0..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#import <JavaNativeFoundation/JavaNativeFoundation.h>
-
-
-@interface AppleScriptExecutionContext : NSObject {
-    NSString *source;
-    BOOL isFile;
-    NSDictionary *context;
-    NSDictionary *error;
-    id returnValue;
-}
-
-@property (nonatomic, retain) NSString *source;
-@property (nonatomic, retain) NSDictionary *context;
-@property (nonatomic, retain) NSDictionary *error;
-@property (nonatomic, retain) id returnValue;
-
-- (id) initWithSource:(NSString *)source context:(NSDictionary *)context;
-- (id) initWithFile:(NSString *)filename context:(NSDictionary *)context;
-- (id) invokeWithEnv:(JNIEnv *)env;
-
-@end
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.m b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.m
deleted file mode 100644
index 9b4d4d705e1..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptExecutionContext.m
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#import "AppleScriptExecutionContext.h"
-
-#import <Carbon/Carbon.h>
-
-#import "AS_NS_ConversionUtils.h"
-
-
-@implementation AppleScriptExecutionContext
-
-@synthesize source;
-@synthesize context;
-@synthesize error;
-@synthesize returnValue;
-
-- (id) init:(NSString *)sourceIn context:(id)contextIn {
-    self = [super init];
-    if (!self) return self;
-
-    self.source = sourceIn;
-    self.context = contextIn;
-    self.returnValue = nil;
-    self.error = nil;
-
-    return self;
-}
-
-- (id) initWithSource:(NSString *)sourceIn context:(NSDictionary *)contextIn {
-    self = [self init:sourceIn context:contextIn];
-    isFile = NO;
-    return self;
-}
-
-- (id) initWithFile:(NSString *)filenameIn context:(NSDictionary *)contextIn {
-    self = [self init:filenameIn context:contextIn];
-    isFile = YES;
-    return self;
-}
-
-- (void) dealloc {
-    self.source = nil;
-    self.context = nil;
-    self.returnValue = nil;
-    self.error = nil;
-
-    [super dealloc];
-}
-
-- (NSAppleScript *) scriptFromURL {
-    NSURL *url = [NSURL URLWithString:source];
-    NSDictionary *err = nil;
-    NSAppleScript *script = [[[NSAppleScript alloc] initWithContentsOfURL:url error:(&err)] autorelease];
-    if (err != nil) self.error = err;
-    return script;
-}
-
-- (NSAppleScript *) scriptFromSource {
-    return [[[NSAppleScript alloc] initWithSource:source] autorelease];
-}
-
-- (NSAppleEventDescriptor *) functionInvocationEvent {
-    NSString *function = [[context objectForKey:@"javax_script_function"] description];
-    if (function == nil) return nil;
-
-    // wrap the arg in an array if it is not already a list
-    id args = [context objectForKey:@"javax_script_argv"];
-    if (![args isKindOfClass:[NSArray class]]) {
-        args = [NSArray arrayWithObjects:args, nil];
-    }
-
-    // triangulate our target
-    int pid = [[NSProcessInfo processInfo] processIdentifier];
-    NSAppleEventDescriptor* targetAddress = [NSAppleEventDescriptor descriptorWithDescriptorType:typeKernelProcessID
-                                                                                           bytes:&pid
-                                                                                          length:sizeof(pid)];
-
-    // create the event to call a subroutine in the script
-    NSAppleEventDescriptor* event = [[NSAppleEventDescriptor alloc] initWithEventClass:kASAppleScriptSuite
-                                                                               eventID:kASSubroutineEvent
-                                                                      targetDescriptor:targetAddress
-                                                                              returnID:kAutoGenerateReturnID
-                                                                         transactionID:kAnyTransactionID];
-
-    // set up the handler
-    NSAppleEventDescriptor* subroutineDescriptor = [NSAppleEventDescriptor descriptorWithString:[function lowercaseString]];
-    [event setParamDescriptor:subroutineDescriptor forKeyword:keyASSubroutineName];
-
-    // set up the arguments
-    [event setParamDescriptor:[args aeDescriptorValue] forKeyword:keyDirectObject];
-
-    return [event autorelease];
-}
-
-- (void) invoke {
-    // create our script
-    NSAppleScript *script = isFile ? [self scriptFromURL] : [self scriptFromSource];
-    if (self.error != nil) return;
-
-    // find out if we have a subroutine to call
-    NSAppleEventDescriptor *fxnInvkEvt = [self functionInvocationEvent];
-
-    // exec!
-    NSAppleEventDescriptor *desc = nil;
-    NSDictionary *err = nil;
-    if (fxnInvkEvt == nil) {
-        desc = [script executeAndReturnError:(&err)];
-    } else {
-        desc = [script executeAppleEvent:fxnInvkEvt error:(&err)];
-    }
-
-    // if we encountered an exception, stash and bail
-    if (err != nil) {
-        self.error = err;
-        return;
-    }
-
-    // convert to NSObjects, and return in ivar
-    self.returnValue = [desc objCObjectValue];
-}
-
-- (id) invokeWithEnv:(JNIEnv *)env {
-    BOOL useAnyThread = [@"any-thread" isEqual:[context valueForKey:@"javax_script_threading"]];
-
-    // check if we are already on the AppKit thread, if desired
-    if(pthread_main_np() || useAnyThread) {
-        [self invoke];
-    } else {
-        [JNFRunLoop performOnMainThread:@selector(invoke) on:self withObject:nil waitUntilDone:YES];
-    }
-
-    // if we have an exception parked in our ivar, snarf the message (if there is one), and toss a ScriptException
-    if (self.error != nil) {
-        NSString *asErrString = [self.error objectForKey:NSAppleScriptErrorMessage];
-        if (!asErrString) asErrString = @"AppleScriptEngine failed to execute script."; // usually when we fail to load a file
-        [JNFException raise:env as:"javax/script/ScriptException" reason:[asErrString UTF8String]];
-    }
-
-    return self.returnValue;
-}
-
-@end
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.h b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.h
deleted file mode 100644
index 8e5bd24b766..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#import <JavaNativeFoundation/JavaNativeFoundation.h>
-
-
-@interface JavaAppleScriptEngineCoercion : NSObject
-
-+ (JNFTypeCoercer *) coercer;
-
-@end
diff --git a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.m b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.m
deleted file mode 100644
index 6114ce7a3bb..00000000000
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/NS_Java_ConversionUtils.m
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#import "NS_Java_ConversionUtils.h"
-
-#import <Cocoa/Cocoa.h>
-
-
-@interface JavaAppleScriptBaseConverter : NSObject <JNFTypeCoercion>
-@end
-
-@interface JavaAppleScriptImageConverter : NSObject <JNFTypeCoercion>
-@end
-
-@interface JavaAppleScriptVersionConverter : NSObject <JNFTypeCoercion>
-@end
-
-@interface JavaAppleScriptNullConverter : NSObject <JNFTypeCoercion>
-@end
-
-
-@implementation JavaAppleScriptEngineCoercion
-
-static JNFTypeCoercer *appleScriptCoercer = nil;
-
-+ (JNFTypeCoercer *) coercer {
-    if (appleScriptCoercer) return appleScriptCoercer;
-
-    id asSpecificCoercions = [[JNFDefaultCoercions defaultCoercer] deriveCoercer];
-    [asSpecificCoercions addCoercion:[[[JavaAppleScriptImageConverter alloc] init] autorelease] forNSClass:[NSImage class] javaClass:@"java/awt/Image"];
-    [asSpecificCoercions addCoercion:[[[JavaAppleScriptVersionConverter alloc] init] autorelease] forNSClass:[NSAppleEventDescriptor class] javaClass:nil];
-    [asSpecificCoercions addCoercion:[[[JavaAppleScriptNullConverter alloc] init] autorelease] forNSClass:[NSNull class] javaClass:nil];
-
-    return appleScriptCoercer = [asSpecificCoercions retain];
-}
-
-@end
-
-
-// [NSObject description] <-> java.lang.Object.toString()
-@implementation JavaAppleScriptBaseConverter
-
-// by default, bizzare NSObjects will have -description called on them, and passed back to Java like that
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return JNFNSToJavaString(env, [obj description]);
-}
-
-// by default, bizzare Java objects will be toString()'d and passed to AppleScript like that
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return JNFObjectToString(env, obj);
-}
-
-@end
-
-
-// NSImage <-> apple.awt.CImage
-@implementation JavaAppleScriptImageConverter
-
-static JNF_CLASS_CACHE(jc_CImage, "apple/awt/CImage");
-static JNF_STATIC_MEMBER_CACHE(jm_CImage_getCreator, jc_CImage, "getCreator", "()Lapple/awt/CImage$Creator;");
-static JNF_MEMBER_CACHE(jm_CImage_getNSImage, jc_CImage, "getNSImage", "()J");
-
-static JNF_CLASS_CACHE(jc_CImage_Generator, "apple/awt/CImage$Creator");
-static JNF_MEMBER_CACHE(jm_CImage_Generator_createImageFromPtr, jc_CImage_Generator, "createImage", "(J)Ljava/awt/image/BufferedImage;");
-static JNF_MEMBER_CACHE(jm_CImage_Generator_createImageFromImg, jc_CImage_Generator, "createImage", "(Ljava/awt/Image;)Lapple/awt/CImage;");
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    NSImage *img = (NSImage *)obj;
-    CFRetain(img);
-    jobject creator = JNFCallStaticObjectMethod(env, jm_CImage_getCreator);
-    jobject jobj = JNFCallObjectMethod(env, creator, jm_CImage_Generator_createImageFromPtr, ptr_to_jlong(img));
-    return jobj;
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    jobject cimage = obj;
-    if (!JNFIsInstanceOf(env, obj, &jc_CImage)) {
-        jobject creator = JNFCallStaticObjectMethod(env, jm_CImage_getCreator);
-        cimage = JNFCallObjectMethod(env, creator, jm_CImage_Generator_createImageFromImg, obj);
-    }
-
-    jlong nsImagePtr = JNFCallLongMethod(env, cimage, jm_CImage_getNSImage);
-
-    NSImage *img = (NSImage *)jlong_to_ptr(nsImagePtr);
-    return [[img retain] autorelease];
-}
-
-@end
-
-
-// NSAppleEventDescriptor('vers') -> java.lang.String
-@implementation JavaAppleScriptVersionConverter
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    NSAppleEventDescriptor *desc = (NSAppleEventDescriptor *)obj;
-
-    const AEDesc *aeDesc = [desc aeDesc];
-    if (aeDesc->descriptorType == typeNull) {
-        return NULL;
-    }
-
-    return JNFNSToJavaString(env, [obj description]);
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return nil; // there is no Java object that represents a "version"
-}
-
-@end
-
-
-// NSNull <-> null
-@implementation JavaAppleScriptNullConverter
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return NULL;
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return nil;
-}
-
-@end

From 5bfc44dca23a7c9c29b280595df85cbb0417ec16 Mon Sep 17 00:00:00 2001
From: Prasanta Sadhukhan <psadhukhan@openjdk.org>
Date: Tue, 8 Dec 2015 11:25:47 +0300
Subject: [PATCH 20/62] 7160052: GlyphVector.setGlyphPosition can throw an
 exception on valid input

Reviewed-by: jdv, serb
---
 .../classes/sun/font/StandardGlyphVector.java |  8 ++-
 .../TestStandardGlyphVectorBug.java           | 58 +++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 jdk/test/java/awt/font/GlyphVector/TestStandardGlyphVectorBug.java

diff --git a/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java b/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
index 06abf9de163..69f1d4babc2 100644
--- a/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
+++ b/jdk/src/java.desktop/share/classes/sun/font/StandardGlyphVector.java
@@ -445,13 +445,19 @@ public class StandardGlyphVector extends GlyphVector {
     }
 
     public void setGlyphPosition(int ix, Point2D pos) {
+        if (ix < 0 || ix > glyphs.length) {
+            throw new IndexOutOfBoundsException("ix = " + ix);
+        }
+
         initPositions();
 
         int ix2 = ix << 1;
         positions[ix2] = (float)pos.getX();
         positions[ix2 + 1] = (float)pos.getY();
 
-        clearCaches(ix);
+        if (ix < glyphs.length) {
+            clearCaches(ix);
+        }
         addFlags(FLAG_HAS_POSITION_ADJUSTMENTS);
     }
 
diff --git a/jdk/test/java/awt/font/GlyphVector/TestStandardGlyphVectorBug.java b/jdk/test/java/awt/font/GlyphVector/TestStandardGlyphVectorBug.java
new file mode 100644
index 00000000000..c4dbda40837
--- /dev/null
+++ b/jdk/test/java/awt/font/GlyphVector/TestStandardGlyphVectorBug.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+/**
+ * @test
+ * @bug 7160052
+ * @run main TestStandardGlyphVectorBug
+ * @summary GlyphVector.setGlyphPosition should not throw an exception on valid input
+ */
+public class TestStandardGlyphVectorBug
+{
+    public static void main(String[] args)
+    {
+        Font defaultFont = new Font(null);
+        FontRenderContext defaultFrc = new FontRenderContext(new AffineTransform(),
+                                                             true, true);
+        GlyphVector gv = defaultFont.createGlyphVector(defaultFrc, "test");
+
+        //this causes the bounds to be cached
+        //which is necessary to trigger the bug
+        gv.getGlyphLogicalBounds(0);
+
+        //this correctly gets the position of the overall advance
+        Point2D glyphPosition = gv.getGlyphPosition(gv.getNumGlyphs());
+
+        // this sets the position of the overall advance,
+        // but also incorrectly tries to clear the bounds cache
+        // of a specific glyph indexed by the glyphIndex parameter
+        // even if the glyphIndex represents the overall advance
+        // (i.e. if glyphIndex == getNumGlyphs())
+        gv.setGlyphPosition(gv.getNumGlyphs(), glyphPosition);
+    }
+}

From bb6d5ef30c8b1c8b5ccc6366e3efd8318227abba Mon Sep 17 00:00:00 2001
From: Erik Joelsson <erikj@openjdk.org>
Date: Tue, 8 Dec 2015 12:05:51 +0100
Subject: [PATCH 21/62] 8144857: Intermittent build error building
 jdk/src/demo/solaris/jni/Poller/Poller.c

Reviewed-by: dholmes
---
 jdk/make/CompileDemos.gmk | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jdk/make/CompileDemos.gmk b/jdk/make/CompileDemos.gmk
index 5bb6ed39d2a..423378389cc 100644
--- a/jdk/make/CompileDemos.gmk
+++ b/jdk/make/CompileDemos.gmk
@@ -459,7 +459,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
   # We can only compile native code after java has been compiled (since we
   # depend on generated .h files)
   $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller/Poller.o: \
-      $(BUILD_DEMO_JAVA_POLLER_COMPILE_TARGETS)
+      $(BUILD_DEMO_JAVA_Poller_COMPILE_TARGET)
 
   # Copy to image
   $(SUPPORT_OUTPUTDIR)/demos/image/jni/Poller/README.txt: \

From 7c018b1a000ff5f480b7c5acfd2770a23bb6e583 Mon Sep 17 00:00:00 2001
From: Ambarish Rapte <arapte@openjdk.org>
Date: Wed, 9 Dec 2015 02:41:51 +0400
Subject: [PATCH 22/62] 8060137: Removing Text from TextField / TextArea is not
 possible after typing

Reviewed-by: ssadetsky, psadhukhan
---
 .../share/classes/java/awt/TextComponent.java |  22 ++--
 .../TextAreaEditing/TextAreaEditing.java      |  28 ++++-
 .../TextFieldEditing/TextFieldEditing.java    | 113 ++++++++++++++++++
 3 files changed, 154 insertions(+), 9 deletions(-)
 create mode 100644 jdk/test/java/awt/TextField/TextFieldEditing/TextFieldEditing.java

diff --git a/jdk/src/java.desktop/share/classes/java/awt/TextComponent.java b/jdk/src/java.desktop/share/classes/java/awt/TextComponent.java
index 9e7c22a49bb..191412a30b7 100644
--- a/jdk/src/java.desktop/share/classes/java/awt/TextComponent.java
+++ b/jdk/src/java.desktop/share/classes/java/awt/TextComponent.java
@@ -229,15 +229,21 @@ public class TextComponent extends Component implements Accessible {
      * @see         java.awt.TextComponent#getText
      */
     public synchronized void setText(String t) {
-        boolean skipTextEvent = (text == null || text.isEmpty())
-                && (t == null || t.isEmpty());
-        text = (t != null) ? t : "";
+        if (t == null) {
+            t = "";
+        }
         TextComponentPeer peer = (TextComponentPeer)this.peer;
-        // Please note that we do not want to post an event
-        // if TextArea.setText() or TextField.setText() replaces an empty text
-        // by an empty text, that is, if component's text remains unchanged.
-        if (peer != null && !skipTextEvent) {
-            peer.setText(text);
+        if (peer != null) {
+            text = peer.getText();
+            // Please note that we do not want to post an event
+            // if TextArea.setText() or TextField.setText() replaces text
+            // by same text, that is, if component's text remains unchanged.
+            if (!t.equals(text)) {
+                text = t;
+                peer.setText(text);
+            }
+        } else {
+            text = t;
         }
     }
 
diff --git a/jdk/test/java/awt/TextArea/TextAreaEditing/TextAreaEditing.java b/jdk/test/java/awt/TextArea/TextAreaEditing/TextAreaEditing.java
index f3306784ef8..6b7dcfaf2c0 100644
--- a/jdk/test/java/awt/TextArea/TextAreaEditing/TextAreaEditing.java
+++ b/jdk/test/java/awt/TextArea/TextAreaEditing/TextAreaEditing.java
@@ -23,16 +23,23 @@
 
 /*
  @test
- @bug 8040322
+ @bug 8040322 8060137
+ @library ../../regtesthelpers
+ @build Util
  @summary Test TextArea APIs replaceRange, insert, append & setText
  @run main TextAreaEditing
  */
 
 import java.awt.Frame;
+import java.awt.Robot;
 import java.awt.TextArea;
+import java.awt.AWTException;
+import java.awt.event.KeyEvent;
+import test.java.awt.regtesthelpers.Util;
 
 public class TextAreaEditing {
 
+    final static Robot robot = Util.createRobot();
     private int testFailCount;
     private boolean isTestFail;
     private StringBuilder testFailMessage;
@@ -61,6 +68,7 @@ public class TextAreaEditing {
         textArea.testReplaceRange();
         textArea.testInsert();
         textArea.testAppend();
+        textArea.testSetText();
         textArea.checkFailures();
         textArea.dispose();
     }
@@ -119,6 +127,24 @@ public class TextAreaEditing {
         checkTest("");
     }
 
+    private void testSetText() {
+        textArea.setText(null);
+        textArea.requestFocus();
+        Util.clickOnComp(textArea, robot);
+        Util.waitForIdle(robot);
+        robot.keyPress(KeyEvent.VK_A);
+        robot.delay(5);
+        robot.keyRelease(KeyEvent.VK_A);
+        Util.waitForIdle(robot);
+        textArea.setText(null);
+        checkTest("");
+        textArea.setText("CaseSensitive");
+        checkTest("CaseSensitive");
+        textArea.setText("caseSensitive");
+        checkTest("caseSensitive");
+
+    }
+
     private void checkTest(String str) {
         if (str != null && !str.equals(textArea.getText())) {
             testFailMessage.append("TestFail line : ");
diff --git a/jdk/test/java/awt/TextField/TextFieldEditing/TextFieldEditing.java b/jdk/test/java/awt/TextField/TextFieldEditing/TextFieldEditing.java
new file mode 100644
index 00000000000..503b6e35129
--- /dev/null
+++ b/jdk/test/java/awt/TextField/TextFieldEditing/TextFieldEditing.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8060137
+ @library ../../regtesthelpers
+ @build Util
+ @summary Test TextField setText API
+ @run main TextFieldEditing
+ */
+
+import java.awt.Frame;
+import java.awt.Robot;
+import java.awt.TextField;
+import java.awt.AWTException;
+import java.awt.event.KeyEvent;
+import test.java.awt.regtesthelpers.Util;
+
+public class TextFieldEditing {
+
+    final static Robot robot = Util.createRobot();
+    private int testFailCount;
+    private boolean isTestFail;
+    private StringBuilder testFailMessage;
+
+    private Frame mainFrame;
+    private TextField textField;
+
+    private TextFieldEditing() {
+        testFailMessage = new StringBuilder();
+        mainFrame = new Frame();
+        mainFrame.setSize(200, 200);
+
+        textField = new TextField();
+        mainFrame.add(textField);
+        mainFrame.setVisible(true);
+    }
+
+    private void dispose() {
+        if (mainFrame != null) {
+            mainFrame.dispose();
+        }
+    }
+
+    public static void main(String[] s) {
+        TextFieldEditing textField = new TextFieldEditing();
+        textField.testSetText();
+        textField.checkFailures();
+        textField.dispose();
+    }
+
+    private void testSetText() {
+        textField.setText(null);
+        textField.requestFocus();
+        Util.clickOnComp(textField, robot);
+        Util.waitForIdle(robot);
+        robot.keyPress(KeyEvent.VK_A);
+        robot.delay(5);
+        robot.keyRelease(KeyEvent.VK_A);
+        Util.waitForIdle(robot);
+        textField.setText(null);
+        checkTest("");
+        textField.setText("CaseSensitive");
+        checkTest("CaseSensitive");
+        textField.setText("caseSensitive");
+        checkTest("caseSensitive");
+    }
+
+    private void checkTest(String str) {
+        if (str != null && !str.equals(textField.getText())) {
+            testFailMessage.append("TestFail line : ");
+            testFailMessage.append(Thread.currentThread().getStackTrace()[2].
+                    getLineNumber());
+            testFailMessage.append(" TextField string : \"");
+            testFailMessage.append(textField.getText());
+            testFailMessage.append("\" does not match expected string : \"");
+            testFailMessage.append(str).append("\"");
+            testFailMessage.append(System.getProperty("line.separator"));
+            testFailCount++;
+            isTestFail = true;
+        }
+    }
+
+    private void checkFailures() {
+        if (isTestFail) {
+            testFailMessage.insert(0, "Test Fail count : " + testFailCount
+                    + System.getProperty("line.separator"));
+            dispose();
+            throw new RuntimeException(testFailMessage.toString());
+        }
+    }
+}

From 18ace0f732d8acfd7bfaf8f18a50549d8822bf20 Mon Sep 17 00:00:00 2001
From: Manajit Halder <manajit.halder@oracle.com>
Date: Tue, 8 Dec 2015 19:50:14 +0300
Subject: [PATCH 23/62] 7159591: [macosx] In SetFontTest there's no space for
 the second button

Reviewed-by: arapte, serb
---
 jdk/test/java/awt/List/SetFontTest/SetFontTest.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/jdk/test/java/awt/List/SetFontTest/SetFontTest.html b/jdk/test/java/awt/List/SetFontTest/SetFontTest.html
index db33b8c83a8..3ac0d99fc51 100644
--- a/jdk/test/java/awt/List/SetFontTest/SetFontTest.html
+++ b/jdk/test/java/awt/List/SetFontTest/SetFontTest.html
@@ -38,6 +38,6 @@
 
 <p> See the dialog box (usually in upper left corner) for instructions</p>
 
-<APPLET CODE="SetFontTest.class" WIDTH=200 HEIGHT=200></APPLET>
+<APPLET CODE="SetFontTest.class" WIDTH=200 HEIGHT=220></APPLET>
 </body>
 </html>

From 44a8a73eb6585a158e95946673d8ff6a943daca6 Mon Sep 17 00:00:00 2001
From: Xueming Shen <sherman@openjdk.org>
Date: Tue, 8 Dec 2015 09:25:01 -0800
Subject: [PATCH 24/62] 8142508: To bring j.u.z.ZipFile's native implementation
 to Java to remove the expensive jni cost and mmap crash risk

Reviewed-by: coffeys
---
 jdk/make/mapfiles/libzip/mapfile-vers         |  22 +-
 jdk/make/mapfiles/libzip/reorder-sparc        |  16 -
 jdk/make/mapfiles/libzip/reorder-sparcv9      |  15 -
 jdk/make/mapfiles/libzip/reorder-x86          |  18 -
 .../share/classes/java/util/jar/JarFile.java  |   5 +-
 .../share/classes/java/util/zip/ZipCoder.java |  21 +-
 .../share/classes/java/util/zip/ZipFile.java  | 837 ++++++++++++++----
 .../share/classes/java/util/zip/ZipUtils.java |  79 +-
 .../internal/misc/JavaUtilZipFileAccess.java  |   1 +
 .../java.base/share/classes/sun/misc/VM.java  |   3 -
 .../java.base/share/native/libzip/ZipFile.c   | 406 ---------
 jdk/test/java/util/zip/ZipFile/ReadZip.java   |   3 +-
 .../java/util/zip/ZipFile/TestZipFile.java    | 361 ++++++++
 13 files changed, 1115 insertions(+), 672 deletions(-)
 delete mode 100644 jdk/src/java.base/share/native/libzip/ZipFile.c
 create mode 100644 jdk/test/java/util/zip/ZipFile/TestZipFile.java

diff --git a/jdk/make/mapfiles/libzip/mapfile-vers b/jdk/make/mapfiles/libzip/mapfile-vers
index ceace23f26d..c1ab48c10cf 100644
--- a/jdk/make/mapfiles/libzip/mapfile-vers
+++ b/jdk/make/mapfiles/libzip/mapfile-vers
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2015, 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,7 +27,6 @@
 
 SUNWprivate_1.1 {
 	global:
-		Java_java_util_jar_JarFile_getMetaInfEntryNames;
 		Java_java_util_zip_Adler32_update;
 		Java_java_util_zip_Adler32_updateBytes;
 		Java_java_util_zip_Adler32_updateByteBuffer;
@@ -48,25 +47,6 @@ SUNWprivate_1.1 {
 		Java_java_util_zip_Inflater_initIDs;
 		Java_java_util_zip_Inflater_reset;
 		Java_java_util_zip_Inflater_setDictionary;
-		Java_java_util_zip_ZipFile_close;
-		Java_java_util_zip_ZipFile_getCommentBytes;
-		Java_java_util_zip_ZipFile_freeEntry;
-		Java_java_util_zip_ZipFile_getEntry;
-		Java_java_util_zip_ZipFile_getEntryBytes;
-		Java_java_util_zip_ZipFile_getEntryCrc;
-		Java_java_util_zip_ZipFile_getEntryCSize;
-		Java_java_util_zip_ZipFile_getEntryFlag;
-		Java_java_util_zip_ZipFile_getEntryMethod;
-		Java_java_util_zip_ZipFile_getEntrySize;
-		Java_java_util_zip_ZipFile_getEntryTime;
-		Java_java_util_zip_ZipFile_getNextEntry;
-		Java_java_util_zip_ZipFile_getZipMessage;
-		Java_java_util_zip_ZipFile_getTotal;
-		Java_java_util_zip_ZipFile_initIDs;
-		Java_java_util_zip_ZipFile_open;
-		Java_java_util_zip_ZipFile_read;
-		Java_java_util_zip_ZipFile_startsWithLOC;
-
 		ZIP_Close;
 		ZIP_CRC32;
 		ZIP_FindEntry;
diff --git a/jdk/make/mapfiles/libzip/reorder-sparc b/jdk/make/mapfiles/libzip/reorder-sparc
index 154e7998a53..63b2ad6fc28 100644
--- a/jdk/make/mapfiles/libzip/reorder-sparc
+++ b/jdk/make/mapfiles/libzip/reorder-sparc
@@ -16,30 +16,14 @@ text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
-text: .text%Java_java_util_zip_ZipFile_initIDs;
-text: .text%Java_java_util_zip_ZipFile_open;
-text: .text%Java_java_util_zip_ZipFile_getTotal;
-text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
-text: .text%Java_java_util_zip_ZipFile_getEntry;
-text: .text%Java_java_util_zip_ZipFile_freeEntry;
-text: .text%Java_java_util_zip_ZipFile_getEntryTime;
-text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
-text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
-text: .text%Java_java_util_zip_ZipFile_getEntrySize;
-text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
-text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
-text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
 text: .text%Java_java_util_zip_Inflater_initIDs;
 text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
 text: .text%zcalloc;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
-text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
-text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
 text: .text%Java_java_util_zip_Inflater_reset;
 text: .text%Java_java_util_zip_Inflater_end;
 text: .text%inflateEnd;
-text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
diff --git a/jdk/make/mapfiles/libzip/reorder-sparcv9 b/jdk/make/mapfiles/libzip/reorder-sparcv9
index 89690b8dabb..caca118de98 100644
--- a/jdk/make/mapfiles/libzip/reorder-sparcv9
+++ b/jdk/make/mapfiles/libzip/reorder-sparcv9
@@ -15,19 +15,6 @@ text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
-text: .text%Java_java_util_zip_ZipFile_initIDs;
-text: .text%Java_java_util_zip_ZipFile_open;
-text: .text%Java_java_util_zip_ZipFile_getTotal;
-text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
-text: .text%Java_java_util_zip_ZipFile_getEntry;
-text: .text%Java_java_util_zip_ZipFile_freeEntry;
-text: .text%Java_java_util_zip_ZipFile_getEntryTime;
-text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
-text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
-text: .text%Java_java_util_zip_ZipFile_getEntrySize;
-text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
-text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
-text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
 text: .text%Java_java_util_zip_Inflater_initIDs;
 text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
@@ -35,7 +22,6 @@ text: .text%zcalloc;
 text: .text%inflateReset;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
 text: .text%inflate;
-text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
 text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
@@ -43,6 +29,5 @@ text: .text%ZIP_ReadEntry;
 text: .text%InflateFully;
 text: .text%inflateEnd;
 text: .text%Java_java_util_zip_Inflater_reset;
-text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
 text: .text%Java_java_util_zip_Inflater_end;
diff --git a/jdk/make/mapfiles/libzip/reorder-x86 b/jdk/make/mapfiles/libzip/reorder-x86
index 746948315eb..dfd57c7752e 100644
--- a/jdk/make/mapfiles/libzip/reorder-x86
+++ b/jdk/make/mapfiles/libzip/reorder-x86
@@ -16,34 +16,16 @@ text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
-text: .text%Java_java_util_zip_ZipFile_initIDs;
-text: .text%Java_java_util_zip_ZipFile_open;
-text: .text%Java_java_util_zip_ZipFile_getTotal;
-text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
-text: .text%Java_java_util_zip_ZipFile_getEntry;
-text: .text%Java_java_util_zip_ZipFile_freeEntry;
-text: .text%Java_java_util_zip_ZipFile_getEntryTime;
-text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
-text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
-text: .text%Java_java_util_zip_ZipFile_getEntrySize;
-text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
-text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
-text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
-text: .text%Java_java_util_zip_Inflater_initIDs;
-text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
 text: .text%zcalloc;
 text: .text%inflateReset;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
 text: .text%inflate;
-text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
-text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
 text: .text%ZIP_ReadEntry;
 text: .text%InflateFully;
 text: .text%inflateEnd;
 text: .text%Java_java_util_zip_Inflater_reset;
-text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
 text: .text%Java_java_util_zip_Inflater_end;
diff --git a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java
index 6d16a517ac9..62734ceefbd 100644
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java
@@ -203,7 +203,10 @@ class JarFile extends ZipFile {
         return man;
     }
 
-    private native String[] getMetaInfEntryNames();
+    private String[] getMetaInfEntryNames() {
+        return jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess()
+                                              .getMetaInfEntryNames((ZipFile)this);
+    }
 
     /**
      * Returns the {@code JarEntry} for the given entry name or
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java b/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java
index b920b820e03..243d6e8c065 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java
@@ -43,7 +43,7 @@ import sun.nio.cs.ArrayEncoder;
 
 final class ZipCoder {
 
-    String toString(byte[] ba, int length) {
+    String toString(byte[] ba, int off, int length) {
         CharsetDecoder cd = decoder().reset();
         int len = (int)(length * cd.maxCharsPerByte());
         char[] ca = new char[len];
@@ -53,12 +53,12 @@ final class ZipCoder {
         // CodingErrorAction.REPLACE mode. ZipCoder uses
         // REPORT mode.
         if (isUTF8 && cd instanceof ArrayDecoder) {
-            int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
+            int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca);
             if (clen == -1)    // malformed
                 throw new IllegalArgumentException("MALFORMED");
             return new String(ca, 0, clen);
         }
-        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
+        ByteBuffer bb = ByteBuffer.wrap(ba, off, length);
         CharBuffer cb = CharBuffer.wrap(ca);
         CoderResult cr = cd.decode(bb, cb, true);
         if (!cr.isUnderflow())
@@ -69,8 +69,12 @@ final class ZipCoder {
         return new String(ca, 0, cb.position());
     }
 
+    String toString(byte[] ba, int length) {
+        return toString(ba, 0, length);
+    }
+
     String toString(byte[] ba) {
-        return toString(ba, ba.length);
+        return toString(ba, 0, ba.length);
     }
 
     byte[] getBytes(String s) {
@@ -111,13 +115,16 @@ final class ZipCoder {
         return utf8.getBytes(s);
     }
 
-
     String toStringUTF8(byte[] ba, int len) {
+        return toStringUTF8(ba, 0, len);
+    }
+
+    String toStringUTF8(byte[] ba, int off, int len) {
         if (isUTF8)
-            return toString(ba, len);
+            return toString(ba, off, len);
         if (utf8 == null)
             utf8 = new ZipCoder(StandardCharsets.UTF_8);
-        return utf8.toString(ba, len);
+        return utf8.toString(ba, off, len);
     }
 
     boolean isUTF8() {
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
index 4e3a6d20417..561023c30e7 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -30,14 +30,22 @@ import java.io.InputStream;
 import java.io.IOException;
 import java.io.EOFException;
 import java.io.File;
+import java.io.RandomAccessFile;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.Path;
+import java.nio.file.Files;
+
 import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Deque;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.Spliterator;
 import java.util.Spliterators;
@@ -47,7 +55,9 @@ import java.util.stream.StreamSupport;
 import jdk.internal.misc.JavaUtilZipFileAccess;
 import jdk.internal.misc.SharedSecrets;
 
+import static java.util.zip.ZipConstants.*;
 import static java.util.zip.ZipConstants64.*;
+import static java.util.zip.ZipUtils.*;
 
 /**
  * This class is used to read entries from a zip file.
@@ -60,11 +70,11 @@ import static java.util.zip.ZipConstants64.*;
  */
 public
 class ZipFile implements ZipConstants, Closeable {
-    private long jzfile;  // address of jzfile data
+
     private final String name;     // zip file name
-    private final int total;       // total number of entries
-    private final boolean locsig;  // if zip file starts with LOCSIG (usually true)
     private volatile boolean closeRequested = false;
+    private Source zsrc;
+    private ZipCoder zc;
 
     private static final int STORED = ZipEntry.STORED;
     private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -83,23 +93,6 @@ class ZipFile implements ZipConstants, Closeable {
      */
     public static final int OPEN_DELETE = 0x4;
 
-    static {
-        /* Zip library is loaded from System.initializeSystemClass */
-        initIDs();
-    }
-
-    private static native void initIDs();
-
-    private static final boolean usemmap;
-
-    static {
-        // A system prpperty to disable mmap use to avoid vm crash when
-        // in-use zip file is accidently overwritten by others.
-        String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping");
-        usemmap = (prop == null ||
-                   !(prop.length() == 0 || prop.equalsIgnoreCase("true")));
-    }
-
     /**
      * Opens a zip file for reading.
      *
@@ -165,8 +158,6 @@ class ZipFile implements ZipConstants, Closeable {
         this(file, OPEN_READ);
     }
 
-    private ZipCoder zc;
-
     /**
      * Opens a new {@code ZipFile} to read from the specified
      * {@code File} object in the specified mode.  The mode argument
@@ -214,16 +205,13 @@ class ZipFile implements ZipConstants, Closeable {
                 sm.checkDelete(name);
             }
         }
-        if (charset == null)
-            throw new NullPointerException("charset is null");
+        Objects.requireNonNull(charset, "charset");
         this.zc = ZipCoder.get(charset);
+        this.name = name;
         long t0 = System.nanoTime();
-        jzfile = open(name, mode, file.lastModified(), usemmap);
+        this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
         sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
         sun.misc.PerfCounter.getZipFileCount().increment();
-        this.name = name;
-        this.total = getTotal(jzfile);
-        this.locsig = startsWithLOC(jzfile);
     }
 
     /**
@@ -257,6 +245,7 @@ class ZipFile implements ZipConstants, Closeable {
 
     /**
      * Opens a ZIP file for reading given the specified File object.
+     *
      * @param file the ZIP file to be opened for reading
      * @param charset
      *        The {@linkplain java.nio.charset.Charset charset} to be
@@ -287,10 +276,10 @@ class ZipFile implements ZipConstants, Closeable {
     public String getComment() {
         synchronized (this) {
             ensureOpen();
-            byte[] bcomm = getCommentBytes(jzfile);
-            if (bcomm == null)
+            if (zsrc.comment == null) {
                 return null;
-            return zc.toString(bcomm, bcomm.length);
+            }
+            return zc.toString(zsrc.comment);
         }
     }
 
@@ -303,38 +292,27 @@ class ZipFile implements ZipConstants, Closeable {
      * @throws IllegalStateException if the zip file has been closed
      */
     public ZipEntry getEntry(String name) {
-        if (name == null) {
-            throw new NullPointerException("name");
-        }
-        long jzentry = 0;
+        Objects.requireNonNull(name, "name");
         synchronized (this) {
             ensureOpen();
-            jzentry = getEntry(jzfile, zc.getBytes(name), true);
-            if (jzentry != 0) {
-                ZipEntry ze = getZipEntry(name, jzentry);
-                freeEntry(jzfile, jzentry);
-                return ze;
+            int pos = zsrc.getEntryPos(zc.getBytes(name), true);
+            if (pos != -1) {
+                return getZipEntry(name, pos);
             }
         }
         return null;
     }
 
-    private static native long getEntry(long jzfile, byte[] name,
-                                        boolean addSlash);
-
-    // freeEntry releases the C jzentry struct.
-    private static native void freeEntry(long jzfile, long jzentry);
-
-    // the outstanding inputstreams that need to be closed,
+    // The outstanding inputstreams that need to be closed,
     // mapped to the inflater objects they use.
     private final Map<InputStream, Inflater> streams = new WeakHashMap<>();
 
     /**
      * Returns an input stream for reading the contents of the specified
      * zip file entry.
-     *
-     * <p> Closing this ZIP file will, in turn, close all input
-     * streams that have been returned by invocations of this method.
+     * <p>
+     * Closing this ZIP file will, in turn, close all input streams that
+     * have been returned by invocations of this method.
      *
      * @param entry the zip file entry
      * @return the input stream for reading the contents of the specified
@@ -344,37 +322,38 @@ class ZipFile implements ZipConstants, Closeable {
      * @throws IllegalStateException if the zip file has been closed
      */
     public InputStream getInputStream(ZipEntry entry) throws IOException {
-        if (entry == null) {
-            throw new NullPointerException("entry");
-        }
-        long jzentry = 0;
+        Objects.requireNonNull(entry, "entry");
+        int pos = -1;
         ZipFileInputStream in = null;
         synchronized (this) {
             ensureOpen();
             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
-                jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
+                pos = zsrc.getEntryPos(zc.getBytesUTF8(entry.name), false);
             } else {
-                jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
+                pos = zsrc.getEntryPos(zc.getBytes(entry.name), false);
             }
-            if (jzentry == 0) {
+            if (pos == -1) {
                 return null;
             }
-            in = new ZipFileInputStream(jzentry);
-
-            switch (getEntryMethod(jzentry)) {
+            in = new ZipFileInputStream(zsrc.cen, pos);
+            switch (CENHOW(zsrc.cen, pos)) {
             case STORED:
                 synchronized (streams) {
                     streams.put(in, null);
                 }
                 return in;
             case DEFLATED:
+                // Inflater likes a bit of slack
                 // MORE: Compute good size for inflater stream:
-                long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
-                if (size > 65536) size = 8192;
-                if (size <= 0) size = 4096;
+                long size = CENLEN(zsrc.cen, pos) + 2;
+                if (size > 65536) {
+                    size = 8192;
+                }
+                if (size <= 0) {
+                    size = 4096;
+                }
                 Inflater inf = getInflater();
-                InputStream is =
-                    new ZipFileInflaterInputStream(in, inf, (int)size);
+                InputStream is = new ZipFileInflaterInputStream(in, inf, (int)size);
                 synchronized (streams) {
                     streams.put(is, inf);
                 }
@@ -447,8 +426,8 @@ class ZipFile implements ZipConstants, Closeable {
     private Inflater getInflater() {
         Inflater inf;
         synchronized (inflaterCache) {
-            while (null != (inf = inflaterCache.poll())) {
-                if (false == inf.ended()) {
+            while ((inf = inflaterCache.poll()) != null) {
+                if (!inf.ended()) {
                     return inf;
                 }
             }
@@ -460,7 +439,7 @@ class ZipFile implements ZipConstants, Closeable {
      * Releases the specified inflater to the list of available inflaters.
      */
     private void releaseInflater(Inflater inf) {
-        if (false == inf.ended()) {
+        if (!inf.ended()) {
             inf.reset();
             synchronized (inflaterCache) {
                 inflaterCache.add(inf);
@@ -469,7 +448,7 @@ class ZipFile implements ZipConstants, Closeable {
     }
 
     // List of available Inflater objects for decompression
-    private Deque<Inflater> inflaterCache = new ArrayDeque<>();
+    private final Deque<Inflater> inflaterCache = new ArrayDeque<>();
 
     /**
      * Returns the path name of the ZIP file.
@@ -493,7 +472,7 @@ class ZipFile implements ZipConstants, Closeable {
         public boolean hasNext() {
             synchronized (ZipFile.this) {
                 ensureOpen();
-                return i < total;
+                return i < zsrc.total;
             }
         }
 
@@ -504,28 +483,11 @@ class ZipFile implements ZipConstants, Closeable {
         public ZipEntry next() {
             synchronized (ZipFile.this) {
                 ensureOpen();
-                if (i >= total) {
+                if (i >= zsrc.total) {
                     throw new NoSuchElementException();
                 }
-                long jzentry = getNextEntry(jzfile, i++);
-                if (jzentry == 0) {
-                    String message;
-                    if (closeRequested) {
-                        message = "ZipFile concurrently closed";
-                    } else {
-                        message = getZipMessage(ZipFile.this.jzfile);
-                    }
-                    throw new ZipError("jzentry == 0" +
-                                       ",\n jzfile = " + ZipFile.this.jzfile +
-                                       ",\n total = " + ZipFile.this.total +
-                                       ",\n name = " + ZipFile.this.name +
-                                       ",\n i = " + i +
-                                       ",\n message = " + message
-                        );
-                }
-                ZipEntry ze = getZipEntry(null, jzentry);
-                freeEntry(jzfile, jzentry);
-                return ze;
+                // each "entry" has 3 ints in table entries
+                return getZipEntry(null, zsrc.getEntryPos(i++ * 3));
             }
         }
 
@@ -559,48 +521,53 @@ class ZipFile implements ZipConstants, Closeable {
                         Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
     }
 
-    private ZipEntry getZipEntry(String name, long jzentry) {
+    /* Checks ensureOpen() before invoke this method */
+    private ZipEntry getZipEntry(String name, int pos) {
+        byte[] cen = zsrc.cen;
         ZipEntry e = new ZipEntry();
-        e.flag = getEntryFlag(jzentry);  // get the flag first
+        int nlen = CENNAM(cen, pos);
+        int elen = CENEXT(cen, pos);
+        int clen = CENCOM(cen, pos);
+        e.flag = CENFLG(cen, pos);  // get the flag first
         if (name != null) {
             e.name = name;
         } else {
-            byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
-                e.name = zc.toStringUTF8(bname, bname.length);
+                e.name = zc.toStringUTF8(cen, pos + CENHDR, nlen);
             } else {
-                e.name = zc.toString(bname, bname.length);
+                e.name = zc.toString(cen, pos + CENHDR, nlen);
             }
         }
-        e.xdostime = getEntryTime(jzentry);
-        e.crc = getEntryCrc(jzentry);
-        e.size = getEntrySize(jzentry);
-        e.csize = getEntryCSize(jzentry);
-        e.method = getEntryMethod(jzentry);
-        e.setExtra0(getEntryBytes(jzentry, JZENTRY_EXTRA), false);
-        byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
-        if (bcomm == null) {
-            e.comment = null;
-        } else {
+        e.xdostime = CENTIM(cen, pos);
+        e.crc = CENCRC(cen, pos);
+        e.size = CENLEN(cen, pos);
+        e.csize = CENSIZ(cen, pos);
+        e.method = CENHOW(cen, pos);
+        if (elen != 0) {
+            e.setExtra0(Arrays.copyOfRange(cen, pos + CENHDR + nlen,
+                                           pos + CENHDR + nlen + elen), true);
+        }
+        if (clen != 0) {
             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
-                e.comment = zc.toStringUTF8(bcomm, bcomm.length);
+                e.comment = zc.toStringUTF8(cen, pos + CENHDR + nlen + elen, clen);
             } else {
-                e.comment = zc.toString(bcomm, bcomm.length);
+                e.comment = zc.toString(cen, pos + CENHDR + nlen + elen, clen);
             }
         }
         return e;
     }
 
-    private static native long getNextEntry(long jzfile, int i);
-
     /**
      * Returns the number of entries in the ZIP file.
+     *
      * @return the number of entries in the ZIP file
      * @throws IllegalStateException if the zip file has been closed
      */
     public int size() {
-        ensureOpen();
-        return total;
+        synchronized (this) {
+            ensureOpen();
+            return zsrc.total;
+        }
     }
 
     /**
@@ -612,14 +579,15 @@ class ZipFile implements ZipConstants, Closeable {
      * @throws IOException if an I/O error has occurred
      */
     public void close() throws IOException {
-        if (closeRequested)
+        if (closeRequested) {
             return;
+        }
         closeRequested = true;
 
         synchronized (this) {
             // Close streams, release their inflaters
             synchronized (streams) {
-                if (false == streams.isEmpty()) {
+                if (!streams.isEmpty()) {
                     Map<InputStream, Inflater> copy = new HashMap<>(streams);
                     streams.clear();
                     for (Map.Entry<InputStream, Inflater> e : copy.entrySet()) {
@@ -631,21 +599,17 @@ class ZipFile implements ZipConstants, Closeable {
                     }
                 }
             }
-
             // Release cached inflaters
-            Inflater inf;
             synchronized (inflaterCache) {
-                while (null != (inf = inflaterCache.poll())) {
+                Inflater inf;
+                while ((inf = inflaterCache.poll()) != null) {
                     inf.end();
                 }
             }
-
-            if (jzfile != 0) {
-                // Close the zip file
-                long zf = this.jzfile;
-                jzfile = 0;
-
-                close(zf);
+            // Release zip src
+            if (zsrc != null) {
+                Source.close(zsrc);
+                zsrc = null;
             }
         }
     }
@@ -668,14 +632,11 @@ class ZipFile implements ZipConstants, Closeable {
         close();
     }
 
-    private static native void close(long jzfile);
-
     private void ensureOpen() {
         if (closeRequested) {
             throw new IllegalStateException("zip file closed");
         }
-
-        if (jzfile == 0) {
+        if (zsrc == null) {
             throw new IllegalStateException("The object is not initialized.");
         }
     }
@@ -691,23 +652,86 @@ class ZipFile implements ZipConstants, Closeable {
      * (possibly compressed) zip file entry.
      */
    private class ZipFileInputStream extends InputStream {
-        private volatile boolean zfisCloseRequested = false;
-        protected long jzentry; // address of jzentry data
+        private volatile boolean closeRequested = false;
         private   long pos;     // current position within entry data
         protected long rem;     // number of remaining bytes within entry
         protected long size;    // uncompressed size of this entry
 
-        ZipFileInputStream(long jzentry) {
-            pos = 0;
-            rem = getEntryCSize(jzentry);
-            size = getEntrySize(jzentry);
-            this.jzentry = jzentry;
+        ZipFileInputStream(byte[] cen, int cenpos) throws IOException {
+            rem = CENSIZ(cen, cenpos);
+            size = CENLEN(cen, cenpos);
+            pos = CENOFF(cen, cenpos);
+            // zip64
+            if (rem == ZIP64_MAGICVAL || size == ZIP64_MAGICVAL ||
+                pos == ZIP64_MAGICVAL) {
+                checkZIP64(cen, cenpos);
+            }
+            // negative for lazy initialization, see getDataOffset();
+            pos = - (pos + ZipFile.this.zsrc.locpos);
+        }
+
+        private void checkZIP64(byte[] cen, int cenpos) throws IOException {
+            int off = cenpos + CENHDR + CENNAM(cen, cenpos);
+            int end = off + CENEXT(cen, cenpos);
+            while (off + 4 < end) {
+                int tag = get16(cen, off);
+                int sz = get16(cen, off + 2);
+                off += 4;
+                if (off + sz > end)         // invalid data
+                    break;
+                if (tag == EXTID_ZIP64) {
+                    if (size == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > end)
+                            break;
+                        size = get64(cen, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    if (rem == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > end)
+                            break;
+                        rem = get64(cen, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    if (pos == ZIP64_MAGICVAL) {
+                        if (sz < 8 || (off + 8) > end)
+                            break;
+                        pos = get64(cen, off);
+                        sz -= 8;
+                        off += 8;
+                    }
+                    break;
+                }
+                off += sz;
+            }
+        }
+
+       /* The Zip file spec explicitly allows the LOC extra data size to
+        * be different from the CEN extra data size. Since we cannot trust
+        * the CEN extra data size, we need to read the LOC to determine
+        * the entry data offset.
+        */
+        private long initDataOffset() throws IOException {
+            if (pos <= 0) {
+                byte[] loc = new byte[LOCHDR];
+                pos = -pos;
+                int len = ZipFile.this.zsrc.readFullyAt(loc, 0, loc.length, pos);
+                if (len != LOCHDR) {
+                    throw new ZipException("ZipFile error reading zip file");
+                }
+                if (LOCSIG(loc) != LOCSIG) {
+                    throw new ZipException("ZipFile invalid LOC header (bad signature)");
+                }
+                pos += LOCHDR + LOCNAM(loc) + LOCEXT(loc);
+            }
+            return pos;
         }
 
         public int read(byte b[], int off, int len) throws IOException {
             synchronized (ZipFile.this) {
-                long rem = this.rem;
-                long pos = this.pos;
+                ensureOpenOrZipException();
+                initDataOffset();
                 if (rem == 0) {
                     return -1;
                 }
@@ -717,14 +741,10 @@ class ZipFile implements ZipConstants, Closeable {
                 if (len > rem) {
                     len = (int) rem;
                 }
-
-                // Check if ZipFile open
-                ensureOpenOrZipException();
-                len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
-                                   off, len);
+                len = ZipFile.this.zsrc.readAt(b, off, len, pos);
                 if (len > 0) {
-                    this.pos = (pos + len);
-                    this.rem = (rem - len);
+                    pos += len;
+                    rem -= len;
                 }
             }
             if (rem == 0) {
@@ -742,11 +762,16 @@ class ZipFile implements ZipConstants, Closeable {
             }
         }
 
-        public long skip(long n) {
-            if (n > rem)
-                n = rem;
-            pos += n;
-            rem -= n;
+        public long skip(long n) throws IOException {
+            synchronized (ZipFile.this) {
+                ensureOpenOrZipException();
+                initDataOffset();
+                if (n > rem) {
+                    n = rem;
+                }
+                pos += n;
+                rem -= n;
+            }
             if (rem == 0) {
                 close();
             }
@@ -762,17 +787,11 @@ class ZipFile implements ZipConstants, Closeable {
         }
 
         public void close() {
-            if (zfisCloseRequested)
+            if (closeRequested) {
                 return;
-            zfisCloseRequested = true;
-
-            rem = 0;
-            synchronized (ZipFile.this) {
-                if (jzentry != 0 && ZipFile.this.jzfile != 0) {
-                    freeEntry(ZipFile.this.jzfile, jzentry);
-                    jzentry = 0;
-                }
             }
+            closeRequested = true;
+            rem = 0;
             synchronized (streams) {
                 streams.remove(this);
             }
@@ -787,40 +806,492 @@ class ZipFile implements ZipConstants, Closeable {
         SharedSecrets.setJavaUtilZipFileAccess(
             new JavaUtilZipFileAccess() {
                 public boolean startsWithLocHeader(ZipFile zip) {
-                    return zip.startsWithLocHeader();
+                    return zip.zsrc.locsig;
                 }
-            }
+                public String[] getMetaInfEntryNames(ZipFile zip) {
+                    return zip.getMetaInfEntryNames();
+                }
+             }
         );
     }
 
-    /**
-     * Returns {@code true} if, and only if, the zip file begins with {@code
-     * LOCSIG}.
+    /*
+     * Returns an array of strings representing the names of all entries
+     * that begin with "META-INF/" (case ignored). This method is used
+     * in JarFile, via SharedSecrets, as an optimization when looking up
+     * manifest and signature file entries. Returns null if no entries
+     * were found.
      */
-    private boolean startsWithLocHeader() {
-        return locsig;
+    private String[] getMetaInfEntryNames() {
+        synchronized (this) {
+            ensureOpen();
+            if (zsrc.metanames.size() == 0) {
+                return null;
+            }
+            String[] names = new String[zsrc.metanames.size()];
+            byte[] cen = zsrc.cen;
+            for (int i = 0; i < names.length; i++) {
+                int pos = zsrc.metanames.get(i);
+                names[i] = zc.toStringUTF8(cen, pos + CENHDR,  CENNAM(cen, pos));
+            }
+            return names;
+        }
     }
 
-    private static native long open(String name, int mode, long lastModified,
-                                    boolean usemmap) throws IOException;
-    private static native int getTotal(long jzfile);
-    private static native boolean startsWithLOC(long jzfile);
-    private static native int read(long jzfile, long jzentry,
-                                   long pos, byte[] b, int off, int len);
+    private static class Source {
+        private final Key key;               // the key in files
+        private int refs = 1;
 
-    // access to the native zentry object
-    private static native long getEntryTime(long jzentry);
-    private static native long getEntryCrc(long jzentry);
-    private static native long getEntryCSize(long jzentry);
-    private static native long getEntrySize(long jzentry);
-    private static native int getEntryMethod(long jzentry);
-    private static native int getEntryFlag(long jzentry);
-    private static native byte[] getCommentBytes(long jzfile);
+        private RandomAccessFile zfile;      // zfile of the underlying zip file
+        private byte[] cen;                  // CEN & ENDHDR
+        private long locpos;                 // position of first LOC header (usually 0)
+        private byte[] comment;              // zip file comment
+                                             // list of meta entries in META-INF dir
+        private ArrayList<Integer> metanames = new ArrayList<>();
+        private final boolean locsig;        // true, if zip file starts with LOCSIG (usually true)
 
-    private static final int JZENTRY_NAME = 0;
-    private static final int JZENTRY_EXTRA = 1;
-    private static final int JZENTRY_COMMENT = 2;
-    private static native byte[] getEntryBytes(long jzentry, int type);
+        // A Hashmap for all entries.
+        //
+        // A cen entry of Zip/JAR file. As we have one for every entry in every active Zip/JAR,
+        // We might have a lot of these in a typical system. In order to save space we don't
+        // keep the name in memory, but merely remember a 32 bit {@code hash} value of the
+        // entry name and its offset {@code pos} in the central directory hdeader.
+        //
+        // private static class Entry {
+        //     int hash;       // 32 bit hashcode on name
+        //     int next;       // hash chain: index into entries
+        //     int pos;        // Offset of central directory file header
+        // }
+        // private Entry[] entries;             // array of hashed cen entry
+        //
+        // To reduce the total size of entries further, we use a int[] here to store 3 "int"
+        // {@code hash}, {@code next and {@code "pos for each entry. The entry can then be
+        // referred by their index of their positions in the {@code entries}.
+        //
+        private int[] entries;                  // array of hashed cen entry
+        private int addEntry(int index, int hash, int next, int pos) {
+            entries[index++] = hash;
+            entries[index++] = next;
+            entries[index++] = pos;
+            return index;
+        }
+        private int getEntryHash(int index) { return entries[index]; }
+        private int getEntryNext(int index) { return entries[index + 1]; }
+        private int getEntryPos(int index)  { return entries[index + 2]; }
+        private static final int ZIP_ENDCHAIN  = -1;
+        private int total;                   // total number of entries
+        private int[] table;                 // Hash chain heads: indexes into entries
+        private int tablelen;                // number of hash heads
 
-    private static native String getZipMessage(long jzfile);
+        private static class Key {
+            BasicFileAttributes attrs;
+            File file;
+
+            public Key(File file, BasicFileAttributes attrs) {
+                this.attrs = attrs;
+                this.file = file;
+            }
+
+            public int hashCode() {
+                long t = attrs.lastModifiedTime().toMillis();
+                return ((int)(t ^ (t >>> 32))) + file.hashCode();
+            }
+
+            public boolean equals(Object obj) {
+                if (obj instanceof Key) {
+                    Key key = (Key)obj;
+                    if (!attrs.lastModifiedTime().equals(key.attrs.lastModifiedTime())) {
+                        return false;
+                    }
+                    Object fk = attrs.fileKey();
+                    if (fk != null) {
+                        return  fk.equals(key.attrs.fileKey());
+                    } else {
+                        return file.equals(key.file);
+                    }
+                }
+                return false;
+            }
+        }
+        private static final HashMap<Key, Source> files = new HashMap<>();
+
+        public static Source get(File file, boolean toDelete) throws IOException {
+            Key key = new Key(file,
+                              Files.readAttributes(file.toPath(), BasicFileAttributes.class));
+            Source src = null;
+            synchronized (files) {
+                src = files.get(key);
+                if (src != null) {
+                    src.refs++;
+                    return src;
+                }
+            }
+            src = new Source(key, toDelete);
+            synchronized (files) {
+                if (files.containsKey(key)) {    // someone else put in first
+                    src.close();                 // close the newly created one
+                    src = files.get(key);
+                    src.refs++;
+                    return src;
+                }
+                files.put(key, src);
+                return src;
+            }
+        }
+
+        private static void close(Source src) throws IOException {
+            synchronized (files) {
+                if (--src.refs == 0) {
+                    files.remove(src.key);
+                    src.close();
+                }
+            }
+        }
+
+        private Source(Key key, boolean toDelete) throws IOException {
+            this.key = key;
+            this.zfile = new RandomAccessFile(key.file, "r");
+            if (toDelete) {
+                key.file.delete();
+            }
+            initCEN(-1);
+            byte[] buf = new byte[4];
+            readFullyAt(buf, 0, 4, 0);
+            this.locsig = (LOCSIG(buf) != LOCSIG);
+        }
+
+        private void close() throws IOException {
+            zfile.close();
+            zfile = null;
+            cen = null;
+            entries = null;
+            table = null;
+            metanames = null;
+        }
+
+        private static final int BUF_SIZE = 8192;
+        private final int readFullyAt(byte[] buf, int off, int len, long pos)
+            throws IOException
+        {
+            synchronized(zfile) {
+                zfile.seek(pos);
+                int N = len;
+                while (N > 0) {
+                    int n = Math.min(BUF_SIZE, N);
+                    zfile.readFully(buf, off, n);
+                    off += n;
+                    N -= n;
+                }
+                return len;
+            }
+        }
+
+        private final int readAt(byte[] buf, int off, int len, long pos)
+            throws IOException
+        {
+            synchronized(zfile) {
+                zfile.seek(pos);
+                return zfile.read(buf, off, len);
+            }
+        }
+
+        private static final int hashN(byte[] a, int off, int len) {
+            int h = 1;
+            while (len-- > 0) {
+                h = 31 * h + a[off++];
+            }
+            return h;
+        }
+
+        private static final int hash_append(int hash, byte b) {
+            return hash * 31 + b;
+        }
+
+        private static class End {
+            int  centot;     // 4 bytes
+            long cenlen;     // 4 bytes
+            long cenoff;     // 4 bytes
+            long endpos;     // 4 bytes
+        }
+
+        /*
+         * Searches for end of central directory (END) header. The contents of
+         * the END header will be read and placed in endbuf. Returns the file
+         * position of the END header, otherwise returns -1 if the END header
+         * was not found or an error occurred.
+         */
+        private End findEND() throws IOException {
+            long ziplen = zfile.length();
+            if (ziplen <= 0)
+                zerror("zip file is empty");
+            End end = new End();
+            byte[] buf = new byte[READBLOCKSZ];
+            long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
+            long minPos = minHDR - (buf.length - ENDHDR);
+            for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) {
+                int off = 0;
+                if (pos < 0) {
+                    // Pretend there are some NUL bytes before start of file
+                    off = (int)-pos;
+                    Arrays.fill(buf, 0, off, (byte)0);
+                }
+                int len = buf.length - off;
+                if (readFullyAt(buf, off, len, pos + off) != len ) {
+                    zerror("zip END header not found");
+                }
+                // Now scan the block backwards for END header signature
+                for (int i = buf.length - ENDHDR; i >= 0; i--) {
+                    if (buf[i+0] == (byte)'P'    &&
+                        buf[i+1] == (byte)'K'    &&
+                        buf[i+2] == (byte)'\005' &&
+                        buf[i+3] == (byte)'\006') {
+                        // Found ENDSIG header
+                        byte[] endbuf = Arrays.copyOfRange(buf, i, i + ENDHDR);
+                        end.centot = ENDTOT(endbuf);
+                        end.cenlen = ENDSIZ(endbuf);
+                        end.cenoff = ENDOFF(endbuf);
+                        end.endpos = pos + i;
+                        int comlen = ENDCOM(endbuf);
+                        if (end.endpos + ENDHDR + comlen != ziplen) {
+                            // ENDSIG matched, however the size of file comment in it does
+                            // not match the real size. One "common" cause for this problem
+                            // is some "extra" bytes are padded at the end of the zipfile.
+                            // Let's do some extra verification, we don't care about the
+                            // performance in this situation.
+                            byte[] sbuf = new byte[4];
+                            long cenpos = end.endpos - end.cenlen;
+                            long locpos = cenpos - end.cenoff;
+                            if  (cenpos < 0 ||
+                                 locpos < 0 ||
+                                 readFullyAt(sbuf, 0, sbuf.length, cenpos) != 4 ||
+                                 GETSIG(sbuf) != CENSIG ||
+                                 readFullyAt(sbuf, 0, sbuf.length, locpos) != 4 ||
+                                 GETSIG(sbuf) != LOCSIG) {
+                                continue;
+                            }
+                        }
+                        if (comlen > 0) {    // this zip file has comlen
+                            comment = new byte[comlen];
+                            if (readFullyAt(comment, 0, comlen, end.endpos + ENDHDR) != comlen) {
+                                zerror("zip comment read failed");
+                            }
+                        }
+                        if (end.cenlen == ZIP64_MAGICVAL ||
+                            end.cenoff == ZIP64_MAGICVAL ||
+                            end.centot == ZIP64_MAGICCOUNT)
+                        {
+                            // need to find the zip64 end;
+                            try {
+                                byte[] loc64 = new byte[ZIP64_LOCHDR];
+                                if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
+                                    != loc64.length || GETSIG(loc64) != ZIP64_LOCSIG) {
+                                    return end;
+                                }
+                                long end64pos = ZIP64_LOCOFF(loc64);
+                                byte[] end64buf = new byte[ZIP64_ENDHDR];
+                                if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
+                                    != end64buf.length || GETSIG(end64buf) != ZIP64_ENDSIG) {
+                                    return end;
+                                }
+                                // end64 found, re-calcualte everything.
+                                end.cenlen = ZIP64_ENDSIZ(end64buf);
+                                end.cenoff = ZIP64_ENDOFF(end64buf);
+                                end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
+                                end.endpos = end64pos;
+                            } catch (IOException x) {}    // no zip64 loc/end
+                        }
+                        return end;
+                    }
+                }
+            }
+            zerror("zip END header not found");
+            return null; //make compiler happy
+        }
+
+        // Reads zip file central directory.
+        private void initCEN(int knownTotal) throws IOException {
+            if (knownTotal == -1) {
+                End end = findEND();
+                if (end.endpos == 0) {
+                    locpos = 0;
+                    total = 0;
+                    entries  = new int[0];
+                    cen = null;
+                    return;         // only END header present
+                }
+                if (end.cenlen > end.endpos)
+                    zerror("invalid END header (bad central directory size)");
+                long cenpos = end.endpos - end.cenlen;     // position of CEN table
+                // Get position of first local file (LOC) header, taking into
+                // account that there may be a stub prefixed to the zip file.
+                locpos = cenpos - end.cenoff;
+                if (locpos < 0) {
+                    zerror("invalid END header (bad central directory offset)");
+                }
+                // read in the CEN and END
+                cen = new byte[(int)(end.cenlen + ENDHDR)];
+                if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
+                    zerror("read CEN tables failed");
+                }
+                total = end.centot;
+            } else {
+                total = knownTotal;
+            }
+            // hash table for entries
+            entries  = new int[total * 3];
+            tablelen = ((total/2) | 1); // Odd -> fewer collisions
+            table    =  new int[tablelen];
+            Arrays.fill(table, ZIP_ENDCHAIN);
+            int idx = 0;
+            int hash = 0;
+            int next = -1;
+
+            // list for all meta entries
+            metanames = new ArrayList<>();
+
+            // Iterate through the entries in the central directory
+            int i = 0;
+            int hsh = 0;
+            int pos = 0;
+            int limit = cen.length - ENDHDR;
+            while (pos + CENHDR  <= limit) {
+                if (i >= total) {
+                    // This will only happen if the zip file has an incorrect
+                    // ENDTOT field, which usually means it contains more than
+                    // 65535 entries.
+                    initCEN(countCENHeaders(cen, limit));
+                    return;
+                }
+                if (CENSIG(cen, pos) != CENSIG)
+                    zerror("invalid CEN header (bad signature)");
+                int method = CENHOW(cen, pos);
+                int nlen   = CENNAM(cen, pos);
+                int elen   = CENEXT(cen, pos);
+                int clen   = CENCOM(cen, pos);
+                if ((CENFLG(cen, pos) & 1) != 0)
+                    zerror("invalid CEN header (encrypted entry)");
+                if (method != STORED && method != DEFLATED)
+                    zerror("invalid CEN header (bad compression method: " + method + ")");
+                if (pos + CENHDR + nlen > limit)
+                    zerror("invalid CEN header (bad header size)");
+                // Record the CEN offset and the name hash in our hash cell.
+                hash = hashN(cen, pos + CENHDR, nlen);
+                hsh = (hash & 0x7fffffff) % tablelen;
+                next = table[hsh];
+                table[hsh] = idx;
+                idx = addEntry(idx, hash, next, pos);
+                // Adds name to metanames.
+                if (isMetaName(cen, pos + CENHDR, nlen)) {
+                    metanames.add(pos);
+                }
+                // skip ext and comment
+                pos += (CENHDR + nlen + elen + clen);
+                i++;
+            }
+            total = i;
+            if (pos + ENDHDR != cen.length) {
+                zerror("invalid CEN header (bad header size)");
+            }
+        }
+
+        private static void zerror(String msg) throws ZipException {
+            throw new ZipException(msg);
+        }
+
+        /*
+         * Returns the {@code pos} of the zip cen entry corresponding to the
+         * specified entry name, or -1 if not found.
+         */
+        private int getEntryPos(byte[] name, boolean addSlash) {
+            if (total == 0) {
+                return -1;
+            }
+            int hsh = hashN(name, 0, name.length);
+            int idx = table[(hsh & 0x7fffffff) % tablelen];
+            /*
+             * This while loop is an optimization where a double lookup
+             * for name and name+/ is being performed. The name char
+             * array has enough room at the end to try again with a
+             * slash appended if the first table lookup does not succeed.
+             */
+            while(true) {
+                /*
+                 * Search down the target hash chain for a entry whose
+                 * 32 bit hash matches the hashed name.
+                 */
+                while (idx != ZIP_ENDCHAIN) {
+                    if (getEntryHash(idx) == hsh) {
+                        // The CEN name must match the specfied one
+                        int pos = getEntryPos(idx);
+                        if (name.length == CENNAM(cen, pos)) {
+                            boolean matched = true;
+                            int nameoff = pos + CENHDR;
+                            for (int i = 0; i < name.length; i++) {
+                                if (name[i] != cen[nameoff++]) {
+                                    matched = false;
+                                    break;
+                                }
+                            }
+                            if (matched) {
+                                return pos;
+                            }
+                         }
+                    }
+                    idx = getEntryNext(idx);
+                }
+                /* If not addSlash, or slash is already there, we are done */
+                if (!addSlash  || name[name.length - 1] == '/') {
+                     return -1;
+                }
+                /* Add slash and try once more */
+                name = Arrays.copyOf(name, name.length + 1);
+                name[name.length - 1] = '/';
+                hsh = hash_append(hsh, (byte)'/');
+                //idx = table[hsh % tablelen];
+                idx = table[(hsh & 0x7fffffff) % tablelen];
+                addSlash = false;
+            }
+        }
+
+        private static byte[] metainf = new byte[] {
+            'M', 'E', 'T', 'A', '-', 'I' , 'N', 'F', '/',
+        };
+
+        /*
+         * Returns true if the specified entry's name begins with the string
+         * "META-INF/" irrespective of case.
+         */
+        private static boolean isMetaName(byte[] name,  int off, int len) {
+            if (len < 9 || (name[off] != 'M' && name[off] != 'm')) {  //  sizeof("META-INF/") - 1
+                return false;
+            }
+            off++;
+            for (int i = 1; i < metainf.length; i++) {
+                byte c = name[off++];
+                // Avoid toupper; it's locale-dependent
+                if (c >= 'a' && c <= 'z') {
+                    c += 'A' - 'a';
+                }
+                if (metainf[i] != c) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /*
+         * Counts the number of CEN headers in a central directory extending
+         * from BEG to END.  Might return a bogus answer if the zip file is
+         * corrupt, but will not crash.
+         */
+        static int countCENHeaders(byte[] cen, int end) {
+            int count = 0;
+            int pos = 0;
+            while (pos + CENHDR <= end) {
+                count++;
+                pos += (CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos));
+            }
+            return count;
+        }
+    }
 }
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java
index 81882fdcec6..a6632f0fa83 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java
@@ -31,6 +31,8 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.concurrent.TimeUnit;
 
+import static java.util.zip.ZipConstants.ENDHDR;
+
 class ZipUtils {
 
     // used to adjust values between Windows and java epoch
@@ -133,7 +135,7 @@ class ZipUtils {
      * The bytes are assumed to be in Intel (little-endian) byte order.
      */
     public static final int get16(byte b[], int off) {
-        return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
+        return (b[off] & 0xff) | ((b[off + 1] & 0xff) << 8);
     }
 
     /**
@@ -160,4 +162,79 @@ class ZipUtils {
     public static final int get32S(byte b[], int off) {
         return (get16(b, off) | (get16(b, off+2) << 16));
     }
+
+    // fields access methods
+    static final int CH(byte[] b, int n) {
+        return b[n] & 0xff ;
+    }
+
+    static final int SH(byte[] b, int n) {
+        return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
+    }
+
+    static final long LG(byte[] b, int n) {
+        return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
+    }
+
+    static final long LL(byte[] b, int n) {
+        return (LG(b, n)) | (LG(b, n + 4) << 32);
+    }
+
+    static final long GETSIG(byte[] b) {
+        return LG(b, 0);
+    }
+
+    // local file (LOC) header fields
+    static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
+    static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
+    static final int  LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
+    static final int  LOCHOW(byte[] b) { return SH(b, 8); } // compression method
+    static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
+    static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
+    static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
+    static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
+    static final int  LOCNAM(byte[] b) { return SH(b, 26);} // filename length
+    static final int  LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
+
+    // extra local (EXT) header fields
+    static final long EXTCRC(byte[] b) { return LG(b, 4);}  // crc of uncompressed data
+    static final long EXTSIZ(byte[] b) { return LG(b, 8);}  // compressed size
+    static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
+
+    // end of central directory header (END) fields
+    static final int  ENDSUB(byte[] b) { return SH(b, 8); }  // number of entries on this disk
+    static final int  ENDTOT(byte[] b) { return SH(b, 10);}  // total number of entries
+    static final long ENDSIZ(byte[] b) { return LG(b, 12);}  // central directory size
+    static final long ENDOFF(byte[] b) { return LG(b, 16);}  // central directory offset
+    static final int  ENDCOM(byte[] b) { return SH(b, 20);}  // size of zip file comment
+    static final int  ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
+
+    // zip64 end of central directory recoder fields
+    static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);}  // total number of entries on disk
+    static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);}  // total number of entries
+    static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);}  // central directory size
+    static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);}  // central directory offset
+    static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);}   // zip64 end offset
+
+    // central directory header (CEN) fields
+    static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
+    static final int  CENVEM(byte[] b, int pos) { return SH(b, pos + 4); }
+    static final int  CENVER(byte[] b, int pos) { return SH(b, pos + 6); }
+    static final int  CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
+    static final int  CENHOW(byte[] b, int pos) { return SH(b, pos + 10);}
+    static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);}
+    static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
+    static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);}
+    static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);}
+    static final int  CENNAM(byte[] b, int pos) { return SH(b, pos + 28);}
+    static final int  CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
+    static final int  CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
+    static final int  CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
+    static final int  CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
+    static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
+    static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
+
+    // The END header is followed by a variable length comment of size < 64k.
+    static final long END_MAXLEN = 0xFFFF + ENDHDR;
+    static final int READBLOCKSZ = 128;
 }
diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java
index df10fda22ca..9b9b1e85788 100644
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java
@@ -29,5 +29,6 @@ import java.util.zip.ZipFile;
 
 public interface JavaUtilZipFileAccess {
     public boolean startsWithLocHeader(ZipFile zip);
+    public String[] getMetaInfEntryNames(ZipFile zip);
 }
 
diff --git a/jdk/src/java.base/share/classes/sun/misc/VM.java b/jdk/src/java.base/share/classes/sun/misc/VM.java
index 0c75f10c657..37dc3b38fa1 100644
--- a/jdk/src/java.base/share/classes/sun/misc/VM.java
+++ b/jdk/src/java.base/share/classes/sun/misc/VM.java
@@ -274,9 +274,6 @@ public class VM {
         // used by java.lang.Integer.IntegerCache
         props.remove("java.lang.Integer.IntegerCache.high");
 
-        // used by java.util.zip.ZipFile
-        props.remove("sun.zip.disableMemoryMapping");
-
         // used by sun.launcher.LauncherHelper
         props.remove("sun.java.launcher.diag");
     }
diff --git a/jdk/src/java.base/share/native/libzip/ZipFile.c b/jdk/src/java.base/share/native/libzip/ZipFile.c
deleted file mode 100644
index d7a21a6cf88..00000000000
--- a/jdk/src/java.base/share/native/libzip/ZipFile.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Native method support for java.util.zip.ZipFile
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <assert.h>
-#include "jlong.h"
-#include "jvm.h"
-#include "jni.h"
-#include "jni_util.h"
-#include "zip_util.h"
-#ifdef WIN32
-#include "io_util_md.h"
-#else
-#include "io_util.h"
-#endif
-
-#include "java_util_zip_ZipFile.h"
-#include "java_util_jar_JarFile.h"
-
-#define DEFLATED 8
-#define STORED 0
-
-static jfieldID jzfileID;
-
-static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
-static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
-
-
-/*
- * Declare library specific JNI_Onload entry if static build
- */
-DEF_STATIC_JNI_OnLoad
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
-{
-    jzfileID = (*env)->GetFieldID(env, cls, "jzfile", "J");
-    assert(jzfileID != 0);
-}
-
-static void
-ThrowZipException(JNIEnv *env, const char *msg)
-{
-    jstring s = NULL;
-    jobject x;
-
-    if (msg != NULL) {
-        s = JNU_NewStringPlatform(env, msg);
-    }
-    if (s != NULL) {
-        x = JNU_NewObjectByName(env,
-                            "java/util/zip/ZipException",
-                            "(Ljava/lang/String;)V", s);
-        if (x != NULL) {
-            (*env)->Throw(env, x);
-        }
-    }
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
-                                        jint mode, jlong lastModified,
-                                        jboolean usemmap)
-{
-    const char *path = JNU_GetStringPlatformChars(env, name, 0);
-    char *msg = 0;
-    jlong result = 0;
-    int flag = 0;
-    jzfile *zip = 0;
-
-    if (mode & OPEN_READ) flag |= O_RDONLY;
-
-    if (path != 0) {
-        zip = ZIP_Get_From_Cache(path, &msg, lastModified);
-        if (zip == 0 && msg == 0) {
-            ZFILE zfd = 0;
-#ifdef WIN32
-            if (mode & OPEN_DELETE) flag |= O_TEMPORARY;
-            zfd = winFileHandleOpen(env, name, flag);
-            if (zfd == -1) {
-                /* Exception already pending. */
-                goto finally;
-            }
-#else
-            zfd = open(path, flag, 0);
-            if (zfd < 0) {
-                throwFileNotFoundException(env, name);
-                goto finally;
-            }
-            if (mode & OPEN_DELETE) {
-                unlink(path);
-            }
-#endif
-            zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);
-        }
-
-        if (zip != 0) {
-            result = ptr_to_jlong(zip);
-        } else if (msg != 0) {
-            ThrowZipException(env, msg);
-            free(msg);
-        } else if (errno == ENOMEM) {
-            JNU_ThrowOutOfMemoryError(env, 0);
-        } else {
-            ThrowZipException(env, "error in opening zip file");
-        }
-finally:
-        JNU_ReleaseStringPlatformChars(env, name, path);
-    }
-    return result;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-
-    return zip->total;
-}
-
-JNIEXPORT jboolean JNICALL
-Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-
-    return zip->locsig;
-}
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
-{
-    ZIP_Close(jlong_to_ptr(zfile));
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
-                                    jbyteArray name, jboolean addSlash)
-{
-#define MAXNAME 1024
-    jzfile *zip = jlong_to_ptr(zfile);
-    jsize ulen = (*env)->GetArrayLength(env, name);
-    char buf[MAXNAME+2], *path;
-    jzentry *ze;
-
-    if (ulen > MAXNAME) {
-        path = malloc(ulen + 2);
-        if (path == 0) {
-            JNU_ThrowOutOfMemoryError(env, 0);
-            return 0;
-        }
-    } else {
-        path = buf;
-    }
-    (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
-    path[ulen] = '\0';
-    ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
-    if (path != buf) {
-        free(path);
-    }
-    return ptr_to_jlong(ze);
-}
-
-JNIEXPORT void JNICALL
-Java_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,
-                                    jlong zentry)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    jzentry *ze = jlong_to_ptr(zentry);
-    ZIP_FreeEntry(zip, ze);
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,
-                                        jint n)
-{
-    jzentry *ze = ZIP_GetNextEntry(jlong_to_ptr(zfile), n);
-    return ptr_to_jlong(ze);
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_getEntryMethod(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->csize != 0 ? DEFLATED : STORED;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_getEntryFlag(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->flag;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntryCSize(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->csize != 0 ? ze->csize : ze->size;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntrySize(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return ze->size;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntryTime(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return (jlong)ze->time & 0xffffffffUL;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_ZipFile_getEntryCrc(JNIEnv *env, jclass cls, jlong zentry)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    return (jlong)ze->crc & 0xffffffffUL;
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_java_util_zip_ZipFile_getCommentBytes(JNIEnv *env,
-                                           jclass cls,
-                                           jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    jbyteArray jba = NULL;
-
-    if (zip->comment != NULL) {
-        if ((jba = (*env)->NewByteArray(env, zip->clen)) == NULL)
-            return NULL;
-        (*env)->SetByteArrayRegion(env, jba, 0, zip->clen, (jbyte*)zip->comment);
-    }
-    return jba;
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
-                                         jclass cls,
-                                         jlong zentry, jint type)
-{
-    jzentry *ze = jlong_to_ptr(zentry);
-    int len = 0;
-    jbyteArray jba = NULL;
-    switch (type) {
-    case java_util_zip_ZipFile_JZENTRY_NAME:
-        if (ze->name != 0) {
-            len = (int)ze->nlen;
-            // Unlike for extra and comment, we never return null for
-            // an (extremely rarely seen) empty name
-            if ((jba = (*env)->NewByteArray(env, len)) == NULL)
-                break;
-            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
-        }
-        break;
-    case java_util_zip_ZipFile_JZENTRY_EXTRA:
-        if (ze->extra != 0) {
-            unsigned char *bp = (unsigned char *)&ze->extra[0];
-            len = (bp[0] | (bp[1] << 8));
-            if (len <= 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
-                break;
-            (*env)->SetByteArrayRegion(env, jba, 0, len, &ze->extra[2]);
-        }
-        break;
-    case java_util_zip_ZipFile_JZENTRY_COMMENT:
-        if (ze->comment != 0) {
-            len = (int)strlen(ze->comment);
-            if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
-                break;
-            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte*)ze->comment);
-        }
-        break;
-    }
-    return jba;
-}
-
-JNIEXPORT jint JNICALL
-Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,
-                                jlong zentry, jlong pos, jbyteArray bytes,
-                                jint off, jint len)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    char *msg;
-
-#define BUFSIZE 8192
-    /* copy via tmp stack buffer: */
-    jbyte buf[BUFSIZE];
-
-    if (len > BUFSIZE) {
-        len = BUFSIZE;
-    }
-
-    ZIP_Lock(zip);
-    len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);
-    msg = zip->msg;
-    ZIP_Unlock(zip);
-    if (len != -1) {
-        (*env)->SetByteArrayRegion(env, bytes, off, len, buf);
-    }
-
-    if (len == -1) {
-        if (msg != 0) {
-            ThrowZipException(env, msg);
-        } else {
-            char errmsg[128];
-            sprintf(errmsg, "errno: %d, error: %s\n",
-                    errno, "Error reading ZIP file");
-            JNU_ThrowIOExceptionWithLastError(env, errmsg);
-        }
-    }
-
-    return len;
-}
-
-/*
- * Returns an array of strings representing the names of all entries
- * that begin with "META-INF/" (case ignored). This native method is
- * used in JarFile as an optimization when looking up manifest and
- * signature file entries. Returns null if no entries were found.
- */
-JNIEXPORT jobjectArray JNICALL
-Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)
-{
-    jlong zfile = (*env)->GetLongField(env, obj, jzfileID);
-    jzfile *zip;
-    int i, count;
-    jobjectArray result = 0;
-
-    if (zfile == 0) {
-        JNU_ThrowByName(env,
-                        "java/lang/IllegalStateException", "zip file closed");
-        return NULL;
-    }
-    zip = jlong_to_ptr(zfile);
-
-    /* count the number of valid ZIP metanames */
-    count = 0;
-    if (zip->metanames != 0) {
-        for (i = 0; i < zip->metacount; i++) {
-            if (zip->metanames[i] != 0) {
-                count++;
-            }
-        }
-    }
-
-    /* If some names were found then build array of java strings */
-    if (count > 0) {
-        jclass cls = JNU_ClassString(env);
-        CHECK_NULL_RETURN(cls, NULL);
-        result = (*env)->NewObjectArray(env, count, cls, 0);
-        CHECK_NULL_RETURN(result, NULL);
-        if (result != 0) {
-            for (i = 0; i < count; i++) {
-                jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);
-                if (str == 0) {
-                    break;
-                }
-                (*env)->SetObjectArrayElement(env, result, i, str);
-                (*env)->DeleteLocalRef(env, str);
-            }
-        }
-    }
-    return result;
-}
-
-JNIEXPORT jstring JNICALL
-Java_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile)
-{
-    jzfile *zip = jlong_to_ptr(zfile);
-    char *msg = zip->msg;
-    if (msg == NULL) {
-        return NULL;
-    }
-    return JNU_NewStringPlatform(env, msg);
-}
diff --git a/jdk/test/java/util/zip/ZipFile/ReadZip.java b/jdk/test/java/util/zip/ZipFile/ReadZip.java
index 1052642eda7..fe923e81eee 100644
--- a/jdk/test/java/util/zip/ZipFile/ReadZip.java
+++ b/jdk/test/java/util/zip/ZipFile/ReadZip.java
@@ -30,6 +30,7 @@
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.nio.file.NoSuchFileException;
 import java.nio.file.StandardCopyOption;
 import java.nio.file.StandardOpenOption;
 import java.util.zip.*;
@@ -110,6 +111,6 @@ public class ReadZip {
                                      "input"
                                       + String.valueOf(new java.util.Random().nextInt())
                                       + ".zip")));
-        } catch (FileNotFoundException fnfe) {}
+        } catch (NoSuchFileException nsfe) {}
     }
 }
diff --git a/jdk/test/java/util/zip/ZipFile/TestZipFile.java b/jdk/test/java/util/zip/ZipFile/TestZipFile.java
new file mode 100644
index 00000000000..986877731db
--- /dev/null
+++ b/jdk/test/java/util/zip/ZipFile/TestZipFile.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8142508
+ * @summary Tests various ZipFile apis
+ * @run main/manual TestZipFile
+ */
+
+import java.io.*;
+import java.lang.reflect.Method;
+import java.nio.*;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.zip.*;
+
+public class TestZipFile {
+
+    private static Random r = new Random();
+    private static int    N = 50;
+    private static int    NN = 10;
+    private static int    ENUM = 10000;
+    private static int    ESZ = 10000;
+    private static ExecutorService executor = Executors.newFixedThreadPool(20);
+    private static Set<Path> paths = new HashSet<>();
+
+    static void realMain (String[] args) throws Throwable {
+
+        try {
+            for (int i = 0; i < N; i++) {
+                test(r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+                test(r.nextInt(ENUM), r.nextInt(ESZ), true, true);
+            }
+
+            for (int i = 0; i < NN; i++) {
+                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), false, true);
+                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), true, true);
+                testCachedDelete();
+                testCachedOverwrite();
+                //test(r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+            }
+
+            test(70000, 1000, false, true);   // > 65536 entry number;
+            testDelete();                     // OPEN_DELETE
+
+            executor.shutdown();
+            executor.awaitTermination(10, TimeUnit.MINUTES);
+        } finally {
+            for (Path path : paths) {
+                Files.deleteIfExists(path);
+            }
+        }
+    }
+
+    static void test(int numEntry, int szMax, boolean addPrefix, boolean cleanOld) {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip = new Zip(name, numEntry, szMax, addPrefix, cleanOld);
+        for (int i = 0; i < NN; i++) {
+            executor.submit(() -> doTest(zip));
+        }
+     }
+
+    // test scenario:
+    // (1) open the ZipFile(zip) with OPEN_READ | OPEN_DELETE
+    // (2) test the ZipFile works correctly
+    // (3) check the zip is deleted after ZipFile gets closed
+    static void testDelete() throws Throwable {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+        try (ZipFile zf = new ZipFile(new File(zip.name),
+                                      ZipFile.OPEN_READ | ZipFile.OPEN_DELETE ))
+        {
+            doTest0(zip, zf);
+        }
+        Path p = Paths.get(name);
+        if (Files.exists(p)) {
+            fail("Failed to delete " + name + " with OPEN_DELETE");
+        }
+    }
+
+    // test scenario:
+    // (1) keep a ZipFile(zip1) alive (in ZipFile's cache), dont close it
+    // (2) delete zip1 and create zip2 with the same name the zip1 with zip2
+    // (3) zip1 tests should fail, but no crash
+    // (4) zip2 tasks should all get zip2, then pass normal testing.
+    static void testCachedDelete() throws Throwable {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+
+        try (ZipFile zf = new ZipFile(zip1.name)) {
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> verifyNoCrash(zip1));
+            }
+            // delete the "zip1"  and create a new one to test
+            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+            /*
+                System.out.println("========================================");
+                System.out.printf("    zip1=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
+                    zip1.name, zip1.lastModified, zip1.entries.size(),
+                    zip1.attrs.fileKey(), zip1.attrs.size(), zip1.attrs.lastModifiedTime().toMillis());
+                System.out.printf("    zip2=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
+                    zip2.name, zip2.lastModified, zip2.entries.size(),
+                    zip2.attrs.fileKey(), zip2.attrs.size(), zip2.attrs.lastModifiedTime().toMillis());
+            */
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> doTest(zip2));
+            }
+        }
+    }
+
+   // overwrite the "zip1"  and create a new one to test. So the two zip files
+   // have the same fileKey, but probably different lastModified()
+    static void testCachedOverwrite() throws Throwable {
+        String name = "zftest" + r.nextInt() + ".zip";
+        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
+        try (ZipFile zf = new ZipFile(zip1.name)) {
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> verifyNoCrash(zip1));
+            }
+            // overwrite the "zip1"  with new contents
+            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, false);
+            for (int i = 0; i < NN; i++) {
+                executor.submit(() -> doTest(zip2));
+            }
+        }
+    }
+
+    // just check the entries and contents. since the file has been either overwritten
+    // or deleted/rewritten, we only care if it crahes or not.
+    static void verifyNoCrash(Zip zip) throws RuntimeException {
+        try (ZipFile zf = new ZipFile(zip.name)) {
+            List<ZipEntry> zlist = new ArrayList(zip.entries.keySet());
+            String[] elist = zf.stream().map( e -> e.getName()).toArray(String[]::new);
+            if (!Arrays.equals(elist,
+                               zlist.stream().map( e -> e.getName()).toArray(String[]::new)))
+            {
+                //System.out.printf("++++++ LIST NG [%s] entries.len=%d, expected=%d+++++++%n",
+                //                  zf.getName(), elist.length, zlist.size());
+                return;
+            }
+            for (ZipEntry ze : zlist) {
+                byte[] zdata = zip.entries.get(ze);
+                ZipEntry e = zf.getEntry(ze.getName());
+                if (e != null) {
+                    checkEqual(e, ze);
+                    if (!e.isDirectory()) {
+                        // check with readAllBytes
+                        try (InputStream is = zf.getInputStream(e)) {
+                            if (!Arrays.equals(zdata, is.readAllBytes())) {
+                                //System.out.printf("++++++ BYTES NG  [%s]/[%s] ++++++++%n",
+                                //                  zf.getName(), ze.getName());
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            // t.printStackTrace();
+            // fail(t.toString());
+        }
+    }
+
+    static void checkEqual(ZipEntry x, ZipEntry y) {
+        if (x.getName().equals(y.getName()) &&
+            x.isDirectory() == y.isDirectory() &&
+            x.getMethod() == y.getMethod() &&
+            (x.getTime() / 2000) == y.getTime() / 2000 &&
+            x.getSize() == y.getSize() &&
+            x.getCompressedSize() == y.getCompressedSize() &&
+            x.getCrc() == y.getCrc() &&
+            x.getComment().equals(y.getComment())
+        ) {
+            pass();
+        } else {
+            fail(x + " not equal to " + y);
+            System.out.printf("      %s       %s%n", x.getName(), y.getName());
+            System.out.printf("      %d       %d%n", x.getMethod(), y.getMethod());
+            System.out.printf("      %d       %d%n", x.getTime(), y.getTime());
+            System.out.printf("      %d       %d%n", x.getSize(), y.getSize());
+            System.out.printf("      %d       %d%n", x.getCompressedSize(), y.getCompressedSize());
+            System.out.printf("      %d       %d%n", x.getCrc(), y.getCrc());
+            System.out.println("-----------------");
+        }
+    }
+
+    static void doTest(Zip zip) throws RuntimeException {
+        //Thread me = Thread.currentThread();
+        try (ZipFile zf = new ZipFile(zip.name)) {
+            doTest0(zip, zf);
+        } catch (Throwable t) {
+            throw new RuntimeException(t);
+        }
+    }
+
+    static void doTest0(Zip zip, ZipFile zf) throws Throwable {
+        List<ZipEntry> list = new ArrayList(zip.entries.keySet());
+        // (1) check entry list, in expected order
+        if (!check(Arrays.equals(
+                list.stream().map( e -> e.getName()).toArray(String[]::new),
+                zf.stream().map( e -> e.getName()).toArray(String[]::new)))) {
+            return;
+        }
+        // (2) shuffle, and check each entry and its bytes
+        Collections.shuffle(list);
+        for (ZipEntry ze : list) {
+            byte[] data = zip.entries.get(ze);
+            ZipEntry e = zf.getEntry(ze.getName());
+            checkEqual(e, ze);
+            if (!e.isDirectory()) {
+                // check with readAllBytes
+                try (InputStream is = zf.getInputStream(e)) {
+                    check(Arrays.equals(data, is.readAllBytes()));
+                }
+                // check with smaller sized buf
+                try (InputStream is = zf.getInputStream(e)) {
+                    byte[] buf = new byte[(int)e.getSize()];
+                    int sz = r.nextInt((int)e.getSize()/4 + 1) + 1;
+                    int off = 0;
+                    int n;
+                    while ((n = is.read(buf, off, buf.length - off)) > 0) {
+                        off += n;
+                    }
+                    check(is.read() == -1);
+                    check(Arrays.equals(data, buf));
+                }
+            }
+        }
+        // (3) check getMetaInfEntryNames
+        String[] metas = list.stream()
+                             .map( e -> e.getName())
+                             .filter( s -> s.startsWith("META-INF/"))
+                             .sorted()
+                             .toArray(String[]::new);
+        if (metas.length > 0) {
+            // meta-inf entries
+            Method getMetas = ZipFile.class.getDeclaredMethod("getMetaInfEntryNames");
+            getMetas.setAccessible(true);
+            String[] names = (String[])getMetas.invoke(zf);
+            if (names == null) {
+                fail("Failed to get metanames from " + zf);
+            } else {
+                Arrays.sort(names);
+                check(Arrays.equals(names, metas));
+            }
+        }
+    }
+
+    private static class Zip {
+        String name;
+        Map<ZipEntry, byte[]> entries;
+        BasicFileAttributes attrs;
+        long lastModified;
+
+        Zip(String name, int num, int szMax, boolean prefix, boolean clean) {
+            this.name = name;
+            entries = new LinkedHashMap<>(num);
+            try {
+                Path p = Paths.get(name);
+                if (clean) {
+                    Files.deleteIfExists(p);
+                }
+                paths.add(p);
+            } catch (Exception x) {
+                throw (RuntimeException)x;
+            }
+
+            try (FileOutputStream fos = new FileOutputStream(name);
+                 BufferedOutputStream bos = new BufferedOutputStream(fos);
+                 ZipOutputStream zos = new ZipOutputStream(bos))
+            {
+                if (prefix) {
+                    byte[] bytes = new byte[r.nextInt(1000)];
+                    r.nextBytes(bytes);
+                    bos.write(bytes);
+                }
+                CRC32 crc = new CRC32();
+                for (int i = 0; i < num; i++) {
+                    String ename = "entry-" + i + "-name-" + r.nextLong();
+                    ZipEntry ze = new ZipEntry(ename);
+                    int method = r.nextBoolean() ? ZipEntry.STORED : ZipEntry.DEFLATED;
+                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
+                }
+                // add some manifest entries
+                for (int i = 0; i < r.nextInt(20); i++) {
+                    String meta = "META-INF/" + "entry-" + i + "-metainf-" + r.nextLong();
+                    ZipEntry ze = new ZipEntry(meta);
+                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
+                }
+            } catch (Exception x) {
+                throw (RuntimeException)x;
+            }
+            try {
+                this.attrs = Files.readAttributes(Paths.get(name), BasicFileAttributes.class);
+                this.lastModified = new File(name).lastModified();
+            } catch (Exception x) {
+                throw (RuntimeException)x;
+            }
+        }
+
+        private void writeEntry(ZipOutputStream zos, CRC32 crc,
+                                ZipEntry ze, int method, int szMax)
+            throws IOException
+        {
+            ze.setMethod(method);
+            byte[] data = new byte[r.nextInt(szMax + 1)];
+            r.nextBytes(data);
+            if (method == ZipEntry.STORED) {  // must set size/csize/crc
+                ze.setSize(data.length);
+                ze.setCompressedSize(data.length);
+                crc.reset();
+                crc.update(data);
+                ze.setCrc(crc.getValue());
+            }
+            ze.setTime(System.currentTimeMillis());
+            ze.setComment(ze.getName());
+            zos.putNextEntry(ze);
+            zos.write(data);
+            zos.closeEntry();
+            entries.put(ze, data);
+        }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void pass(String msg) {System.out.println(msg); passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void unexpected(Throwable t, String msg) {
+        System.out.println(msg); failed++; t.printStackTrace();}
+    static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.println("\nPassed = " + passed + " failed = " + failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}

From b0e22f96036337799a90954d9c5eb98d5ffed0e6 Mon Sep 17 00:00:00 2001
From: Xueming Shen <sherman@openjdk.org>
Date: Tue, 8 Dec 2015 16:43:58 -0800
Subject: [PATCH 25/62] 8144958: changes by JDK-8142508 seems to have broken
 jtreg

Reviewed-by: darcy
---
 jdk/make/mapfiles/libzip/mapfile-vers         |  22 +-
 jdk/make/mapfiles/libzip/reorder-sparc        |  16 +
 jdk/make/mapfiles/libzip/reorder-sparcv9      |  15 +
 jdk/make/mapfiles/libzip/reorder-x86          |  18 +
 .../share/classes/java/util/jar/JarFile.java  |   5 +-
 .../share/classes/java/util/zip/ZipCoder.java |  21 +-
 .../share/classes/java/util/zip/ZipFile.java  | 837 ++++--------------
 .../share/classes/java/util/zip/ZipUtils.java |  79 +-
 .../internal/misc/JavaUtilZipFileAccess.java  |   1 -
 .../java.base/share/classes/sun/misc/VM.java  |   3 +
 .../java.base/share/native/libzip/ZipFile.c   | 406 +++++++++
 jdk/test/java/util/zip/ZipFile/ReadZip.java   |   3 +-
 .../java/util/zip/ZipFile/TestZipFile.java    | 361 --------
 13 files changed, 672 insertions(+), 1115 deletions(-)
 create mode 100644 jdk/src/java.base/share/native/libzip/ZipFile.c
 delete mode 100644 jdk/test/java/util/zip/ZipFile/TestZipFile.java

diff --git a/jdk/make/mapfiles/libzip/mapfile-vers b/jdk/make/mapfiles/libzip/mapfile-vers
index c1ab48c10cf..ceace23f26d 100644
--- a/jdk/make/mapfiles/libzip/mapfile-vers
+++ b/jdk/make/mapfiles/libzip/mapfile-vers
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2013, 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,6 +27,7 @@
 
 SUNWprivate_1.1 {
 	global:
+		Java_java_util_jar_JarFile_getMetaInfEntryNames;
 		Java_java_util_zip_Adler32_update;
 		Java_java_util_zip_Adler32_updateBytes;
 		Java_java_util_zip_Adler32_updateByteBuffer;
@@ -47,6 +48,25 @@ SUNWprivate_1.1 {
 		Java_java_util_zip_Inflater_initIDs;
 		Java_java_util_zip_Inflater_reset;
 		Java_java_util_zip_Inflater_setDictionary;
+		Java_java_util_zip_ZipFile_close;
+		Java_java_util_zip_ZipFile_getCommentBytes;
+		Java_java_util_zip_ZipFile_freeEntry;
+		Java_java_util_zip_ZipFile_getEntry;
+		Java_java_util_zip_ZipFile_getEntryBytes;
+		Java_java_util_zip_ZipFile_getEntryCrc;
+		Java_java_util_zip_ZipFile_getEntryCSize;
+		Java_java_util_zip_ZipFile_getEntryFlag;
+		Java_java_util_zip_ZipFile_getEntryMethod;
+		Java_java_util_zip_ZipFile_getEntrySize;
+		Java_java_util_zip_ZipFile_getEntryTime;
+		Java_java_util_zip_ZipFile_getNextEntry;
+		Java_java_util_zip_ZipFile_getZipMessage;
+		Java_java_util_zip_ZipFile_getTotal;
+		Java_java_util_zip_ZipFile_initIDs;
+		Java_java_util_zip_ZipFile_open;
+		Java_java_util_zip_ZipFile_read;
+		Java_java_util_zip_ZipFile_startsWithLOC;
+
 		ZIP_Close;
 		ZIP_CRC32;
 		ZIP_FindEntry;
diff --git a/jdk/make/mapfiles/libzip/reorder-sparc b/jdk/make/mapfiles/libzip/reorder-sparc
index 63b2ad6fc28..154e7998a53 100644
--- a/jdk/make/mapfiles/libzip/reorder-sparc
+++ b/jdk/make/mapfiles/libzip/reorder-sparc
@@ -16,14 +16,30 @@ text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
+text: .text%Java_java_util_zip_ZipFile_initIDs;
+text: .text%Java_java_util_zip_ZipFile_open;
+text: .text%Java_java_util_zip_ZipFile_getTotal;
+text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getEntry;
+text: .text%Java_java_util_zip_ZipFile_freeEntry;
+text: .text%Java_java_util_zip_ZipFile_getEntryTime;
+text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
+text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
+text: .text%Java_java_util_zip_ZipFile_getEntrySize;
+text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
+text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
+text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
 text: .text%Java_java_util_zip_Inflater_initIDs;
 text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
 text: .text%zcalloc;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
+text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
+text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
 text: .text%Java_java_util_zip_Inflater_reset;
 text: .text%Java_java_util_zip_Inflater_end;
 text: .text%inflateEnd;
+text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
diff --git a/jdk/make/mapfiles/libzip/reorder-sparcv9 b/jdk/make/mapfiles/libzip/reorder-sparcv9
index caca118de98..89690b8dabb 100644
--- a/jdk/make/mapfiles/libzip/reorder-sparcv9
+++ b/jdk/make/mapfiles/libzip/reorder-sparcv9
@@ -15,6 +15,19 @@ text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
+text: .text%Java_java_util_zip_ZipFile_initIDs;
+text: .text%Java_java_util_zip_ZipFile_open;
+text: .text%Java_java_util_zip_ZipFile_getTotal;
+text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getEntry;
+text: .text%Java_java_util_zip_ZipFile_freeEntry;
+text: .text%Java_java_util_zip_ZipFile_getEntryTime;
+text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
+text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
+text: .text%Java_java_util_zip_ZipFile_getEntrySize;
+text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
+text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
+text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
 text: .text%Java_java_util_zip_Inflater_initIDs;
 text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
@@ -22,6 +35,7 @@ text: .text%zcalloc;
 text: .text%inflateReset;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
 text: .text%inflate;
+text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
 text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
@@ -29,5 +43,6 @@ text: .text%ZIP_ReadEntry;
 text: .text%InflateFully;
 text: .text%inflateEnd;
 text: .text%Java_java_util_zip_Inflater_reset;
+text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
 text: .text%Java_java_util_zip_Inflater_end;
diff --git a/jdk/make/mapfiles/libzip/reorder-x86 b/jdk/make/mapfiles/libzip/reorder-x86
index dfd57c7752e..746948315eb 100644
--- a/jdk/make/mapfiles/libzip/reorder-x86
+++ b/jdk/make/mapfiles/libzip/reorder-x86
@@ -16,16 +16,34 @@ text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
+text: .text%Java_java_util_zip_ZipFile_initIDs;
+text: .text%Java_java_util_zip_ZipFile_open;
+text: .text%Java_java_util_zip_ZipFile_getTotal;
+text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getEntry;
+text: .text%Java_java_util_zip_ZipFile_freeEntry;
+text: .text%Java_java_util_zip_ZipFile_getEntryTime;
+text: .text%Java_java_util_zip_ZipFile_getEntryCrc;
+text: .text%Java_java_util_zip_ZipFile_getEntryCSize;
+text: .text%Java_java_util_zip_ZipFile_getEntrySize;
+text: .text%Java_java_util_zip_ZipFile_getEntryFlag;
+text: .text%Java_java_util_zip_ZipFile_getEntryMethod;
+text: .text%Java_java_util_zip_ZipFile_getEntryBytes;
+text: .text%Java_java_util_zip_Inflater_initIDs;
+text: .text%Java_java_util_zip_Inflater_init;
 text: .text%inflateInit2_;
 text: .text%zcalloc;
 text: .text%inflateReset;
 text: .text%Java_java_util_zip_Inflater_inflateBytes;
 text: .text%inflate;
+text: .text%Java_java_util_zip_ZipFile_read;
 text: .text%ZIP_Read;
 text: .text%zcfree;
+text: .text%Java_java_util_jar_JarFile_getMetaInfEntryNames;
 text: .text%ZIP_ReadEntry;
 text: .text%InflateFully;
 text: .text%inflateEnd;
 text: .text%Java_java_util_zip_Inflater_reset;
+text: .text%Java_java_util_zip_ZipFile_close;
 text: .text%ZIP_Close;
 text: .text%Java_java_util_zip_Inflater_end;
diff --git a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java
index 62734ceefbd..6d16a517ac9 100644
--- a/jdk/src/java.base/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/java.base/share/classes/java/util/jar/JarFile.java
@@ -203,10 +203,7 @@ class JarFile extends ZipFile {
         return man;
     }
 
-    private String[] getMetaInfEntryNames() {
-        return jdk.internal.misc.SharedSecrets.getJavaUtilZipFileAccess()
-                                              .getMetaInfEntryNames((ZipFile)this);
-    }
+    private native String[] getMetaInfEntryNames();
 
     /**
      * Returns the {@code JarEntry} for the given entry name or
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java b/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java
index 243d6e8c065..b920b820e03 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipCoder.java
@@ -43,7 +43,7 @@ import sun.nio.cs.ArrayEncoder;
 
 final class ZipCoder {
 
-    String toString(byte[] ba, int off, int length) {
+    String toString(byte[] ba, int length) {
         CharsetDecoder cd = decoder().reset();
         int len = (int)(length * cd.maxCharsPerByte());
         char[] ca = new char[len];
@@ -53,12 +53,12 @@ final class ZipCoder {
         // CodingErrorAction.REPLACE mode. ZipCoder uses
         // REPORT mode.
         if (isUTF8 && cd instanceof ArrayDecoder) {
-            int clen = ((ArrayDecoder)cd).decode(ba, off, length, ca);
+            int clen = ((ArrayDecoder)cd).decode(ba, 0, length, ca);
             if (clen == -1)    // malformed
                 throw new IllegalArgumentException("MALFORMED");
             return new String(ca, 0, clen);
         }
-        ByteBuffer bb = ByteBuffer.wrap(ba, off, length);
+        ByteBuffer bb = ByteBuffer.wrap(ba, 0, length);
         CharBuffer cb = CharBuffer.wrap(ca);
         CoderResult cr = cd.decode(bb, cb, true);
         if (!cr.isUnderflow())
@@ -69,12 +69,8 @@ final class ZipCoder {
         return new String(ca, 0, cb.position());
     }
 
-    String toString(byte[] ba, int length) {
-        return toString(ba, 0, length);
-    }
-
     String toString(byte[] ba) {
-        return toString(ba, 0, ba.length);
+        return toString(ba, ba.length);
     }
 
     byte[] getBytes(String s) {
@@ -115,16 +111,13 @@ final class ZipCoder {
         return utf8.getBytes(s);
     }
 
-    String toStringUTF8(byte[] ba, int len) {
-        return toStringUTF8(ba, 0, len);
-    }
 
-    String toStringUTF8(byte[] ba, int off, int len) {
+    String toStringUTF8(byte[] ba, int len) {
         if (isUTF8)
-            return toString(ba, off, len);
+            return toString(ba, len);
         if (utf8 == null)
             utf8 = new ZipCoder(StandardCharsets.UTF_8);
-        return utf8.toString(ba, off, len);
+        return utf8.toString(ba, len);
     }
 
     boolean isUTF8() {
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
index 561023c30e7..4e3a6d20417 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -30,22 +30,14 @@ import java.io.InputStream;
 import java.io.IOException;
 import java.io.EOFException;
 import java.io.File;
-import java.io.RandomAccessFile;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.Path;
-import java.nio.file.Files;
-
 import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Deque;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
 import java.util.NoSuchElementException;
 import java.util.Spliterator;
 import java.util.Spliterators;
@@ -55,9 +47,7 @@ import java.util.stream.StreamSupport;
 import jdk.internal.misc.JavaUtilZipFileAccess;
 import jdk.internal.misc.SharedSecrets;
 
-import static java.util.zip.ZipConstants.*;
 import static java.util.zip.ZipConstants64.*;
-import static java.util.zip.ZipUtils.*;
 
 /**
  * This class is used to read entries from a zip file.
@@ -70,11 +60,11 @@ import static java.util.zip.ZipUtils.*;
  */
 public
 class ZipFile implements ZipConstants, Closeable {
-
+    private long jzfile;  // address of jzfile data
     private final String name;     // zip file name
+    private final int total;       // total number of entries
+    private final boolean locsig;  // if zip file starts with LOCSIG (usually true)
     private volatile boolean closeRequested = false;
-    private Source zsrc;
-    private ZipCoder zc;
 
     private static final int STORED = ZipEntry.STORED;
     private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -93,6 +83,23 @@ class ZipFile implements ZipConstants, Closeable {
      */
     public static final int OPEN_DELETE = 0x4;
 
+    static {
+        /* Zip library is loaded from System.initializeSystemClass */
+        initIDs();
+    }
+
+    private static native void initIDs();
+
+    private static final boolean usemmap;
+
+    static {
+        // A system prpperty to disable mmap use to avoid vm crash when
+        // in-use zip file is accidently overwritten by others.
+        String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping");
+        usemmap = (prop == null ||
+                   !(prop.length() == 0 || prop.equalsIgnoreCase("true")));
+    }
+
     /**
      * Opens a zip file for reading.
      *
@@ -158,6 +165,8 @@ class ZipFile implements ZipConstants, Closeable {
         this(file, OPEN_READ);
     }
 
+    private ZipCoder zc;
+
     /**
      * Opens a new {@code ZipFile} to read from the specified
      * {@code File} object in the specified mode.  The mode argument
@@ -205,13 +214,16 @@ class ZipFile implements ZipConstants, Closeable {
                 sm.checkDelete(name);
             }
         }
-        Objects.requireNonNull(charset, "charset");
+        if (charset == null)
+            throw new NullPointerException("charset is null");
         this.zc = ZipCoder.get(charset);
-        this.name = name;
         long t0 = System.nanoTime();
-        this.zsrc = Source.get(file, (mode & OPEN_DELETE) != 0);
+        jzfile = open(name, mode, file.lastModified(), usemmap);
         sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
         sun.misc.PerfCounter.getZipFileCount().increment();
+        this.name = name;
+        this.total = getTotal(jzfile);
+        this.locsig = startsWithLOC(jzfile);
     }
 
     /**
@@ -245,7 +257,6 @@ class ZipFile implements ZipConstants, Closeable {
 
     /**
      * Opens a ZIP file for reading given the specified File object.
-     *
      * @param file the ZIP file to be opened for reading
      * @param charset
      *        The {@linkplain java.nio.charset.Charset charset} to be
@@ -276,10 +287,10 @@ class ZipFile implements ZipConstants, Closeable {
     public String getComment() {
         synchronized (this) {
             ensureOpen();
-            if (zsrc.comment == null) {
+            byte[] bcomm = getCommentBytes(jzfile);
+            if (bcomm == null)
                 return null;
-            }
-            return zc.toString(zsrc.comment);
+            return zc.toString(bcomm, bcomm.length);
         }
     }
 
@@ -292,27 +303,38 @@ class ZipFile implements ZipConstants, Closeable {
      * @throws IllegalStateException if the zip file has been closed
      */
     public ZipEntry getEntry(String name) {
-        Objects.requireNonNull(name, "name");
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+        long jzentry = 0;
         synchronized (this) {
             ensureOpen();
-            int pos = zsrc.getEntryPos(zc.getBytes(name), true);
-            if (pos != -1) {
-                return getZipEntry(name, pos);
+            jzentry = getEntry(jzfile, zc.getBytes(name), true);
+            if (jzentry != 0) {
+                ZipEntry ze = getZipEntry(name, jzentry);
+                freeEntry(jzfile, jzentry);
+                return ze;
             }
         }
         return null;
     }
 
-    // The outstanding inputstreams that need to be closed,
+    private static native long getEntry(long jzfile, byte[] name,
+                                        boolean addSlash);
+
+    // freeEntry releases the C jzentry struct.
+    private static native void freeEntry(long jzfile, long jzentry);
+
+    // the outstanding inputstreams that need to be closed,
     // mapped to the inflater objects they use.
     private final Map<InputStream, Inflater> streams = new WeakHashMap<>();
 
     /**
      * Returns an input stream for reading the contents of the specified
      * zip file entry.
-     * <p>
-     * Closing this ZIP file will, in turn, close all input streams that
-     * have been returned by invocations of this method.
+     *
+     * <p> Closing this ZIP file will, in turn, close all input
+     * streams that have been returned by invocations of this method.
      *
      * @param entry the zip file entry
      * @return the input stream for reading the contents of the specified
@@ -322,38 +344,37 @@ class ZipFile implements ZipConstants, Closeable {
      * @throws IllegalStateException if the zip file has been closed
      */
     public InputStream getInputStream(ZipEntry entry) throws IOException {
-        Objects.requireNonNull(entry, "entry");
-        int pos = -1;
+        if (entry == null) {
+            throw new NullPointerException("entry");
+        }
+        long jzentry = 0;
         ZipFileInputStream in = null;
         synchronized (this) {
             ensureOpen();
             if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
-                pos = zsrc.getEntryPos(zc.getBytesUTF8(entry.name), false);
+                jzentry = getEntry(jzfile, zc.getBytesUTF8(entry.name), false);
             } else {
-                pos = zsrc.getEntryPos(zc.getBytes(entry.name), false);
+                jzentry = getEntry(jzfile, zc.getBytes(entry.name), false);
             }
-            if (pos == -1) {
+            if (jzentry == 0) {
                 return null;
             }
-            in = new ZipFileInputStream(zsrc.cen, pos);
-            switch (CENHOW(zsrc.cen, pos)) {
+            in = new ZipFileInputStream(jzentry);
+
+            switch (getEntryMethod(jzentry)) {
             case STORED:
                 synchronized (streams) {
                     streams.put(in, null);
                 }
                 return in;
             case DEFLATED:
-                // Inflater likes a bit of slack
                 // MORE: Compute good size for inflater stream:
-                long size = CENLEN(zsrc.cen, pos) + 2;
-                if (size > 65536) {
-                    size = 8192;
-                }
-                if (size <= 0) {
-                    size = 4096;
-                }
+                long size = getEntrySize(jzentry) + 2; // Inflater likes a bit of slack
+                if (size > 65536) size = 8192;
+                if (size <= 0) size = 4096;
                 Inflater inf = getInflater();
-                InputStream is = new ZipFileInflaterInputStream(in, inf, (int)size);
+                InputStream is =
+                    new ZipFileInflaterInputStream(in, inf, (int)size);
                 synchronized (streams) {
                     streams.put(is, inf);
                 }
@@ -426,8 +447,8 @@ class ZipFile implements ZipConstants, Closeable {
     private Inflater getInflater() {
         Inflater inf;
         synchronized (inflaterCache) {
-            while ((inf = inflaterCache.poll()) != null) {
-                if (!inf.ended()) {
+            while (null != (inf = inflaterCache.poll())) {
+                if (false == inf.ended()) {
                     return inf;
                 }
             }
@@ -439,7 +460,7 @@ class ZipFile implements ZipConstants, Closeable {
      * Releases the specified inflater to the list of available inflaters.
      */
     private void releaseInflater(Inflater inf) {
-        if (!inf.ended()) {
+        if (false == inf.ended()) {
             inf.reset();
             synchronized (inflaterCache) {
                 inflaterCache.add(inf);
@@ -448,7 +469,7 @@ class ZipFile implements ZipConstants, Closeable {
     }
 
     // List of available Inflater objects for decompression
-    private final Deque<Inflater> inflaterCache = new ArrayDeque<>();
+    private Deque<Inflater> inflaterCache = new ArrayDeque<>();
 
     /**
      * Returns the path name of the ZIP file.
@@ -472,7 +493,7 @@ class ZipFile implements ZipConstants, Closeable {
         public boolean hasNext() {
             synchronized (ZipFile.this) {
                 ensureOpen();
-                return i < zsrc.total;
+                return i < total;
             }
         }
 
@@ -483,11 +504,28 @@ class ZipFile implements ZipConstants, Closeable {
         public ZipEntry next() {
             synchronized (ZipFile.this) {
                 ensureOpen();
-                if (i >= zsrc.total) {
+                if (i >= total) {
                     throw new NoSuchElementException();
                 }
-                // each "entry" has 3 ints in table entries
-                return getZipEntry(null, zsrc.getEntryPos(i++ * 3));
+                long jzentry = getNextEntry(jzfile, i++);
+                if (jzentry == 0) {
+                    String message;
+                    if (closeRequested) {
+                        message = "ZipFile concurrently closed";
+                    } else {
+                        message = getZipMessage(ZipFile.this.jzfile);
+                    }
+                    throw new ZipError("jzentry == 0" +
+                                       ",\n jzfile = " + ZipFile.this.jzfile +
+                                       ",\n total = " + ZipFile.this.total +
+                                       ",\n name = " + ZipFile.this.name +
+                                       ",\n i = " + i +
+                                       ",\n message = " + message
+                        );
+                }
+                ZipEntry ze = getZipEntry(null, jzentry);
+                freeEntry(jzfile, jzentry);
+                return ze;
             }
         }
 
@@ -521,53 +559,48 @@ class ZipFile implements ZipConstants, Closeable {
                         Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
     }
 
-    /* Checks ensureOpen() before invoke this method */
-    private ZipEntry getZipEntry(String name, int pos) {
-        byte[] cen = zsrc.cen;
+    private ZipEntry getZipEntry(String name, long jzentry) {
         ZipEntry e = new ZipEntry();
-        int nlen = CENNAM(cen, pos);
-        int elen = CENEXT(cen, pos);
-        int clen = CENCOM(cen, pos);
-        e.flag = CENFLG(cen, pos);  // get the flag first
+        e.flag = getEntryFlag(jzentry);  // get the flag first
         if (name != null) {
             e.name = name;
         } else {
+            byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME);
             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
-                e.name = zc.toStringUTF8(cen, pos + CENHDR, nlen);
+                e.name = zc.toStringUTF8(bname, bname.length);
             } else {
-                e.name = zc.toString(cen, pos + CENHDR, nlen);
+                e.name = zc.toString(bname, bname.length);
             }
         }
-        e.xdostime = CENTIM(cen, pos);
-        e.crc = CENCRC(cen, pos);
-        e.size = CENLEN(cen, pos);
-        e.csize = CENSIZ(cen, pos);
-        e.method = CENHOW(cen, pos);
-        if (elen != 0) {
-            e.setExtra0(Arrays.copyOfRange(cen, pos + CENHDR + nlen,
-                                           pos + CENHDR + nlen + elen), true);
-        }
-        if (clen != 0) {
+        e.xdostime = getEntryTime(jzentry);
+        e.crc = getEntryCrc(jzentry);
+        e.size = getEntrySize(jzentry);
+        e.csize = getEntryCSize(jzentry);
+        e.method = getEntryMethod(jzentry);
+        e.setExtra0(getEntryBytes(jzentry, JZENTRY_EXTRA), false);
+        byte[] bcomm = getEntryBytes(jzentry, JZENTRY_COMMENT);
+        if (bcomm == null) {
+            e.comment = null;
+        } else {
             if (!zc.isUTF8() && (e.flag & EFS) != 0) {
-                e.comment = zc.toStringUTF8(cen, pos + CENHDR + nlen + elen, clen);
+                e.comment = zc.toStringUTF8(bcomm, bcomm.length);
             } else {
-                e.comment = zc.toString(cen, pos + CENHDR + nlen + elen, clen);
+                e.comment = zc.toString(bcomm, bcomm.length);
             }
         }
         return e;
     }
 
+    private static native long getNextEntry(long jzfile, int i);
+
     /**
      * Returns the number of entries in the ZIP file.
-     *
      * @return the number of entries in the ZIP file
      * @throws IllegalStateException if the zip file has been closed
      */
     public int size() {
-        synchronized (this) {
-            ensureOpen();
-            return zsrc.total;
-        }
+        ensureOpen();
+        return total;
     }
 
     /**
@@ -579,15 +612,14 @@ class ZipFile implements ZipConstants, Closeable {
      * @throws IOException if an I/O error has occurred
      */
     public void close() throws IOException {
-        if (closeRequested) {
+        if (closeRequested)
             return;
-        }
         closeRequested = true;
 
         synchronized (this) {
             // Close streams, release their inflaters
             synchronized (streams) {
-                if (!streams.isEmpty()) {
+                if (false == streams.isEmpty()) {
                     Map<InputStream, Inflater> copy = new HashMap<>(streams);
                     streams.clear();
                     for (Map.Entry<InputStream, Inflater> e : copy.entrySet()) {
@@ -599,17 +631,21 @@ class ZipFile implements ZipConstants, Closeable {
                     }
                 }
             }
+
             // Release cached inflaters
+            Inflater inf;
             synchronized (inflaterCache) {
-                Inflater inf;
-                while ((inf = inflaterCache.poll()) != null) {
+                while (null != (inf = inflaterCache.poll())) {
                     inf.end();
                 }
             }
-            // Release zip src
-            if (zsrc != null) {
-                Source.close(zsrc);
-                zsrc = null;
+
+            if (jzfile != 0) {
+                // Close the zip file
+                long zf = this.jzfile;
+                jzfile = 0;
+
+                close(zf);
             }
         }
     }
@@ -632,11 +668,14 @@ class ZipFile implements ZipConstants, Closeable {
         close();
     }
 
+    private static native void close(long jzfile);
+
     private void ensureOpen() {
         if (closeRequested) {
             throw new IllegalStateException("zip file closed");
         }
-        if (zsrc == null) {
+
+        if (jzfile == 0) {
             throw new IllegalStateException("The object is not initialized.");
         }
     }
@@ -652,86 +691,23 @@ class ZipFile implements ZipConstants, Closeable {
      * (possibly compressed) zip file entry.
      */
    private class ZipFileInputStream extends InputStream {
-        private volatile boolean closeRequested = false;
+        private volatile boolean zfisCloseRequested = false;
+        protected long jzentry; // address of jzentry data
         private   long pos;     // current position within entry data
         protected long rem;     // number of remaining bytes within entry
         protected long size;    // uncompressed size of this entry
 
-        ZipFileInputStream(byte[] cen, int cenpos) throws IOException {
-            rem = CENSIZ(cen, cenpos);
-            size = CENLEN(cen, cenpos);
-            pos = CENOFF(cen, cenpos);
-            // zip64
-            if (rem == ZIP64_MAGICVAL || size == ZIP64_MAGICVAL ||
-                pos == ZIP64_MAGICVAL) {
-                checkZIP64(cen, cenpos);
-            }
-            // negative for lazy initialization, see getDataOffset();
-            pos = - (pos + ZipFile.this.zsrc.locpos);
-        }
-
-        private void checkZIP64(byte[] cen, int cenpos) throws IOException {
-            int off = cenpos + CENHDR + CENNAM(cen, cenpos);
-            int end = off + CENEXT(cen, cenpos);
-            while (off + 4 < end) {
-                int tag = get16(cen, off);
-                int sz = get16(cen, off + 2);
-                off += 4;
-                if (off + sz > end)         // invalid data
-                    break;
-                if (tag == EXTID_ZIP64) {
-                    if (size == ZIP64_MAGICVAL) {
-                        if (sz < 8 || (off + 8) > end)
-                            break;
-                        size = get64(cen, off);
-                        sz -= 8;
-                        off += 8;
-                    }
-                    if (rem == ZIP64_MAGICVAL) {
-                        if (sz < 8 || (off + 8) > end)
-                            break;
-                        rem = get64(cen, off);
-                        sz -= 8;
-                        off += 8;
-                    }
-                    if (pos == ZIP64_MAGICVAL) {
-                        if (sz < 8 || (off + 8) > end)
-                            break;
-                        pos = get64(cen, off);
-                        sz -= 8;
-                        off += 8;
-                    }
-                    break;
-                }
-                off += sz;
-            }
-        }
-
-       /* The Zip file spec explicitly allows the LOC extra data size to
-        * be different from the CEN extra data size. Since we cannot trust
-        * the CEN extra data size, we need to read the LOC to determine
-        * the entry data offset.
-        */
-        private long initDataOffset() throws IOException {
-            if (pos <= 0) {
-                byte[] loc = new byte[LOCHDR];
-                pos = -pos;
-                int len = ZipFile.this.zsrc.readFullyAt(loc, 0, loc.length, pos);
-                if (len != LOCHDR) {
-                    throw new ZipException("ZipFile error reading zip file");
-                }
-                if (LOCSIG(loc) != LOCSIG) {
-                    throw new ZipException("ZipFile invalid LOC header (bad signature)");
-                }
-                pos += LOCHDR + LOCNAM(loc) + LOCEXT(loc);
-            }
-            return pos;
+        ZipFileInputStream(long jzentry) {
+            pos = 0;
+            rem = getEntryCSize(jzentry);
+            size = getEntrySize(jzentry);
+            this.jzentry = jzentry;
         }
 
         public int read(byte b[], int off, int len) throws IOException {
             synchronized (ZipFile.this) {
-                ensureOpenOrZipException();
-                initDataOffset();
+                long rem = this.rem;
+                long pos = this.pos;
                 if (rem == 0) {
                     return -1;
                 }
@@ -741,10 +717,14 @@ class ZipFile implements ZipConstants, Closeable {
                 if (len > rem) {
                     len = (int) rem;
                 }
-                len = ZipFile.this.zsrc.readAt(b, off, len, pos);
+
+                // Check if ZipFile open
+                ensureOpenOrZipException();
+                len = ZipFile.read(ZipFile.this.jzfile, jzentry, pos, b,
+                                   off, len);
                 if (len > 0) {
-                    pos += len;
-                    rem -= len;
+                    this.pos = (pos + len);
+                    this.rem = (rem - len);
                 }
             }
             if (rem == 0) {
@@ -762,16 +742,11 @@ class ZipFile implements ZipConstants, Closeable {
             }
         }
 
-        public long skip(long n) throws IOException {
-            synchronized (ZipFile.this) {
-                ensureOpenOrZipException();
-                initDataOffset();
-                if (n > rem) {
-                    n = rem;
-                }
-                pos += n;
-                rem -= n;
-            }
+        public long skip(long n) {
+            if (n > rem)
+                n = rem;
+            pos += n;
+            rem -= n;
             if (rem == 0) {
                 close();
             }
@@ -787,11 +762,17 @@ class ZipFile implements ZipConstants, Closeable {
         }
 
         public void close() {
-            if (closeRequested) {
+            if (zfisCloseRequested)
                 return;
-            }
-            closeRequested = true;
+            zfisCloseRequested = true;
+
             rem = 0;
+            synchronized (ZipFile.this) {
+                if (jzentry != 0 && ZipFile.this.jzfile != 0) {
+                    freeEntry(ZipFile.this.jzfile, jzentry);
+                    jzentry = 0;
+                }
+            }
             synchronized (streams) {
                 streams.remove(this);
             }
@@ -806,492 +787,40 @@ class ZipFile implements ZipConstants, Closeable {
         SharedSecrets.setJavaUtilZipFileAccess(
             new JavaUtilZipFileAccess() {
                 public boolean startsWithLocHeader(ZipFile zip) {
-                    return zip.zsrc.locsig;
+                    return zip.startsWithLocHeader();
                 }
-                public String[] getMetaInfEntryNames(ZipFile zip) {
-                    return zip.getMetaInfEntryNames();
-                }
-             }
+            }
         );
     }
 
-    /*
-     * Returns an array of strings representing the names of all entries
-     * that begin with "META-INF/" (case ignored). This method is used
-     * in JarFile, via SharedSecrets, as an optimization when looking up
-     * manifest and signature file entries. Returns null if no entries
-     * were found.
+    /**
+     * Returns {@code true} if, and only if, the zip file begins with {@code
+     * LOCSIG}.
      */
-    private String[] getMetaInfEntryNames() {
-        synchronized (this) {
-            ensureOpen();
-            if (zsrc.metanames.size() == 0) {
-                return null;
-            }
-            String[] names = new String[zsrc.metanames.size()];
-            byte[] cen = zsrc.cen;
-            for (int i = 0; i < names.length; i++) {
-                int pos = zsrc.metanames.get(i);
-                names[i] = zc.toStringUTF8(cen, pos + CENHDR,  CENNAM(cen, pos));
-            }
-            return names;
-        }
+    private boolean startsWithLocHeader() {
+        return locsig;
     }
 
-    private static class Source {
-        private final Key key;               // the key in files
-        private int refs = 1;
+    private static native long open(String name, int mode, long lastModified,
+                                    boolean usemmap) throws IOException;
+    private static native int getTotal(long jzfile);
+    private static native boolean startsWithLOC(long jzfile);
+    private static native int read(long jzfile, long jzentry,
+                                   long pos, byte[] b, int off, int len);
 
-        private RandomAccessFile zfile;      // zfile of the underlying zip file
-        private byte[] cen;                  // CEN & ENDHDR
-        private long locpos;                 // position of first LOC header (usually 0)
-        private byte[] comment;              // zip file comment
-                                             // list of meta entries in META-INF dir
-        private ArrayList<Integer> metanames = new ArrayList<>();
-        private final boolean locsig;        // true, if zip file starts with LOCSIG (usually true)
+    // access to the native zentry object
+    private static native long getEntryTime(long jzentry);
+    private static native long getEntryCrc(long jzentry);
+    private static native long getEntryCSize(long jzentry);
+    private static native long getEntrySize(long jzentry);
+    private static native int getEntryMethod(long jzentry);
+    private static native int getEntryFlag(long jzentry);
+    private static native byte[] getCommentBytes(long jzfile);
 
-        // A Hashmap for all entries.
-        //
-        // A cen entry of Zip/JAR file. As we have one for every entry in every active Zip/JAR,
-        // We might have a lot of these in a typical system. In order to save space we don't
-        // keep the name in memory, but merely remember a 32 bit {@code hash} value of the
-        // entry name and its offset {@code pos} in the central directory hdeader.
-        //
-        // private static class Entry {
-        //     int hash;       // 32 bit hashcode on name
-        //     int next;       // hash chain: index into entries
-        //     int pos;        // Offset of central directory file header
-        // }
-        // private Entry[] entries;             // array of hashed cen entry
-        //
-        // To reduce the total size of entries further, we use a int[] here to store 3 "int"
-        // {@code hash}, {@code next and {@code "pos for each entry. The entry can then be
-        // referred by their index of their positions in the {@code entries}.
-        //
-        private int[] entries;                  // array of hashed cen entry
-        private int addEntry(int index, int hash, int next, int pos) {
-            entries[index++] = hash;
-            entries[index++] = next;
-            entries[index++] = pos;
-            return index;
-        }
-        private int getEntryHash(int index) { return entries[index]; }
-        private int getEntryNext(int index) { return entries[index + 1]; }
-        private int getEntryPos(int index)  { return entries[index + 2]; }
-        private static final int ZIP_ENDCHAIN  = -1;
-        private int total;                   // total number of entries
-        private int[] table;                 // Hash chain heads: indexes into entries
-        private int tablelen;                // number of hash heads
+    private static final int JZENTRY_NAME = 0;
+    private static final int JZENTRY_EXTRA = 1;
+    private static final int JZENTRY_COMMENT = 2;
+    private static native byte[] getEntryBytes(long jzentry, int type);
 
-        private static class Key {
-            BasicFileAttributes attrs;
-            File file;
-
-            public Key(File file, BasicFileAttributes attrs) {
-                this.attrs = attrs;
-                this.file = file;
-            }
-
-            public int hashCode() {
-                long t = attrs.lastModifiedTime().toMillis();
-                return ((int)(t ^ (t >>> 32))) + file.hashCode();
-            }
-
-            public boolean equals(Object obj) {
-                if (obj instanceof Key) {
-                    Key key = (Key)obj;
-                    if (!attrs.lastModifiedTime().equals(key.attrs.lastModifiedTime())) {
-                        return false;
-                    }
-                    Object fk = attrs.fileKey();
-                    if (fk != null) {
-                        return  fk.equals(key.attrs.fileKey());
-                    } else {
-                        return file.equals(key.file);
-                    }
-                }
-                return false;
-            }
-        }
-        private static final HashMap<Key, Source> files = new HashMap<>();
-
-        public static Source get(File file, boolean toDelete) throws IOException {
-            Key key = new Key(file,
-                              Files.readAttributes(file.toPath(), BasicFileAttributes.class));
-            Source src = null;
-            synchronized (files) {
-                src = files.get(key);
-                if (src != null) {
-                    src.refs++;
-                    return src;
-                }
-            }
-            src = new Source(key, toDelete);
-            synchronized (files) {
-                if (files.containsKey(key)) {    // someone else put in first
-                    src.close();                 // close the newly created one
-                    src = files.get(key);
-                    src.refs++;
-                    return src;
-                }
-                files.put(key, src);
-                return src;
-            }
-        }
-
-        private static void close(Source src) throws IOException {
-            synchronized (files) {
-                if (--src.refs == 0) {
-                    files.remove(src.key);
-                    src.close();
-                }
-            }
-        }
-
-        private Source(Key key, boolean toDelete) throws IOException {
-            this.key = key;
-            this.zfile = new RandomAccessFile(key.file, "r");
-            if (toDelete) {
-                key.file.delete();
-            }
-            initCEN(-1);
-            byte[] buf = new byte[4];
-            readFullyAt(buf, 0, 4, 0);
-            this.locsig = (LOCSIG(buf) != LOCSIG);
-        }
-
-        private void close() throws IOException {
-            zfile.close();
-            zfile = null;
-            cen = null;
-            entries = null;
-            table = null;
-            metanames = null;
-        }
-
-        private static final int BUF_SIZE = 8192;
-        private final int readFullyAt(byte[] buf, int off, int len, long pos)
-            throws IOException
-        {
-            synchronized(zfile) {
-                zfile.seek(pos);
-                int N = len;
-                while (N > 0) {
-                    int n = Math.min(BUF_SIZE, N);
-                    zfile.readFully(buf, off, n);
-                    off += n;
-                    N -= n;
-                }
-                return len;
-            }
-        }
-
-        private final int readAt(byte[] buf, int off, int len, long pos)
-            throws IOException
-        {
-            synchronized(zfile) {
-                zfile.seek(pos);
-                return zfile.read(buf, off, len);
-            }
-        }
-
-        private static final int hashN(byte[] a, int off, int len) {
-            int h = 1;
-            while (len-- > 0) {
-                h = 31 * h + a[off++];
-            }
-            return h;
-        }
-
-        private static final int hash_append(int hash, byte b) {
-            return hash * 31 + b;
-        }
-
-        private static class End {
-            int  centot;     // 4 bytes
-            long cenlen;     // 4 bytes
-            long cenoff;     // 4 bytes
-            long endpos;     // 4 bytes
-        }
-
-        /*
-         * Searches for end of central directory (END) header. The contents of
-         * the END header will be read and placed in endbuf. Returns the file
-         * position of the END header, otherwise returns -1 if the END header
-         * was not found or an error occurred.
-         */
-        private End findEND() throws IOException {
-            long ziplen = zfile.length();
-            if (ziplen <= 0)
-                zerror("zip file is empty");
-            End end = new End();
-            byte[] buf = new byte[READBLOCKSZ];
-            long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
-            long minPos = minHDR - (buf.length - ENDHDR);
-            for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) {
-                int off = 0;
-                if (pos < 0) {
-                    // Pretend there are some NUL bytes before start of file
-                    off = (int)-pos;
-                    Arrays.fill(buf, 0, off, (byte)0);
-                }
-                int len = buf.length - off;
-                if (readFullyAt(buf, off, len, pos + off) != len ) {
-                    zerror("zip END header not found");
-                }
-                // Now scan the block backwards for END header signature
-                for (int i = buf.length - ENDHDR; i >= 0; i--) {
-                    if (buf[i+0] == (byte)'P'    &&
-                        buf[i+1] == (byte)'K'    &&
-                        buf[i+2] == (byte)'\005' &&
-                        buf[i+3] == (byte)'\006') {
-                        // Found ENDSIG header
-                        byte[] endbuf = Arrays.copyOfRange(buf, i, i + ENDHDR);
-                        end.centot = ENDTOT(endbuf);
-                        end.cenlen = ENDSIZ(endbuf);
-                        end.cenoff = ENDOFF(endbuf);
-                        end.endpos = pos + i;
-                        int comlen = ENDCOM(endbuf);
-                        if (end.endpos + ENDHDR + comlen != ziplen) {
-                            // ENDSIG matched, however the size of file comment in it does
-                            // not match the real size. One "common" cause for this problem
-                            // is some "extra" bytes are padded at the end of the zipfile.
-                            // Let's do some extra verification, we don't care about the
-                            // performance in this situation.
-                            byte[] sbuf = new byte[4];
-                            long cenpos = end.endpos - end.cenlen;
-                            long locpos = cenpos - end.cenoff;
-                            if  (cenpos < 0 ||
-                                 locpos < 0 ||
-                                 readFullyAt(sbuf, 0, sbuf.length, cenpos) != 4 ||
-                                 GETSIG(sbuf) != CENSIG ||
-                                 readFullyAt(sbuf, 0, sbuf.length, locpos) != 4 ||
-                                 GETSIG(sbuf) != LOCSIG) {
-                                continue;
-                            }
-                        }
-                        if (comlen > 0) {    // this zip file has comlen
-                            comment = new byte[comlen];
-                            if (readFullyAt(comment, 0, comlen, end.endpos + ENDHDR) != comlen) {
-                                zerror("zip comment read failed");
-                            }
-                        }
-                        if (end.cenlen == ZIP64_MAGICVAL ||
-                            end.cenoff == ZIP64_MAGICVAL ||
-                            end.centot == ZIP64_MAGICCOUNT)
-                        {
-                            // need to find the zip64 end;
-                            try {
-                                byte[] loc64 = new byte[ZIP64_LOCHDR];
-                                if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
-                                    != loc64.length || GETSIG(loc64) != ZIP64_LOCSIG) {
-                                    return end;
-                                }
-                                long end64pos = ZIP64_LOCOFF(loc64);
-                                byte[] end64buf = new byte[ZIP64_ENDHDR];
-                                if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
-                                    != end64buf.length || GETSIG(end64buf) != ZIP64_ENDSIG) {
-                                    return end;
-                                }
-                                // end64 found, re-calcualte everything.
-                                end.cenlen = ZIP64_ENDSIZ(end64buf);
-                                end.cenoff = ZIP64_ENDOFF(end64buf);
-                                end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
-                                end.endpos = end64pos;
-                            } catch (IOException x) {}    // no zip64 loc/end
-                        }
-                        return end;
-                    }
-                }
-            }
-            zerror("zip END header not found");
-            return null; //make compiler happy
-        }
-
-        // Reads zip file central directory.
-        private void initCEN(int knownTotal) throws IOException {
-            if (knownTotal == -1) {
-                End end = findEND();
-                if (end.endpos == 0) {
-                    locpos = 0;
-                    total = 0;
-                    entries  = new int[0];
-                    cen = null;
-                    return;         // only END header present
-                }
-                if (end.cenlen > end.endpos)
-                    zerror("invalid END header (bad central directory size)");
-                long cenpos = end.endpos - end.cenlen;     // position of CEN table
-                // Get position of first local file (LOC) header, taking into
-                // account that there may be a stub prefixed to the zip file.
-                locpos = cenpos - end.cenoff;
-                if (locpos < 0) {
-                    zerror("invalid END header (bad central directory offset)");
-                }
-                // read in the CEN and END
-                cen = new byte[(int)(end.cenlen + ENDHDR)];
-                if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
-                    zerror("read CEN tables failed");
-                }
-                total = end.centot;
-            } else {
-                total = knownTotal;
-            }
-            // hash table for entries
-            entries  = new int[total * 3];
-            tablelen = ((total/2) | 1); // Odd -> fewer collisions
-            table    =  new int[tablelen];
-            Arrays.fill(table, ZIP_ENDCHAIN);
-            int idx = 0;
-            int hash = 0;
-            int next = -1;
-
-            // list for all meta entries
-            metanames = new ArrayList<>();
-
-            // Iterate through the entries in the central directory
-            int i = 0;
-            int hsh = 0;
-            int pos = 0;
-            int limit = cen.length - ENDHDR;
-            while (pos + CENHDR  <= limit) {
-                if (i >= total) {
-                    // This will only happen if the zip file has an incorrect
-                    // ENDTOT field, which usually means it contains more than
-                    // 65535 entries.
-                    initCEN(countCENHeaders(cen, limit));
-                    return;
-                }
-                if (CENSIG(cen, pos) != CENSIG)
-                    zerror("invalid CEN header (bad signature)");
-                int method = CENHOW(cen, pos);
-                int nlen   = CENNAM(cen, pos);
-                int elen   = CENEXT(cen, pos);
-                int clen   = CENCOM(cen, pos);
-                if ((CENFLG(cen, pos) & 1) != 0)
-                    zerror("invalid CEN header (encrypted entry)");
-                if (method != STORED && method != DEFLATED)
-                    zerror("invalid CEN header (bad compression method: " + method + ")");
-                if (pos + CENHDR + nlen > limit)
-                    zerror("invalid CEN header (bad header size)");
-                // Record the CEN offset and the name hash in our hash cell.
-                hash = hashN(cen, pos + CENHDR, nlen);
-                hsh = (hash & 0x7fffffff) % tablelen;
-                next = table[hsh];
-                table[hsh] = idx;
-                idx = addEntry(idx, hash, next, pos);
-                // Adds name to metanames.
-                if (isMetaName(cen, pos + CENHDR, nlen)) {
-                    metanames.add(pos);
-                }
-                // skip ext and comment
-                pos += (CENHDR + nlen + elen + clen);
-                i++;
-            }
-            total = i;
-            if (pos + ENDHDR != cen.length) {
-                zerror("invalid CEN header (bad header size)");
-            }
-        }
-
-        private static void zerror(String msg) throws ZipException {
-            throw new ZipException(msg);
-        }
-
-        /*
-         * Returns the {@code pos} of the zip cen entry corresponding to the
-         * specified entry name, or -1 if not found.
-         */
-        private int getEntryPos(byte[] name, boolean addSlash) {
-            if (total == 0) {
-                return -1;
-            }
-            int hsh = hashN(name, 0, name.length);
-            int idx = table[(hsh & 0x7fffffff) % tablelen];
-            /*
-             * This while loop is an optimization where a double lookup
-             * for name and name+/ is being performed. The name char
-             * array has enough room at the end to try again with a
-             * slash appended if the first table lookup does not succeed.
-             */
-            while(true) {
-                /*
-                 * Search down the target hash chain for a entry whose
-                 * 32 bit hash matches the hashed name.
-                 */
-                while (idx != ZIP_ENDCHAIN) {
-                    if (getEntryHash(idx) == hsh) {
-                        // The CEN name must match the specfied one
-                        int pos = getEntryPos(idx);
-                        if (name.length == CENNAM(cen, pos)) {
-                            boolean matched = true;
-                            int nameoff = pos + CENHDR;
-                            for (int i = 0; i < name.length; i++) {
-                                if (name[i] != cen[nameoff++]) {
-                                    matched = false;
-                                    break;
-                                }
-                            }
-                            if (matched) {
-                                return pos;
-                            }
-                         }
-                    }
-                    idx = getEntryNext(idx);
-                }
-                /* If not addSlash, or slash is already there, we are done */
-                if (!addSlash  || name[name.length - 1] == '/') {
-                     return -1;
-                }
-                /* Add slash and try once more */
-                name = Arrays.copyOf(name, name.length + 1);
-                name[name.length - 1] = '/';
-                hsh = hash_append(hsh, (byte)'/');
-                //idx = table[hsh % tablelen];
-                idx = table[(hsh & 0x7fffffff) % tablelen];
-                addSlash = false;
-            }
-        }
-
-        private static byte[] metainf = new byte[] {
-            'M', 'E', 'T', 'A', '-', 'I' , 'N', 'F', '/',
-        };
-
-        /*
-         * Returns true if the specified entry's name begins with the string
-         * "META-INF/" irrespective of case.
-         */
-        private static boolean isMetaName(byte[] name,  int off, int len) {
-            if (len < 9 || (name[off] != 'M' && name[off] != 'm')) {  //  sizeof("META-INF/") - 1
-                return false;
-            }
-            off++;
-            for (int i = 1; i < metainf.length; i++) {
-                byte c = name[off++];
-                // Avoid toupper; it's locale-dependent
-                if (c >= 'a' && c <= 'z') {
-                    c += 'A' - 'a';
-                }
-                if (metainf[i] != c) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        /*
-         * Counts the number of CEN headers in a central directory extending
-         * from BEG to END.  Might return a bogus answer if the zip file is
-         * corrupt, but will not crash.
-         */
-        static int countCENHeaders(byte[] cen, int end) {
-            int count = 0;
-            int pos = 0;
-            while (pos + CENHDR <= end) {
-                count++;
-                pos += (CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos));
-            }
-            return count;
-        }
-    }
+    private static native String getZipMessage(long jzfile);
 }
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java
index a6632f0fa83..81882fdcec6 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipUtils.java
@@ -31,8 +31,6 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.concurrent.TimeUnit;
 
-import static java.util.zip.ZipConstants.ENDHDR;
-
 class ZipUtils {
 
     // used to adjust values between Windows and java epoch
@@ -135,7 +133,7 @@ class ZipUtils {
      * The bytes are assumed to be in Intel (little-endian) byte order.
      */
     public static final int get16(byte b[], int off) {
-        return (b[off] & 0xff) | ((b[off + 1] & 0xff) << 8);
+        return Byte.toUnsignedInt(b[off]) | (Byte.toUnsignedInt(b[off+1]) << 8);
     }
 
     /**
@@ -162,79 +160,4 @@ class ZipUtils {
     public static final int get32S(byte b[], int off) {
         return (get16(b, off) | (get16(b, off+2) << 16));
     }
-
-    // fields access methods
-    static final int CH(byte[] b, int n) {
-        return b[n] & 0xff ;
-    }
-
-    static final int SH(byte[] b, int n) {
-        return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8);
-    }
-
-    static final long LG(byte[] b, int n) {
-        return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL;
-    }
-
-    static final long LL(byte[] b, int n) {
-        return (LG(b, n)) | (LG(b, n + 4) << 32);
-    }
-
-    static final long GETSIG(byte[] b) {
-        return LG(b, 0);
-    }
-
-    // local file (LOC) header fields
-    static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature
-    static final int  LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract
-    static final int  LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags
-    static final int  LOCHOW(byte[] b) { return SH(b, 8); } // compression method
-    static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time
-    static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data
-    static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size
-    static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size
-    static final int  LOCNAM(byte[] b) { return SH(b, 26);} // filename length
-    static final int  LOCEXT(byte[] b) { return SH(b, 28);} // extra field length
-
-    // extra local (EXT) header fields
-    static final long EXTCRC(byte[] b) { return LG(b, 4);}  // crc of uncompressed data
-    static final long EXTSIZ(byte[] b) { return LG(b, 8);}  // compressed size
-    static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size
-
-    // end of central directory header (END) fields
-    static final int  ENDSUB(byte[] b) { return SH(b, 8); }  // number of entries on this disk
-    static final int  ENDTOT(byte[] b) { return SH(b, 10);}  // total number of entries
-    static final long ENDSIZ(byte[] b) { return LG(b, 12);}  // central directory size
-    static final long ENDOFF(byte[] b) { return LG(b, 16);}  // central directory offset
-    static final int  ENDCOM(byte[] b) { return SH(b, 20);}  // size of zip file comment
-    static final int  ENDCOM(byte[] b, int off) { return SH(b, off + 20);}
-
-    // zip64 end of central directory recoder fields
-    static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);}  // total number of entries on disk
-    static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);}  // total number of entries
-    static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);}  // central directory size
-    static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);}  // central directory offset
-    static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);}   // zip64 end offset
-
-    // central directory header (CEN) fields
-    static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); }
-    static final int  CENVEM(byte[] b, int pos) { return SH(b, pos + 4); }
-    static final int  CENVER(byte[] b, int pos) { return SH(b, pos + 6); }
-    static final int  CENFLG(byte[] b, int pos) { return SH(b, pos + 8); }
-    static final int  CENHOW(byte[] b, int pos) { return SH(b, pos + 10);}
-    static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);}
-    static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);}
-    static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);}
-    static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);}
-    static final int  CENNAM(byte[] b, int pos) { return SH(b, pos + 28);}
-    static final int  CENEXT(byte[] b, int pos) { return SH(b, pos + 30);}
-    static final int  CENCOM(byte[] b, int pos) { return SH(b, pos + 32);}
-    static final int  CENDSK(byte[] b, int pos) { return SH(b, pos + 34);}
-    static final int  CENATT(byte[] b, int pos) { return SH(b, pos + 36);}
-    static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);}
-    static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);}
-
-    // The END header is followed by a variable length comment of size < 64k.
-    static final long END_MAXLEN = 0xFFFF + ENDHDR;
-    static final int READBLOCKSZ = 128;
 }
diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java
index 9b9b1e85788..df10fda22ca 100644
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaUtilZipFileAccess.java
@@ -29,6 +29,5 @@ import java.util.zip.ZipFile;
 
 public interface JavaUtilZipFileAccess {
     public boolean startsWithLocHeader(ZipFile zip);
-    public String[] getMetaInfEntryNames(ZipFile zip);
 }
 
diff --git a/jdk/src/java.base/share/classes/sun/misc/VM.java b/jdk/src/java.base/share/classes/sun/misc/VM.java
index 37dc3b38fa1..0c75f10c657 100644
--- a/jdk/src/java.base/share/classes/sun/misc/VM.java
+++ b/jdk/src/java.base/share/classes/sun/misc/VM.java
@@ -274,6 +274,9 @@ public class VM {
         // used by java.lang.Integer.IntegerCache
         props.remove("java.lang.Integer.IntegerCache.high");
 
+        // used by java.util.zip.ZipFile
+        props.remove("sun.zip.disableMemoryMapping");
+
         // used by sun.launcher.LauncherHelper
         props.remove("sun.java.launcher.diag");
     }
diff --git a/jdk/src/java.base/share/native/libzip/ZipFile.c b/jdk/src/java.base/share/native/libzip/ZipFile.c
new file mode 100644
index 00000000000..d7a21a6cf88
--- /dev/null
+++ b/jdk/src/java.base/share/native/libzip/ZipFile.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 1998, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Native method support for java.util.zip.ZipFile
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <assert.h>
+#include "jlong.h"
+#include "jvm.h"
+#include "jni.h"
+#include "jni_util.h"
+#include "zip_util.h"
+#ifdef WIN32
+#include "io_util_md.h"
+#else
+#include "io_util.h"
+#endif
+
+#include "java_util_zip_ZipFile.h"
+#include "java_util_jar_JarFile.h"
+
+#define DEFLATED 8
+#define STORED 0
+
+static jfieldID jzfileID;
+
+static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
+static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
+
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
+{
+    jzfileID = (*env)->GetFieldID(env, cls, "jzfile", "J");
+    assert(jzfileID != 0);
+}
+
+static void
+ThrowZipException(JNIEnv *env, const char *msg)
+{
+    jstring s = NULL;
+    jobject x;
+
+    if (msg != NULL) {
+        s = JNU_NewStringPlatform(env, msg);
+    }
+    if (s != NULL) {
+        x = JNU_NewObjectByName(env,
+                            "java/util/zip/ZipException",
+                            "(Ljava/lang/String;)V", s);
+        if (x != NULL) {
+            (*env)->Throw(env, x);
+        }
+    }
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
+                                        jint mode, jlong lastModified,
+                                        jboolean usemmap)
+{
+    const char *path = JNU_GetStringPlatformChars(env, name, 0);
+    char *msg = 0;
+    jlong result = 0;
+    int flag = 0;
+    jzfile *zip = 0;
+
+    if (mode & OPEN_READ) flag |= O_RDONLY;
+
+    if (path != 0) {
+        zip = ZIP_Get_From_Cache(path, &msg, lastModified);
+        if (zip == 0 && msg == 0) {
+            ZFILE zfd = 0;
+#ifdef WIN32
+            if (mode & OPEN_DELETE) flag |= O_TEMPORARY;
+            zfd = winFileHandleOpen(env, name, flag);
+            if (zfd == -1) {
+                /* Exception already pending. */
+                goto finally;
+            }
+#else
+            zfd = open(path, flag, 0);
+            if (zfd < 0) {
+                throwFileNotFoundException(env, name);
+                goto finally;
+            }
+            if (mode & OPEN_DELETE) {
+                unlink(path);
+            }
+#endif
+            zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);
+        }
+
+        if (zip != 0) {
+            result = ptr_to_jlong(zip);
+        } else if (msg != 0) {
+            ThrowZipException(env, msg);
+            free(msg);
+        } else if (errno == ENOMEM) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+        } else {
+            ThrowZipException(env, "error in opening zip file");
+        }
+finally:
+        JNU_ReleaseStringPlatformChars(env, name, path);
+    }
+    return result;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getTotal(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+
+    return zip->total;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_util_zip_ZipFile_startsWithLOC(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+
+    return zip->locsig;
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
+{
+    ZIP_Close(jlong_to_ptr(zfile));
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntry(JNIEnv *env, jclass cls, jlong zfile,
+                                    jbyteArray name, jboolean addSlash)
+{
+#define MAXNAME 1024
+    jzfile *zip = jlong_to_ptr(zfile);
+    jsize ulen = (*env)->GetArrayLength(env, name);
+    char buf[MAXNAME+2], *path;
+    jzentry *ze;
+
+    if (ulen > MAXNAME) {
+        path = malloc(ulen + 2);
+        if (path == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
+            return 0;
+        }
+    } else {
+        path = buf;
+    }
+    (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
+    path[ulen] = '\0';
+    ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
+    if (path != buf) {
+        free(path);
+    }
+    return ptr_to_jlong(ze);
+}
+
+JNIEXPORT void JNICALL
+Java_java_util_zip_ZipFile_freeEntry(JNIEnv *env, jclass cls, jlong zfile,
+                                    jlong zentry)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    jzentry *ze = jlong_to_ptr(zentry);
+    ZIP_FreeEntry(zip, ze);
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getNextEntry(JNIEnv *env, jclass cls, jlong zfile,
+                                        jint n)
+{
+    jzentry *ze = ZIP_GetNextEntry(jlong_to_ptr(zfile), n);
+    return ptr_to_jlong(ze);
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getEntryMethod(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->csize != 0 ? DEFLATED : STORED;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getEntryFlag(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->flag;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntryCSize(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->csize != 0 ? ze->csize : ze->size;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntrySize(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return ze->size;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntryTime(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return (jlong)ze->time & 0xffffffffUL;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_util_zip_ZipFile_getEntryCrc(JNIEnv *env, jclass cls, jlong zentry)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    return (jlong)ze->crc & 0xffffffffUL;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_util_zip_ZipFile_getCommentBytes(JNIEnv *env,
+                                           jclass cls,
+                                           jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    jbyteArray jba = NULL;
+
+    if (zip->comment != NULL) {
+        if ((jba = (*env)->NewByteArray(env, zip->clen)) == NULL)
+            return NULL;
+        (*env)->SetByteArrayRegion(env, jba, 0, zip->clen, (jbyte*)zip->comment);
+    }
+    return jba;
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
+                                         jclass cls,
+                                         jlong zentry, jint type)
+{
+    jzentry *ze = jlong_to_ptr(zentry);
+    int len = 0;
+    jbyteArray jba = NULL;
+    switch (type) {
+    case java_util_zip_ZipFile_JZENTRY_NAME:
+        if (ze->name != 0) {
+            len = (int)ze->nlen;
+            // Unlike for extra and comment, we never return null for
+            // an (extremely rarely seen) empty name
+            if ((jba = (*env)->NewByteArray(env, len)) == NULL)
+                break;
+            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
+        }
+        break;
+    case java_util_zip_ZipFile_JZENTRY_EXTRA:
+        if (ze->extra != 0) {
+            unsigned char *bp = (unsigned char *)&ze->extra[0];
+            len = (bp[0] | (bp[1] << 8));
+            if (len <= 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
+                break;
+            (*env)->SetByteArrayRegion(env, jba, 0, len, &ze->extra[2]);
+        }
+        break;
+    case java_util_zip_ZipFile_JZENTRY_COMMENT:
+        if (ze->comment != 0) {
+            len = (int)strlen(ze->comment);
+            if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
+                break;
+            (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte*)ze->comment);
+        }
+        break;
+    }
+    return jba;
+}
+
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,
+                                jlong zentry, jlong pos, jbyteArray bytes,
+                                jint off, jint len)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    char *msg;
+
+#define BUFSIZE 8192
+    /* copy via tmp stack buffer: */
+    jbyte buf[BUFSIZE];
+
+    if (len > BUFSIZE) {
+        len = BUFSIZE;
+    }
+
+    ZIP_Lock(zip);
+    len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);
+    msg = zip->msg;
+    ZIP_Unlock(zip);
+    if (len != -1) {
+        (*env)->SetByteArrayRegion(env, bytes, off, len, buf);
+    }
+
+    if (len == -1) {
+        if (msg != 0) {
+            ThrowZipException(env, msg);
+        } else {
+            char errmsg[128];
+            sprintf(errmsg, "errno: %d, error: %s\n",
+                    errno, "Error reading ZIP file");
+            JNU_ThrowIOExceptionWithLastError(env, errmsg);
+        }
+    }
+
+    return len;
+}
+
+/*
+ * Returns an array of strings representing the names of all entries
+ * that begin with "META-INF/" (case ignored). This native method is
+ * used in JarFile as an optimization when looking up manifest and
+ * signature file entries. Returns null if no entries were found.
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_java_util_jar_JarFile_getMetaInfEntryNames(JNIEnv *env, jobject obj)
+{
+    jlong zfile = (*env)->GetLongField(env, obj, jzfileID);
+    jzfile *zip;
+    int i, count;
+    jobjectArray result = 0;
+
+    if (zfile == 0) {
+        JNU_ThrowByName(env,
+                        "java/lang/IllegalStateException", "zip file closed");
+        return NULL;
+    }
+    zip = jlong_to_ptr(zfile);
+
+    /* count the number of valid ZIP metanames */
+    count = 0;
+    if (zip->metanames != 0) {
+        for (i = 0; i < zip->metacount; i++) {
+            if (zip->metanames[i] != 0) {
+                count++;
+            }
+        }
+    }
+
+    /* If some names were found then build array of java strings */
+    if (count > 0) {
+        jclass cls = JNU_ClassString(env);
+        CHECK_NULL_RETURN(cls, NULL);
+        result = (*env)->NewObjectArray(env, count, cls, 0);
+        CHECK_NULL_RETURN(result, NULL);
+        if (result != 0) {
+            for (i = 0; i < count; i++) {
+                jstring str = (*env)->NewStringUTF(env, zip->metanames[i]);
+                if (str == 0) {
+                    break;
+                }
+                (*env)->SetObjectArrayElement(env, result, i, str);
+                (*env)->DeleteLocalRef(env, str);
+            }
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jstring JNICALL
+Java_java_util_zip_ZipFile_getZipMessage(JNIEnv *env, jclass cls, jlong zfile)
+{
+    jzfile *zip = jlong_to_ptr(zfile);
+    char *msg = zip->msg;
+    if (msg == NULL) {
+        return NULL;
+    }
+    return JNU_NewStringPlatform(env, msg);
+}
diff --git a/jdk/test/java/util/zip/ZipFile/ReadZip.java b/jdk/test/java/util/zip/ZipFile/ReadZip.java
index fe923e81eee..1052642eda7 100644
--- a/jdk/test/java/util/zip/ZipFile/ReadZip.java
+++ b/jdk/test/java/util/zip/ZipFile/ReadZip.java
@@ -30,7 +30,6 @@
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.nio.file.NoSuchFileException;
 import java.nio.file.StandardCopyOption;
 import java.nio.file.StandardOpenOption;
 import java.util.zip.*;
@@ -111,6 +110,6 @@ public class ReadZip {
                                      "input"
                                       + String.valueOf(new java.util.Random().nextInt())
                                       + ".zip")));
-        } catch (NoSuchFileException nsfe) {}
+        } catch (FileNotFoundException fnfe) {}
     }
 }
diff --git a/jdk/test/java/util/zip/ZipFile/TestZipFile.java b/jdk/test/java/util/zip/ZipFile/TestZipFile.java
deleted file mode 100644
index 986877731db..00000000000
--- a/jdk/test/java/util/zip/ZipFile/TestZipFile.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (c) 2015, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8142508
- * @summary Tests various ZipFile apis
- * @run main/manual TestZipFile
- */
-
-import java.io.*;
-import java.lang.reflect.Method;
-import java.nio.*;
-import java.nio.file.*;
-import java.nio.file.attribute.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.zip.*;
-
-public class TestZipFile {
-
-    private static Random r = new Random();
-    private static int    N = 50;
-    private static int    NN = 10;
-    private static int    ENUM = 10000;
-    private static int    ESZ = 10000;
-    private static ExecutorService executor = Executors.newFixedThreadPool(20);
-    private static Set<Path> paths = new HashSet<>();
-
-    static void realMain (String[] args) throws Throwable {
-
-        try {
-            for (int i = 0; i < N; i++) {
-                test(r.nextInt(ENUM), r.nextInt(ESZ), false, true);
-                test(r.nextInt(ENUM), r.nextInt(ESZ), true, true);
-            }
-
-            for (int i = 0; i < NN; i++) {
-                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), false, true);
-                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), true, true);
-                testCachedDelete();
-                testCachedOverwrite();
-                //test(r.nextInt(ENUM), r.nextInt(ESZ), false, true);
-            }
-
-            test(70000, 1000, false, true);   // > 65536 entry number;
-            testDelete();                     // OPEN_DELETE
-
-            executor.shutdown();
-            executor.awaitTermination(10, TimeUnit.MINUTES);
-        } finally {
-            for (Path path : paths) {
-                Files.deleteIfExists(path);
-            }
-        }
-    }
-
-    static void test(int numEntry, int szMax, boolean addPrefix, boolean cleanOld) {
-        String name = "zftest" + r.nextInt() + ".zip";
-        Zip zip = new Zip(name, numEntry, szMax, addPrefix, cleanOld);
-        for (int i = 0; i < NN; i++) {
-            executor.submit(() -> doTest(zip));
-        }
-     }
-
-    // test scenario:
-    // (1) open the ZipFile(zip) with OPEN_READ | OPEN_DELETE
-    // (2) test the ZipFile works correctly
-    // (3) check the zip is deleted after ZipFile gets closed
-    static void testDelete() throws Throwable {
-        String name = "zftest" + r.nextInt() + ".zip";
-        Zip zip = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
-        try (ZipFile zf = new ZipFile(new File(zip.name),
-                                      ZipFile.OPEN_READ | ZipFile.OPEN_DELETE ))
-        {
-            doTest0(zip, zf);
-        }
-        Path p = Paths.get(name);
-        if (Files.exists(p)) {
-            fail("Failed to delete " + name + " with OPEN_DELETE");
-        }
-    }
-
-    // test scenario:
-    // (1) keep a ZipFile(zip1) alive (in ZipFile's cache), dont close it
-    // (2) delete zip1 and create zip2 with the same name the zip1 with zip2
-    // (3) zip1 tests should fail, but no crash
-    // (4) zip2 tasks should all get zip2, then pass normal testing.
-    static void testCachedDelete() throws Throwable {
-        String name = "zftest" + r.nextInt() + ".zip";
-        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
-
-        try (ZipFile zf = new ZipFile(zip1.name)) {
-            for (int i = 0; i < NN; i++) {
-                executor.submit(() -> verifyNoCrash(zip1));
-            }
-            // delete the "zip1"  and create a new one to test
-            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
-            /*
-                System.out.println("========================================");
-                System.out.printf("    zip1=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
-                    zip1.name, zip1.lastModified, zip1.entries.size(),
-                    zip1.attrs.fileKey(), zip1.attrs.size(), zip1.attrs.lastModifiedTime().toMillis());
-                System.out.printf("    zip2=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
-                    zip2.name, zip2.lastModified, zip2.entries.size(),
-                    zip2.attrs.fileKey(), zip2.attrs.size(), zip2.attrs.lastModifiedTime().toMillis());
-            */
-            for (int i = 0; i < NN; i++) {
-                executor.submit(() -> doTest(zip2));
-            }
-        }
-    }
-
-   // overwrite the "zip1"  and create a new one to test. So the two zip files
-   // have the same fileKey, but probably different lastModified()
-    static void testCachedOverwrite() throws Throwable {
-        String name = "zftest" + r.nextInt() + ".zip";
-        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
-        try (ZipFile zf = new ZipFile(zip1.name)) {
-            for (int i = 0; i < NN; i++) {
-                executor.submit(() -> verifyNoCrash(zip1));
-            }
-            // overwrite the "zip1"  with new contents
-            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, false);
-            for (int i = 0; i < NN; i++) {
-                executor.submit(() -> doTest(zip2));
-            }
-        }
-    }
-
-    // just check the entries and contents. since the file has been either overwritten
-    // or deleted/rewritten, we only care if it crahes or not.
-    static void verifyNoCrash(Zip zip) throws RuntimeException {
-        try (ZipFile zf = new ZipFile(zip.name)) {
-            List<ZipEntry> zlist = new ArrayList(zip.entries.keySet());
-            String[] elist = zf.stream().map( e -> e.getName()).toArray(String[]::new);
-            if (!Arrays.equals(elist,
-                               zlist.stream().map( e -> e.getName()).toArray(String[]::new)))
-            {
-                //System.out.printf("++++++ LIST NG [%s] entries.len=%d, expected=%d+++++++%n",
-                //                  zf.getName(), elist.length, zlist.size());
-                return;
-            }
-            for (ZipEntry ze : zlist) {
-                byte[] zdata = zip.entries.get(ze);
-                ZipEntry e = zf.getEntry(ze.getName());
-                if (e != null) {
-                    checkEqual(e, ze);
-                    if (!e.isDirectory()) {
-                        // check with readAllBytes
-                        try (InputStream is = zf.getInputStream(e)) {
-                            if (!Arrays.equals(zdata, is.readAllBytes())) {
-                                //System.out.printf("++++++ BYTES NG  [%s]/[%s] ++++++++%n",
-                                //                  zf.getName(), ze.getName());
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (Throwable t) {
-            // t.printStackTrace();
-            // fail(t.toString());
-        }
-    }
-
-    static void checkEqual(ZipEntry x, ZipEntry y) {
-        if (x.getName().equals(y.getName()) &&
-            x.isDirectory() == y.isDirectory() &&
-            x.getMethod() == y.getMethod() &&
-            (x.getTime() / 2000) == y.getTime() / 2000 &&
-            x.getSize() == y.getSize() &&
-            x.getCompressedSize() == y.getCompressedSize() &&
-            x.getCrc() == y.getCrc() &&
-            x.getComment().equals(y.getComment())
-        ) {
-            pass();
-        } else {
-            fail(x + " not equal to " + y);
-            System.out.printf("      %s       %s%n", x.getName(), y.getName());
-            System.out.printf("      %d       %d%n", x.getMethod(), y.getMethod());
-            System.out.printf("      %d       %d%n", x.getTime(), y.getTime());
-            System.out.printf("      %d       %d%n", x.getSize(), y.getSize());
-            System.out.printf("      %d       %d%n", x.getCompressedSize(), y.getCompressedSize());
-            System.out.printf("      %d       %d%n", x.getCrc(), y.getCrc());
-            System.out.println("-----------------");
-        }
-    }
-
-    static void doTest(Zip zip) throws RuntimeException {
-        //Thread me = Thread.currentThread();
-        try (ZipFile zf = new ZipFile(zip.name)) {
-            doTest0(zip, zf);
-        } catch (Throwable t) {
-            throw new RuntimeException(t);
-        }
-    }
-
-    static void doTest0(Zip zip, ZipFile zf) throws Throwable {
-        List<ZipEntry> list = new ArrayList(zip.entries.keySet());
-        // (1) check entry list, in expected order
-        if (!check(Arrays.equals(
-                list.stream().map( e -> e.getName()).toArray(String[]::new),
-                zf.stream().map( e -> e.getName()).toArray(String[]::new)))) {
-            return;
-        }
-        // (2) shuffle, and check each entry and its bytes
-        Collections.shuffle(list);
-        for (ZipEntry ze : list) {
-            byte[] data = zip.entries.get(ze);
-            ZipEntry e = zf.getEntry(ze.getName());
-            checkEqual(e, ze);
-            if (!e.isDirectory()) {
-                // check with readAllBytes
-                try (InputStream is = zf.getInputStream(e)) {
-                    check(Arrays.equals(data, is.readAllBytes()));
-                }
-                // check with smaller sized buf
-                try (InputStream is = zf.getInputStream(e)) {
-                    byte[] buf = new byte[(int)e.getSize()];
-                    int sz = r.nextInt((int)e.getSize()/4 + 1) + 1;
-                    int off = 0;
-                    int n;
-                    while ((n = is.read(buf, off, buf.length - off)) > 0) {
-                        off += n;
-                    }
-                    check(is.read() == -1);
-                    check(Arrays.equals(data, buf));
-                }
-            }
-        }
-        // (3) check getMetaInfEntryNames
-        String[] metas = list.stream()
-                             .map( e -> e.getName())
-                             .filter( s -> s.startsWith("META-INF/"))
-                             .sorted()
-                             .toArray(String[]::new);
-        if (metas.length > 0) {
-            // meta-inf entries
-            Method getMetas = ZipFile.class.getDeclaredMethod("getMetaInfEntryNames");
-            getMetas.setAccessible(true);
-            String[] names = (String[])getMetas.invoke(zf);
-            if (names == null) {
-                fail("Failed to get metanames from " + zf);
-            } else {
-                Arrays.sort(names);
-                check(Arrays.equals(names, metas));
-            }
-        }
-    }
-
-    private static class Zip {
-        String name;
-        Map<ZipEntry, byte[]> entries;
-        BasicFileAttributes attrs;
-        long lastModified;
-
-        Zip(String name, int num, int szMax, boolean prefix, boolean clean) {
-            this.name = name;
-            entries = new LinkedHashMap<>(num);
-            try {
-                Path p = Paths.get(name);
-                if (clean) {
-                    Files.deleteIfExists(p);
-                }
-                paths.add(p);
-            } catch (Exception x) {
-                throw (RuntimeException)x;
-            }
-
-            try (FileOutputStream fos = new FileOutputStream(name);
-                 BufferedOutputStream bos = new BufferedOutputStream(fos);
-                 ZipOutputStream zos = new ZipOutputStream(bos))
-            {
-                if (prefix) {
-                    byte[] bytes = new byte[r.nextInt(1000)];
-                    r.nextBytes(bytes);
-                    bos.write(bytes);
-                }
-                CRC32 crc = new CRC32();
-                for (int i = 0; i < num; i++) {
-                    String ename = "entry-" + i + "-name-" + r.nextLong();
-                    ZipEntry ze = new ZipEntry(ename);
-                    int method = r.nextBoolean() ? ZipEntry.STORED : ZipEntry.DEFLATED;
-                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
-                }
-                // add some manifest entries
-                for (int i = 0; i < r.nextInt(20); i++) {
-                    String meta = "META-INF/" + "entry-" + i + "-metainf-" + r.nextLong();
-                    ZipEntry ze = new ZipEntry(meta);
-                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
-                }
-            } catch (Exception x) {
-                throw (RuntimeException)x;
-            }
-            try {
-                this.attrs = Files.readAttributes(Paths.get(name), BasicFileAttributes.class);
-                this.lastModified = new File(name).lastModified();
-            } catch (Exception x) {
-                throw (RuntimeException)x;
-            }
-        }
-
-        private void writeEntry(ZipOutputStream zos, CRC32 crc,
-                                ZipEntry ze, int method, int szMax)
-            throws IOException
-        {
-            ze.setMethod(method);
-            byte[] data = new byte[r.nextInt(szMax + 1)];
-            r.nextBytes(data);
-            if (method == ZipEntry.STORED) {  // must set size/csize/crc
-                ze.setSize(data.length);
-                ze.setCompressedSize(data.length);
-                crc.reset();
-                crc.update(data);
-                ze.setCrc(crc.getValue());
-            }
-            ze.setTime(System.currentTimeMillis());
-            ze.setComment(ze.getName());
-            zos.putNextEntry(ze);
-            zos.write(data);
-            zos.closeEntry();
-            entries.put(ze, data);
-        }
-    }
-
-    //--------------------- Infrastructure ---------------------------
-    static volatile int passed = 0, failed = 0;
-    static void pass() {passed++;}
-    static void pass(String msg) {System.out.println(msg); passed++;}
-    static void fail() {failed++; Thread.dumpStack();}
-    static void fail(String msg) {System.out.println(msg); fail();}
-    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
-    static void unexpected(Throwable t, String msg) {
-        System.out.println(msg); failed++; t.printStackTrace();}
-    static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
-
-    public static void main(String[] args) throws Throwable {
-        try {realMain(args);} catch (Throwable t) {unexpected(t);}
-        System.out.println("\nPassed = " + passed + " failed = " + failed);
-        if (failed > 0) throw new AssertionError("Some tests failed");}
-}

From d42e70fc3c5552af8dcaa1375322f9464019efad Mon Sep 17 00:00:00 2001
From: Stuart Marks <smarks@openjdk.org>
Date: Tue, 8 Dec 2015 13:48:22 -0800
Subject: [PATCH 26/62] 8139232: JEP-269 initial API and skeleton
 implementations

Reviewed-by: psandoz, rriggs
---
 .../classes/java/util/KeyValueHolder.java     | 126 +++++
 .../share/classes/java/util/List.java         | 332 +++++++++++-
 .../share/classes/java/util/Map.java          | 496 +++++++++++++++++-
 .../share/classes/java/util/Set.java          | 362 ++++++++++++-
 jdk/test/java/util/Collection/MOAT.java       | 125 ++++-
 .../java/util/Collection/SetFactories.java    | 275 ++++++++++
 jdk/test/java/util/List/ListFactories.java    | 234 +++++++++
 jdk/test/java/util/Map/MapFactories.java      | 380 ++++++++++++++
 8 files changed, 2315 insertions(+), 15 deletions(-)
 create mode 100644 jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
 create mode 100644 jdk/test/java/util/Collection/SetFactories.java
 create mode 100644 jdk/test/java/util/List/ListFactories.java
 create mode 100644 jdk/test/java/util/Map/MapFactories.java

diff --git a/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
new file mode 100644
index 00000000000..96ca0753ac6
--- /dev/null
+++ b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util;
+
+/**
+ * An immutable container for a key and a value, suitable for use
+ * in creating and populating {@code Map} instances.
+ *
+ * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
+ * class; use of identity-sensitive operations (including reference equality
+ * ({@code ==}), identity hash code, or synchronization) on instances of
+ * {@code KeyValueHolder} may have unpredictable results and should be avoided.
+ *
+ * @apiNote
+ * This class is not public. Instances can be created using the
+ * {@link Map#entry Map.entry(k, v)} factory method, which is public.
+ *
+ * <p>This class differs from AbstractMap.SimpleImmutableEntry in the following ways:
+ * it is not serializable, it is final, and its key and value must be non-null.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ *
+ * @see Map#ofEntries Map.ofEntries()
+ * @since 9
+ */
+final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
+    final K key;
+    final V value;
+
+    KeyValueHolder(K k, V v) {
+        key = Objects.requireNonNull(k);
+        value = Objects.requireNonNull(v);
+    }
+
+    /**
+     * Gets the key from this holder.
+     *
+     * @return the key
+     */
+    @Override
+    public K getKey() {
+        return key;
+    }
+
+    /**
+     * Gets the value from this holder.
+     *
+     * @return the value
+     */
+    @Override
+    public V getValue() {
+        return value;
+    }
+
+    /**
+     * Throws {@link UnsupportedOperationException}.
+     *
+     * @param value ignored
+     * @return never returns normally
+     */
+    @Override
+    public V setValue(V value) {
+        throw new UnsupportedOperationException("not supported");
+    }
+
+    /**
+     * Compares the specified object with this entry for equality.
+     * Returns {@code true} if the given object is also a map entry and
+     * the two entries' keys and values are equal. Note that key and
+     * value are non-null, so equals() can be called safely on them.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map.Entry))
+            return false;
+        Map.Entry<?,?> e = (Map.Entry<?,?>)o;
+        return key.equals(e.getKey()) && value.equals(e.getValue());
+    }
+
+    /**
+     * Returns the hash code value for this map entry. The hash code
+     * is {@code key.hashCode() ^ value.hashCode()}. Note that key and
+     * value are non-null, so hashCode() can be called safely on them.
+     */
+    @Override
+    public int hashCode() {
+        return key.hashCode() ^ value.hashCode();
+    }
+
+    /**
+     * Returns a String representation of this map entry.  This
+     * implementation returns the string representation of this
+     * entry's key followed by the equals character ("{@code =}")
+     * followed by the string representation of this entry's value.
+     *
+     * @return a String representation of this map entry
+     */
+    @Override
+    public String toString() {
+        return key + "=" + value;
+    }
+}
diff --git a/jdk/src/java.base/share/classes/java/util/List.java b/jdk/src/java.base/share/classes/java/util/List.java
index 6e3751fa046..48464801316 100644
--- a/jdk/src/java.base/share/classes/java/util/List.java
+++ b/jdk/src/java.base/share/classes/java/util/List.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -87,6 +87,28 @@ import java.util.function.UnaryOperator;
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
+ * <h2><a name="immutable">Immutable List Static Factory Methods</a></h2>
+ * <p>The {@link List#of(Object...) List.of()} static factory methods
+ * provide a convenient way to create immutable lists. The {@code List}
+ * instances created by these methods have the following characteristics:
+ *
+ * <ul>
+ * <li>They are <em>structurally immutable</em>. Elements cannot be added, removed,
+ * or replaced. Attempts to do so result in {@code UnsupportedOperationException}.
+ * However, if the contained elements are themselves mutable,
+ * this may cause the List's contents to appear to change.
+ * <li>They disallow {@code null} elements. Attempts to create them with
+ * {@code null} elements result in {@code NullPointerException}.
+ * <li>They are serializable if all elements are serializable.
+ * <li>The order of elements in the list is the same as the order of the
+ * provided arguments, or of the elements in the provided array.
+ * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
+ * Callers should make no assumptions about the identity of the returned instances.
+ * Factories are free to create new instances or reuse existing ones. Therefore,
+ * identity-sensitive operations on these instances (reference equality ({@code ==}),
+ * identity hash code, and synchronization) are unreliable and should be avoided.
+ * </ul>
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
@@ -731,4 +753,312 @@ public interface List<E> extends Collection<E> {
     default Spliterator<E> spliterator() {
         return Spliterators.spliterator(this, Spliterator.ORDERED);
     }
+
+    /**
+     * Returns an immutable list containing zero elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @return an empty {@code List}
+     *
+     * @since 9
+     */
+    static <E> List<E> of() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Returns an immutable list containing one element.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the single element
+     * @return a {@code List} containing the specified element
+     * @throws NullPointerException if the element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1) {
+        return Collections.singletonList(Objects.requireNonNull(e1));
+    }
+
+    /**
+     * Returns an immutable list containing two elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2)));
+    }
+
+    /**
+     * Returns an immutable list containing three elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3)));
+    }
+
+    /**
+     * Returns an immutable list containing four elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4)));
+    }
+
+    /**
+     * Returns an immutable list containing five elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5)));
+    }
+
+    /**
+     * Returns an immutable list containing six elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6)));
+    }
+
+    /**
+     * Returns an immutable list containing seven elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6),
+                          Objects.requireNonNull(e7)));
+    }
+
+    /**
+     * Returns an immutable list containing eight elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6),
+                          Objects.requireNonNull(e7),
+                          Objects.requireNonNull(e8)));
+    }
+
+    /**
+     * Returns an immutable list containing nine elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @param e9 the ninth element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6),
+                          Objects.requireNonNull(e7),
+                          Objects.requireNonNull(e8),
+                          Objects.requireNonNull(e9)));
+    }
+
+    /**
+     * Returns an immutable list containing ten elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @param e9 the ninth element
+     * @param e10 the tenth element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6),
+                          Objects.requireNonNull(e7),
+                          Objects.requireNonNull(e8),
+                          Objects.requireNonNull(e9),
+                          Objects.requireNonNull(e10)));
+    }
+
+    /**
+     * Returns an immutable list containing an arbitrary number of elements.
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @apiNote
+     * This method also accepts a single array as an argument. The element type of
+     * the resulting list will be the component type of the array, and the size of
+     * the list will be equal to the length of the array. To create a list with
+     * a single element that is an array, do the following:
+     *
+     * <pre>{@code
+     *     String[] array = ... ;
+     *     List<String[]> list = List.<String[]>of(array);
+     * }</pre>
+     *
+     * This will cause the {@link List#of(Object) List.of(E)} method
+     * to be invoked instead.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param elements the elements to be contained in the list
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
+     *
+     * @since 9
+     */
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    static <E> List<E> of(E... elements) {
+        elements = elements.clone(); // throws NPE if es is null
+        for (E e : elements) {
+            Objects.requireNonNull(e);
+        }
+        return Collections.unmodifiableList(Arrays.asList(elements));
+    }
 }
diff --git a/jdk/src/java.base/share/classes/java/util/Map.java b/jdk/src/java.base/share/classes/java/util/Map.java
index 9d79c6ce7a9..f958607dfc5 100644
--- a/jdk/src/java.base/share/classes/java/util/Map.java
+++ b/jdk/src/java.base/share/classes/java/util/Map.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -110,6 +110,31 @@ import java.io.Serializable;
  * Implementations may optionally handle the self-referential scenario, however
  * most current implementations do not do so.
  *
+ * <h2><a name="immutable">Immutable Map Static Factory Methods</a></h2>
+ * <p>The {@link Map#of() Map.of()} and
+ * {@link Map#ofEntries(Map.Entry...) Map.ofEntries()}
+ * static factory methods provide a convenient way to create immutable maps.
+ * The {@code Map}
+ * instances created by these methods have the following characteristics:
+ *
+ * <ul>
+ * <li>They are <em>structurally immutable</em>. Keys and values cannot be added,
+ * removed, or updated. Attempts to do so result in {@code UnsupportedOperationException}.
+ * However, if the contained keys or values are themselves mutable, this may cause the
+ * Map to behave inconsistently or its contents to appear to change.
+ * <li>They disallow {@code null} keys and values. Attempts to create them with
+ * {@code null} keys or values result in {@code NullPointerException}.
+ * <li>They are serializable if all keys and values are serializable.
+ * <li>They reject duplicate keys at creation time. Duplicate keys
+ * passed to a static factory method result in {@code IllegalArgumentException}.
+ * <li>The iteration order of mappings is unspecified and is subject to change.
+ * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
+ * Callers should make no assumptions about the identity of the returned instances.
+ * Factories are free to create new instances or reuse existing ones. Therefore,
+ * identity-sensitive operations on these instances (reference equality ({@code ==}),
+ * identity hash code, and synchronization) are unreliable and should be avoided.
+ * </ul>
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
@@ -126,7 +151,7 @@ import java.io.Serializable;
  * @see Set
  * @since 1.2
  */
-public interface Map<K,V> {
+public interface Map<K, V> {
     // Query Operations
 
     /**
@@ -373,7 +398,7 @@ public interface Map<K,V> {
      * @see Map#entrySet()
      * @since 1.2
      */
-    interface Entry<K,V> {
+    interface Entry<K, V> {
         /**
          * Returns the key corresponding to this entry.
          *
@@ -468,7 +493,7 @@ public interface Map<K,V> {
          * @see Comparable
          * @since 1.8
          */
-        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
+        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
             return (Comparator<Map.Entry<K, V>> & Serializable)
                 (c1, c2) -> c1.getKey().compareTo(c2.getKey());
         }
@@ -485,7 +510,7 @@ public interface Map<K,V> {
          * @see Comparable
          * @since 1.8
          */
-        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
+        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
             return (Comparator<Map.Entry<K, V>> & Serializable)
                 (c1, c2) -> c1.getValue().compareTo(c2.getValue());
         }
@@ -1233,4 +1258,465 @@ public interface Map<K,V> {
         }
         return newValue;
     }
+
+    /**
+     * Returns an immutable map containing zero mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @return an empty {@code Map}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of() {
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Returns an immutable map containing a single mapping.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the mapping's key
+     * @param v1 the mapping's value
+     * @return a {@code Map} containing the specified mapping
+     * @throws NullPointerException if the key or the value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1) {
+        return Collections.singletonMap(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+    }
+
+    /**
+     * Returns an immutable map containing two mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if the keys are duplicates
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
+        Map<K, V> map = new HashMap<>(3); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        if (map.size() != 2) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing three mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
+        Map<K, V> map = new HashMap<>(5); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        if (map.size() != 3) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing four mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
+        Map<K, V> map = new HashMap<>(6); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        if (map.size() != 4) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing five mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
+        Map<K, V> map = new HashMap<>(7); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        if (map.size() != 5) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing six mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6) {
+        Map<K, V> map = new HashMap<>(9); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        if (map.size() != 6) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing seven mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7) {
+        Map<K, V> map = new HashMap<>(10); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        if (map.size() != 7) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing eight mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @param k8 the eighth mapping's key
+     * @param v8 the eighth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7, K k8, V v8) {
+        Map<K, V> map = new HashMap<>(11); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
+        if (map.size() != 8) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing nine mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @param k8 the eighth mapping's key
+     * @param v8 the eighth mapping's value
+     * @param k9 the ninth mapping's key
+     * @param v9 the ninth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
+        Map<K, V> map = new HashMap<>(13); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
+        map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
+        if (map.size() != 9) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing ten mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @param k8 the eighth mapping's key
+     * @param v8 the eighth mapping's value
+     * @param k9 the ninth mapping's key
+     * @param v9 the ninth mapping's value
+     * @param k10 the tenth mapping's key
+     * @param v10 the tenth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
+        Map<K, V> map = new HashMap<>(14); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
+        map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
+        map.put(Objects.requireNonNull(k10), Objects.requireNonNull(v10));
+        if (map.size() != 10) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing keys and values extracted from the given entries.
+     * The entries themselves are not stored in the map.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @apiNote
+     * It is convenient to create the map entries using the {@link Map#entry Map.entry()} method.
+     * For example,
+     *
+     * <pre>{@code
+     *     import static java.util.Map.entry;
+     *
+     *     Map<Integer,String> map = Map.ofEntries(
+     *         entry(1, "a"),
+     *         entry(2, "b"),
+     *         entry(3, "c"),
+     *         ...
+     *         entry(26, "z"));
+     * }</pre>
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param entries {@code Map.Entry}s containing the keys and values from which the map is populated
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any entry, key, or value is {@code null}, or if
+     *         the {@code entries} array is {@code null}
+     *
+     * @see Map#entry Map.entry()
+     * @since 9
+     */
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    static <K, V> Map<K, V> ofEntries(Entry<K, V>... entries) {
+        Map<K, V> map = new HashMap<>(entries.length * 4 / 3 + 1); // throws NPE if entries is null
+        for (Entry<K, V> e : entries) {
+            // next line throws NPE if e is null
+            map.put(Objects.requireNonNull(e.getKey()), Objects.requireNonNull(e.getValue()));
+        }
+        if (map.size() != entries.length) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable {@link Entry} containing the given key and value.
+     * These entries are suitable for populating {@code Map} instances using the
+     * {@link Map#ofEntries Map.ofEntries()} method.
+     * The {@code Entry} instances created by this method have the following characteristics:
+     *
+     * <ul>
+     * <li>They disallow {@code null} keys and values. Attempts to create them using a {@code null}
+     * key or value result in {@code NullPointerException}.
+     * <li>They are immutable. Calls to {@link Entry#setValue Entry.setValue()}
+     * on a returned {@code Entry} result in {@code UnsupportedOperationException}.
+     * <li>They are not serializable.
+     * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
+     * Callers should make no assumptions about the identity of the returned instances.
+     * This method is free to create new instances or reuse existing ones. Therefore,
+     * identity-sensitive operations on these instances (reference equality ({@code ==}),
+     * identity hash code, and synchronization) are unreliable and should be avoided.
+     * </ul>
+     *
+     * @apiNote
+     * For a serializable {@code Entry}, see {@link AbstractMap.SimpleEntry} or
+     * {@link AbstractMap.SimpleImmutableEntry}.
+     *
+     * @param <K> the key's type
+     * @param <V> the value's type
+     * @param k the key
+     * @param v the value
+     * @return an {@code Entry} containing the specified key and value
+     * @throws NullPointerException if the key or value is {@code null}
+     *
+     * @see Map#ofEntries Map.ofEntries()
+     * @since 9
+     */
+    static <K, V> Entry<K, V> entry(K k, V v) {
+        // KeyValueHolder checks for nulls
+        return new KeyValueHolder<>(k, v);
+    }
 }
diff --git a/jdk/src/java.base/share/classes/java/util/Set.java b/jdk/src/java.base/share/classes/java/util/Set.java
index 93d008c20f1..b0db7fc55bd 100644
--- a/jdk/src/java.base/share/classes/java/util/Set.java
+++ b/jdk/src/java.base/share/classes/java/util/Set.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -63,6 +63,29 @@ package java.util;
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
+ * <h2><a name="immutable">Immutable Set Static Factory Methods</a></h2>
+ * <p>The {@link Set#of(Object...) Set.of()} static factory methods
+ * provide a convenient way to create immutable sets. The {@code Set}
+ * instances created by these methods have the following characteristics:
+ *
+ * <ul>
+ * <li>They are <em>structurally immutable</em>. Elements cannot be added or
+ * removed. Attempts to do so result in {@code UnsupportedOperationException}.
+ * However, if the contained elements are themselves mutable, this may cause the
+ * Set to behave inconsistently or its contents to appear to change.
+ * <li>They disallow {@code null} elements. Attempts to create them with
+ * {@code null} elements result in {@code NullPointerException}.
+ * <li>They are serializable if all elements are serializable.
+ * <li>They reject duplicate elements at creation time. Duplicate elements
+ * passed to a static factory method result in {@code IllegalArgumentException}.
+ * <li>The iteration order of set elements is unspecified and is subject to change.
+ * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
+ * Callers should make no assumptions about the identity of the returned instances.
+ * Factories are free to create new instances or reuse existing ones. Therefore,
+ * identity-sensitive operations on these instances (reference equality ({@code ==}),
+ * identity hash code, and synchronization) are unreliable and should be avoided.
+ * </ul>
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
@@ -410,4 +433,341 @@ public interface Set<E> extends Collection<E> {
     default Spliterator<E> spliterator() {
         return Spliterators.spliterator(this, Spliterator.DISTINCT);
     }
+
+    /**
+     * Returns an immutable set containing zero elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @return an empty {@code Set}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of() {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns an immutable set containing one element.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the single element
+     * @return a {@code Set} containing the specified element
+     * @throws NullPointerException if the element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1) {
+        return Collections.singleton(Objects.requireNonNull(e1));
+    }
+
+    /**
+     * Returns an immutable set containing two elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if the elements are duplicates
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2)));
+        if (set.size() != 2) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing three elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3)));
+        if (set.size() != 3) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing four elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4)));
+        if (set.size() != 4) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing five elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5)));
+        if (set.size() != 5) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing six elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6)));
+        if (set.size() != 6) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing seven elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7)));
+        if (set.size() != 7) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing eight elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7),
+                                                 Objects.requireNonNull(e8)));
+        if (set.size() != 8) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing nine elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @param e9 the ninth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7),
+                                                 Objects.requireNonNull(e8),
+                                                 Objects.requireNonNull(e9)));
+        if (set.size() != 9) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing ten elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @param e9 the ninth element
+     * @param e10 the tenth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7),
+                                                 Objects.requireNonNull(e8),
+                                                 Objects.requireNonNull(e9),
+                                                 Objects.requireNonNull(e10)));
+        if (set.size() != 10) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing an arbitrary number of elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @apiNote
+     * This method also accepts a single array as an argument. The element type of
+     * the resulting set will be the component type of the array, and the size of
+     * the set will be equal to the length of the array. To create a set with
+     * a single element that is an array, do the following:
+     *
+     * <pre>{@code
+     *     String[] array = ... ;
+     *     Set<String[]> list = Set.<String[]>of(array);
+     * }</pre>
+     *
+     * This will cause the {@link Set#of(Object) Set.of(E)} method
+     * to be invoked instead.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param elements the elements to be contained in the set
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
+     *
+     * @since 9
+     */
+    @SafeVarargs
+    static <E> Set<E> of(E... elements) {
+        for (E e : elements) { // throws NPE if es is null
+            Objects.requireNonNull(e);
+        }
+        @SuppressWarnings("varargs")
+        Set<E> set = new HashSet<>(Arrays.asList(elements));
+        if (set.size() != elements.length) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
 }
diff --git a/jdk/test/java/util/Collection/MOAT.java b/jdk/test/java/util/Collection/MOAT.java
index 6a1165e9ba6..fe17c5034a3 100644
--- a/jdk/test/java/util/Collection/MOAT.java
+++ b/jdk/test/java/util/Collection/MOAT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, 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
@@ -58,6 +58,21 @@ import static java.util.Collections.*;
 import java.lang.reflect.*;
 
 public class MOAT {
+    // Collections under test must not be initialized to contain this value,
+    // and maps under test must not contain this value as a key.
+    // It's used as a sentinel for absent-element testing.
+    static final int ABSENT_VALUE = 778347983;
+
+    static final Integer[] integerArray;
+    static {
+        Integer[] ia = new Integer[20];
+        // fill with 1..20 inclusive
+        for (int i = 0; i < ia.length; i++) {
+            ia[i] = i + 1;
+        }
+        integerArray = ia;
+    }
+
     public static void realMain(String[] args) {
 
         testCollection(new NewAbstractCollection<Integer>());
@@ -178,6 +193,70 @@ public class MOAT {
         equal(singletonMap.size(), 1);
         testMap(singletonMap);
         testImmutableMap(singletonMap);
+
+        // Immutable List
+        testEmptyList(List.of());
+        for (List<Integer> list : Arrays.asList(
+                List.<Integer>of(),
+                List.of(1),
+                List.of(1, 2),
+                List.of(1, 2, 3),
+                List.of(1, 2, 3, 4),
+                List.of(1, 2, 3, 4, 5),
+                List.of(1, 2, 3, 4, 5, 6),
+                List.of(1, 2, 3, 4, 5, 6, 7),
+                List.of(1, 2, 3, 4, 5, 6, 7, 8),
+                List.of(1, 2, 3, 4, 5, 6, 7, 8, 9),
+                List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
+                List.of(integerArray))) {
+            testCollection(list);
+            testImmutableList(list);
+        }
+
+        // Immutable Set
+        testEmptySet(Set.of());
+        for (Set<Integer> set : Arrays.asList(
+                Set.<Integer>of(),
+                Set.of(1),
+                Set.of(1, 2),
+                Set.of(1, 2, 3),
+                Set.of(1, 2, 3, 4),
+                Set.of(1, 2, 3, 4, 5),
+                Set.of(1, 2, 3, 4, 5, 6),
+                Set.of(1, 2, 3, 4, 5, 6, 7),
+                Set.of(1, 2, 3, 4, 5, 6, 7, 8),
+                Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9),
+                Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
+                Set.of(integerArray))) {
+            testCollection(set);
+            testImmutableSet(set);
+        }
+
+        // Immutable Map
+
+        @SuppressWarnings("unchecked")
+        Map.Entry<Integer,Integer>[] ea = (Map.Entry<Integer,Integer>[])new Map.Entry<?,?>[20];
+        for (int i = 0; i < ea.length; i++) {
+            ea[i] = Map.entry(i+1, i+101);
+        }
+
+        testEmptyMap(Map.of());
+        for (Map<Integer,Integer> map : Arrays.asList(
+                Map.<Integer,Integer>of(),
+                Map.of(1, 101),
+                Map.of(1, 101, 2, 202),
+                Map.of(1, 101, 2, 202, 3, 303),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808, 9, 909),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808, 9, 909, 10, 1010),
+                Map.ofEntries(ea))) {
+            testMap(map);
+            testImmutableMap(map);
+        }
     }
 
     private static void checkContainsSelf(Collection<Integer> c) {
@@ -190,6 +269,17 @@ public class MOAT {
         check(c.containsAll(new ArrayList<Integer>()));
     }
 
+    private static void checkUnique(Set<Integer> s) {
+        for (Integer i : s) {
+            int count = 0;
+            for (Integer j : s) {
+                if (Objects.equals(i,j))
+                    ++count;
+            }
+            check(count == 1);
+        }
+    }
+
     private static <T> void testEmptyCollection(Collection<T> c) {
         check(c.isEmpty());
         equal(c.size(), 0);
@@ -330,19 +420,19 @@ public class MOAT {
     }
 
     private static boolean supportsAdd(Collection<Integer> c) {
-        try { check(c.add(778347983)); }
+        try { check(c.add(ABSENT_VALUE)); }
         catch (UnsupportedOperationException t) { return false; }
         catch (Throwable t) { unexpected(t); }
 
         try {
-            check(c.contains(778347983));
-            check(c.remove(778347983));
+            check(c.contains(ABSENT_VALUE));
+            check(c.remove(ABSENT_VALUE));
         } catch (Throwable t) { unexpected(t); }
         return true;
     }
 
     private static boolean supportsRemove(Collection<Integer> c) {
-        try { check(! c.remove(19134032)); }
+        try { check(! c.remove(ABSENT_VALUE)); }
         catch (UnsupportedOperationException t) { return false; }
         catch (Throwable t) { unexpected(t); }
         return true;
@@ -359,6 +449,7 @@ public class MOAT {
             checkContainsSelf(c);
             checkContainsEmpty(c);
             check(c.size() != 0 ^ c.isEmpty());
+            check(! c.contains(ABSENT_VALUE));
 
             {
                 int size = 0;
@@ -366,6 +457,10 @@ public class MOAT {
                 check(c.size() == size);
             }
 
+            if (c instanceof Set) {
+                checkUnique((Set<Integer>)c);
+            }
+
             check(c.toArray().length == c.size());
             check(c.toArray().getClass() == Object[].class
                   ||
@@ -861,6 +956,20 @@ public class MOAT {
         checkFunctionalInvariants(m.keySet());
         checkFunctionalInvariants(m.values());
         check(m.size() != 0 ^ m.isEmpty());
+        check(! m.containsKey(ABSENT_VALUE));
+
+        if (m instanceof Serializable) {
+            //System.out.printf("Serializing %s%n", m.getClass().getName());
+            try {
+                Object clone = serialClone(m);
+                equal(m instanceof Serializable,
+                      clone instanceof Serializable);
+                equal(m, clone);
+            } catch (Error xxx) {
+                if (! (xxx.getCause() instanceof NotSerializableException))
+                    throw xxx;
+            }
+        }
     }
 
     private static void testMap(Map<Integer,Integer> m) {
@@ -910,13 +1019,13 @@ public class MOAT {
         // We're asking for .equals(...) semantics
         if (m instanceof IdentityHashMap) return false;
 
-        try { check(m.put(778347983,12735) == null); }
+        try { check(m.put(ABSENT_VALUE,12735) == null); }
         catch (UnsupportedOperationException t) { return false; }
         catch (Throwable t) { unexpected(t); }
 
         try {
-            check(m.containsKey(778347983));
-            check(m.remove(778347983) != null);
+            check(m.containsKey(ABSENT_VALUE));
+            check(m.remove(ABSENT_VALUE) != null);
         } catch (Throwable t) { unexpected(t); }
         return true;
     }
diff --git a/jdk/test/java/util/Collection/SetFactories.java b/jdk/test/java/util/Collection/SetFactories.java
new file mode 100644
index 00000000000..aabeaa344a7
--- /dev/null
+++ b/jdk/test/java/util/Collection/SetFactories.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on Set.
+ * @run testng SetFactories
+ */
+
+
+public class SetFactories {
+
+    static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
+    static final String[] stringArray;
+    static {
+        String[] sa = new String[NUM_STRINGS];
+        for (int i = 0; i < NUM_STRINGS; i++) {
+            sa[i] = String.valueOf((char)('a' + i));
+        }
+        stringArray = sa;
+    }
+
+    static Object[] a(Set<String> act, Set<String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    static Set<String> hashSetOf(String... args) {
+        return new HashSet<>(Arrays.asList(args));
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            // actual, expected
+            a(Set.of(), Collections.emptySet())
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    public Iterator<Object[]> nonempty() {
+        return Arrays.asList(
+            // actual, expected
+            a(   Set.of("a"),
+              hashSetOf("a")),
+            a(   Set.of("a", "b"),
+              hashSetOf("a", "b")),
+            a(   Set.of("a", "b", "c"),
+              hashSetOf("a", "b", "c")),
+            a(   Set.of("a", "b", "c", "d"),
+              hashSetOf("a", "b", "c", "d")),
+            a(   Set.of("a", "b", "c", "d", "e"),
+              hashSetOf("a", "b", "c", "d", "e")),
+            a(   Set.of("a", "b", "c", "d", "e", "f"),
+              hashSetOf("a", "b", "c", "d", "e", "f")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g", "h")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+            a(   Set.of(stringArray),
+              hashSetOf(stringArray))
+        ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAdd(Set<String> act, Set<String> exp) {
+        act.add("x");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(Set<String> act, Set<String> exp) {
+        act.remove(act.iterator().next());
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(Set<String> act, Set<String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed2() {
+        Set<String> set = Set.of("a", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed3() {
+        Set<String> set = Set.of("a", "b", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed4() {
+        Set<String> set = Set.of("a", "b", "c", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed5() {
+        Set<String> set = Set.of("a", "b", "c", "d", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed6() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed7() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed8() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "g", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed9() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "g", "h", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed10() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = array[1];
+        Set<String> set = Set.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed1() {
+        Set.of((String)null); // force one-arg overload
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2a() {
+        Set.of("a", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2b() {
+        Set.of(null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed3() {
+        Set.of("a", "b", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed4() {
+        Set.of("a", "b", "c", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed5() {
+        Set.of("a", "b", "c", "d", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed6() {
+        Set.of("a", "b", "c", "d", "e", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed7() {
+        Set.of("a", "b", "c", "d", "e", "f", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed8() {
+        Set.of("a", "b", "c", "d", "e", "f", "g", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed9() {
+        Set.of("a", "b", "c", "d", "e", "f", "g", "h", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed10() {
+        Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = null;
+        Set.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        Set.of((Object[])null);
+    }
+
+    @Test(dataProvider="all")
+    public void serialEquality(Set<String> act, Set<String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        Set<String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.close();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
diff --git a/jdk/test/java/util/List/ListFactories.java b/jdk/test/java/util/List/ListFactories.java
new file mode 100644
index 00000000000..e34ca660705
--- /dev/null
+++ b/jdk/test/java/util/List/ListFactories.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.util.Arrays.asList;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on List.
+ * @run testng ListFactories
+ */
+
+public class ListFactories {
+
+    static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
+    static final String[] stringArray;
+    static {
+        String[] sa = new String[NUM_STRINGS];
+        for (int i = 0; i < NUM_STRINGS; i++) {
+            sa[i] = String.valueOf((char)('a' + i));
+        }
+        stringArray = sa;
+    }
+
+    // returns array of [actual, expected]
+    static Object[] a(List<String> act, List<String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            a(List.of(), Collections.emptyList())
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    public Iterator<Object[]> nonempty() {
+        return asList(
+            a(List.of("a"),
+               asList("a")),
+            a(List.of("a", "b"),
+               asList("a", "b")),
+            a(List.of("a", "b", "c"),
+               asList("a", "b", "c")),
+            a(List.of("a", "b", "c", "d"),
+               asList("a", "b", "c", "d")),
+            a(List.of("a", "b", "c", "d", "e"),
+               asList("a", "b", "c", "d", "e")),
+            a(List.of("a", "b", "c", "d", "e", "f"),
+               asList("a", "b", "c", "d", "e", "f")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g"),
+               asList("a", "b", "c", "d", "e", "f", "g")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+            a(List.of(stringArray),
+               asList(stringArray))
+        ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAddLast(List<String> act, List<String> exp) {
+        act.add("x");
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAddFirst(List<String> act, List<String> exp) {
+        act.add(0, "x");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(List<String> act, List<String> exp) {
+        act.remove(0);
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotSet(List<String> act, List<String> exp) {
+        act.set(0, "x");
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(List<String> act, List<String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed1() {
+        List.of((Object)null); // force one-arg overload
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2a() {
+        List.of("a", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2b() {
+        List.of(null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed3() {
+        List.of("a", "b", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed4() {
+        List.of("a", "b", "c", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed5() {
+        List.of("a", "b", "c", "d", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed6() {
+        List.of("a", "b", "c", "d", "e", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed7() {
+        List.of("a", "b", "c", "d", "e", "f", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed8() {
+        List.of("a", "b", "c", "d", "e", "f", "g", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed9() {
+        List.of("a", "b", "c", "d", "e", "f", "g", "h", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed10() {
+        List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = null;
+        List.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        List.of((Object[])null);
+    }
+
+    @Test
+    public void ensureArrayCannotModifyList() {
+        String[] array = stringArray.clone();
+        List<String> list = List.of(array);
+        array[0] = "xyzzy";
+        assertEquals(list, Arrays.asList(stringArray));
+    }
+
+    @Test(dataProvider="all")
+    public void serialEquality(List<String> act, List<String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        List<String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.close();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
diff --git a/jdk/test/java/util/Map/MapFactories.java b/jdk/test/java/util/Map/MapFactories.java
new file mode 100644
index 00000000000..1bdb020680d
--- /dev/null
+++ b/jdk/test/java/util/Map/MapFactories.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on Map.
+ * @run testng MapFactories
+ */
+
+public class MapFactories {
+
+    static final int MAX_ENTRIES = 20; // should be larger than the largest fixed-arg overload
+    static String valueFor(int i) {
+        // the String literal below should be of length MAX_ENTRIES
+        return "abcdefghijklmnopqrst".substring(i, i+1);
+    }
+
+    // for "expected" values
+    Map<Integer,String> genMap(int n) {
+        Map<Integer,String> result = new HashMap<>();
+        for (int i = 0; i < n; i++) {
+            result.put(i, valueFor(i));
+        }
+        return result;
+    }
+
+    // for varargs Map.Entry methods
+    @SuppressWarnings("unchecked")
+    Map.Entry<Integer,String>[] genEntries(int n) {
+        return IntStream.range(0, n)
+            .mapToObj(i -> Map.entry(i, valueFor(i)))
+            .toArray(Map.Entry[]::new);
+    }
+
+    // returns array of [actual, expected]
+    static Object[] a(Map<Integer,String> act, Map<Integer,String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            a(Map.of(), genMap(0))
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    @SuppressWarnings("unchecked")
+    public Iterator<Object[]> nonempty() {
+        return Arrays.asList(
+            a(Map.of(0, "a"), genMap(1)),
+            a(Map.of(0, "a", 1, "b"), genMap(2)),
+            a(Map.of(0, "a", 1, "b", 2, "c"), genMap(3)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d"), genMap(4)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e"), genMap(5)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f"), genMap(6)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g"), genMap(7)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h"), genMap(8)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i"), genMap(9)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"), genMap(10)),
+            a(Map.ofEntries(genEntries(MAX_ENTRIES)), genMap(MAX_ENTRIES))
+        ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotPutNew(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.put(-1, "xyzzy");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotPutOld(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.put(0, "a");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.remove(act.keySet().iterator().next());
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(Map<Integer,String> act, Map<Integer,String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed2() {
+        Map<Integer, String> map = Map.of(0, "a", 0, "b");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed3() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 0, "c");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed4() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 0, "d");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed5() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 0, "e");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed6() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          0, "f");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed7() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 0, "g");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed8() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 0, "h");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed9() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 0, "i");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed10() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, "i", 0, "j");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[MAX_ENTRIES-1] = Map.entry(0, "xxx");
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed1() {
+        Map<Integer, String> map = Map.of(null, "a");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed1() {
+        Map<Integer, String> map = Map.of(0, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed2() {
+        Map<Integer, String> map = Map.of(0, "a", null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed2() {
+        Map<Integer, String> map = Map.of(0, "a", 1, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed3() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", null, "c");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed3() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed4() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", null, "d");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed4() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed5() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", null, "e");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed5() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed6() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          null, "f");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed6() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed7() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", null, "g");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed7() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed8() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", null, "h");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed8() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed9() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", null, "i");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed9() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed10() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, "i", null, "j");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed10() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, "i", 9, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[0] = new AbstractMap.SimpleImmutableEntry(null, "a");
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[0] = new AbstractMap.SimpleImmutableEntry(0, null);
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullEntryDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[5] = null;
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        Map.ofEntries(null);
+    }
+
+    @Test(dataProvider="all")
+    public void serialEquality(Map<Integer, String> act, Map<Integer, String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        Map<Integer, String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.close();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    // Map.entry() tests
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void entryWithNullKeyDisallowed() {
+        Map.Entry<Integer,String> e = Map.entry(null, "x");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void entryWithNullValueDisallowed() {
+        Map.Entry<Integer,String> e = Map.entry(0, null);
+    }
+
+    @Test
+    public void entryBasicTests() {
+        Map.Entry<String,String> kvh1 = Map.entry("xyzzy", "plugh");
+        Map.Entry<String,String> kvh2 = Map.entry("foobar", "blurfl");
+        Map.Entry<String,String> sie = new AbstractMap.SimpleImmutableEntry("xyzzy", "plugh");
+
+        assertTrue(kvh1.equals(sie));
+        assertTrue(sie.equals(kvh1));
+        assertFalse(kvh2.equals(sie));
+        assertFalse(sie.equals(kvh2));
+        assertEquals(sie.hashCode(), kvh1.hashCode());
+        assertEquals(sie.toString(), kvh1.toString());
+    }
+
+}

From 30655cc742f0faffb01cfb996ad0d243baac078a Mon Sep 17 00:00:00 2001
From: Xue-Lei Andrew Fan <xuelei@openjdk.org>
Date: Wed, 9 Dec 2015 10:36:33 +0000
Subject: [PATCH 27/62] 8141651: Deadlock in sun.security.ssl.SSLSocketImpl

Reviewed-by: weijun
---
 .../classes/sun/security/ssl/SSLSocketImpl.java    | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
index e3919c5d043..0162dc3b477 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -766,17 +766,27 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
         // records, so this also increases robustness.
         //
         if (length > 0) {
+            IOException ioe = null;
+            byte description = 0;    // 0: never used, make the compiler happy
             writeLock.lock();
             try {
                 outputRecord.deliver(source, offset, length);
             } catch (SSLHandshakeException she) {
                 // may be record sequence number overflow
-                fatal(Alerts.alert_handshake_failure, she);
+                description = Alerts.alert_handshake_failure;
+                ioe = she;
             } catch (IOException e) {
-                fatal(Alerts.alert_unexpected_message, e);
+                description = Alerts.alert_unexpected_message;
+                ioe = e;
             } finally {
                 writeLock.unlock();
             }
+
+            // Be care of deadlock. Please don't place the call to fatal()
+            // into the writeLock locked block.
+            if (ioe != null) {
+                fatal(description, ioe);
+            }
         }
 
         /*

From 6af208a48532af66103cec241250426ee12f8483 Mon Sep 17 00:00:00 2001
From: Rob McKenna <robm@openjdk.org>
Date: Wed, 9 Dec 2015 15:16:00 +0000
Subject: [PATCH 28/62] 8143397: It looks like InetAddress.isReachable(timeout)
 works incorrectly

Reviewed-by: xuelei, msheppar
---
 .../windows/native/libnet/Inet4AddressImpl.c  | 21 ++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c
index 5213383c1e5..8f70ebe0c12 100644
--- a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c
+++ b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c
@@ -295,6 +295,7 @@ ping4(JNIEnv *env,
     char SendData[32] = {0};
     LPVOID ReplyBuffer = NULL;
     DWORD ReplySize = 0;
+    jboolean ret = JNI_FALSE;
 
     hIcmpFile = IcmpCreateFile();
     if (hIcmpFile == INVALID_HANDLE_VALUE) {
@@ -318,7 +319,11 @@ ping4(JNIEnv *env,
                                 NULL,       // PIP_OPTION_INFORMATION RequestOptions,
                                 ReplyBuffer,// LPVOID ReplyBuffer,
                                 ReplySize,  // DWORD ReplySize,
-                                timeout);   // DWORD Timeout
+                                // Note: IcmpSendEcho and its derivatives
+                                // seem to have an undocumented minimum
+                                // timeout of 1000ms below which the
+                                // api behaves inconsistently.
+                                (timeout < 1000) ? 1000 : timeout);   // DWORD Timeout
     } else {
         dwRetVal = IcmpSendEcho2Ex(hIcmpFile,  // HANDLE IcmpHandle,
                                    NULL,       // HANDLE Event
@@ -331,17 +336,19 @@ ping4(JNIEnv *env,
                                    NULL,       // PIP_OPTION_INFORMATION RequestOptions,
                                    ReplyBuffer,// LPVOID ReplyBuffer,
                                    ReplySize,  // DWORD ReplySize,
-                                   timeout);   // DWORD Timeout
+                                   (timeout < 1000) ? 1000 : timeout);   // DWORD Timeout
+    }
+
+    if (dwRetVal != 0) {
+        PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
+        if ((int)pEchoReply->RoundTripTime <= timeout)
+            ret = JNI_TRUE;
     }
 
     free(ReplyBuffer);
     IcmpCloseHandle(hIcmpFile);
 
-    if (dwRetVal != 0) {
-        return JNI_TRUE;
-    } else {
-        return JNI_FALSE;
-    }
+    return ret;
 }
 
 /*

From d37bb2422b487bc19e58bf5642a8fbbea4825d5f Mon Sep 17 00:00:00 2001
From: Claes Redestad <redestad@openjdk.org>
Date: Wed, 9 Dec 2015 18:25:36 +0100
Subject: [PATCH 29/62] 8143127: InvokerBytecodeGenerator emitConst should
 handle Byte, Short, Character

Reviewed-by: vlivanov, shade, forax
---
 .../lang/invoke/InvokerBytecodeGenerator.java | 73 ++++++++++++-------
 1 file changed, 45 insertions(+), 28 deletions(-)

diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
index 83d66d52299..08c53447a80 100644
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
@@ -324,27 +324,54 @@ class InvokerBytecodeGenerator {
             emitIconstInsn((int) con);
             return;
         }
+        if (con instanceof Byte) {
+            emitIconstInsn((byte)con);
+            return;
+        }
+        if (con instanceof Short) {
+            emitIconstInsn((short)con);
+            return;
+        }
+        if (con instanceof Character) {
+            emitIconstInsn((char)con);
+            return;
+        }
         if (con instanceof Long) {
             long x = (long) con;
-            if (x == (short) x) {
-                emitIconstInsn((int) x);
-                mv.visitInsn(Opcodes.I2L);
+            short sx = (short)x;
+            if (x == sx) {
+                if (sx >= 0 && sx <= 1) {
+                    mv.visitInsn(Opcodes.LCONST_0 + (int) sx);
+                } else {
+                    emitIconstInsn((int) x);
+                    mv.visitInsn(Opcodes.I2L);
+                }
                 return;
             }
         }
         if (con instanceof Float) {
             float x = (float) con;
-            if (x == (short) x) {
-                emitIconstInsn((int) x);
-                mv.visitInsn(Opcodes.I2F);
+            short sx = (short)x;
+            if (x == sx) {
+                if (sx >= 0 && sx <= 2) {
+                    mv.visitInsn(Opcodes.FCONST_0 + (int) sx);
+                } else {
+                    emitIconstInsn((int) x);
+                    mv.visitInsn(Opcodes.I2F);
+                }
                 return;
             }
         }
         if (con instanceof Double) {
             double x = (double) con;
-            if (x == (short) x) {
-                emitIconstInsn((int) x);
-                mv.visitInsn(Opcodes.I2D);
+            short sx = (short)x;
+            if (x == sx) {
+                if (sx >= 0 && sx <= 1) {
+                    mv.visitInsn(Opcodes.DCONST_0 + (int) sx);
+                } else {
+                    emitIconstInsn((int) x);
+                    mv.visitInsn(Opcodes.I2D);
+                }
                 return;
             }
         }
@@ -356,26 +383,16 @@ class InvokerBytecodeGenerator {
         mv.visitLdcInsn(con);
     }
 
-    private void emitIconstInsn(int i) {
-        int opcode;
-        switch (i) {
-        case 0:  opcode = Opcodes.ICONST_0;  break;
-        case 1:  opcode = Opcodes.ICONST_1;  break;
-        case 2:  opcode = Opcodes.ICONST_2;  break;
-        case 3:  opcode = Opcodes.ICONST_3;  break;
-        case 4:  opcode = Opcodes.ICONST_4;  break;
-        case 5:  opcode = Opcodes.ICONST_5;  break;
-        default:
-            if (i == (byte) i) {
-                mv.visitIntInsn(Opcodes.BIPUSH, i & 0xFF);
-            } else if (i == (short) i) {
-                mv.visitIntInsn(Opcodes.SIPUSH, (char) i);
-            } else {
-                mv.visitLdcInsn(i);
-            }
-            return;
+    private void emitIconstInsn(final int cst) {
+        if (cst >= -1 && cst <= 5) {
+            mv.visitInsn(Opcodes.ICONST_0 + cst);
+        } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
+            mv.visitIntInsn(Opcodes.BIPUSH, cst);
+        } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
+            mv.visitIntInsn(Opcodes.SIPUSH, cst);
+        } else {
+            mv.visitLdcInsn(cst);
         }
-        mv.visitInsn(opcode);
     }
 
     /*

From 8da753e1be0d4de4cbb71b80a85668c4a141a4ea Mon Sep 17 00:00:00 2001
From: Rob McKenna <robm@openjdk.org>
Date: Wed, 9 Dec 2015 17:34:09 +0000
Subject: [PATCH 30/62] 8141370: com/sun/jndi/ldap/LdapTimeoutTest.java failed
 intermittently

Reviewed-by: vinnie
---
 jdk/test/ProblemList.txt                      |   7 +
 .../sun/jndi/ldap/DeadSSLLdapTimeoutTest.java | 210 ++++++++++++++++++
 .../com/sun/jndi/ldap/LdapTimeoutTest.java    |  38 ----
 3 files changed, 217 insertions(+), 38 deletions(-)
 create mode 100644 jdk/test/com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java

diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index 8d61ebc654e..51abaacbf53 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -407,3 +407,10 @@ sun/tools/jinfo/JInfoRunningProcessFlagTest.java		generic-all
 sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java    generic-all
 
 ############################################################################
+
+# jdk_other
+
+############################################################################
+
+# 8141370
+com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java			linux-i586,macosx-all
diff --git a/jdk/test/com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java
new file mode 100644
index 00000000000..1301c4c2466
--- /dev/null
+++ b/jdk/test/com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @run main/othervm DeadSSLLdapTimeoutTest
+ * @bug 8141370
+ * @key intermittent
+ */
+
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.net.SocketTimeoutException;
+import java.io.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import java.util.List;
+import java.util.Hashtable;
+import java.util.ArrayList;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLHandshakeException;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+
+class DeadServerTimeoutSSLTest implements Callable {
+
+    Hashtable env;
+    DeadSSLServer server;
+    boolean passed = false;
+    private int HANGING_TEST_TIMEOUT = 20_000;
+
+    public DeadServerTimeoutSSLTest(Hashtable env) throws IOException {
+        this.server = new DeadSSLServer();
+        this.env = env;
+    }
+
+    public void performOp(InitialContext ctx) throws NamingException {}
+
+    public void handleNamingException(NamingException e, long start, long end) {
+        if (e.getCause() instanceof SocketTimeoutException) {
+            // SSL connect will timeout via readReply using
+            // SocketTimeoutException
+            e.printStackTrace();
+            pass();
+        } else if (e.getCause() instanceof SSLHandshakeException
+                && e.getCause().getCause() instanceof EOFException) {
+            // test seems to be failing intermittently on some
+            // platforms.
+            pass();
+        } else {
+            fail(e);
+        }
+    }
+
+    public void pass() {
+        this.passed = true;
+    }
+
+    public void fail() {
+        throw new RuntimeException("Test failed");
+    }
+
+    public void fail(Exception e) {
+        throw new RuntimeException("Test failed", e);
+    }
+
+    boolean shutItDown(InitialContext ctx) {
+        try {
+            if (ctx != null) ctx.close();
+            return true;
+        } catch (NamingException ex) {
+            return false;
+        }
+    }
+
+    public Boolean call() {
+        InitialContext ctx = null;
+        ScheduledFuture killer = null;
+        long start = System.nanoTime();
+
+        try {
+            while(!server.accepting())
+                Thread.sleep(200); // allow the server to start up
+            Thread.sleep(200); // to be sure
+
+            env.put(Context.PROVIDER_URL, "ldap://localhost:" +
+                    server.getLocalPort());
+
+            try {
+                ctx = new InitialDirContext(env);
+                performOp(ctx);
+                fail();
+            } catch (NamingException e) {
+                long end = System.nanoTime();
+                System.out.println(this.getClass().toString() + " - elapsed: "
+                        + NANOSECONDS.toMillis(end - start));
+                handleNamingException(e, start, end);
+            } finally {
+                if (killer != null && !killer.isDone())
+                    killer.cancel(true);
+                shutItDown(ctx);
+                server.close();
+            }
+            return passed;
+        } catch (IOException|InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
+
+class DeadSSLServer extends Thread {
+    ServerSocket serverSock;
+    boolean accepting = false;
+
+    public DeadSSLServer() throws IOException {
+        this.serverSock = new ServerSocket(0);
+        start();
+    }
+
+    public void run() {
+        while(true) {
+            try {
+                accepting = true;
+                Socket socket = serverSock.accept();
+            } catch (Exception e) {
+                break;
+            }
+        }
+    }
+
+    public int getLocalPort() {
+        return serverSock.getLocalPort();
+    }
+
+    public boolean accepting() {
+        return accepting;
+    }
+
+    public void close() throws IOException {
+        serverSock.close();
+    }
+}
+
+public class DeadSSLLdapTimeoutTest {
+
+    static Hashtable createEnv() {
+        Hashtable env = new Hashtable(11);
+        env.put(Context.INITIAL_CONTEXT_FACTORY,
+            "com.sun.jndi.ldap.LdapCtxFactory");
+        return env;
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        InitialContext ctx = null;
+
+        //
+        // Running this test serially as it seems to tickle a problem
+        // on older kernels
+        //
+        // run the DeadServerTest with connect / read timeouts set
+        // and ssl enabled
+        // this should exit with a SocketTimeoutException as the root cause
+        // it should also use the connect timeout instead of the read timeout
+        System.out.println("Running connect timeout test with 10ms connect timeout, 3000ms read timeout & SSL");
+        Hashtable sslenv = createEnv();
+        sslenv.put("com.sun.jndi.ldap.connect.timeout", "10");
+        sslenv.put("com.sun.jndi.ldap.read.timeout", "3000");
+        sslenv.put(Context.SECURITY_PROTOCOL, "ssl");
+        boolean testFailed =
+            (new DeadServerTimeoutSSLTest(sslenv).call()) ? false : true;
+
+        if (testFailed) {
+            throw new AssertionError("some tests failed");
+        }
+
+    }
+
+}
+
diff --git a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
index fe48073a6b3..5da62ee647e 100644
--- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
@@ -225,29 +225,6 @@ class DeadServerTimeoutTest extends DeadServerTest {
     }
 }
 
-class DeadServerTimeoutSSLTest extends DeadServerTest {
-
-    public DeadServerTimeoutSSLTest(Hashtable env) throws IOException {
-        super(env);
-    }
-
-    public void handleNamingException(NamingException e, long start, long end) {
-        if (e.getCause() instanceof SocketTimeoutException) {
-            // SSL connect will timeout via readReply using
-            // SocketTimeoutException
-            e.printStackTrace();
-            pass();
-        } else if (e.getCause() instanceof SSLHandshakeException
-                && e.getCause().getCause() instanceof EOFException) {
-            // test seems to be failing intermittently on some
-            // platforms.
-            pass();
-        } else {
-            fail(e);
-        }
-    }
-}
-
 
 class ReadServerNoTimeoutTest extends ReadServerTest {
 
@@ -454,21 +431,6 @@ public class LdapTimeoutTest {
                 }
             }
 
-            //
-            // Running this test serially as it seems to tickle a problem
-            // on older kernels
-            //
-            // run the DeadServerTest with connect / read timeouts set
-            // and ssl enabled
-            // this should exit with a SocketTimeoutException as the root cause
-            // it should also use the connect timeout instead of the read timeout
-            System.out.println("Running connect timeout test with 10ms connect timeout, 3000ms read timeout & SSL");
-            Hashtable sslenv = createEnv();
-            sslenv.put("com.sun.jndi.ldap.connect.timeout", "10");
-            sslenv.put("com.sun.jndi.ldap.read.timeout", "3000");
-            sslenv.put(Context.SECURITY_PROTOCOL, "ssl");
-            testFailed = (new DeadServerTimeoutSSLTest(sslenv).call()) ? false : true;
-
             if (testFailed) {
                 throw new AssertionError("some tests failed");
             }

From ee046050d6aaa2aaef4b79d3ae70becff8a0bc5b Mon Sep 17 00:00:00 2001
From: Rachna Goel <rgoel@openjdk.org>
Date: Wed, 9 Dec 2015 14:20:51 +0530
Subject: [PATCH 31/62] 8025547: Locale.toString() documentation error

Updated API doc of Locale.toString method.

Reviewed-by: okutsu
---
 jdk/src/java.base/share/classes/java/util/Locale.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jdk/src/java.base/share/classes/java/util/Locale.java b/jdk/src/java.base/share/classes/java/util/Locale.java
index 0a7c02965f6..d01891be0c5 100644
--- a/jdk/src/java.base/share/classes/java/util/Locale.java
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java
@@ -1248,7 +1248,7 @@ public final class Locale implements Cloneable, Serializable {
      * object, consisting of language, country, variant, script,
      * and extensions as below:
      * <blockquote>
-     * language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions
+     * language + "_" + country + "_" + (variant + "_#" | "#") + script + "_" + extensions
      * </blockquote>
      *
      * Language is always lower case, country is always upper case, script is always title
@@ -1278,7 +1278,7 @@ public final class Locale implements Cloneable, Serializable {
      * <li>{@code en_US_WIN}</li>
      * <li>{@code de__POSIX}</li>
      * <li>{@code zh_CN_#Hans}</li>
-     * <li>{@code zh_TW_#Hant-x-java}</li>
+     * <li>{@code zh_TW_#Hant_x-java}</li>
      * <li>{@code th_TH_TH_#u-nu-thai}</li></ul>
      *
      * @return A string representation of the Locale, for debugging.

From f23d71b4f4f446dd99d0a7f70928a633c803a87e Mon Sep 17 00:00:00 2001
From: Ambarish Rapte <arapte@openjdk.org>
Date: Wed, 9 Dec 2015 18:12:49 +0300
Subject: [PATCH 32/62] 8144915: TextField throws NPE

Reviewed-by: ssadetsky, serb
---
 jdk/src/java.desktop/share/classes/java/awt/TextField.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/jdk/src/java.desktop/share/classes/java/awt/TextField.java b/jdk/src/java.desktop/share/classes/java/awt/TextField.java
index 2dfd19c4128..7c5563088c3 100644
--- a/jdk/src/java.desktop/share/classes/java/awt/TextField.java
+++ b/jdk/src/java.desktop/share/classes/java/awt/TextField.java
@@ -309,6 +309,9 @@ public class TextField extends TextComponent {
      * @return      Returns text after replacing EOL characters.
      */
     private static String replaceEOL(String text) {
+        if (text == null) {
+            return text;
+        }
         String[] strEOLs = {System.lineSeparator(), "\n"};
         for (String eol : strEOLs) {
             if (text.contains(eol)) {

From 3144cc4a273306a9f18d6a7863a5386c97b4915d Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov <serb@openjdk.org>
Date: Wed, 9 Dec 2015 18:56:59 +0300
Subject: [PATCH 33/62] 8143909: Behavior of null arguments not specified in
 javax.sound.midi.spi

The specification change was reviewed by Florian Bomers also

Reviewed-by: amenkov
---
 .../sound/AbstractMidiDeviceProvider.java     |   8 +-
 .../sun/media/sound/JARSoundbankReader.java   |   6 +-
 .../sound/RealTimeSequencerProvider.java      |   5 +-
 .../com/sun/media/sound/SoftProvider.java     |   5 +-
 .../media/sound/StandardMidiFileWriter.java   |  34 ++-
 .../classes/javax/sound/midi/MidiSystem.java  |  82 +++++--
 .../sound/midi/spi/MidiDeviceProvider.java    |   6 +-
 .../javax/sound/midi/spi/MidiFileReader.java  |   8 +-
 .../javax/sound/midi/spi/MidiFileWriter.java  |   8 +-
 .../javax/sound/midi/spi/SoundbankReader.java |   5 +-
 .../midi/MidiDeviceProvider/NullInfo.java     |  71 ------
 .../MidiDeviceProvider/ExpectedNPEOnNull.java |  94 ++++++++
 .../MidiDeviceProvider/FakeInfo.java          |   0
 .../MidiDeviceProvider/UnsupportedInfo.java   |   0
 .../spi/MidiFileReader/ExpectedNPEOnNull.java | 130 +++++++++++
 .../spi/MidiFileWriter/ExpectedNPEOnNull.java | 215 ++++++++++++++++++
 .../SoundbankReader/ExpectedNPEOnNull.java    |  94 ++++++++
 17 files changed, 647 insertions(+), 124 deletions(-)
 delete mode 100644 jdk/test/javax/sound/midi/MidiDeviceProvider/NullInfo.java
 create mode 100644 jdk/test/javax/sound/midi/spi/MidiDeviceProvider/ExpectedNPEOnNull.java
 rename jdk/test/javax/sound/midi/{ => spi}/MidiDeviceProvider/FakeInfo.java (100%)
 rename jdk/test/javax/sound/midi/{ => spi}/MidiDeviceProvider/UnsupportedInfo.java (100%)
 create mode 100644 jdk/test/javax/sound/midi/spi/MidiFileReader/ExpectedNPEOnNull.java
 create mode 100644 jdk/test/javax/sound/midi/spi/MidiFileWriter/ExpectedNPEOnNull.java
 create mode 100644 jdk/test/javax/sound/midi/spi/SoundbankReader/ExpectedNPEOnNull.java

diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java
index 8d0003cc987..6ff1ccde6b0 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AbstractMidiDeviceProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -25,10 +25,11 @@
 
 package com.sun.media.sound;
 
+import java.util.Objects;
+
 import javax.sound.midi.MidiDevice;
 import javax.sound.midi.spi.MidiDeviceProvider;
 
-
 /**
  * Super class for MIDI input or output device provider.
  *
@@ -127,7 +128,8 @@ public abstract class AbstractMidiDeviceProvider extends MidiDeviceProvider {
     }
 
     @Override
-    public final MidiDevice getDevice(MidiDevice.Info info) {
+    public final MidiDevice getDevice(final MidiDevice.Info info) {
+        Objects.requireNonNull(info);
         if (info instanceof Info) {
             readDeviceInfos();
             MidiDevice[] devices = getDeviceCache();
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java
index 32fc90ffbb7..30c49810771 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -22,6 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package com.sun.media.sound;
 
 import java.io.BufferedReader;
@@ -32,6 +33,8 @@ import java.io.InputStreamReader;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
+import java.util.Objects;
+
 import javax.sound.midi.InvalidMidiDataException;
 import javax.sound.midi.Soundbank;
 import javax.sound.midi.spi.SoundbankReader;
@@ -112,6 +115,7 @@ public final class JARSoundbankReader extends SoundbankReader {
 
     public Soundbank getSoundbank(InputStream stream)
             throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(stream);
         return null;
     }
 
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java
index fa5bfa1afbf..32ca9ff5331 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RealTimeSequencerProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -25,6 +25,8 @@
 
 package com.sun.media.sound;
 
+import java.util.Objects;
+
 import javax.sound.midi.MidiDevice;
 import javax.sound.midi.spi.MidiDeviceProvider;
 
@@ -42,6 +44,7 @@ public final class RealTimeSequencerProvider extends MidiDeviceProvider {
 
     @Override
     public MidiDevice getDevice(final MidiDevice.Info info) {
+        Objects.requireNonNull(info);
         if (RealTimeSequencer.info.equals(info)) {
             return new RealTimeSequencer();
         }
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java
index 89d85362539..e4bc1a7e342 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, 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
@@ -25,6 +25,8 @@
 
 package com.sun.media.sound;
 
+import java.util.Objects;
+
 import javax.sound.midi.MidiDevice;
 import javax.sound.midi.spi.MidiDeviceProvider;
 
@@ -42,6 +44,7 @@ public final class SoftProvider extends MidiDeviceProvider {
 
     @Override
     public MidiDevice getDevice(final MidiDevice.Info info) {
+        Objects.requireNonNull(info);
         if (SoftSynthesizer.info.equals(info)) {
             return new SoftSynthesizer();
         }
diff --git a/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java b/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java
index f03921e72df..cc75e40e251 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/StandardMidiFileWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -25,21 +25,22 @@
 
 package com.sun.media.sound;
 
-import java.io.DataOutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
-import java.io.SequenceInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.SequenceInputStream;
+import java.util.Objects;
 
 import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.MidiEvent;
 import javax.sound.midi.MetaMessage;
+import javax.sound.midi.MidiEvent;
 import javax.sound.midi.Sequence;
 import javax.sound.midi.ShortMessage;
 import javax.sound.midi.SysexMessage;
@@ -115,24 +116,16 @@ public final class StandardMidiFileWriter extends MidiFileWriter {
         return typesArray;
     }
 
-    public boolean isFileTypeSupported(int type) {
-        for(int i=0; i<types.length; i++) {
-            if( type == types[i] ) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public int write(Sequence in, int type, OutputStream out) throws IOException {
+        Objects.requireNonNull(out);
+        if (!isFileTypeSupported(type, in)) {
+            throw new IllegalArgumentException("Could not write MIDI file");
+        }
         byte [] buffer = null;
 
         int bytesRead = 0;
         long bytesWritten = 0;
 
-        if( !isFileTypeSupported(type,in) ) {
-            throw new IllegalArgumentException("Could not write MIDI file");
-        }
         // First get the fileStream from this sequence
         InputStream fileStream = getFileStream(type,in);
         if (fileStream == null) {
@@ -149,6 +142,7 @@ public final class StandardMidiFileWriter extends MidiFileWriter {
     }
 
     public int write(Sequence in, int type, File out) throws IOException {
+        Objects.requireNonNull(in);
         FileOutputStream fos = new FileOutputStream(out); // throws IOException
         int bytesWritten = write( in, type, fos );
         fos.close();
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java
index aa8d46b0360..7a58b1a728b 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/MidiSystem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -35,6 +35,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Properties;
 import java.util.Set;
 
@@ -179,10 +180,12 @@ public class MidiSystem {
      *         due to resource restrictions
      * @throws IllegalArgumentException if the info object does not represent a
      *         MIDI device installed on the system
+     * @throws NullPointerException if {@code info} is {@code null}
      * @see #getMidiDeviceInfo
      */
     public static MidiDevice getMidiDevice(final MidiDevice.Info info)
             throws MidiUnavailableException {
+        Objects.requireNonNull(info);
         for (final MidiDeviceProvider provider : getMidiDeviceProviders()) {
             if (provider.isDeviceSupported(info)) {
                 return provider.getDevice(info);
@@ -447,11 +450,13 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the stream does not point to valid
      *         MIDI soundbank data recognized by the system
      * @throws IOException if an I/O error occurred when loading the soundbank
+     * @throws NullPointerException if {@code stream} is {@code null}
      * @see InputStream#markSupported
      * @see InputStream#mark
      */
-    public static Soundbank getSoundbank(InputStream stream)
-        throws InvalidMidiDataException, IOException {
+    public static Soundbank getSoundbank(final InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(stream);
 
         SoundbankReader sp = null;
         Soundbank s = null;
@@ -479,9 +484,11 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the URL does not point to valid MIDI
      *         soundbank data recognized by the system
      * @throws IOException if an I/O error occurred when loading the soundbank
+     * @throws NullPointerException if {@code url} is {@code null}
      */
-    public static Soundbank getSoundbank(URL url)
-        throws InvalidMidiDataException, IOException {
+    public static Soundbank getSoundbank(final URL url)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(url);
 
         SoundbankReader sp = null;
         Soundbank s = null;
@@ -509,9 +516,11 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the {@code File} does not point to
      *         valid MIDI soundbank data recognized by the system
      * @throws IOException if an I/O error occurred when loading the soundbank
+     * @throws NullPointerException if {@code file} is {@code null}
      */
-    public static Soundbank getSoundbank(File file)
-        throws InvalidMidiDataException, IOException {
+    public static Soundbank getSoundbank(final File file)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(file);
 
         SoundbankReader sp = null;
         Soundbank s = null;
@@ -556,13 +565,15 @@ public class MidiSystem {
      *         MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs while accessing the
      *         stream
+     * @throws NullPointerException if {@code stream} is {@code null}
      * @see #getMidiFileFormat(URL)
      * @see #getMidiFileFormat(File)
      * @see InputStream#markSupported
      * @see InputStream#mark
      */
-    public static MidiFileFormat getMidiFileFormat(InputStream stream)
-        throws InvalidMidiDataException, IOException {
+    public static MidiFileFormat getMidiFileFormat(final InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(stream);
 
         List<MidiFileReader> providers = getMidiFileReaders();
         MidiFileFormat format = null;
@@ -602,11 +613,13 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the URL does not point to valid MIDI
      *         file data recognized by the system
      * @throws IOException if an I/O exception occurs while accessing the URL
+     * @throws NullPointerException if {@code url} is {@code null}
      * @see #getMidiFileFormat(InputStream)
      * @see #getMidiFileFormat(File)
      */
-    public static MidiFileFormat getMidiFileFormat(URL url)
-        throws InvalidMidiDataException, IOException {
+    public static MidiFileFormat getMidiFileFormat(final URL url)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(url);
 
         List<MidiFileReader> providers = getMidiFileReaders();
         MidiFileFormat format = null;
@@ -646,11 +659,13 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the {@code File} does not point to
      *         valid MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs while accessing the file
+     * @throws NullPointerException if {@code file} is {@code null}
      * @see #getMidiFileFormat(InputStream)
      * @see #getMidiFileFormat(URL)
      */
-    public static MidiFileFormat getMidiFileFormat(File file)
-        throws InvalidMidiDataException, IOException {
+    public static MidiFileFormat getMidiFileFormat(final File file)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(file);
 
         List<MidiFileReader> providers = getMidiFileReaders();
         MidiFileFormat format = null;
@@ -699,11 +714,13 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the stream does not point to valid
      *         MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs while accessing the stream
+     * @throws NullPointerException if {@code stream} is {@code null}
      * @see InputStream#markSupported
      * @see InputStream#mark
      */
-    public static Sequence getSequence(InputStream stream)
-        throws InvalidMidiDataException, IOException {
+    public static Sequence getSequence(final InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(stream);
 
         List<MidiFileReader> providers = getMidiFileReaders();
         Sequence sequence = null;
@@ -743,9 +760,11 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the URL does not point to valid MIDI
      *         file data recognized by the system
      * @throws IOException if an I/O exception occurs while accessing the URL
+     * @throws NullPointerException if {@code url} is {@code null}
      */
-    public static Sequence getSequence(URL url)
-        throws InvalidMidiDataException, IOException {
+    public static Sequence getSequence(final URL url)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(url);
 
         List<MidiFileReader> providers = getMidiFileReaders();
         Sequence sequence = null;
@@ -787,9 +806,11 @@ public class MidiSystem {
      * @throws InvalidMidiDataException if the File does not point to valid MIDI
      *         file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code file} is {@code null}
      */
-    public static Sequence getSequence(File file)
-        throws InvalidMidiDataException, IOException {
+    public static Sequence getSequence(final File file)
+            throws InvalidMidiDataException, IOException {
+        Objects.requireNonNull(file);
 
         List<MidiFileReader> providers = getMidiFileReaders();
         Sequence sequence = null;
@@ -870,8 +891,10 @@ public class MidiSystem {
      * @param  sequence the sequence for which MIDI file type support is queried
      * @return the set of unique supported file types. If no file types are
      *         supported, returns an array of length 0.
+     * @throws NullPointerException if {@code sequence} is {@code null}
      */
-    public static int[] getMidiFileTypes(Sequence sequence) {
+    public static int[] getMidiFileTypes(final Sequence sequence) {
+        Objects.requireNonNull(sequence);
 
         List<MidiFileWriter> providers = getMidiFileWriters();
         Set<Integer> allTypes = new HashSet<>();
@@ -903,8 +926,11 @@ public class MidiSystem {
      * @param  sequence the sequence for which file writing support is queried
      * @return {@code true} if the file type is supported for this sequence,
      *         otherwise {@code false}
+     * @throws NullPointerException if {@code sequence} is {@code null}
      */
-    public static boolean isFileTypeSupported(int fileType, Sequence sequence) {
+    public static boolean isFileTypeSupported(final int fileType,
+                                              final Sequence sequence) {
+        Objects.requireNonNull(sequence);
 
         List<MidiFileWriter> providers = getMidiFileWriters();
 
@@ -929,10 +955,15 @@ public class MidiSystem {
      * @throws IOException if an I/O exception occurs
      * @throws IllegalArgumentException if the file format is not supported by
      *         the system
+     * @throws NullPointerException if {@code in} or {@code out} are
+     *         {@code null}
      * @see #isFileTypeSupported(int, Sequence)
      * @see #getMidiFileTypes(Sequence)
      */
-    public static int write(Sequence in, int fileType, OutputStream out) throws IOException {
+    public static int write(final Sequence in, final int fileType,
+                            final OutputStream out) throws IOException {
+        Objects.requireNonNull(in);
+        Objects.requireNonNull(out);
 
         List<MidiFileWriter> providers = getMidiFileWriters();
         //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
@@ -963,10 +994,15 @@ public class MidiSystem {
      * @throws IOException if an I/O exception occurs
      * @throws IllegalArgumentException if the file type is not supported by the
      *         system
+     * @throws NullPointerException if {@code in} or {@code out} are
+     *         {@code null}
      * @see #isFileTypeSupported(int, Sequence)
      * @see #getMidiFileTypes(Sequence)
      */
-    public static int write(Sequence in, int type, File out) throws IOException {
+    public static int write(final Sequence in, final int type, final File out)
+            throws IOException {
+        Objects.requireNonNull(in);
+        Objects.requireNonNull(out);
 
         List<MidiFileWriter> providers = getMidiFileWriters();
         //$$fb 2002-04-17: Fix for 4635287: Standard MidiFileWriter cannot write empty Sequences
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java
index 97c9d92b7f0..4f820b497d7 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiDeviceProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -26,6 +26,7 @@
 package javax.sound.midi.spi;
 
 import java.util.Arrays;
+import java.util.Objects;
 
 import javax.sound.midi.MidiDevice;
 
@@ -46,8 +47,10 @@ public abstract class MidiDeviceProvider {
      *         is queried
      * @return {@code true} if the specified device is supported, otherwise
      *         {@code false}
+     * @throws NullPointerException if {@code info} is {@code null}
      */
     public boolean isDeviceSupported(final MidiDevice.Info info) {
+        Objects.requireNonNull(info);
         return Arrays.asList(getDeviceInfo()).contains(info);
     }
 
@@ -67,6 +70,7 @@ public abstract class MidiDeviceProvider {
      * @throws IllegalArgumentException if the info object specified does not
      *         match the info object for a device supported by this
      *         {@code MidiDeviceProvider}
+     * @throws NullPointerException if {@code info} is {@code null}
      */
     public abstract MidiDevice getDevice(MidiDevice.Info info);
 }
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java
index bbdca9e97bb..f1c3b6f6ff5 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -60,6 +60,7 @@ public abstract class MidiFileReader {
      * @throws InvalidMidiDataException if the stream does not point to valid
      *         MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code stream} is {@code null}
      * @see InputStream#markSupported
      * @see InputStream#mark
      */
@@ -76,6 +77,7 @@ public abstract class MidiFileReader {
      * @throws InvalidMidiDataException if the URL does not point to valid MIDI
      *         file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code url} is {@code null}
      */
     public abstract MidiFileFormat getMidiFileFormat(URL url)
             throws InvalidMidiDataException, IOException;
@@ -90,6 +92,7 @@ public abstract class MidiFileReader {
      * @throws InvalidMidiDataException if the {@code File} does not point to
      *         valid MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code file} is {@code null}
      */
     public abstract MidiFileFormat getMidiFileFormat(File file)
             throws InvalidMidiDataException, IOException;
@@ -110,6 +113,7 @@ public abstract class MidiFileReader {
      * @throws InvalidMidiDataException if the stream does not point to valid
      *         MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code stream} is {@code null}
      * @see InputStream#markSupported
      * @see InputStream#mark
      */
@@ -126,6 +130,7 @@ public abstract class MidiFileReader {
      * @throws InvalidMidiDataException if the URL does not point to valid MIDI
      *         file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code url} is {@code null}
      */
     public abstract Sequence getSequence(URL url)
             throws InvalidMidiDataException, IOException;
@@ -141,6 +146,7 @@ public abstract class MidiFileReader {
      * @throws InvalidMidiDataException if the {@code File} does not point to
      *         valid MIDI file data recognized by the system
      * @throws IOException if an I/O exception occurs
+     * @throws NullPointerException if {@code file} is {@code null}
      */
     public abstract Sequence getSequence(File file)
             throws InvalidMidiDataException, IOException;
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java
index a1800f7f701..9a3fdcbc62e 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/MidiFileWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -58,6 +58,7 @@ public abstract class MidiFileWriter {
      *         queried
      * @return array of file types. If no file types are supported, returns an
      *         array of length 0.
+     * @throws NullPointerException if {@code sequence} is {@code null}
      */
     public abstract int[] getMidiFileTypes(Sequence sequence);
 
@@ -88,6 +89,7 @@ public abstract class MidiFileWriter {
      * @param  sequence the sequence for which file writing support is queried
      * @return {@code true} if the file type is supported for this sequence,
      *         otherwise {@code false}
+     * @throws NullPointerException if {@code sequence} is {@code null}
      */
     public boolean isFileTypeSupported(int fileType, Sequence sequence) {
 
@@ -111,6 +113,8 @@ public abstract class MidiFileWriter {
      * @throws IOException if an I/O exception occurs
      * @throws IllegalArgumentException if the file type is not supported by
      *         this file writer
+     * @throws NullPointerException if {@code in} or {@code out} are
+     *         {@code null}
      * @see #isFileTypeSupported(int, Sequence)
      * @see #getMidiFileTypes(Sequence)
      */
@@ -129,6 +133,8 @@ public abstract class MidiFileWriter {
      * @throws IOException if an I/O exception occurs
      * @throws IllegalArgumentException if the file type is not supported by
      *         this file writer
+     * @throws NullPointerException if {@code in} or {@code out} are
+     *         {@code null}
      * @see #isFileTypeSupported(int, Sequence)
      * @see #getMidiFileTypes(Sequence)
      */
diff --git a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java
index 501c18b6ad5..8690b0d18ed 100644
--- a/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java
+++ b/jdk/src/java.desktop/share/classes/javax/sound/midi/spi/SoundbankReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, 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
@@ -52,6 +52,7 @@ public abstract class SoundbankReader {
      * @throws InvalidMidiDataException if the URL does not point to valid MIDI
      *         soundbank data recognized by this soundbank reader
      * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if {@code url} is {@code null}
      */
     public abstract Soundbank getSoundbank(URL url)
             throws InvalidMidiDataException, IOException;
@@ -64,6 +65,7 @@ public abstract class SoundbankReader {
      * @throws InvalidMidiDataException if the stream does not point to valid
      *         MIDI soundbank data recognized by this soundbank reader
      * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if {@code stream} is {@code null}
      */
     public abstract Soundbank getSoundbank(InputStream stream)
             throws InvalidMidiDataException, IOException;
@@ -76,6 +78,7 @@ public abstract class SoundbankReader {
      * @throws InvalidMidiDataException if the file does not point to valid MIDI
      *         soundbank data recognized by this soundbank reader
      * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if {@code file} is {@code null}
      */
     public abstract Soundbank getSoundbank(File file)
             throws InvalidMidiDataException, IOException;
diff --git a/jdk/test/javax/sound/midi/MidiDeviceProvider/NullInfo.java b/jdk/test/javax/sound/midi/MidiDeviceProvider/NullInfo.java
deleted file mode 100644
index 9fa00c03172..00000000000
--- a/jdk/test/javax/sound/midi/MidiDeviceProvider/NullInfo.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.Collection;
-import java.util.HashSet;
-
-import javax.sound.midi.MidiDevice;
-import javax.sound.midi.MidiSystem;
-import javax.sound.midi.MidiUnavailableException;
-import javax.sound.midi.spi.MidiDeviceProvider;
-
-import static java.util.ServiceLoader.load;
-
-/**
- * @test
- * @bug 8058115
- * @summary MidiDeviceProvider shouldn't returns incorrect results or throw NPE
- *          in case of null MidiDevice.Info
- * @author Sergey Bylokhov
- */
-public final class NullInfo {
-
-    public static void main(final String[] args) {
-        // MidiSystem API
-        try {
-            MidiSystem.getMidiDevice(null);
-            throw new RuntimeException("IllegalArgumentException expected");
-        } catch (final MidiUnavailableException e) {
-            throw new RuntimeException("IllegalArgumentException expected", e);
-        } catch (final IllegalArgumentException ignored) {
-            // expected
-        }
-        // MidiDeviceProvider API
-        final Collection<String> errors = new HashSet<>();
-        for (final MidiDeviceProvider mdp : load(MidiDeviceProvider.class)) {
-            try {
-                if (mdp.isDeviceSupported(null)) {
-                    throw new RuntimeException("null is supported");
-                }
-                final MidiDevice device = mdp.getDevice(null);
-                System.err.println("MidiDevice: " + device);
-                throw new RuntimeException("IllegalArgumentException expected");
-            } catch (final IllegalArgumentException e) {
-                errors.add(e.getMessage());
-            }
-        }
-        if (errors.size() != 1) {
-            throw new RuntimeException("Wrong number of messages:" + errors);
-        }
-    }
-}
diff --git a/jdk/test/javax/sound/midi/spi/MidiDeviceProvider/ExpectedNPEOnNull.java b/jdk/test/javax/sound/midi/spi/MidiDeviceProvider/ExpectedNPEOnNull.java
new file mode 100644
index 00000000000..efb57eeeae2
--- /dev/null
+++ b/jdk/test/javax/sound/midi/spi/MidiDeviceProvider/ExpectedNPEOnNull.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Objects;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+import static java.util.ServiceLoader.load;
+
+/**
+ * @test
+ * @bug 8143909
+ * @author Sergey Bylokhov
+ */
+public final class ExpectedNPEOnNull {
+
+    public static void main(final String[] args) throws Exception {
+        testMS();
+        for (final MidiDeviceProvider mdp : load(MidiDeviceProvider.class)) {
+            testMDP(mdp);
+        }
+        testMDP(customMDP);
+    }
+
+    /**
+     * Tests the part of MidiSystem API, which implemented via
+     * MidiDeviceProvider.
+     */
+    private static void testMS() throws Exception {
+        // MidiSystem#getMidiDevice(MidiDevice.Info)
+        try {
+            MidiSystem.getMidiDevice(null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+    }
+
+    /**
+     * Tests the MidiDeviceProvider API directly.
+     */
+    private static void testMDP(final MidiDeviceProvider mdp) throws Exception {
+        // MidiDeviceProvider#isDeviceSupported(Info)
+        try {
+            mdp.isDeviceSupported(null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiDeviceProvider#getDevice(Info)
+        try {
+            mdp.getDevice(null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+    }
+
+    /**
+     * Tests some default implementation of MidiDeviceProvider API, using the
+     * custom {@code MidiDeviceProvider}, which support nothing.
+     */
+    static MidiDeviceProvider customMDP = new MidiDeviceProvider() {
+        @Override
+        public MidiDevice.Info[] getDeviceInfo() {
+            return new MidiDevice.Info[0];
+        }
+
+        @Override
+        public MidiDevice getDevice(MidiDevice.Info info) {
+            Objects.requireNonNull(info);
+            return null;
+        }
+    };
+}
diff --git a/jdk/test/javax/sound/midi/MidiDeviceProvider/FakeInfo.java b/jdk/test/javax/sound/midi/spi/MidiDeviceProvider/FakeInfo.java
similarity index 100%
rename from jdk/test/javax/sound/midi/MidiDeviceProvider/FakeInfo.java
rename to jdk/test/javax/sound/midi/spi/MidiDeviceProvider/FakeInfo.java
diff --git a/jdk/test/javax/sound/midi/MidiDeviceProvider/UnsupportedInfo.java b/jdk/test/javax/sound/midi/spi/MidiDeviceProvider/UnsupportedInfo.java
similarity index 100%
rename from jdk/test/javax/sound/midi/MidiDeviceProvider/UnsupportedInfo.java
rename to jdk/test/javax/sound/midi/spi/MidiDeviceProvider/UnsupportedInfo.java
diff --git a/jdk/test/javax/sound/midi/spi/MidiFileReader/ExpectedNPEOnNull.java b/jdk/test/javax/sound/midi/spi/MidiFileReader/ExpectedNPEOnNull.java
new file mode 100644
index 00000000000..bb4b75f3302
--- /dev/null
+++ b/jdk/test/javax/sound/midi/spi/MidiFileReader/ExpectedNPEOnNull.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.spi.MidiFileReader;
+
+import static java.util.ServiceLoader.load;
+
+/**
+ * @test
+ * @bug 8143909
+ * @author Sergey Bylokhov
+ */
+public final class ExpectedNPEOnNull {
+
+    public static void main(final String[] args) throws Exception {
+        testMS();
+        for (final MidiFileReader mfr : load(MidiFileReader.class)) {
+            testMFR(mfr);
+        }
+    }
+
+    /**
+     * Tests the part of MidiSystem API, which implemented via MidiFileReader.
+     */
+    private static void testMS() throws Exception {
+        // MidiSystem#getMidiFileFormat(InputStream)
+        try {
+            MidiSystem.getMidiFileFormat((InputStream) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getMidiFileFormat(URL)
+        try {
+            MidiSystem.getMidiFileFormat((URL) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getMidiFileFormat(File)
+        try {
+            MidiSystem.getMidiFileFormat((File) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getSequence(InputStream)
+        try {
+            MidiSystem.getSequence((InputStream) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getSequence(URL)
+        try {
+            MidiSystem.getSequence((URL) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getSequence(File)
+        try {
+            MidiSystem.getSequence((File) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+    }
+
+    /**
+     * Tests the MidiFileReader API directly.
+     */
+    private static void testMFR(final MidiFileReader mfr) throws Exception {
+        // MidiFileReader#getMidiFileFormat(InputStream)
+        try {
+            mfr.getMidiFileFormat((InputStream) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiFileReader#getMidiFileFormat(URL)
+        try {
+            mfr.getMidiFileFormat((URL) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiFileReader#getMidiFileFormat(File)
+        try {
+            mfr.getMidiFileFormat((File) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiFileReader#getSequence(InputStream)
+        try {
+            mfr.getSequence((InputStream) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiFileReader#getSequence(URL)
+        try {
+            mfr.getSequence((URL) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiFileReader#getSequence(File)
+        try {
+            mfr.getSequence((File) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+    }
+}
diff --git a/jdk/test/javax/sound/midi/spi/MidiFileWriter/ExpectedNPEOnNull.java b/jdk/test/javax/sound/midi/spi/MidiFileWriter/ExpectedNPEOnNull.java
new file mode 100644
index 00000000000..6a96dbe6b52
--- /dev/null
+++ b/jdk/test/javax/sound/midi/spi/MidiFileWriter/ExpectedNPEOnNull.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.OutputStream;
+import java.util.Objects;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.Sequence;
+import javax.sound.midi.spi.MidiFileWriter;
+
+import static java.util.ServiceLoader.load;
+
+/**
+ * @test
+ * @bug 8143909
+ * @author Sergey Bylokhov
+ */
+public final class ExpectedNPEOnNull {
+
+    public static void main(final String[] args) throws Exception {
+        testMS();
+        for (final MidiFileWriter mfw : load(MidiFileWriter.class)) {
+            testMFW(mfw);
+        }
+        testMFW(customMFW);
+    }
+
+    /**
+     * Tests the part of MidiSystem API, which implemented via MidiFileWriter.
+     */
+    private static void testMS() throws Exception {
+        // MidiSystem#getMidiFileTypes(Sequence)
+        try {
+            MidiSystem.getMidiFileTypes(null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+
+        // MidiSystem#isFileTypeSupported(int, Sequence)
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.isFileTypeSupported(type, null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        // MidiSystem#write(Sequence, int, OutputStream)
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.write(null, type, new NullOutputStream());
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.write(new Sequence(0, 0), type, (OutputStream) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.write(null, type, (OutputStream) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        // MidiSystem#write(Sequence, int, File)
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.write(null, type, new File(""));
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.write(new Sequence(0, 0), type, (File) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                MidiSystem.write(null, type, (File) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+    }
+
+    /**
+     * Tests the MidiFileWriter API directly.
+     */
+    private static void testMFW(final MidiFileWriter mfw) throws Exception {
+        // MidiFileWriter#getMidiFileTypes(Sequence)
+        try {
+            mfw.getMidiFileTypes(null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiFileWriter#isFileTypeSupported(int, Sequence)
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.isFileTypeSupported(type, null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        // MidiFileWriter#write(Sequence, int, OutputStream)
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.write(null, type, new NullOutputStream());
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.write(new Sequence(0, 0), type, (OutputStream) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.write(null, type, (OutputStream) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        // MidiFileWriter#write(Sequence, int, File)
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.write(null, type, new File(""));
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.write(new Sequence(0, 0), type, (File) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+        for (final int type : MidiSystem.getMidiFileTypes()) {
+            try {
+                mfw.write(null, type, (File) null);
+                throw new RuntimeException("NPE is expected");
+            } catch (final NullPointerException ignored) {
+            }
+        }
+    }
+    /**
+     * Tests some default implementation of MidiFileWriter API, using the custom
+     * {@code MidiFileWriter}, which support nothing.
+     */
+    static MidiFileWriter customMFW = new MidiFileWriter() {
+        @Override
+        public int[] getMidiFileTypes() {
+            return new int[0];
+        }
+
+        @Override
+        public int[] getMidiFileTypes(Sequence sequence) {
+            Objects.requireNonNull(sequence);
+            return new int[0];
+        }
+
+        @Override
+        public int write(Sequence in, int fileType, OutputStream out) {
+            Objects.requireNonNull(in);
+            Objects.requireNonNull(out);
+            return 0;
+        }
+
+        @Override
+        public int write(Sequence in, int fileType, File out) {
+            Objects.requireNonNull(in);
+            Objects.requireNonNull(out);
+            return 0;
+        }
+    };
+
+    private static final class NullOutputStream extends OutputStream {
+
+        @Override
+        public void write(final int b) {
+            //do nothing
+        }
+    }
+}
diff --git a/jdk/test/javax/sound/midi/spi/SoundbankReader/ExpectedNPEOnNull.java b/jdk/test/javax/sound/midi/spi/SoundbankReader/ExpectedNPEOnNull.java
new file mode 100644
index 00000000000..6ce3742fc9e
--- /dev/null
+++ b/jdk/test/javax/sound/midi/spi/SoundbankReader/ExpectedNPEOnNull.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.spi.SoundbankReader;
+
+import static java.util.ServiceLoader.load;
+
+/**
+ * @test
+ * @bug 8143909
+ * @author Sergey Bylokhov
+ */
+public final class ExpectedNPEOnNull {
+
+    public static void main(final String[] args) throws Exception {
+        testMS();
+        for (final SoundbankReader sbr : load(SoundbankReader.class)) {
+            testSBR(sbr);
+        }
+    }
+
+    /**
+     * Tests the part of MidiSystem API, which implemented via SoundbankReader.
+     */
+    private static void testMS() throws Exception {
+        // MidiSystem#getSoundbank(InputStream)
+        try {
+            MidiSystem.getSoundbank((InputStream) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getSoundbank(URL)
+        try {
+            MidiSystem.getSoundbank((URL) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // MidiSystem#getSoundbank(File)
+        try {
+            MidiSystem.getSoundbank((File) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+    }
+
+    /**
+     * Tests the SoundbankReader API directly.
+     */
+    private static void testSBR(final SoundbankReader sbr) throws Exception {
+        // SoundbankReader#getSoundbank(InputStream)
+        try {
+            sbr.getSoundbank((InputStream) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // SoundbankReader#getSoundbank(URL)
+        try {
+            sbr.getSoundbank((URL) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+        // SoundbankReader#getSoundbank(File)
+        try {
+            sbr.getSoundbank((File) null);
+            throw new RuntimeException("NPE is expected");
+        } catch (final NullPointerException ignored) {
+        }
+    }
+}

From 7d2c07c70d55d4fc692f18cfec0c9c0634b26e0b Mon Sep 17 00:00:00 2001
From: Nadeesh TV <ntv@openjdk.org>
Date: Wed, 9 Dec 2015 15:27:21 -0500
Subject: [PATCH 34/62] 8142936: Add java.time.Duration methods for days,
 hours, minutes, seconds, etc

Reviewed-by: rriggs, scolebourne
---
 .../share/classes/java/time/Duration.java     | 118 ++++++++++++++-
 .../java/time/tck/java/time/TCKDuration.java  | 141 ++++++++++++++++++
 2 files changed, 254 insertions(+), 5 deletions(-)

diff --git a/jdk/src/java.base/share/classes/java/time/Duration.java b/jdk/src/java.base/share/classes/java/time/Duration.java
index 9bf25ba8c27..b7060a91ef4 100644
--- a/jdk/src/java.base/share/classes/java/time/Duration.java
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java
@@ -61,6 +61,7 @@
  */
 package java.time;
 
+import static java.time.LocalTime.MINUTES_PER_HOUR;
 import static java.time.LocalTime.NANOS_PER_SECOND;
 import static java.time.LocalTime.SECONDS_PER_DAY;
 import static java.time.LocalTime.SECONDS_PER_HOUR;
@@ -973,7 +974,7 @@ public final class Duration
         if (multiplicand == 1) {
             return this;
         }
-        return create(toSeconds().multiply(BigDecimal.valueOf(multiplicand)));
+        return create(toBigDecimalSeconds().multiply(BigDecimal.valueOf(multiplicand)));
      }
 
     /**
@@ -992,7 +993,7 @@ public final class Duration
         if (divisor == 1) {
             return this;
         }
-        return create(toSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
+        return create(toBigDecimalSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
      }
 
     /**
@@ -1001,7 +1002,7 @@ public final class Duration
      *
      * @return the total length of the duration in seconds, with a scale of 9, not null
      */
-    private BigDecimal toSeconds() {
+    private BigDecimal toBigDecimalSeconds() {
         return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
     }
 
@@ -1167,6 +1168,19 @@ public final class Duration
         return seconds / SECONDS_PER_MINUTE;
     }
 
+    /**
+     * Gets the number of seconds in this duration.
+     * <p>
+     * This returns the total number of whole seconds in the duration.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the whole seconds part of the length of the duration, positive or negative
+     */
+    public long toSeconds() {
+        return seconds;
+    }
+
     /**
      * Converts this duration to the total length in milliseconds.
      * <p>
@@ -1201,6 +1215,100 @@ public final class Duration
         return totalNanos;
     }
 
+    /**
+     * Extracts the number of days in the duration.
+     * <p>
+     * This returns the total number of days in the duration by dividing the
+     * number of seconds by 86400.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of days in the duration, may be negative
+     */
+    public long toDaysPart(){
+        return seconds / SECONDS_PER_DAY;
+    }
+
+    /**
+     * Extracts the number of hours part in the duration.
+     * <p>
+     * This returns the number of remaining hours when dividing {@link #toHours}
+     * by hours in a day.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of hours part in the duration, may be negative
+     */
+    public int toHoursPart(){
+        return (int) (toHours() % 24);
+    }
+
+    /**
+     * Extracts the number of minutes part in the duration.
+     * <p>
+     * This returns the number of remaining minutes when dividing {@link #toMinutes}
+     * by minutes in an hour.
+     * This is based on the standard definition of an hour as 60 minutes.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of minutes parts in the duration, may be negative
+     * may be negative
+     */
+    public int toMinutesPart(){
+        return (int) (toMinutes() % MINUTES_PER_HOUR);
+    }
+
+    /**
+     * Extracts the number of seconds part in the duration.
+     * <p>
+     * This returns the remaining seconds when dividing {@link #toSeconds}
+     * by seconds in a minute.
+     * This is based on the standard definition of a minute as 60 seconds.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of seconds parts in the duration, may be negative
+     */
+    public int toSecondsPart(){
+        return (int) (seconds % SECONDS_PER_MINUTE);
+    }
+
+    /**
+     * Extracts the number of milliseconds part of the duration.
+     * <p>
+     * This returns the milliseconds part by dividing the number of nanoseconds by 1,000,000.
+     * The length of the duration is stored using two fields - seconds and nanoseconds.
+     * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
+     * the length in seconds.
+     * The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of milliseconds part of the duration.
+     */
+    public int toMillisPart(){
+        return nanos / 1000_000;
+    }
+
+    /**
+     * Get the nanoseconds part within seconds of the duration.
+     * <p>
+     * The length of the duration is stored using two fields - seconds and nanoseconds.
+     * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
+     * the length in seconds.
+     * The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
+     */
+    public int toNanosPart(){
+        return nanos;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this duration to the specified {@code Duration}.
@@ -1208,7 +1316,7 @@ public final class Duration
      * The comparison is based on the total length of the durations.
      * It is "consistent with equals", as defined by {@link Comparable}.
      *
-     * @param otherDuration  the other duration to compare to, not null
+     * @param otherDuration the other duration to compare to, not null
      * @return the comparator value, negative if less, positive if greater
      */
     @Override
@@ -1226,7 +1334,7 @@ public final class Duration
      * <p>
      * The comparison is based on the total length of the durations.
      *
-     * @param otherDuration  the other duration, null returns false
+     * @param otherDuration the other duration, null returns false
      * @return true if the other duration is equal to this one
      */
     @Override
diff --git a/jdk/test/java/time/tck/java/time/TCKDuration.java b/jdk/test/java/time/tck/java/time/TCKDuration.java
index fe6a9f98088..7f70916ac95 100644
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java
@@ -2474,6 +2474,147 @@ public class TCKDuration extends AbstractTCKTest {
         test.toMillis();
     }
 
+    //-----------------------------------------------------------------------
+    // toSeconds()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toSeconds_provider")
+    Object[][] provider_toSeconds() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 31556926L},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -31556927L},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, 123_456_789), -31556926L},
+            {Duration.ofSeconds(0), 0L},
+            {Duration.ofSeconds(0, 123_456_789), 0L},
+            {Duration.ofSeconds(0, -123_456_789), -1L},
+            {Duration.ofSeconds(Long.MAX_VALUE), 9223372036854775807L},
+            {Duration.ofSeconds(Long.MIN_VALUE), -9223372036854775808L},
+        };
+    }
+
+    @Test(dataProvider="toSeconds_provider")
+    public void test_toSeconds(Duration dur, long seconds) {
+        assertEquals(dur.toSeconds(), seconds);
+    }
+
+    //-----------------------------------------------------------------------
+    // toDaysPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toDaysPart_provider")
+    Object[][] provider_toDaysPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 365L},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -365L},
+            {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 123_456_789), 0L},
+            {Duration.ofDays(365), 365L},
+            {Duration.ofHours(2), 0L},
+            {Duration.ofHours(-2), 0L},
+        };
+    }
+
+    @Test(dataProvider="toDaysPart_provider")
+    public void test_toDaysPart(Duration dur, long days) {
+        assertEquals(dur.toDaysPart(), days);
+    }
+
+    //-----------------------------------------------------------------------
+    // toHoursPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toHoursPart_provider")
+    Object[][] provider_toHoursPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 5},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -5},
+            {Duration.ofSeconds(48 * 60 + 46, 123_456_789), 0},
+            {Duration.ofHours(2), 2},
+            {Duration.ofHours(-2), -2},
+        };
+    }
+
+    @Test(dataProvider="toHoursPart_provider")
+    public void test_toHoursPart(Duration dur, int hours) {
+        assertEquals(dur.toHoursPart(), hours);
+    }
+
+    //-----------------------------------------------------------------------
+    // toMinutesPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toMinutesPart_provider")
+    Object[][] provider_toMinutesPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 48},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -48},
+            {Duration.ofSeconds(46, 123_456_789),0},
+            {Duration.ofMinutes(48), 48},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2),0},
+        };
+    }
+
+    @Test(dataProvider="toMinutesPart_provider")
+    public void test_toMinutesPart(Duration dur, int minutes) {
+        assertEquals(dur.toMinutesPart(), minutes);
+    }
+
+    //-----------------------------------------------------------------------
+    // toSecondsPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toSecondsPart_provider")
+    Object[][] provider_toSecondsPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 46},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -47},
+            {Duration.ofSeconds(0, 123_456_789), 0},
+            {Duration.ofSeconds(46), 46},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2), 0},
+        };
+    }
+
+    @Test(dataProvider="toSecondsPart_provider")
+    public void test_toSecondsPart(Duration dur, int seconds) {
+        assertEquals(dur.toSecondsPart(), seconds);
+    }
+
+    //-----------------------------------------------------------------------
+    // toMillisPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toMillisPart_provider")
+    Object[][] provider_toMillisPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 123},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), 876},
+            {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 0), 0},
+            {Duration.ofMillis(123), 123},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2), 0},
+        };
+    }
+
+    @Test(dataProvider="toMillisPart_provider")
+    public void test_toMillisPart(Duration dur, int millis) {
+        assertEquals(dur.toMillisPart(), millis);
+    }
+
+    //-----------------------------------------------------------------------
+    // toNanosPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toNanosPart_provider")
+    Object[][] provider_toNanosPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 123_456_789},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), 876_543_211},
+            {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 0), 0},
+            {Duration.ofNanos(123_456_789), 123_456_789},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2), 0},
+        };
+    }
+
+    @Test(dataProvider="toNanosPart_provider")
+    public void test_toNanosPart(Duration dur, int nanos) {
+        assertEquals(dur.toNanosPart(), nanos);
+    }
+
     //-----------------------------------------------------------------------
     // compareTo()
     //-----------------------------------------------------------------------

From dcf0684317b79872294bc77c3a668ba237e30d49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20Bourg=C3=A8s?= <lbourges@openjdk.org>
Date: Wed, 9 Dec 2015 13:59:45 -0800
Subject: [PATCH 35/62] 8144828: Marlin renderer causes unaligned write
 accesses

Reviewed-by: prr, flar
---
 .../sun/java2d/marlin/MarlinCache.java        | 25 ++++++++++++++-----
 .../sun/java2d/marlin/MarlinConst.java        |  2 ++
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java
index a281b4e5ecf..9aa35132772 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java
@@ -156,8 +156,6 @@ public final class MarlinCache implements MarlinConst {
                     // rewritten to avoid division:
                     || (width * heightSubPixel) >
                             ((edgeSumDeltaY - heightSubPixel) << BLOCK_SIZE_LG);
-//                            ((edgeSumDeltaY - heightSubPixel) * RLE_THRESHOLD);
-//                            ((edgeSumDeltaY - heightSubPixel) << BLOCK_TH_LG);
 
                 if (doTrace && !useRLE) {
                     final float meanCrossings
@@ -293,8 +291,10 @@ public final class MarlinCache implements MarlinConst {
         // update row index to current position:
         rowAAChunkIndex[row] = pos;
 
-        // determine need array size (may overflow):
-        final long needSize = pos + (px_bbox1 - px0);
+        // determine need array size:
+        // for RLE encoding, position must be aligned to 4 bytes (int):
+        // align - 1 = 3 so add +3 and round-off by mask ~3 = -4
+        final long needSize = pos + ((px_bbox1 - px0 + 3) & -4);
 
         // update next position (bytes):
         rowAAChunkPos = needSize;
@@ -401,8 +401,7 @@ public final class MarlinCache implements MarlinConst {
 
         // determine need array size:
         // pessimistic: max needed size = deltaX x 4 (1 int)
-        final int maxLen = (to - from);
-        final long needSize = initialPos + (maxLen << 2);
+        final long needSize = initialPos + ((to - from) << 2);
 
         // update row data:
         OffHeapArray _rowAAChunk = rowAAChunk;
@@ -465,6 +464,13 @@ public final class MarlinCache implements MarlinConst {
                             // note: last pixel exclusive (>= 0)
                             // note: it should check X is smaller than 23bits (overflow)!
 
+                            // check address alignment to 4 bytes:
+                            if (doCheckUnsafe) {
+                                if ((addr_off & 3) != 0) {
+                                    MarlinUtils.logInfo("Misaligned Unsafe address: " + addr_off);
+                                }
+                            }
+
                             // special case to encode entries into a single int:
                             if (val == 0) {
                                 _unsafe.putInt(addr_off,
@@ -521,6 +527,13 @@ public final class MarlinCache implements MarlinConst {
         // note: last pixel exclusive (>= 0)
         // note: it should check X is smaller than 23bits (overflow)!
 
+        // check address alignment to 4 bytes:
+        if (doCheckUnsafe) {
+            if ((addr_off & 3) != 0) {
+                MarlinUtils.logInfo("Misaligned Unsafe address: " + addr_off);
+            }
+        }
+
         // special case to encode entries into a single int:
         if (val == 0) {
             _unsafe.putInt(addr_off,
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
index 6ff24a04b64..e799504318d 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
@@ -40,6 +40,8 @@ interface MarlinConst {
     // log misc.Unsafe alloc/realloc/free
     static final boolean logUnsafeMalloc = enableLogs
         && MarlinProperties.isLogUnsafeMalloc();
+    // do check unsafe alignment:
+    static final boolean doCheckUnsafe = false;
 
     // do statistics
     static final boolean doStats = enableLogs && MarlinProperties.isDoStats();

From 5999226f522df00e970dbc84a94f11df0350f605 Mon Sep 17 00:00:00 2001
From: Phil Race <prr@openjdk.org>
Date: Wed, 9 Dec 2015 15:20:39 -0800
Subject: [PATCH 36/62] 8137106: EUDC (End User Defined Characters) are not
 displayed on Windows with Java 8u60+

Reviewed-by: serb, jgodinez
---
 .../share/classes/sun/font/TrueTypeFont.java  | 33 ++++++++++++++-----
 .../classes/sun/awt/Win32FontManager.java     |  2 +-
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java b/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
index c4893b6dd60..7668b6572a8 100644
--- a/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
+++ b/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
@@ -176,6 +176,13 @@ public class TrueTypeFont extends FileFont {
     private String localeFamilyName;
     private String localeFullName;
 
+    public TrueTypeFont(String platname, Object nativeNames, int fIndex,
+                 boolean javaRasterizer)
+        throws FontFormatException
+    {
+        this(platname, nativeNames, fIndex, javaRasterizer, true);
+    }
+
     /**
      * - does basic verification of the file
      * - reads the header table for this font (within a collection)
@@ -186,14 +193,17 @@ public class TrueTypeFont extends FileFont {
      * or fails verification,  or there's no usable cmap
      */
     public TrueTypeFont(String platname, Object nativeNames, int fIndex,
-                 boolean javaRasterizer)
+                 boolean javaRasterizer, boolean useFilePool)
         throws FontFormatException {
         super(platname, nativeNames);
         useJavaRasterizer = javaRasterizer;
         fontRank = Font2D.TTF_RANK;
         try {
-            verify();
+            verify(useFilePool);
             init(fIndex);
+            if (!useFilePool) {
+               close();
+            }
         } catch (Throwable t) {
             close();
             if (t instanceof FontFormatException) {
@@ -280,6 +290,10 @@ public class TrueTypeFont extends FileFont {
     }
 
 
+    private synchronized FileChannel open() throws FontFormatException {
+        return open(true);
+     }
+
     /* This is intended to be called, and the returned value used,
      * from within a block synchronized on this font object.
      * ie the channel returned may be nulled out at any time by "close()"
@@ -287,7 +301,8 @@ public class TrueTypeFont extends FileFont {
      * Deadlock warning: FontManager.addToPool(..) acquires a global lock,
      * which means nested locks may be in effect.
      */
-    private synchronized FileChannel open() throws FontFormatException {
+    private synchronized FileChannel open(boolean usePool)
+                                     throws FontFormatException {
         if (disposerRecord.channel == null) {
             if (FontUtilities.isLogging()) {
                 FontUtilities.getLogger().info("open TTF: " + platName);
@@ -306,9 +321,11 @@ public class TrueTypeFont extends FileFont {
                 });
                 disposerRecord.channel = raf.getChannel();
                 fileSize = (int)disposerRecord.channel.size();
-                FontManager fm = FontManagerFactory.getInstance();
-                if (fm instanceof SunFontManager) {
-                    ((SunFontManager) fm).addToPool(this);
+                if (usePool) {
+                    FontManager fm = FontManagerFactory.getInstance();
+                    if (fm instanceof SunFontManager) {
+                        ((SunFontManager) fm).addToPool(this);
+                    }
                 }
             } catch (NullPointerException e) {
                 close();
@@ -492,8 +509,8 @@ public class TrueTypeFont extends FileFont {
         }
     }
 
-    private void verify() throws FontFormatException {
-        open();
+    private void verify(boolean usePool) throws FontFormatException {
+        open(usePool);
     }
 
     /* sizes, in bytes, of TT/TTC header records */
diff --git a/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java b/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java
index ee50f24a293..815393eaa1c 100644
--- a/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java
@@ -61,7 +61,7 @@ public final class Win32FontManager extends SunFontManager {
                              * enumerate (allow direct use) of EUDC fonts.
                              */
                             eudcFont = new TrueTypeFont(eudcFile, null, 0,
-                                                        true);
+                                                        true, false);
                         } catch (FontFormatException e) {
                         }
                     }

From e03cf9daf6d006a077fa3ee30c5bac5c6e9d91bf Mon Sep 17 00:00:00 2001
From: Xue-Lei Andrew Fan <xuelei@openjdk.org>
Date: Thu, 10 Dec 2015 06:09:36 +0000
Subject: [PATCH 37/62] 8136410: AlgorithmDecomposer is not parsing padding
 correctly

Reviewed-by: weijun
---
 .../security/util/AlgorithmDecomposer.java    |  4 +-
 .../DecomposeAlgorithms.java                  | 71 +++++++++++++++++++
 2 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 jdk/test/sun/security/util/AlgorithmConstraints/DecomposeAlgorithms.java

diff --git a/jdk/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java b/jdk/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java
index 82e61cbb06b..4410a3102be 100644
--- a/jdk/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java
+++ b/jdk/src/java.base/share/classes/sun/security/util/AlgorithmDecomposer.java
@@ -35,8 +35,10 @@ import java.util.regex.Pattern;
 public class AlgorithmDecomposer {
 
     private static final Pattern transPattern = Pattern.compile("/");
+
+    // '(?<!padd)in': match 'in' but not preceded with 'padd'.
     private static final Pattern pattern =
-                    Pattern.compile("with|and|in", Pattern.CASE_INSENSITIVE);
+            Pattern.compile("with|and|(?<!padd)in", Pattern.CASE_INSENSITIVE);
 
     /**
      * Decompose the standard algorithm name into sub-elements.
diff --git a/jdk/test/sun/security/util/AlgorithmConstraints/DecomposeAlgorithms.java b/jdk/test/sun/security/util/AlgorithmConstraints/DecomposeAlgorithms.java
new file mode 100644
index 00000000000..84543d2e041
--- /dev/null
+++ b/jdk/test/sun/security/util/AlgorithmConstraints/DecomposeAlgorithms.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8136410
+ * @summary AlgorithmDecomposer is not parsing padding correctly
+ * @modules java.base/sun.security.util
+ */
+
+import sun.security.util.AlgorithmDecomposer;
+import java.util.Set;
+
+public class DecomposeAlgorithms {
+
+    public static void main(String[] args) throws Exception {
+        AlgorithmDecomposer decomposer = new AlgorithmDecomposer();
+
+        check(decomposer, "AES/CBC/NoPadding", new String[] {
+                "AES", "CBC", "NoPadding"});
+        check(decomposer, "DES/CBC/PKCS5Padding", new String[] {
+                "DES", "CBC", "PKCS5Padding"});
+        check(decomposer, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", new String[] {
+                "RSA", "ECB", "OAEP", "SHA1", "SHA-1", "MGF1Padding"});
+        check(decomposer, "OAEPWithSHA-512AndMGF1Padding", new String[] {
+                "OAEP", "SHA512", "SHA-512", "MGF1Padding"});
+        check(decomposer, "OAEPWithSHA-512AndMGF1Padding", new String[] {
+                "OAEP", "SHA512", "SHA-512", "MGF1Padding"});
+        check(decomposer, "PBEWithSHA1AndRC2_40", new String[] {
+                "PBE", "SHA1", "SHA-1", "RC2_40"});
+        check(decomposer, "PBEWithHmacSHA224AndAES_128", new String[] {
+                "PBE", "HmacSHA224", "AES_128"});
+    }
+
+    private static void check(AlgorithmDecomposer parser,
+            String fullAlgName, String[] components) throws Exception {
+
+        Set<String> parsed = parser.decompose(fullAlgName);
+        if (parsed.size() != components.length) {
+            throw new Exception("Not expected components number: " + parsed);
+        }
+
+        for (String component : components) {
+            if (!parsed.contains(component)) {
+                throw new Exception("Not a expected component: " + component);
+            }
+        }
+
+        System.out.println("OK: " + fullAlgName);
+    }
+}

From edabf4afb36e8fd400f31742aac920a6b2528220 Mon Sep 17 00:00:00 2001
From: Chris Hegarty <chegar@openjdk.org>
Date: Thu, 10 Dec 2015 10:04:41 +0000
Subject: [PATCH 38/62] 8145082: Remove sun.misc.Unsafe dependency from
 sun.nio.cs.StringUTF16

Reviewed-by: psandoz, sherman
---
 jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java b/jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java
index f1608cab5d5..13e1d8cca5a 100644
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java
@@ -25,8 +25,8 @@
 
 package sun.nio.cs;
 
-import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
-import static sun.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
+import static jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
+import static jdk.internal.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
 
 class StringUTF16 {
 
@@ -35,5 +35,5 @@ class StringUTF16 {
                               ARRAY_BYTE_BASE_OFFSET + ARRAY_BYTE_INDEX_SCALE * index * 2L);
     }
 
-    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+    private static final jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
 }

From 7d9d3a469949a3874f35ebacb140e0aaf49c12f0 Mon Sep 17 00:00:00 2001
From: Avik Niyogi <aniyogi@openjdk.org>
Date: Thu, 10 Dec 2015 14:21:44 +0300
Subject: [PATCH 39/62] 8139169: [macosx] Action registered for keyboard
 shortcut is called twice

Reviewed-by: serb, alexsch
---
 .../native/libawt_lwawt/awt/CMenuItem.m       | 300 ++++++++++--------
 .../8139169/ScreenMenuBarInputTwice.java      | 234 ++++++++++++++
 2 files changed, 405 insertions(+), 129 deletions(-)
 create mode 100644 jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java

diff --git a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
index 8e483468074..28e4f386d78 100644
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CMenuItem.m
@@ -24,6 +24,7 @@
  */
 
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
+#include <Carbon/Carbon.h>
 
 #import "CMenuItem.h"
 #import "CMenu.h"
@@ -40,7 +41,7 @@
 @implementation CMenuItem
 
 - (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{
-AWT_ASSERT_APPKIT_THREAD;
+    AWT_ASSERT_APPKIT_THREAD;
     self = [super initWithPeer:peer];
     if (self) {
         if ([asSeparator boolValue]) {
@@ -63,13 +64,48 @@ AWT_ASSERT_APPKIT_THREAD;
 - (BOOL) worksWhenModal {
     return YES;
 }
+// This is a method written using Carbon framework methods to remove
+// All modifiers including "Shift" modifier.
+// Example 1: Shortcut set is "Command Shift m" returns "m"
+// Example 2: Shortcut set is "Command m" returns "m"
+// Example 3: Shortcut set is "Alt Shift ," returns ","
+
+CFStringRef createStringForKey(CGKeyCode keyCode)
+{
+    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+//  currentKeyboard now contains the current input source
+    CFDataRef layoutData =
+    TISGetInputSourceProperty(currentKeyboard,
+                              kTISPropertyUnicodeKeyLayoutData);
+//  the UNICODE keyLayout is fetched from currentKeyboard in layoutData
+    const UCKeyboardLayout *keyboardLayout =
+    (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
+//  A read-only data pointer is fetched from layoutData
+    UInt32 keysDown = 0;
+    UniChar chars[4];
+    UniCharCount realLength;
+    
+    UCKeyTranslate(keyboardLayout,
+                   keyCode,
+                   kUCKeyActionDisplay,
+                   0,
+                   LMGetKbdType(),
+                   kUCKeyTranslateNoDeadKeysBit,
+                   &keysDown,
+                   sizeof(chars) / sizeof(chars[0]),
+                   &realLength,
+                   chars);
+    CFRelease(currentKeyboard);
+//  Converts keyCode, modifier and dead-key state into UNICODE characters
+    return CFStringCreateWithCharacters(kCFAllocatorDefault, chars, 1);
+}
 
 // Events
 - (void)handleAction:(NSMenuItem *)sender {
-AWT_ASSERT_APPKIT_THREAD;
+    AWT_ASSERT_APPKIT_THREAD;
     JNIEnv *env = [ThreadUtilities getJNIEnv];
-JNF_COCOA_ENTER(env);
-
+    JNF_COCOA_ENTER(env);
+    
     // If we are called as a result of user pressing a shortcut, do nothing,
     // because AVTView has already sent corresponding key event to the Java
     // layer from performKeyEquivalent.
@@ -82,31 +118,37 @@ JNF_COCOA_ENTER(env);
     NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
     if ([currEvent type] == NSKeyDown) {
         NSString *menuKey = [sender keyEquivalent];
-        NSString *eventKey = [currEvent charactersIgnoringModifiers];
-
-        // Apple uses characters from private Unicode range for some of the
-        // keys, so we need to do the same translation here that we do
-        // for the regular key down events
-        if ([eventKey length] == 1) {
-            unichar origChar = [eventKey characterAtIndex:0];
-            unichar newChar =  NsCharToJavaChar(origChar, 0);
-            if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) {
-                newChar = origChar;
-            }
-
-            eventKey = [NSString stringWithCharacters: &newChar length: 1];
-        }
-
+//      If shortcut is "Command Shift ," the menuKey gets the value ","
+//      But [currEvent charactersIgnoringModifiers]; returns "<" and not ","
+//      because the charactersIgnoreingModifiers does not ignore "Shift"
+//      So a shortcut like "Command Shift m" will return "M" where as the
+//      MenuKey will have the value "m". To remove this issue the below
+//      createStringForKey is used.
+        NSString *eventKey = createStringForKey([currEvent keyCode]);
+        
+//      Apple uses characters from private Unicode range for some of the
+//      keys, so we need to do the same translation here that we do
+//      for the regular key down events
+                if ([eventKey length] == 1) {
+                    unichar origChar = [eventKey characterAtIndex:0];
+                    unichar newChar =  NsCharToJavaChar(origChar, 0);
+                    if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) {
+                        newChar = origChar;
+                    }
+        
+                    eventKey = [NSString stringWithCharacters: &newChar length: 1];
+                }
+        
         NSWindow *keyWindow = [NSApp keyWindow];
         if ([menuKey isEqualToString:eventKey] && keyWindow != nil) {
             return;
         }
     }
-
+    
     if (fIsCheckbox) {
         static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem");
         static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V");
-
+        
         // Send the opposite of what's currently checked -- the action
         // indicates what state we're going to.
         NSInteger state = [sender state];
@@ -115,26 +157,26 @@ JNF_COCOA_ENTER(env);
     } else {
         static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem");
         static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event)
-
+        
         NSUInteger modifiers = [currEvent modifierFlags];
         jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO);
-
+        
         JNFCallVoidMethod(env, fPeer, jm_handleAction, UTC(currEvent), javaModifiers); // AWT_THREADING Safe (event)
     }
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 - (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
-
+    
     NSUInteger modifierMask = 0;
-
+    
     if (![theKeyEquivalent isEqualToString:@""]) {
         // Force the key equivalent to lower case if not using the shift key.
         // Otherwise AppKit will draw a Shift glyph in the menu.
         if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) == 0) {
             theKeyEquivalent = [theKeyEquivalent lowercaseString];
         }
-
+        
         // Hack for the question mark -- SHIFT and / means use the question mark.
         if ((modifiers & java_awt_event_KeyEvent_SHIFT_MASK) != 0 &&
             [theKeyEquivalent isEqualToString:@"/"])
@@ -142,10 +184,10 @@ JNF_COCOA_EXIT(env);
             theKeyEquivalent = @"?";
             modifiers &= ~java_awt_event_KeyEvent_SHIFT_MASK;
         }
-
+        
         modifierMask = JavaModifiersToNsKeyModifiers(modifiers, NO);
     }
-
+    
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
         [fMenuItem setKeyEquivalent:theKeyEquivalent];
         [fMenuItem setKeyEquivalentModifierMask:modifierMask];
@@ -154,14 +196,14 @@ JNF_COCOA_EXIT(env);
 }
 
 - (void) setJavaImage:(NSImage *)theImage {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [fMenuItem setImage:theImage];
     }];
 }
 
 - (void) setJavaToolTipText:(NSString *)theText {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [fMenuItem setToolTip:theText];
     }];
@@ -169,11 +211,11 @@ JNF_COCOA_EXIT(env);
 
 
 - (void)setJavaEnabled:(BOOL) enabled {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         @synchronized(self) {
             fIsEnabled = enabled;
-
+            
             // Warning:  This won't work if the parent menu is disabled.
             // See [CMenu syncFromJava]. We still need to call it here so
             // the NSMenuItem itself gets properly updated.
@@ -183,7 +225,7 @@ JNF_COCOA_EXIT(env);
 }
 
 - (BOOL)isEnabled {
-
+    
     BOOL enabled = NO;
     @synchronized(self) {
         enabled = fIsEnabled;
@@ -193,7 +235,7 @@ JNF_COCOA_EXIT(env);
 
 
 - (void)setJavaState:(BOOL)newState {
-
+    
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
         [fMenuItem setState:(newState ? NSOnState : NSOffState)];
     }];
@@ -207,7 +249,7 @@ JNF_COCOA_EXIT(env);
 - (void)dealloc {
     [fMenuItem release];
     fMenuItem = nil;
-
+    
     [super dealloc];
 }
 
@@ -240,7 +282,7 @@ JNF_COCOA_EXIT(env);
 /** Convert a Java keycode for SetMenuItemCmd */
 static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
     unichar macKey = 0;
-
+    
     if ((awtKey >= java_awt_event_KeyEvent_VK_0 && awtKey <= java_awt_event_KeyEvent_VK_9) ||
         (awtKey >= java_awt_event_KeyEvent_VK_A && awtKey <= java_awt_event_KeyEvent_VK_Z))
     {
@@ -255,68 +297,68 @@ static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
     } else {
         // Special characters
         switch (awtKey) {
-        case java_awt_event_KeyEvent_VK_BACK_QUOTE      : macKey = '`'; break;
-        case java_awt_event_KeyEvent_VK_QUOTE           : macKey = '\''; break;
-
-        case java_awt_event_KeyEvent_VK_ESCAPE          : macKey = 0x1B; break;
-        case java_awt_event_KeyEvent_VK_SPACE           : macKey = ' '; break;
-        case java_awt_event_KeyEvent_VK_PAGE_UP         : macKey = NSPageUpFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_PAGE_DOWN       : macKey = NSPageDownFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_END             : macKey = NSEndFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_HOME            : macKey = NSHomeFunctionKey; break;
-
-        case java_awt_event_KeyEvent_VK_LEFT            : macKey = NSLeftArrowFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_UP              : macKey = NSUpArrowFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_RIGHT           : macKey = NSRightArrowFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_DOWN            : macKey = NSDownArrowFunctionKey; break;
-
-        case java_awt_event_KeyEvent_VK_COMMA           : macKey = ','; break;
-
-        // Mac OS doesn't distinguish between the two '-' keys...
-        case java_awt_event_KeyEvent_VK_MINUS           :
-        case java_awt_event_KeyEvent_VK_SUBTRACT        : macKey = '-'; break;
-
-        // or the two '.' keys...
-        case java_awt_event_KeyEvent_VK_DECIMAL         :
-        case java_awt_event_KeyEvent_VK_PERIOD          : macKey = '.'; break;
-
-        // or the two '/' keys.
-        case java_awt_event_KeyEvent_VK_DIVIDE          :
-        case java_awt_event_KeyEvent_VK_SLASH           : macKey = '/'; break;
-
-        case java_awt_event_KeyEvent_VK_SEMICOLON       : macKey = ';'; break;
-        case java_awt_event_KeyEvent_VK_EQUALS          : macKey = '='; break;
-
-        case java_awt_event_KeyEvent_VK_OPEN_BRACKET    : macKey = '['; break;
-        case java_awt_event_KeyEvent_VK_BACK_SLASH      : macKey = '\\'; break;
-        case java_awt_event_KeyEvent_VK_CLOSE_BRACKET   : macKey = ']'; break;
-
-        case java_awt_event_KeyEvent_VK_MULTIPLY        : macKey = '*'; break;
-        case java_awt_event_KeyEvent_VK_ADD             : macKey = '+'; break;
-
-        case java_awt_event_KeyEvent_VK_HELP            : macKey = NSHelpFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_TAB             : macKey = NSTabCharacter; break;
-        case java_awt_event_KeyEvent_VK_ENTER           : macKey = NSNewlineCharacter; break;
-        case java_awt_event_KeyEvent_VK_BACK_SPACE      : macKey = NSBackspaceCharacter; break;
-        case java_awt_event_KeyEvent_VK_DELETE          : macKey = NSDeleteCharacter; break;
-        case java_awt_event_KeyEvent_VK_CLEAR           : macKey = NSClearDisplayFunctionKey; break;
-        case java_awt_event_KeyEvent_VK_AMPERSAND       : macKey = '&'; break;
-        case java_awt_event_KeyEvent_VK_ASTERISK        : macKey = '*'; break;
-        case java_awt_event_KeyEvent_VK_QUOTEDBL        : macKey = '\"'; break;
-        case java_awt_event_KeyEvent_VK_LESS            : macKey = '<'; break;
-        case java_awt_event_KeyEvent_VK_GREATER         : macKey = '>'; break;
-        case java_awt_event_KeyEvent_VK_BRACELEFT       : macKey = '{'; break;
-        case java_awt_event_KeyEvent_VK_BRACERIGHT      : macKey = '}'; break;
-        case java_awt_event_KeyEvent_VK_AT              : macKey = '@'; break;
-        case java_awt_event_KeyEvent_VK_COLON           : macKey = ':'; break;
-        case java_awt_event_KeyEvent_VK_CIRCUMFLEX      : macKey = '^'; break;
-        case java_awt_event_KeyEvent_VK_DOLLAR          : macKey = '$'; break;
-        case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
-        case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
-        case java_awt_event_KeyEvent_VK_NUMBER_SIGN     : macKey = '#'; break;
-        case java_awt_event_KeyEvent_VK_PLUS            : macKey = '+'; break;
-        case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
-        case java_awt_event_KeyEvent_VK_UNDERSCORE      : macKey = '_'; break;
+            case java_awt_event_KeyEvent_VK_BACK_QUOTE      : macKey = '`'; break;
+            case java_awt_event_KeyEvent_VK_QUOTE           : macKey = '\''; break;
+                
+            case java_awt_event_KeyEvent_VK_ESCAPE          : macKey = 0x1B; break;
+            case java_awt_event_KeyEvent_VK_SPACE           : macKey = ' '; break;
+            case java_awt_event_KeyEvent_VK_PAGE_UP         : macKey = NSPageUpFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_PAGE_DOWN       : macKey = NSPageDownFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_END             : macKey = NSEndFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_HOME            : macKey = NSHomeFunctionKey; break;
+                
+            case java_awt_event_KeyEvent_VK_LEFT            : macKey = NSLeftArrowFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_UP              : macKey = NSUpArrowFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_RIGHT           : macKey = NSRightArrowFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_DOWN            : macKey = NSDownArrowFunctionKey; break;
+                
+            case java_awt_event_KeyEvent_VK_COMMA           : macKey = ','; break;
+                
+                // Mac OS doesn't distinguish between the two '-' keys...
+            case java_awt_event_KeyEvent_VK_MINUS           :
+            case java_awt_event_KeyEvent_VK_SUBTRACT        : macKey = '-'; break;
+                
+                // or the two '.' keys...
+            case java_awt_event_KeyEvent_VK_DECIMAL         :
+            case java_awt_event_KeyEvent_VK_PERIOD          : macKey = '.'; break;
+                
+                // or the two '/' keys.
+            case java_awt_event_KeyEvent_VK_DIVIDE          :
+            case java_awt_event_KeyEvent_VK_SLASH           : macKey = '/'; break;
+                
+            case java_awt_event_KeyEvent_VK_SEMICOLON       : macKey = ';'; break;
+            case java_awt_event_KeyEvent_VK_EQUALS          : macKey = '='; break;
+                
+            case java_awt_event_KeyEvent_VK_OPEN_BRACKET    : macKey = '['; break;
+            case java_awt_event_KeyEvent_VK_BACK_SLASH      : macKey = '\\'; break;
+            case java_awt_event_KeyEvent_VK_CLOSE_BRACKET   : macKey = ']'; break;
+                
+            case java_awt_event_KeyEvent_VK_MULTIPLY        : macKey = '*'; break;
+            case java_awt_event_KeyEvent_VK_ADD             : macKey = '+'; break;
+                
+            case java_awt_event_KeyEvent_VK_HELP            : macKey = NSHelpFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_TAB             : macKey = NSTabCharacter; break;
+            case java_awt_event_KeyEvent_VK_ENTER           : macKey = NSNewlineCharacter; break;
+            case java_awt_event_KeyEvent_VK_BACK_SPACE      : macKey = NSBackspaceCharacter; break;
+            case java_awt_event_KeyEvent_VK_DELETE          : macKey = NSDeleteCharacter; break;
+            case java_awt_event_KeyEvent_VK_CLEAR           : macKey = NSClearDisplayFunctionKey; break;
+            case java_awt_event_KeyEvent_VK_AMPERSAND       : macKey = '&'; break;
+            case java_awt_event_KeyEvent_VK_ASTERISK        : macKey = '*'; break;
+            case java_awt_event_KeyEvent_VK_QUOTEDBL        : macKey = '\"'; break;
+            case java_awt_event_KeyEvent_VK_LESS            : macKey = '<'; break;
+            case java_awt_event_KeyEvent_VK_GREATER         : macKey = '>'; break;
+            case java_awt_event_KeyEvent_VK_BRACELEFT       : macKey = '{'; break;
+            case java_awt_event_KeyEvent_VK_BRACERIGHT      : macKey = '}'; break;
+            case java_awt_event_KeyEvent_VK_AT              : macKey = '@'; break;
+            case java_awt_event_KeyEvent_VK_COLON           : macKey = ':'; break;
+            case java_awt_event_KeyEvent_VK_CIRCUMFLEX      : macKey = '^'; break;
+            case java_awt_event_KeyEvent_VK_DOLLAR          : macKey = '$'; break;
+            case java_awt_event_KeyEvent_VK_EXCLAMATION_MARK : macKey = '!'; break;
+            case java_awt_event_KeyEvent_VK_LEFT_PARENTHESIS : macKey = '('; break;
+            case java_awt_event_KeyEvent_VK_NUMBER_SIGN     : macKey = '#'; break;
+            case java_awt_event_KeyEvent_VK_PLUS            : macKey = '+'; break;
+            case java_awt_event_KeyEvent_VK_RIGHT_PARENTHESIS: macKey = ')'; break;
+            case java_awt_event_KeyEvent_VK_UNDERSCORE      : macKey = '_'; break;
         }
     }
     return macKey;
@@ -330,27 +372,27 @@ static unichar AWTKeyToMacShortcut(jint awtKey, BOOL doShift) {
 JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
 (JNIEnv *env, jobject peer,
-     jlong menuItemObj, jstring label,
-     jchar shortcutKey, jint shortcutKeyCode, jint mods)
+ jlong menuItemObj, jstring label,
+ jchar shortcutKey, jint shortcutKeyCode, jint mods)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     NSString *theLabel = JNFJavaToNSString(env, label);
     NSString *theKeyEquivalent = nil;
     unichar macKey = shortcutKey;
-
+    
     if (macKey == 0) {
         macKey = AWTKeyToMacShortcut(shortcutKeyCode, (mods & java_awt_event_KeyEvent_SHIFT_MASK) != 0);
     }
-
+    
     if (macKey != 0) {
         unichar equivalent[1] = {macKey};
         theKeyEquivalent = [NSString stringWithCharacters:equivalent length:1];
     } else {
         theKeyEquivalent = @"";
     }
-
+    
     [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaLabel:theLabel shortcut:theKeyEquivalent modifierMask:mods];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -362,10 +404,10 @@ JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeSetTooltip
 (JNIEnv *env, jobject peer, jlong menuItemObj, jstring tooltip)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     NSString *theTooltip = JNFJavaToNSString(env, tooltip);
     [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaToolTipText:theTooltip];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -377,9 +419,9 @@ JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeSetImage
 (JNIEnv *env, jobject peer, jlong menuItemObj, jlong image)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     [((CMenuItem *)jlong_to_ptr(menuItemObj)) setJavaImage:(NSImage*)jlong_to_ptr(image)];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -389,38 +431,38 @@ JNF_COCOA_EXIT(env);
  */
 JNIEXPORT jlong JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeCreate
-    (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
+(JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
 {
-
+    
     CMenuItem *aCMenuItem = nil;
     CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
-JNF_COCOA_ENTER(env);
-
+    JNF_COCOA_ENTER(env);
+    
     jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
-
+    
     NSMutableArray *args = nil;
-
+    
     // Create a new item....
     if (isSeparator == JNI_TRUE) {
         args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES],  nil];
     } else {
         args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO],  nil];
     }
-
+    
     [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];
-
+    
     aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
-
+    
     if (aCMenuItem == nil) {
         return 0L;
     }
-
+    
     // and add it to the parent item.
     [parentCMenu addJavaMenuItem: aCMenuItem];
-
+    
     // setLabel will be called after creation completes.
-
-JNF_COCOA_EXIT(env);
+    
+    JNF_COCOA_EXIT(env);
     return ptr_to_jlong(aCMenuItem);
 }
 
@@ -433,10 +475,10 @@ JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CMenuItem_nativeSetEnabled
 (JNIEnv *env, jobject peer, jlong menuItemObj, jboolean enable)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
     [item setJavaEnabled: (enable == JNI_TRUE)];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -448,10 +490,10 @@ JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetState
 (JNIEnv *env, jobject peer, jlong menuItemObj, jboolean state)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
     [item setJavaState: (state == JNI_TRUE)];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
 
 /*
@@ -463,8 +505,8 @@ JNIEXPORT void JNICALL
 Java_sun_lwawt_macosx_CCheckboxMenuItem_nativeSetIsCheckbox
 (JNIEnv *env, jobject peer, jlong menuItemObj)
 {
-JNF_COCOA_ENTER(env);
+    JNF_COCOA_ENTER(env);
     CMenuItem *item = (CMenuItem *)jlong_to_ptr(menuItemObj);
     [item setIsCheckbox];
-JNF_COCOA_EXIT(env);
+    JNF_COCOA_EXIT(env);
 }
diff --git a/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java b/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java
new file mode 100644
index 00000000000..b591e6bc585
--- /dev/null
+++ b/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8139169
+ * @summary verifies if TextArea gets input twice due to Apple's Screen Menubar
+ * @requires (os.family=="mac")
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main ScreenMenuBarInputTwice
+ */
+import java.awt.BorderLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import static java.awt.event.KeyEvent.VK_COMMA;
+import static java.awt.event.KeyEvent.VK_META;
+import static java.awt.event.KeyEvent.VK_SHIFT;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+import javax.swing.text.BadLocationException;
+
+public class ScreenMenuBarInputTwice {
+
+    public static final String TEST_STRING = "Check string";
+
+    private static Robot robot;
+    private static JFrame frame;
+    private static JPanel content;
+    private static JTextArea textArea;
+    private static JMenuBar menuBar;
+    private static JMenu menu;
+    private static JMenuItem menuItem;
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        createUIWithSeperateMenuBar();
+        robot.delay(2000);
+        shortcutTestCase();
+        robot.delay(2000);
+        cleanUp();
+        createUIWithIntegratedMenuBar();
+        robot.delay(2000);
+        menuTestCase();
+        robot.delay(2000);
+        cleanUp();
+    }
+
+    private static void createUIWithSeperateMenuBar() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                System.setProperty(
+                        "com.apple.mrj.application.apple.menu.about.name",
+                        "A test frame");
+                System.setProperty("apple.laf.useScreenMenuBar", "true");
+                frame = new JFrame("Text input twice check");
+                content = new JPanel(new BorderLayout());
+                textArea = new JTextArea();
+                content.add(new JScrollPane(textArea,
+                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
+                        BorderLayout.CENTER);
+                menuBar = new JMenuBar();
+                frame.setJMenuBar(menuBar);
+                Action a = new AbstractAction("Insert some text") {
+                    @Override
+                    public void actionPerformed(ActionEvent arg0) {
+                        try {
+
+                            textArea.getDocument()
+                                    .insertString(0, TEST_STRING, null);
+                        } catch (BadLocationException e) {
+                            frame.dispose();
+                            throw new RuntimeException("Bad location: ", e);
+                        }
+                    }
+                };
+                KeyStroke keyStroke = KeyStroke.getKeyStroke(
+                        "meta shift COMMA");
+                a.putValue(Action.ACCELERATOR_KEY, keyStroke);
+                textArea.getInputMap().put(keyStroke, "myAction");
+                textArea.getActionMap().put("myAction", a);
+                menu = new JMenu("The Menu");
+                menuItem = new JMenuItem(a);
+                menuItem.setAccelerator((KeyStroke) a.getValue(
+                        Action.ACCELERATOR_KEY));
+                menu.add(menuItem);
+                menuBar.add(menu);
+                frame.getContentPane().add(content);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setLocationRelativeTo(null);
+                frame.setSize(500, 500);
+                frame.setVisible(true);
+                frame.toFront();
+            }
+        });
+    }
+
+    private static void createUIWithIntegratedMenuBar() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                System.setProperty(
+                        "com.apple.mrj.application.apple.menu.about.name",
+                        "A test frame");
+                System.setProperty("apple.laf.useScreenMenuBar", "false");
+                frame = new JFrame("Text input twice check");
+                content = new JPanel(new BorderLayout());
+                textArea = new JTextArea();
+                content.add(new JScrollPane(textArea,
+                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
+                        BorderLayout.CENTER);
+                menuBar = new JMenuBar();
+                frame.setJMenuBar(menuBar);
+                Action a = new AbstractAction("Insert some text") {
+                    @Override
+                    public void actionPerformed(ActionEvent arg0) {
+                        try {
+
+                            textArea.getDocument()
+                                    .insertString(0, TEST_STRING, null);
+                        } catch (BadLocationException e) {
+                            frame.dispose();
+                            throw new RuntimeException("Bad location: ", e);
+                        }
+                    }
+                };
+                KeyStroke keyStroke = KeyStroke.getKeyStroke(
+                        "meta shift COMMA");
+                a.putValue(Action.ACCELERATOR_KEY, keyStroke);
+                textArea.getInputMap().put(keyStroke, "myAction");
+                textArea.getActionMap().put("myAction", a);
+                menu = new JMenu("The Menu");
+                menuItem = new JMenuItem(a);
+                menuItem.setAccelerator((KeyStroke) a.getValue(
+                        Action.ACCELERATOR_KEY));
+                menu.add(menuItem);
+                menuBar.add(menu);
+                frame.getContentPane().add(content);
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setSize(500, 500);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+                frame.toFront();
+            }
+        });
+    }
+
+    private static void shortcutTestCase() throws Exception {
+        robot.keyPress(KeyEvent.VK_META);
+        robot.keyPress(KeyEvent.VK_SHIFT);
+        robot.keyPress(KeyEvent.VK_COMMA);
+        robot.keyRelease(VK_COMMA);
+        robot.keyRelease(VK_SHIFT);
+        robot.keyRelease(VK_META);
+        robot.delay(2000);
+        checkText(textArea.getText());
+    }
+
+    private static void menuTestCase() throws Exception {
+        Point mousePoint;
+        mousePoint = Util.getCenterPoint(menu);
+        robot.mouseMove(mousePoint.x, mousePoint.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(2000);
+        mousePoint = Util.getCenterPoint(menuItem);
+        robot.mouseMove(mousePoint.x, mousePoint.y);
+        robot.delay(2000);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(2000);
+        checkText(textArea.getText());
+    }
+
+    private static void checkText(String text) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                if (TEST_STRING.equals(text)) {
+                    textArea.setText("");
+                } else {
+                    frame.dispose();
+                    throw new RuntimeException("Failed. "
+                            + " Menu item shortcut invoked twice");
+                }
+            }
+        });
+    }
+
+    private static void cleanUp() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+    }
+}

From 946e0bc9cc01c228cb3c9a6b86aa145904788b04 Mon Sep 17 00:00:00 2001
From: Prasanta Sadhukhan <psadhukhan@openjdk.org>
Date: Thu, 10 Dec 2015 16:09:42 +0300
Subject: [PATCH 40/62] 8040139: Test
 closed/javax/print/attribute/Services_getDocFl.java fails with
 NullpointerException

Reviewed-by: jdv, prr
---
 .../classes/sun/print/IPPPrintService.java    |  5 +-
 .../print/attribute/Services_getDocFl.java    | 84 +++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 jdk/test/javax/print/attribute/Services_getDocFl.java

diff --git a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java
index 7782d543219..9587067a750 100644
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java
+++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java
@@ -926,7 +926,10 @@ public class IPPPrintService implements PrintService, SunPrinterJobService {
                 return copyflavors;
             }
         }
-        return null;
+        DocFlavor[] flavor = new DocFlavor[2];
+        flavor[0] = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
+        flavor[1] = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
+        return flavor;
     }
 
 
diff --git a/jdk/test/javax/print/attribute/Services_getDocFl.java b/jdk/test/javax/print/attribute/Services_getDocFl.java
new file mode 100644
index 00000000000..e3f0a850e3f
--- /dev/null
+++ b/jdk/test/javax/print/attribute/Services_getDocFl.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.print.DocFlavor;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.attribute.HashPrintRequestAttributeSet;
+
+/*
+ * @test
+ * @bug 4901243 8040139
+ * @summary JPG, GIF, and PNG DocFlavors (URL) should be supported if Postscript is supported.
+ * @run main Services_getDocFl
+*/
+
+
+public class Services_getDocFl {
+    public static void main (String [] args) {
+
+        HashPrintRequestAttributeSet prSet = null;
+        boolean psSupported = false,
+            pngImagesSupported = false,
+            gifImagesSupported = false,
+            jpgImagesSupported = false;
+        String mimeType;
+
+        PrintService[] serv = PrintServiceLookup.lookupPrintServices(null, null);
+        if (serv.length==0) {
+            System.out.println("no PrintService  found");
+        } else {
+            System.out.println("number of Services "+serv.length);
+        }
+
+
+        for (int i = 0; i<serv.length ;i++) {
+            System.out.println("           PRINT SERVICE: "+ i+" "+serv[i]);
+            DocFlavor[] flavors = serv[i].getSupportedDocFlavors();
+            pngImagesSupported = false;
+            gifImagesSupported = false;
+            jpgImagesSupported = false;
+            for (int j=0; j<flavors.length; j++) {
+                System.out.println(flavors[j]);
+
+                if (flavors[j].equals(DocFlavor.URL.PNG)) {
+                    pngImagesSupported = true;
+                } else if (flavors[j].equals(DocFlavor.URL.GIF)) {
+                    gifImagesSupported = true;
+                } else if (flavors[j].equals(DocFlavor.URL.JPEG)) {
+                    jpgImagesSupported = true;
+                } else if (flavors[j].getMimeType().indexOf("postscript") != -1) {
+                    psSupported = true;
+                }
+            }
+
+            if (psSupported && !(pngImagesSupported && gifImagesSupported &&
+                jpgImagesSupported)) {
+
+                throw new RuntimeException("Error: URL image DocFlavors are not reported as supported");
+            }
+        }
+
+    }
+}
+

From 6f930291df342af57807dfc210e264a104e229eb Mon Sep 17 00:00:00 2001
From: Lana Steuck <lana@openjdk.org>
Date: Thu, 10 Dec 2015 08:17:08 -0800
Subject: [PATCH 41/62] Added tag jdk-9+96 for changeset 25e9d31417fa

---
 jdk/.hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jdk/.hgtags b/jdk/.hgtags
index e1f07ad834d..e4b1c1f57c3 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -338,3 +338,4 @@ b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90
 2f12392d0dde768150c83087cdbdd0d33a4d866c jdk9-b93
 559b626b01179420a94feb9c3d0f246970d2e3fa jdk9-b94
 8581faf0d474472e32f589bbc16db7eec912d83f jdk-9+95
+c021b855f51e572e63982654b17742cb1f814fb4 jdk-9+96

From eb2d3e3a7b73d31c8fe1c856480acf1ced980943 Mon Sep 17 00:00:00 2001
From: Peter Brunet <peter.brunet@oracle.com>
Date: Thu, 10 Dec 2015 12:16:29 -0600
Subject: [PATCH 42/62] 8071334: Investigate JAB changes required to support
 the version string change

Remove use of java.version property; no longer needed

Reviewed-by: van, alexsch
---
 .../accessibility/util/AWTEventMonitor.java   | 20 ++-----------------
 .../accessibility/internal/AccessBridge.java  | 10 ++--------
 2 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
index 7b0f8c29e06..257bbb72953 100644
--- a/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
+++ b/jdk/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java
@@ -48,8 +48,6 @@ import sun.awt.AWTPermissions;
 @jdk.Exported
 public class AWTEventMonitor {
 
-    static private boolean runningOnJDK1_4 = false;
-
     /**
      * The current component with keyboard focus.
      *
@@ -638,15 +636,9 @@ public class AWTEventMonitor {
          * @see AWTEventMonitor
          */
         public AWTEventsListener() {
-            String version = System.getProperty("java.version");
-            if (version != null) {
-                runningOnJDK1_4 = (version.compareTo("1.4") >= 0);
-            }
             initializeIntrospection();
             installListeners();
-            if (runningOnJDK1_4) {
-                MenuSelectionManager.defaultManager().addChangeListener(this);
-            }
+            MenuSelectionManager.defaultManager().addChangeListener(this);
             EventQueueMonitor.addTopLevelWindowListener(this);
         }
 
@@ -848,15 +840,7 @@ public class AWTEventMonitor {
             case EventID.FOCUS:
                 c.removeFocusListener(this);
                 c.addFocusListener(this);
-
-                if (runningOnJDK1_4) {
-                    processFocusGained();
-
-                } else {        // not runningOnJDK1_4
-                    if ((c != componentWithFocus_private) && c.hasFocus()) {
-                        componentWithFocus_private = c;
-                    }
-                }
+                processFocusGained();
                 break;
 
             case EventID.ITEM:
diff --git a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java
index ee1a63f5ec9..47832a4455b 100644
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java
@@ -140,10 +140,6 @@ final public class AccessBridge {
         // initialize AccessibleRole map
         initAccessibleRoleMap();
 
-        // determine which version of the JDK is running
-        String version = getJavaVersionProperty();
-        debugString("JDK version = "+version);
-
         // initialize the methods that map HWNDs and Java top-level
         // windows
         initHWNDcalls();
@@ -215,9 +211,7 @@ final public class AccessBridge {
         } catch (Exception e) {}
 
     /*
-      Build the extendedVirtualNameSearchRoles array list.  I chose this method
-      because some of the Accessible Roles that need to be added to it are not
-      available in all versions of the J2SE that we want to support.
+      Build the extendedVirtualNameSearchRoles array list.
     */
     extendedVirtualNameSearchRoles.add (AccessibleRole.COMBO_BOX);
     try {
@@ -5919,7 +5913,7 @@ final public class AccessBridge {
      */
     AccessibleRole.UNKNOWN,
 
-    // These roles are only available in JDK 1.4
+    // These roles are available since JDK 1.4
 
     /**
      * A STATUS_BAR is an simple component that can contain

From c588dd42dd368d2ef8b6350ec6766c5837c3b39a Mon Sep 17 00:00:00 2001
From: Phil Race <prr@openjdk.org>
Date: Thu, 10 Dec 2015 12:51:08 -0800
Subject: [PATCH 43/62] 8144858: HBShaper.c does not compiler with VS2010

Reviewed-by: serb, simonis
---
 .../share/native/libfontmanager/HBShaper.c    | 22 ++++++++++---------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
index 422575cb165..00c6ee1fa44 100644
--- a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
+++ b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
@@ -80,15 +80,18 @@ int storeGVData(JNIEnv* env,
     float scale = 1.0f/64.0f;
     unsigned int* glyphs;
     float* positions;
+    int initialCount, glyphArrayLen, posArrayLen, maxGlyphs, storeadv;
+    unsigned int* indices;
+    jarray glyphArray, posArray, inxArray;
 
     if (!init_JNI_IDs(env)) {
         return 0;
     }
 
-    int initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
-    jarray glyphArray =
+    initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
+    glyphArray =
        (jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
-    jarray posArray =
+    posArray =
         (jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
 
     if (glyphArray == NULL || posArray == NULL)
@@ -101,9 +104,9 @@ int storeGVData(JNIEnv* env,
     // and re-invokes layout. I suppose this is expected to be rare
     // because at least in a single threaded case there should be
     // re-use of the same container, but it is a little wasteful/distateful.
-    int glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
-    int posArrayLen = (*env)->GetArrayLength(env, posArray);
-    int maxGlyphs = glyphCount + initialCount;
+    glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
+    posArrayLen = (*env)->GetArrayLength(env, posArray);
+    maxGlyphs = glyphCount + initialCount;
     if ((maxGlyphs >  glyphArrayLen) ||
         (maxGlyphs * 2 + 2 >  posArrayLen))
     {
@@ -125,7 +128,7 @@ int storeGVData(JNIEnv* env,
         x += glyphPos[i].x_advance * scale;
         y += glyphPos[i].y_advance * scale;
     }
-    int storeadv = initialCount+glyphCount;
+    storeadv = initialCount+glyphCount;
     // The final slot in the positions array is important
     // because when the GlyphVector is created from this
     // data it determines the overall advance of the glyphvector
@@ -138,11 +141,10 @@ int storeGVData(JNIEnv* env,
     (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
     (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
     putFloat(env, startPt,positions[(storeadv*2)],positions[(storeadv*2)+1] );
-    jarray inxArray =
+    inxArray =
         (jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
-    unsigned int* indices =
+    indices =
         (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
-    int prevCluster = -1;
     for (i = 0; i < glyphCount; i++) {
         int cluster = glyphInfo[i].cluster;
         if (direction == HB_DIRECTION_LTR) {

From bb10c3f0de78a4672b09296c90d3e54fe5fd22ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20Bourg=C3=A8s?= <lbourges@openjdk.org>
Date: Thu, 10 Dec 2015 15:45:18 -0800
Subject: [PATCH 44/62] 8144446: Automate the Marlin crash test

Reviewed-by: prr, flar
---
 .../classes/sun/java2d/marlin/Renderer.java   |  7 +++
 jdk/test/sun/java2d/marlin/CrashTest.java     | 59 ++++++++++---------
 2 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
index d4aa005eadb..f59785cd92f 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
@@ -629,6 +629,13 @@ final class Renderer implements PathConsumer2D, MarlinConst {
         }
 
         if (edgeMinY != Float.POSITIVE_INFINITY) {
+            // if context is maked as DIRTY:
+            if (rdrCtx.dirty) {
+                // may happen if an exception if thrown in the pipeline processing:
+                // clear completely buckets arrays:
+                buckets_minY = 0;
+                buckets_maxY = boundsMaxY - boundsMinY;
+            }
             // clear used part
             if (edgeBuckets == edgeBuckets_initial) {
                 // fill only used part
diff --git a/jdk/test/sun/java2d/marlin/CrashTest.java b/jdk/test/sun/java2d/marlin/CrashTest.java
index b5f760a65e3..b5283fdf332 100644
--- a/jdk/test/sun/java2d/marlin/CrashTest.java
+++ b/jdk/test/sun/java2d/marlin/CrashTest.java
@@ -31,31 +31,44 @@ import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import javax.imageio.ImageIO;
-import sun.java2d.pipe.RenderingEngine;
 
 /**
- * Simple crash rendering test using huge GeneralPaths with marlin renderer
- *
- * run it with large heap (2g):
- * java -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine marlin.CrashTest
- *
- * @author bourgesl
- */
+ * @test
+ * @summary Simple crash rendering test using huge GeneralPaths with the Marlin renderer
+ * @run main/othervm -mx512m CrashTest
+ * @ignore tests that take a long time and consumes 5Gb memory
+ * @run main/othervm -ms4g -mx4g CrashTest -slow
+*/
 public class CrashTest {
 
     static final boolean SAVE_IMAGE = false;
     static boolean USE_ROUND_CAPS_AND_JOINS = true;
 
     public static void main(String[] args) {
+        boolean runSlowTests = (args.length != 0 && "-slow".equals(args[0]));
+
+        // First display which renderer is tested:
+        System.setProperty("sun.java2d.renderer.verbose", "true");
+
         // try insane image sizes:
 
         // subpixel coords may overflow:
-//        testHugeImage((Integer.MAX_VALUE >> 3) + 1, 6);
+        // check MAX_VALUE / (8 * 2); overflow may happen due to orientation flag
+        // But as it is impossible to allocate an image larger than 2Gb (byte) then
+        // it is also impossible to have rowAAChunk larger than 2Gb !
+
+        // Disabled test as it consumes 4GB heap + offheap (2Gb) ie > 6Gb !
+        if (runSlowTests) {
+            testHugeImage((Integer.MAX_VALUE >> 4) - 100, 16);
+        }
+
         // larger than 23 bits: (RLE)
         testHugeImage(8388608 + 1, 10);
 
-        test(0.1f, false, 0);
-        test(0.1f, true, 7f);
+        if (runSlowTests) {
+            test(0.1f, false, 0);
+            test(0.1f, true, 7f);
+        }
 
         // Exceed 2Gb OffHeap buffer for edges:
         try {
@@ -67,17 +80,15 @@ public class CrashTest {
             if (th instanceof ArrayIndexOutOfBoundsException) {
                 System.out.println("ArrayIndexOutOfBoundsException expected.");
             } else {
-                System.out.println("Exception occured:");
-                th.printStackTrace();
+                throw new RuntimeException("Unexpected exception", th);
             }
         }
-
     }
 
     private static void test(final float lineStroke,
                              final boolean useDashes,
                              final float dashMinLen)
-    throws ArrayIndexOutOfBoundsException
+        throws ArrayIndexOutOfBoundsException
     {
         System.out.println("---\n" + "test: "
             + "lineStroke=" + lineStroke
@@ -85,9 +96,6 @@ public class CrashTest {
             +", dashMinLen=" + dashMinLen
         );
 
-        final String renderer = RenderingEngine.getInstance().getClass().getSimpleName();
-        System.out.println("Testing renderer = " + renderer);
-
         final BasicStroke stroke = createStroke(lineStroke, useDashes, dashMinLen);
 
         // TODO: test Dasher.firstSegmentsBuffer resizing ?
@@ -135,7 +143,7 @@ public class CrashTest {
 
             if (SAVE_IMAGE) {
                 try {
-                    final File file = new File("CrashTest-" + renderer + "-dash-" + useDashes + ".bmp");
+                    final File file = new File("CrashTest-dash-" + useDashes + ".bmp");
 
                     System.out.println("Writing file: " + file.getAbsolutePath());
                     ImageIO.write(image, "BMP", file);
@@ -150,15 +158,10 @@ public class CrashTest {
     }
 
     private static void testHugeImage(final int width, final int height)
-    throws ArrayIndexOutOfBoundsException
+        throws ArrayIndexOutOfBoundsException
     {
         System.out.println("---\n" + "testHugeImage: "
-            + "width=" + width
-            + ", height=" + height
-        );
-
-        final String renderer = RenderingEngine.getInstance().getClass().getSimpleName();
-        System.out.println("Testing renderer = " + renderer);
+            + "width=" + width + ", height=" + height);
 
         final BasicStroke stroke = createStroke(2.5f, false, 0);
 
@@ -195,8 +198,8 @@ public class CrashTest {
 
             if (SAVE_IMAGE) {
                 try {
-                    final File file = new File("CrashTest-" + renderer +
-                                               "-huge-" + width + "x" +height + ".bmp");
+                    final File file = new File("CrashTest-huge-"
+                        + width + "x" +height + ".bmp");
 
                     System.out.println("Writing file: " + file.getAbsolutePath());
                     ImageIO.write(image, "BMP", file);

From 80222f5b67383332c7c7ba63eaa6f40bbc30181f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20Bourg=C3=A8s?= <lbourges@openjdk.org>
Date: Thu, 10 Dec 2015 15:52:14 -0800
Subject: [PATCH 45/62] 8144445: Maximum size checking in Marlin ArrayCache
 utility methods is not optimal

Reviewed-by: prr, flar
---
 .../classes/sun/java2d/marlin/ArrayCache.java |  38 +++--
 .../classes/sun/java2d/marlin/Stroker.java    |   5 +-
 .../sun/java2d/marlin/ArrayCacheSizeTest.java | 131 ++++++++++++++++++
 3 files changed, 161 insertions(+), 13 deletions(-)
 create mode 100644 jdk/test/sun/java2d/marlin/ArrayCacheSizeTest.java

diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java
index bc4bc54d0d5..e518c4d2261 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ArrayCache.java
@@ -166,18 +166,31 @@ public final class ArrayCache implements MarlinConst {
      * @return new array size
      */
     public static int getNewSize(final int curSize, final int needSize) {
+        // check if needSize is negative or integer overflow:
+        if (needSize < 0) {
+            // hard overflow failure - we can't even accommodate
+            // new items without overflowing
+            throw new ArrayIndexOutOfBoundsException(
+                          "array exceeds maximum capacity !");
+        }
+        assert curSize >= 0;
         final int initial = (curSize & MASK_CLR_1);
         int size;
         if (initial > THRESHOLD_ARRAY_SIZE) {
             size = initial + (initial >> 1); // x(3/2)
         } else {
-            size = (initial) << 1; // x2
+            size = (initial << 1); // x2
         }
         // ensure the new size is >= needed size:
         if (size < needSize) {
-            // align to 4096:
+            // align to 4096 (may overflow):
             size = ((needSize >> 12) + 1) << 12;
         }
+        // check integer overflow:
+        if (size < 0) {
+            // resize to maximum capacity:
+            size = Integer.MAX_VALUE;
+        }
         return size;
     }
 
@@ -188,26 +201,29 @@ public final class ArrayCache implements MarlinConst {
      * @return new array size
      */
     public static long getNewLargeSize(final long curSize, final long needSize) {
+        // check if needSize is negative or integer overflow:
+        if ((needSize >> 31L) != 0L) {
+            // hard overflow failure - we can't even accommodate
+            // new items without overflowing
+            throw new ArrayIndexOutOfBoundsException(
+                          "array exceeds maximum capacity !");
+        }
+        assert curSize >= 0L;
         long size;
         if (curSize > THRESHOLD_HUGE_ARRAY_SIZE) {
             size = curSize + (curSize >> 2L); // x(5/4)
         } else  if (curSize > THRESHOLD_LARGE_ARRAY_SIZE) {
             size = curSize + (curSize >> 1L); // x(3/2)
         } else {
-            size = curSize << 1L; // x2
+            size = (curSize << 1L); // x2
         }
         // ensure the new size is >= needed size:
         if (size < needSize) {
             // align to 4096:
-            size = ((needSize >> 12) + 1) << 12;
+            size = ((needSize >> 12L) + 1L) << 12L;
         }
-        if (size >= Integer.MAX_VALUE) {
-            if (curSize >= Integer.MAX_VALUE) {
-                // hard overflow failure - we can't even accommodate
-                // new items without overflowing
-                throw new ArrayIndexOutOfBoundsException(
-                              "array exceeds maximum capacity !");
-            }
+        // check integer overflow:
+        if (size > Integer.MAX_VALUE) {
             // resize to maximum capacity:
             size = Integer.MAX_VALUE;
         }
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java
index 76c93494d57..1aa48411f04 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java
@@ -1265,14 +1265,15 @@ final class Stroker implements PathConsumer2D, MarlinConst {
         }
 
         private void ensureSpace(final int n) {
-            if (end + n > curves.length) {
+            // use substraction to avoid integer overflow:
+            if (curves.length - end < n) {
                 if (doStats) {
                     RendererContext.stats.stat_array_stroker_polystack_curves
                         .add(end + n);
                 }
                 curves = rdrCtx.widenDirtyFloatArray(curves, end, end + n);
             }
-            if (numCurves + 1 > curveTypes.length) {
+            if (curveTypes.length <= numCurves) {
                 if (doStats) {
                     RendererContext.stats.stat_array_stroker_polystack_curveTypes
                         .add(numCurves + 1);
diff --git a/jdk/test/sun/java2d/marlin/ArrayCacheSizeTest.java b/jdk/test/sun/java2d/marlin/ArrayCacheSizeTest.java
new file mode 100644
index 00000000000..8c40fe4cfae
--- /dev/null
+++ b/jdk/test/sun/java2d/marlin/ArrayCacheSizeTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import sun.java2d.marlin.ArrayCache;
+
+/**
+ * @test
+ * @bug 8144445
+ * @summary Check the ArrayCache getNewLargeSize() method
+ * @run main ArrayCacheSizeTest
+ */
+public class ArrayCacheSizeTest {
+
+    public static void main(String[] args) {
+        testNewSize();
+        testNewLargeSize();
+    }
+
+    private static void testNewSize() {
+        testNewSize(0, 1);
+        testNewSize(0, 100000);
+
+        testNewSize(4096, 4097);
+        testNewSize(4096 * 16, 4096 * 16 + 1);
+
+        testNewSize(4096 * 4096 * 4, 4096 * 4096 * 4 + 1);
+
+        testNewSize(4096 * 4096 * 4, Integer.MAX_VALUE);
+
+        testNewSize(Integer.MAX_VALUE - 1000, Integer.MAX_VALUE);
+
+        testNewSizeExpectAIOB(Integer.MAX_VALUE - 1000, Integer.MAX_VALUE + 1);
+        testNewSizeExpectAIOB(1, -1);
+        testNewSizeExpectAIOB(Integer.MAX_VALUE, -1);
+    }
+
+    private static void testNewSizeExpectAIOB(final int curSize,
+                                              final int needSize) {
+        try {
+            testNewSize(curSize, needSize);
+            throw new RuntimeException("ArrayIndexOutOfBoundsException not thrown");
+        } catch (ArrayIndexOutOfBoundsException aiobe) {
+            System.out.println("ArrayIndexOutOfBoundsException expected.");
+        } catch (RuntimeException re) {
+            throw re;
+        } catch (Throwable th) {
+            throw new RuntimeException("Unexpected exception", th);
+        }
+    }
+
+    private static void testNewSize(final int curSize,
+                                    final int needSize) {
+
+        int size = ArrayCache.getNewSize(curSize, needSize);
+
+        System.out.println("getNewSize(" + curSize + ", " + needSize
+            + ") = " + size);
+
+        if (size < 0 || size < needSize) {
+            throw new IllegalStateException("Invalid getNewSize("
+                + curSize + ", " + needSize + ") = " + size + " !");
+        }
+    }
+
+    private static void testNewLargeSize() {
+        testNewLargeSize(0, 1);
+        testNewLargeSize(0, 100000);
+
+        testNewLargeSize(4096, 4097);
+        testNewLargeSize(4096 * 16, 4096 * 16 + 1);
+
+        testNewLargeSize(4096 * 4096 * 4, 4096 * 4096 * 4 + 1);
+
+        testNewLargeSize(4096 * 4096 * 4, Integer.MAX_VALUE);
+
+        testNewLargeSize(Integer.MAX_VALUE - 1000, Integer.MAX_VALUE);
+
+        testNewLargeSizeExpectAIOB(Integer.MAX_VALUE - 1000, Integer.MAX_VALUE + 1L);
+        testNewLargeSizeExpectAIOB(1, -1L);
+        testNewLargeSizeExpectAIOB(Integer.MAX_VALUE, -1L);
+    }
+
+    private static void testNewLargeSizeExpectAIOB(final long curSize,
+                                                   final long needSize) {
+        try {
+            testNewLargeSize(curSize, needSize);
+            throw new RuntimeException("ArrayIndexOutOfBoundsException not thrown");
+        } catch (ArrayIndexOutOfBoundsException aiobe) {
+            System.out.println("ArrayIndexOutOfBoundsException expected.");
+        } catch (RuntimeException re) {
+            throw re;
+        } catch (Throwable th) {
+            throw new RuntimeException("Unexpected exception", th);
+        }
+    }
+
+    private static void testNewLargeSize(final long curSize,
+                                         final long needSize) {
+
+        long size = ArrayCache.getNewLargeSize(curSize, needSize);
+
+        System.out.println("getNewLargeSize(" + curSize + ", " + needSize
+            + ") = " + size);
+
+        if (size < 0 || size < needSize || size > Integer.MAX_VALUE) {
+            throw new IllegalStateException("Invalid getNewLargeSize("
+                + curSize + ", " + needSize + ") = " + size + " !");
+        }
+    }
+
+}

From 583937011af76bd244566791f598991fbd7cd995 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20Bourg=C3=A8s?= <lbourges@openjdk.org>
Date: Thu, 10 Dec 2015 15:58:01 -0800
Subject: [PATCH 46/62] 8144654: Improve Marlin logging

Reviewed-by: prr, flar
---
 .../sun/java2d/marlin/ByteArrayCache.java     |  4 ++--
 .../sun/java2d/marlin/FloatArrayCache.java    |  4 ++--
 .../sun/java2d/marlin/IntArrayCache.java      |  4 ++--
 .../sun/java2d/marlin/MarlinConst.java        |  9 ++++----
 .../sun/java2d/marlin/MarlinProperties.java   |  4 ++++
 .../sun/java2d/marlin/MarlinUtils.java        | 22 ++++---------------
 .../sun/java2d/marlin/RendererContext.java    | 22 +++++++------------
 7 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java
index cd6ebee89e8..226a3d2e30d 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/ByteArrayCache.java
@@ -74,7 +74,7 @@ final class ByteArrayCache implements MarlinConst {
     void putDirtyArray(final byte[] array, final int length) {
         if (length != arraySize) {
             if (doChecks) {
-                System.out.println("ArrayCache: bad length = " + length);
+                MarlinUtils.logInfo("ArrayCache: bad length = " + length);
             }
             return;
         }
@@ -98,7 +98,7 @@ final class ByteArrayCache implements MarlinConst {
     {
         if (length != arraySize) {
             if (doChecks) {
-                System.out.println("ArrayCache: bad length = " + length);
+                MarlinUtils.logInfo("ArrayCache: bad length = " + length);
             }
             return;
         }
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java
index a068ad80fbc..06d7f351e28 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatArrayCache.java
@@ -75,7 +75,7 @@ final class FloatArrayCache implements MarlinConst {
     void putDirtyArray(final float[] array, final int length) {
         if (length != arraySize) {
             if (doChecks) {
-                System.out.println("ArrayCache: bad length = " + length);
+                MarlinUtils.logInfo("ArrayCache: bad length = " + length);
             }
             return;
         }
@@ -99,7 +99,7 @@ final class FloatArrayCache implements MarlinConst {
     {
         if (length != arraySize) {
             if (doChecks) {
-                System.out.println("ArrayCache: bad length = " + length);
+                MarlinUtils.logInfo("ArrayCache: bad length = " + length);
             }
             return;
         }
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java
index ccd239cb534..11c5aae84f6 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/IntArrayCache.java
@@ -74,7 +74,7 @@ final class IntArrayCache implements MarlinConst {
     void putDirtyArray(final int[] array, final int length) {
         if (length != arraySize) {
             if (doChecks) {
-                System.out.println("ArrayCache: bad length = " + length);
+                MarlinUtils.logInfo("ArrayCache: bad length = " + length);
             }
             return;
         }
@@ -98,7 +98,7 @@ final class IntArrayCache implements MarlinConst {
     {
         if (length != arraySize) {
             if (doChecks) {
-                System.out.println("ArrayCache: bad length = " + length);
+                MarlinUtils.logInfo("ArrayCache: bad length = " + length);
             }
             return;
         }
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
index e799504318d..72993ebfd7c 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinConst.java
@@ -30,8 +30,8 @@ package sun.java2d.marlin;
  */
 interface MarlinConst {
     // enable Logs (logger or stdout)
-    static final boolean enableLogs = false;
-    // enable Logger
+    static final boolean enableLogs = MarlinProperties.isLoggingEnabled();
+    // use Logger instead of stdout
     static final boolean useLogger = enableLogs && MarlinProperties.isUseLogger();
 
     // log new RendererContext
@@ -47,9 +47,10 @@ interface MarlinConst {
     static final boolean doStats = enableLogs && MarlinProperties.isDoStats();
     // do monitors
     // disabled to reduce byte-code size a bit...
-    static final boolean doMonitors = enableLogs && false; // MarlinProperties.isDoMonitors();
+    static final boolean doMonitors = false;
+//    static final boolean doMonitors = enableLogs && MarlinProperties.isDoMonitors();
     // do checks
-    static final boolean doChecks = false; // MarlinProperties.isDoChecks();
+    static final boolean doChecks = enableLogs && MarlinProperties.isDoChecks();
 
     // do AA range checks: disable when algorithm / code is stable
     static final boolean DO_AA_RANGE_CHECK = false;
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java
index 002f16d9d5b..bbee15a13fb 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java
@@ -136,6 +136,10 @@ public final class MarlinProperties {
 
     // logging parameters
 
+    public static boolean isLoggingEnabled() {
+        return getBoolean("sun.java2d.renderer.log", "false");
+    }
+
     public static boolean isUseLogger() {
         return getBoolean("sun.java2d.renderer.useLogger", "false");
     }
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java
index d218d06f545..aeeacca57bd 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java
@@ -27,12 +27,12 @@ package sun.java2d.marlin;
 
 
 public final class MarlinUtils {
-    // TODO: use sun.util.logging.PlatformLogger once in JDK9
-    private static final java.util.logging.Logger log;
+    // Marlin logger
+    private static final sun.util.logging.PlatformLogger log;
 
     static {
         if (MarlinConst.useLogger) {
-            log = java.util.logging.Logger.getLogger("sun.java2d.marlin");
+            log = sun.util.logging.PlatformLogger.getLogger("sun.java2d.marlin");
         } else {
             log = null;
         }
@@ -53,25 +53,11 @@ public final class MarlinUtils {
 
     public static void logException(final String msg, final Throwable th) {
         if (MarlinConst.useLogger) {
-//            log.warning(msg, th);
-            log.log(java.util.logging.Level.WARNING, msg, th);
+            log.warning(msg, th);
         } else if (MarlinConst.enableLogs) {
             System.out.print("WARNING: ");
             System.out.println(msg);
             th.printStackTrace(System.err);
         }
     }
-
-    // Returns the caller's class and method's name; best effort
-    // if cannot infer, return the logger's name.
-    static String getCallerInfo(String className) {
-        String sourceClassName = null;
-        String sourceMethodName = null;
-
-        if (sourceClassName != null) {
-            return sourceClassName + " " + sourceMethodName;
-        } else {
-            return "unknown";
-        }
-    }
 }
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
index 7af675b16b7..a767651f5d5 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
@@ -31,7 +31,6 @@ import java.lang.ref.WeakReference;
 import java.util.concurrent.atomic.AtomicInteger;
 import static sun.java2d.marlin.ArrayCache.*;
 import sun.java2d.marlin.MarlinRenderingEngine.NormalizingPathIterator;
-import static sun.java2d.marlin.MarlinUtils.getCallerInfo;
 import static sun.java2d.marlin.MarlinUtils.logInfo;
 
 /**
@@ -39,7 +38,6 @@ import static sun.java2d.marlin.MarlinUtils.logInfo;
  */
 final class RendererContext implements MarlinConst {
 
-    private static final String className = RendererContext.class.getName();
     // RendererContext creation counter
     private static final AtomicInteger contextCount = new AtomicInteger(1);
     // RendererContext statistics
@@ -214,8 +212,7 @@ final class RendererContext implements MarlinConst {
         }
 
         if (doLogOverSize) {
-            logInfo("getDirtyByteArray[oversize]: length=\t" + length
-                    + "\tfrom=\t" + getCallerInfo(className));
+            logInfo("getDirtyByteArray[oversize]: length=\t" + length);
         }
 
         return new byte[length];
@@ -254,7 +251,7 @@ final class RendererContext implements MarlinConst {
         if (doLogWidenArray) {
             logInfo("widenDirtyByteArray[" + res.length + "]: usedSize=\t"
                     + usedSize + "\tlength=\t" + length + "\tneeded length=\t"
-                    + needSize + "\tfrom=\t" + getCallerInfo(className));
+                    + needSize);
         }
         return res;
     }
@@ -275,8 +272,7 @@ final class RendererContext implements MarlinConst {
         }
 
         if (doLogOverSize) {
-            logInfo("getIntArray[oversize]: length=\t" + length + "\tfrom=\t"
-                    + getCallerInfo(className));
+            logInfo("getIntArray[oversize]: length=\t" + length);
         }
 
         return new int[length];
@@ -306,7 +302,7 @@ final class RendererContext implements MarlinConst {
         if (doLogWidenArray) {
             logInfo("widenIntArray[" + res.length + "]: usedSize=\t"
                     + usedSize + "\tlength=\t" + length + "\tneeded length=\t"
-                    + needSize + "\tfrom=\t" + getCallerInfo(className));
+                    + needSize);
         }
         return res;
     }
@@ -338,8 +334,7 @@ final class RendererContext implements MarlinConst {
         }
 
         if (doLogOverSize) {
-            logInfo("getDirtyIntArray[oversize]: length=\t" + length
-                    + "\tfrom=\t" + getCallerInfo(className));
+            logInfo("getDirtyIntArray[oversize]: length=\t" + length);
         }
 
         return new int[length];
@@ -369,7 +364,7 @@ final class RendererContext implements MarlinConst {
         if (doLogWidenArray) {
             logInfo("widenDirtyIntArray[" + res.length + "]: usedSize=\t"
                     + usedSize + "\tlength=\t" + length + "\tneeded length=\t"
-                    + needSize + "\tfrom=\t" + getCallerInfo(className));
+                    + needSize);
         }
         return res;
     }
@@ -399,8 +394,7 @@ final class RendererContext implements MarlinConst {
         }
 
         if (doLogOverSize) {
-            logInfo("getDirtyFloatArray[oversize]: length=\t" + length
-                    + "\tfrom=\t" + getCallerInfo(className));
+            logInfo("getDirtyFloatArray[oversize]: length=\t" + length);
         }
 
         return new float[length];
@@ -430,7 +424,7 @@ final class RendererContext implements MarlinConst {
         if (doLogWidenArray) {
             logInfo("widenDirtyFloatArray[" + res.length + "]: usedSize=\t"
                     + usedSize + "\tlength=\t" + length + "\tneeded length=\t"
-                    + needSize + "\tfrom=\t" + getCallerInfo(className));
+                    + needSize);
         }
         return res;
     }

From 5b1765f25dc24d89046d2acf08859b68301d145e Mon Sep 17 00:00:00 2001
From: Brian Burkhalter <bpb@openjdk.org>
Date: Fri, 11 Dec 2015 11:38:18 -0800
Subject: [PATCH 47/62] 8144245: [PIT]
 javax/imageio/plugins/shared/WriteAfterAbort.java

Reset stream position after abort; change IAEs to NPEs.

Reviewed-by: prr, serb
---
 .../com/sun/imageio/plugins/tiff/TIFFIFD.java |   9 +-
 .../imageio/plugins/tiff/TIFFImageWriter.java |  56 ++-
 jdk/test/ProblemList.txt                      |   2 -
 .../plugins/shared/WriteAfterAbort.java       |  16 +-
 .../tiff/WriteToSequenceAfterAbort.java       | 376 ++++++++++++++++++
 5 files changed, 449 insertions(+), 10 deletions(-)
 create mode 100644 jdk/test/javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java

diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
index 6803f634762..7c14f8daf85 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
@@ -472,6 +472,13 @@ public class TIFFIFD extends TIFFDirectory {
             // Read tag number, value type, and value count.
             int tagNumber = stream.readUnsignedShort();
             int type = stream.readUnsignedShort();
+            int sizeOfType;
+            try {
+                sizeOfType = TIFFTag.getSizeOfType(type);
+            } catch (IllegalArgumentException e) {
+                throw new IIOException("Illegal type " + type
+                    + " for tag number " + tagNumber, e);
+            }
             int count = (int)stream.readUnsignedInt();
 
             // Get the associated TIFFTag.
@@ -510,7 +517,7 @@ public class TIFFIFD extends TIFFDirectory {
                 }
             }
 
-            int size = count*TIFFTag.getSizeOfType(type);
+            int size = count*sizeOfType;
             if (size > 4 || tag.isIFDPointer()) {
                 // The IFD entry value is a pointer to the actual field value.
                 long offset = stream.readUnsignedInt();
diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
index 08c1f0ecb9a..6a90e0677c9 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
@@ -205,6 +205,10 @@ public class TIFFImageWriter extends ImageWriter {
     // Next available space.
     private long nextSpace = 0L;
 
+    private long prevStreamPosition;
+    private long prevHeaderPosition;
+    private long prevNextSpace;
+
     // Whether a sequence is being written.
     private boolean isWritingSequence = false;
     private boolean isInsertingEmpty = false;
@@ -2300,7 +2304,14 @@ public class TIFFImageWriter extends ImageWriter {
     public void write(IIOMetadata sm,
                       IIOImage iioimage,
                       ImageWriteParam p) throws IOException {
+        if (stream == null) {
+            throw new IllegalStateException("output == null!");
+        }
+        markPositions();
         write(sm, iioimage, p, true, true);
+        if (abortRequested()) {
+            resetPositions();
+        }
     }
 
     private void writeHeader() throws IOException {
@@ -2333,7 +2344,7 @@ public class TIFFImageWriter extends ImageWriter {
             throw new IllegalStateException("output == null!");
         }
         if (iioimage == null) {
-            throw new NullPointerException("image == null!");
+            throw new IllegalArgumentException("image == null!");
         }
         if(iioimage.hasRaster() && !canWriteRasters()) {
             throw new UnsupportedOperationException
@@ -2767,7 +2778,7 @@ public class TIFFImageWriter extends ImageWriter {
             throw new IllegalStateException("Output not set!");
         }
         if (image == null) {
-            throw new NullPointerException("image == null!");
+            throw new IllegalArgumentException("image == null!");
         }
 
         // Locate the position of the old IFD (ifd) and the location
@@ -2779,9 +2790,16 @@ public class TIFFImageWriter extends ImageWriter {
         // imageIndex is < -1 or is too big thereby satisfying the spec.
         locateIFD(imageIndex, ifdpos, ifd);
 
+        markPositions();
+
         // Seek to the position containing the pointer to the old IFD.
         stream.seek(ifdpos[0]);
 
+        // Save the previous pointer value in case of abort.
+        stream.mark();
+        long prevPointerValue = stream.readUnsignedInt();
+        stream.reset();
+
         // Update next space pointer in anticipation of next write.
         if(ifdpos[0] + 4 > nextSpace) {
             nextSpace = ifdpos[0] + 4;
@@ -2805,6 +2823,12 @@ public class TIFFImageWriter extends ImageWriter {
         // Update the new IFD to point to the old IFD.
         stream.writeInt((int)ifd[0]);
         // Don't need to update nextSpace here as already done in write().
+
+        if (abortRequested()) {
+            stream.seek(ifdpos[0]);
+            stream.writeInt((int)prevPointerValue);
+            resetPositions();
+        }
     }
 
     // ----- BEGIN insert/writeEmpty methods -----
@@ -2834,7 +2858,7 @@ public class TIFFImageWriter extends ImageWriter {
         }
 
         if(imageType == null) {
-            throw new NullPointerException("imageType == null!");
+            throw new IllegalArgumentException("imageType == null!");
         }
 
         if(width < 1 || height < 1) {
@@ -2891,6 +2915,10 @@ public class TIFFImageWriter extends ImageWriter {
                                   IIOMetadata imageMetadata,
                                   List<? extends BufferedImage> thumbnails,
                                   ImageWriteParam param) throws IOException {
+        if (stream == null) {
+            throw new IllegalStateException("output == null!");
+        }
+
         checkParamsEmpty(imageType, width, height, thumbnails);
 
         this.isWritingEmpty = true;
@@ -2901,8 +2929,12 @@ public class TIFFImageWriter extends ImageWriter {
                            0, 0, emptySM.getWidth(), emptySM.getHeight(),
                            emptySM, imageType.getColorModel());
 
+        markPositions();
         write(streamMetadata, new IIOImage(emptyImage, null, imageMetadata),
               param, true, false);
+        if (abortRequested()) {
+            resetPositions();
+        }
     }
 
     public void endInsertEmpty() throws IOException {
@@ -3015,7 +3047,7 @@ public class TIFFImageWriter extends ImageWriter {
                 throw new IllegalStateException("Output not set!");
             }
             if (region == null) {
-                throw new NullPointerException("region == null!");
+                throw new IllegalArgumentException("region == null!");
             }
             if (region.getWidth() < 1) {
                 throw new IllegalArgumentException("region.getWidth() < 1!");
@@ -3200,7 +3232,7 @@ public class TIFFImageWriter extends ImageWriter {
             }
 
             if (image == null) {
-                throw new NullPointerException("image == null!");
+                throw new IllegalArgumentException("image == null!");
             }
 
             if (!inReplacePixelsNest) {
@@ -3559,6 +3591,20 @@ public class TIFFImageWriter extends ImageWriter {
 
     // ----- END replacePixels methods -----
 
+    // Save stream positions for use when aborted.
+    private void markPositions() throws IOException {
+        prevStreamPosition = stream.getStreamPosition();
+        prevHeaderPosition = headerPosition;
+        prevNextSpace = nextSpace;
+    }
+
+    // Reset to positions saved by markPositions().
+    private void resetPositions() throws IOException {
+        stream.seek(prevStreamPosition);
+        headerPosition = prevHeaderPosition;
+        nextSpace = prevNextSpace;
+    }
+
     public void reset() {
         super.reset();
 
diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index 51abaacbf53..2a18c6adef2 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -310,8 +310,6 @@ javax/sound/midi/Gervill/SoftProvider/GetDevice.java            generic-all
 
 # jdk_imageio
 
-javax/imageio/plugins/shared/WriteAfterAbort.java               generic-all
-
 ############################################################################
 
 # jdk_swing
diff --git a/jdk/test/javax/imageio/plugins/shared/WriteAfterAbort.java b/jdk/test/javax/imageio/plugins/shared/WriteAfterAbort.java
index 4b503d2fe6f..f1be068cdfe 100644
--- a/jdk/test/javax/imageio/plugins/shared/WriteAfterAbort.java
+++ b/jdk/test/javax/imageio/plugins/shared/WriteAfterAbort.java
@@ -130,13 +130,25 @@ public final class WriteAfterAbort implements IIOWriteProgressListener {
                 ImageWriterSpi.class, provider -> true, true);
 
         // Validates all supported ImageWriters
+        int numFailures = 0;
         while (iter.hasNext()) {
             final WriteAfterAbort writeAfterAbort = new WriteAfterAbort();
             final ImageWriter writer = iter.next().createWriterInstance();
             System.out.println("ImageWriter = " + writer);
-            writeAfterAbort.test(writer);
+            try {
+                writeAfterAbort.test(writer);
+            } catch (Exception e) {
+                System.err.println("Test failed for \""
+                    + writer.getOriginatingProvider().getFormatNames()[0]
+                    + "\" format.");
+                numFailures++;
+            }
+        }
+        if (numFailures == 0) {
+            System.out.println("Test passed.");
+        } else {
+            throw new RuntimeException("Test failed.");
         }
-        System.out.println("Test passed");
     }
 
     // Callbacks
diff --git a/jdk/test/javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java b/jdk/test/javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java
new file mode 100644
index 00000000000..55461f36f24
--- /dev/null
+++ b/jdk/test/javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.stream.ImageOutputStream;
+
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.Vector;
+import javax.imageio.IIOImage;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+/**
+ * @test
+ * @bug 8144245
+ * @summary Ensure aborting write works properly for a TIFF sequence.
+ */
+public final class WriteToSequenceAfterAbort implements IIOWriteProgressListener {
+
+    private volatile boolean abortFlag = true;
+    private volatile boolean isAbortCalled;
+    private volatile boolean isCompleteCalled;
+    private volatile boolean isProgressCalled;
+    private volatile boolean isStartedCalled;
+    private static final int WIDTH = 100;
+    private static final int HEIGHT = 100;
+    private static final int NUM_TILES_XY = 3;
+
+    private class TiledImage implements RenderedImage {
+        private final BufferedImage tile;
+        private final BufferedImage image;
+        private final int numXTiles, numYTiles;
+        private boolean isImageInitialized = false;
+
+        TiledImage(BufferedImage tile, int numXTiles, int numYTiles) {
+            this.tile = tile;
+            this.numXTiles = numXTiles;
+            this.numYTiles = numYTiles;
+            image = new BufferedImage(getWidth(), getHeight(), tile.getType());
+        }
+
+        @Override
+        public Vector<RenderedImage> getSources() {
+            return null;
+        }
+
+        @Override
+        public Object getProperty(String string) {
+            return java.awt.Image.UndefinedProperty;
+        }
+
+        @Override
+        public String[] getPropertyNames() {
+            return new String[0];
+        }
+
+        @Override
+        public ColorModel getColorModel() {
+            return tile.getColorModel();
+        }
+
+        @Override
+        public SampleModel getSampleModel() {
+            return tile.getSampleModel();
+        }
+
+        @Override
+        public int getWidth() {
+            return numXTiles*tile.getWidth();
+        }
+
+        @Override
+        public int getHeight() {
+            return numYTiles*tile.getHeight();
+        }
+
+        @Override
+        public int getMinX() {
+            return 0;
+        }
+
+        @Override
+        public int getMinY() {
+            return 0;
+        }
+
+        @Override
+        public int getNumXTiles() {
+            return numXTiles;
+        }
+
+        @Override
+        public int getNumYTiles() {
+            return numYTiles;
+        }
+
+        @Override
+        public int getMinTileX() {
+            return 0;
+        }
+
+        @Override
+        public int getMinTileY() {
+            return 0;
+        }
+
+        @Override
+        public int getTileWidth() {
+            return tile.getWidth();
+        }
+
+        @Override
+        public int getTileHeight() {
+            return tile.getHeight();
+        }
+
+        @Override
+        public int getTileGridXOffset() {
+            return 0;
+        }
+
+        @Override
+        public int getTileGridYOffset() {
+            return 0;
+        }
+
+        @Override
+        public Raster getTile(int x, int y) {
+            WritableRaster r = tile.getRaster();
+            return r.createWritableTranslatedChild(x*tile.getWidth(),
+                y*tile.getHeight());
+        }
+
+        @Override
+        public Raster getData() {
+            return getAsBufferedImage().getData();
+        }
+
+        @Override
+        public Raster getData(Rectangle r) {
+            return getAsBufferedImage().getData(r);
+        }
+
+        @Override
+        public WritableRaster copyData(WritableRaster wr) {
+            return getAsBufferedImage().copyData(wr);
+        }
+
+        public BufferedImage getAsBufferedImage() {
+            synchronized (image) {
+                if (!isImageInitialized) {
+                    int tx0 = getMinTileX(), ty0 = getMinTileY();
+                    int txN = tx0 + getNumXTiles(), tyN = ty0 + getNumYTiles();
+                    for (int j = ty0; j < tyN; j++) {
+                        for (int i = tx0; i < txN; i++) {
+                            image.setData(getTile(i, j));
+                        }
+                    }
+                }
+                isImageInitialized = true;
+            }
+            return image;
+        }
+    }
+
+    private void test(final ImageWriter writer) throws IOException {
+        String suffix = writer.getOriginatingProvider().getFileSuffixes()[0];
+
+        // Image initialization
+        BufferedImage imageUpperLeft =
+                new BufferedImage(WIDTH, HEIGHT, TYPE_BYTE_BINARY);
+        Graphics2D g = imageUpperLeft.createGraphics();
+        g.setColor(Color.WHITE);
+        g.fillRect(0, 0, WIDTH/2, HEIGHT/2);
+        g.dispose();
+        BufferedImage imageLowerRight =
+                new BufferedImage(WIDTH, HEIGHT, TYPE_BYTE_BINARY);
+        g = imageLowerRight.createGraphics();
+        g.setColor(Color.WHITE);
+        g.fillRect(WIDTH/2, HEIGHT/2, WIDTH/2, HEIGHT/2);
+        g.dispose();
+        TiledImage[] images = new TiledImage[] {
+            new TiledImage(imageUpperLeft, NUM_TILES_XY, NUM_TILES_XY),
+            new TiledImage(imageUpperLeft, NUM_TILES_XY, NUM_TILES_XY),
+            new TiledImage(imageLowerRight, NUM_TILES_XY, NUM_TILES_XY),
+            new TiledImage(imageLowerRight, NUM_TILES_XY, NUM_TILES_XY)
+        };
+
+        // File initialization
+        File file = File.createTempFile("temp", "." + suffix);
+        file.deleteOnExit();
+        FileOutputStream fos = new SkipWriteOnAbortOutputStream(file);
+        ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
+        writer.setOutput(ios);
+        writer.addIIOWriteProgressListener(this);
+
+        writer.prepareWriteSequence(null);
+        boolean[] abortions = new boolean[] {true, false, true, false};
+        for (int i = 0; i < 4; i++) {
+            abortFlag = abortions[i];
+            isAbortCalled = false;
+            isCompleteCalled = false;
+            isProgressCalled = false;
+            isStartedCalled = false;
+
+            TiledImage image = images[i];
+            if (abortFlag) {
+                // This write will be aborted, and file will not be touched
+                writer.writeToSequence(new IIOImage(image, null, null), null);
+                if (!isStartedCalled) {
+                    throw new RuntimeException("Started should be called");
+                }
+                if (!isProgressCalled) {
+                    throw new RuntimeException("Progress should be called");
+                }
+                if (!isAbortCalled) {
+                    throw new RuntimeException("Abort should be called");
+                }
+                if (isCompleteCalled) {
+                    throw new RuntimeException("Complete should not be called");
+                }
+            } else {
+                // This write should be completed successfully and the file should
+                // contain correct image data.
+                writer.writeToSequence(new IIOImage(image, null, null), null);
+                if (!isStartedCalled) {
+                    throw new RuntimeException("Started should be called");
+                }
+                if (!isProgressCalled) {
+                    throw new RuntimeException("Progress should be called");
+                }
+                if (isAbortCalled) {
+                    throw new RuntimeException("Abort should not be called");
+                }
+                if (!isCompleteCalled) {
+                    throw new RuntimeException("Complete should be called");
+                }
+            }
+        }
+
+        writer.endWriteSequence();
+        writer.dispose();
+        ios.close();
+
+        // Validates content of the file.
+        ImageReader reader = ImageIO.getImageReader(writer);
+        ImageInputStream iis = ImageIO.createImageInputStream(file);
+        reader.setInput(iis);
+        for (int i = 0; i < 2; i++) {
+            System.out.println("Testing image " + i);
+            BufferedImage imageRead = reader.read(i);
+            BufferedImage imageWrite = images[2 * i].getAsBufferedImage();
+            for (int x = 0; x < WIDTH; ++x) {
+                for (int y = 0; y < HEIGHT; ++y) {
+                    if (imageRead.getRGB(x, y) != imageWrite.getRGB(x, y)) {
+                        throw new RuntimeException("Test failed for image " + i);
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(final String[] args) throws IOException {
+        WriteToSequenceAfterAbort writeAfterAbort = new WriteToSequenceAfterAbort();
+        ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
+        writeAfterAbort.test(writer);
+        System.out.println("Test passed.");
+    }
+
+    // Callbacks
+
+    @Override
+    public void imageComplete(ImageWriter source) {
+        isCompleteCalled = true;
+    }
+
+    @Override
+    public void imageProgress(ImageWriter source, float percentageDone) {
+        isProgressCalled = true;
+        if (percentageDone > 50 && abortFlag) {
+            source.abort();
+        }
+    }
+
+    @Override
+    public void imageStarted(ImageWriter source, int imageIndex) {
+        isStartedCalled = true;
+    }
+
+    @Override
+    public void writeAborted(final ImageWriter source) {
+        isAbortCalled = true;
+    }
+
+    @Override
+    public void thumbnailComplete(ImageWriter source) {
+    }
+
+    @Override
+    public void thumbnailProgress(ImageWriter source, float percentageDone) {
+    }
+
+    @Override
+    public void thumbnailStarted(ImageWriter source, int imageIndex,
+                                 int thumbnailIndex) {
+    }
+
+    /**
+     * We need to skip writes on abort, because content of the file after abort
+     * is undefined.
+     */
+    private class SkipWriteOnAbortOutputStream extends FileOutputStream {
+
+        SkipWriteOnAbortOutputStream(File file) throws FileNotFoundException {
+            super(file);
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            if (!abortFlag) {
+                super.write(b);
+            }
+        }
+
+        @Override
+        public void write(byte[] b) throws IOException {
+            if (!abortFlag) {
+                super.write(b);
+            }
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            if (!abortFlag) {
+                super.write(b, off, len);
+            }
+        }
+    }
+}
+

From a3e2ce543cd9e7c283ef7a44905bbf829e913969 Mon Sep 17 00:00:00 2001
From: Brian Burkhalter <bpb@openjdk.org>
Date: Fri, 11 Dec 2015 15:07:35 -0800
Subject: [PATCH 48/62] 8144997: "IIOException: Field data is past
 end-of-stream" when calling TIFFImageReader.read()

Instead of failing for an IFD entry with bad type or offset, continue with the next entry.

Reviewed-by: prr
---
 .../classes/com/sun/imageio/plugins/tiff/TIFFIFD.java    | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
index 7c14f8daf85..e8f4a5d05b3 100644
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFIFD.java
@@ -475,9 +475,10 @@ public class TIFFIFD extends TIFFDirectory {
             int sizeOfType;
             try {
                 sizeOfType = TIFFTag.getSizeOfType(type);
-            } catch (IllegalArgumentException e) {
-                throw new IIOException("Illegal type " + type
-                    + " for tag number " + tagNumber, e);
+            } catch (IllegalArgumentException ignored) {
+                // Continue with the next IFD entry.
+                stream.skipBytes(4);
+                continue;
             }
             int count = (int)stream.readUnsignedInt();
 
@@ -524,7 +525,7 @@ public class TIFFIFD extends TIFFDirectory {
 
                 // Check whether the the field value is within the stream.
                 if (haveStreamLength && offset + size > streamLength) {
-                    throw new IIOException("Field data is past end-of-stream");
+                    continue;
                 }
 
                 // Add a TIFFIFDEntry as a placeholder. This avoids a mark,

From fb053862e58eb8380bb65f96e04afa99cf6342d8 Mon Sep 17 00:00:00 2001
From: Sebastian Sickelmann <sebastian@openjdk.org>
Date: Tue, 15 Dec 2015 17:35:27 +0100
Subject: [PATCH 49/62] 4906983: java.net.URL constructors throw
 MalformedURLException in undocumented way

Added some testcases for the corner-cases in question and clarified javadoc

Reviewed-by: chegar, msheppar
---
 .../java.base/share/classes/java/net/URL.java | 24 +++++++++++------
 jdk/test/java/net/URL/TestPort.java           | 27 +++++++++++--------
 2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/jdk/src/java.base/share/classes/java/net/URL.java b/jdk/src/java.base/share/classes/java/net/URL.java
index 1a32a236ba0..73e488831a5 100644
--- a/jdk/src/java.base/share/classes/java/net/URL.java
+++ b/jdk/src/java.base/share/classes/java/net/URL.java
@@ -310,7 +310,8 @@ public final class URL implements java.io.Serializable {
      * @param      host       the name of the host.
      * @param      port       the port number on the host.
      * @param      file       the file on the host
-     * @exception  MalformedURLException  if an unknown protocol is specified.
+     * @exception  MalformedURLException  if an unknown protocol or the port
+     *                  is a negative number other than -1
      * @see        java.lang.System#getProperty(java.lang.String)
      * @see        java.net.URL#setURLStreamHandlerFactory(
      *                  java.net.URLStreamHandlerFactory)
@@ -329,9 +330,9 @@ public final class URL implements java.io.Serializable {
      * name, {@code host} name, and {@code file} name. The
      * default port for the specified protocol is used.
      * <p>
-     * This method is equivalent to calling the four-argument
-     * constructor with the arguments being {@code protocol},
-     * {@code host}, {@code -1}, and {@code file}.
+     * This constructor is equivalent to the four-argument
+     * constructor with the only difference of using the
+     * default port for the specified protocol.
      *
      * No validation of the inputs is performed by this constructor.
      *
@@ -372,7 +373,8 @@ public final class URL implements java.io.Serializable {
      * @param      port       the port number on the host.
      * @param      file       the file on the host
      * @param      handler    the stream handler for the URL.
-     * @exception  MalformedURLException  if an unknown protocol is specified.
+     * @exception  MalformedURLException  if an unknown protocol or the port
+                        is a negative number other than -1
      * @exception  SecurityException
      *        if a security manager exists and its
      *        {@code checkPermission} method doesn't allow
@@ -446,7 +448,9 @@ public final class URL implements java.io.Serializable {
      *
      * @param      spec   the {@code String} to parse as a URL.
      * @exception  MalformedURLException  if no protocol is specified, or an
-     *               unknown protocol is found, or {@code spec} is {@code null}.
+     *               unknown protocol is found, or {@code spec} is {@code null},
+     *               or the parsed URL fails to comply with the specific syntax
+     *               of the associated protocol.
      * @see        java.net.URL#URL(java.net.URL, java.lang.String)
      */
     public URL(String spec) throws MalformedURLException {
@@ -493,7 +497,9 @@ public final class URL implements java.io.Serializable {
      * @param      context   the context in which to parse the specification.
      * @param      spec      the {@code String} to parse as a URL.
      * @exception  MalformedURLException  if no protocol is specified, or an
-     *               unknown protocol is found, or {@code spec} is {@code null}.
+     *               unknown protocol is found, or {@code spec} is {@code null},
+     *               or the parsed URL fails to comply with the specific syntax
+     *               of the associated protocol.
      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
      *                  int, java.lang.String)
      * @see        java.net.URLStreamHandler
@@ -513,7 +519,9 @@ public final class URL implements java.io.Serializable {
      * @param      spec      the {@code String} to parse as a URL.
      * @param      handler   the stream handler for the URL.
      * @exception  MalformedURLException  if no protocol is specified, or an
-     *               unknown protocol is found, or {@code spec} is {@code null}.
+     *               unknown protocol is found, or {@code spec} is {@code null},
+     *               or the parsed URL fails to comply with the specific syntax
+     *               of the associated protocol.
      * @exception  SecurityException
      *        if a security manager exists and its
      *        {@code checkPermission} method doesn't allow
diff --git a/jdk/test/java/net/URL/TestPort.java b/jdk/test/java/net/URL/TestPort.java
index ece89b48194..e018b658a19 100644
--- a/jdk/test/java/net/URL/TestPort.java
+++ b/jdk/test/java/net/URL/TestPort.java
@@ -23,28 +23,33 @@
 
 /*
  * @test
- * @bug 4101492 4444213
+ * @bug 4101492 4444213 4906983
  * @summary The java.net.URL constructor allows port < 0 and port > 65535
  */
 
 import java.net.*;
 
 public class TestPort {
-    public static void main(String[] args) {
-        URL url = null;
+    public static void main(String[] args) throws MalformedURLException {
+        // URLs are able to have port bigger than TCP-Port 65535 and
+        // to have no port (-1) at all.:
+        URL url = new URL("http","server",Integer.MAX_VALUE,"/path");
+        url = new URL("http://server:"+Integer.MAX_VALUE+"/path");
+        url = new URL("http://server/path");
+        url = new URL("http","server",-1,"/path");
+
         try {
             url = new URL("ftp", "java.sun.com", -20, "/pub/");
-        } catch (MalformedURLException e) {
-            url = null;
-        }
-        if (url != null)
             throw new RuntimeException("MalformedURLException not thrown!");
+        } catch (MalformedURLException e) {
+            // Everything fine. MalformedURLException expected
+        }
+
         try {
             url = new URL("ftp://java.sun.com:-20/pub/");
-        } catch (MalformedURLException e) {
-            url = null;
-        }
-        if (url != null)
             throw new RuntimeException("MalformedURLException not thrown!");
+        } catch (MalformedURLException e) {
+            // Everything fine. MalformedURLException expected
+        }
     }
 }

From 5f1918e76e199d1eec5d5e3cc89c5a43079093f3 Mon Sep 17 00:00:00 2001
From: Claes Redestad <redestad@openjdk.org>
Date: Mon, 21 Dec 2015 20:54:00 +0100
Subject: [PATCH 50/62] 8145680: Remove unnecessary explicit initialization of
 volatile variables in java.base

Reviewed-by: alanb, chegar, jfranck, shade
---
 .../classes/sun/nio/ch/EPollSelectorImpl.java |  3 +-
 .../com/sun/crypto/provider/SunJCE.java       |  2 +-
 .../classes/java/io/PipedInputStream.java     |  6 ++--
 .../share/classes/java/lang/Class.java        | 27 ++++++++++--------
 .../share/classes/java/lang/System.java       | 11 ++++----
 .../share/classes/java/lang/Thread.java       |  8 ++----
 .../classes/java/lang/ref/ReferenceQueue.java |  2 +-
 .../classes/java/lang/reflect/Parameter.java  |  4 +--
 .../java.base/share/classes/java/net/URI.java | 13 ++++-----
 .../share/classes/java/nio/Bits.java          |  5 ++--
 .../java/nio/channels/SelectionKey.java       |  4 +--
 .../spi/AbstractInterruptibleChannel.java     | 18 +++++-------
 .../classes/java/nio/charset/Charset.java     |  6 ++--
 .../classes/java/security/SecureRandom.java   | 10 ++++---
 .../classes/java/text/DateFormatSymbols.java  |  8 ++++--
 .../java/text/DecimalFormatSymbols.java       |  8 +-----
 .../share/classes/java/util/Locale.java       | 28 ++++++++++---------
 .../classes/java/util/regex/Pattern.java      | 16 +++++------
 .../share/classes/java/util/zip/ZipFile.java  |  6 ++--
 .../jdk/internal/logger/LazyLoggers.java      | 10 ++++---
 .../java.base/share/classes/sun/misc/VM.java  |  7 ++---
 .../classes/sun/net/www/http/HttpCapture.java | 10 +++----
 .../classes/sun/net/www/http/HttpClient.java  |  2 +-
 .../AsynchronousServerSocketChannelImpl.java  | 10 +++----
 .../nio/ch/AsynchronousSocketChannelImpl.java | 12 ++++----
 .../sun/nio/ch/DatagramChannelImpl.java       |  4 +--
 .../sun/nio/ch/DatagramSocketAdaptor.java     |  2 +-
 .../classes/sun/nio/ch/FileLockImpl.java      | 10 +++----
 .../classes/sun/nio/ch/MembershipKeyImpl.java |  7 ++---
 .../share/classes/sun/nio/ch/Net.java         |  3 +-
 .../sun/nio/ch/ServerSocketAdaptor.java       |  2 +-
 .../sun/nio/ch/ServerSocketChannelImpl.java   |  2 +-
 .../classes/sun/nio/ch/SocketAdaptor.java     |  4 +--
 .../classes/sun/nio/ch/SocketChannelImpl.java |  4 +--
 .../share/classes/sun/nio/ch/Util.java        |  9 ++----
 .../classes/sun/nio/cs/StreamDecoder.java     | 10 +++----
 .../classes/sun/nio/cs/StreamEncoder.java     | 10 +++----
 .../sun/reflect/MethodAccessorGenerator.java  |  6 ++--
 .../AnnotationInvocationHandler.java          |  2 +-
 .../sun/security/ssl/SSLSessionImpl.java      |  2 +-
 .../sun/security/x509/X509CRLImpl.java        | 17 ++++++-----
 .../sun/util/calendar/CalendarSystem.java     |  9 +-----
 .../classes/sun/util/locale/BaseLocale.java   |  6 ++--
 .../provider/JRELocaleProviderAdapter.java    | 24 ++++++++--------
 .../provider/LocaleProviderAdapter.java       |  2 +-
 .../resources/OpenListResourceBundle.java     |  2 +-
 .../classes/sun/nio/ch/SinkChannelImpl.java   |  2 +-
 .../classes/sun/nio/ch/SourceChannelImpl.java |  2 +-
 .../sun/nio/fs/MimeTypesFileTypeDetector.java |  2 +-
 .../sun/nio/ch/WindowsSelectorImpl.java       |  2 +-
 50 files changed, 181 insertions(+), 200 deletions(-)

diff --git a/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java b/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
index 1528b9e16b8..d9ae5ebe334 100644
--- a/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
+++ b/jdk/src/java.base/linux/classes/sun/nio/ch/EPollSelectorImpl.java
@@ -29,7 +29,6 @@ import java.io.IOException;
 import java.nio.channels.*;
 import java.nio.channels.spi.*;
 import java.util.*;
-import sun.misc.*;
 
 /**
  * An implementation of Selector for Linux 2.6+ kernels that uses
@@ -50,7 +49,7 @@ class EPollSelectorImpl
     private Map<Integer,SelectionKeyImpl> fdToKey;
 
     // True if this Selector has been closed
-    private volatile boolean closed = false;
+    private volatile boolean closed;
 
     // Lock for interrupt triggering and clearing
     private final Object interruptLock = new Object();
diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
index b2352b48603..089a662dce5 100644
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java
@@ -93,7 +93,7 @@ public final class SunJCE extends Provider {
 
     // Instance of this provider, so we don't have to call the provider list
     // to find ourselves or run the risk of not being in the list.
-    private static volatile SunJCE instance = null;
+    private static volatile SunJCE instance;
 
     // lazy initialize SecureRandom to avoid potential recursion if Sun
     // provider has not been installed yet
diff --git a/jdk/src/java.base/share/classes/java/io/PipedInputStream.java b/jdk/src/java.base/share/classes/java/io/PipedInputStream.java
index 7f27fde0893..b55c1b08b75 100644
--- a/jdk/src/java.base/share/classes/java/io/PipedInputStream.java
+++ b/jdk/src/java.base/share/classes/java/io/PipedInputStream.java
@@ -48,9 +48,9 @@ package java.io;
  * @since   1.0
  */
 public class PipedInputStream extends InputStream {
-    boolean closedByWriter = false;
-    volatile boolean closedByReader = false;
-    boolean connected = false;
+    boolean closedByWriter;
+    volatile boolean closedByReader;
+    boolean connected;
 
         /* REMIND: identification of the read and write sides needs to be
            more sophisticated.  Either using thread groups (but what about
diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java
index 77913c3187d..013b5843a1e 100644
--- a/jdk/src/java.base/share/classes/java/lang/Class.java
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java
@@ -2518,7 +2518,7 @@ public final class Class<T> implements java.io.Serializable,
 
     // Incremented by the VM on each call to JVM TI RedefineClasses()
     // that redefines this class or a superclass.
-    private transient volatile int classRedefinedCount = 0;
+    private transient volatile int classRedefinedCount;
 
     // Lazily create and cache ReflectionData
     private ReflectionData<T> reflectionData() {
@@ -3331,7 +3331,8 @@ public final class Class<T> implements java.io.Serializable,
      * uncloned, cached, and shared by all callers.
      */
     T[] getEnumConstantsShared() {
-        if (enumConstants == null) {
+        T[] constants = enumConstants;
+        if (constants == null) {
             if (!isEnum()) return null;
             try {
                 final Method values = getMethod("values");
@@ -3344,16 +3345,16 @@ public final class Class<T> implements java.io.Serializable,
                         });
                 @SuppressWarnings("unchecked")
                 T[] temporaryConstants = (T[])values.invoke(null);
-                enumConstants = temporaryConstants;
+                enumConstants = constants = temporaryConstants;
             }
             // These can happen when users concoct enum-like classes
             // that don't comply with the enum spec.
             catch (InvocationTargetException | NoSuchMethodException |
                    IllegalAccessException ex) { return null; }
         }
-        return enumConstants;
+        return constants;
     }
-    private transient volatile T[] enumConstants = null;
+    private transient volatile T[] enumConstants;
 
     /**
      * Returns a map from simple name to enum constant.  This package-private
@@ -3363,19 +3364,21 @@ public final class Class<T> implements java.io.Serializable,
      * created lazily on first use.  Typically it won't ever get created.
      */
     Map<String, T> enumConstantDirectory() {
-        if (enumConstantDirectory == null) {
+        Map<String, T> directory = enumConstantDirectory;
+        if (directory == null) {
             T[] universe = getEnumConstantsShared();
             if (universe == null)
                 throw new IllegalArgumentException(
                     getName() + " is not an enum type");
-            Map<String, T> m = new HashMap<>(2 * universe.length);
-            for (T constant : universe)
-                m.put(((Enum<?>)constant).name(), constant);
-            enumConstantDirectory = m;
+            directory = new HashMap<>(2 * universe.length);
+            for (T constant : universe) {
+                directory.put(((Enum<?>)constant).name(), constant);
+            }
+            enumConstantDirectory = directory;
         }
-        return enumConstantDirectory;
+        return directory;
     }
-    private transient volatile Map<String, T> enumConstantDirectory = null;
+    private transient volatile Map<String, T> enumConstantDirectory;
 
     /**
      * Casts an object to the class or interface represented
diff --git a/jdk/src/java.base/share/classes/java/lang/System.java b/jdk/src/java.base/share/classes/java/lang/System.java
index cf44391082c..ea3ad405cfc 100644
--- a/jdk/src/java.base/share/classes/java/lang/System.java
+++ b/jdk/src/java.base/share/classes/java/lang/System.java
@@ -132,7 +132,7 @@ public final class System {
 
     /* The security manager for the system.
      */
-    private static volatile SecurityManager security = null;
+    private static volatile SecurityManager security;
 
     /**
      * Reassigns the "standard" input stream.
@@ -206,7 +206,7 @@ public final class System {
         setErr0(err);
     }
 
-    private static volatile Console cons = null;
+    private static volatile Console cons;
     /**
      * Returns the unique {@link java.io.Console Console} object associated
      * with the current Java virtual machine, if any.
@@ -216,12 +216,13 @@ public final class System {
      * @since   1.6
      */
      public static Console console() {
-         if (cons == null) {
+         Console c = cons;
+         if (c == null) {
              synchronized (System.class) {
-                 cons = SharedSecrets.getJavaIOAccess().console();
+                 cons = c = SharedSecrets.getJavaIOAccess().console();
              }
          }
-         return cons;
+         return c;
      }
 
     /**
diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java
index e40aa6f0d51..56935eabd34 100644
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java
@@ -207,12 +207,10 @@ class Thread implements Runnable {
     /* For generating thread ID */
     private static long threadSeqNumber;
 
-    /* Java thread status for tools,
-     * initialized to indicate thread 'not yet started'
+    /*
+     * Java thread status for tools, default indicates thread 'not yet started'
      */
-
-    private volatile int threadStatus = 0;
-
+    private volatile int threadStatus;
 
     private static synchronized long nextThreadID() {
         return ++threadSeqNumber;
diff --git a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
index d23491906c1..dcd50ae8575 100644
--- a/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
+++ b/jdk/src/java.base/share/classes/java/lang/ref/ReferenceQueue.java
@@ -53,7 +53,7 @@ public class ReferenceQueue<T> {
 
     private static class Lock { };
     private Lock lock = new Lock();
-    private volatile Reference<? extends T> head = null;
+    private volatile Reference<? extends T> head;
     private long queueLength = 0;
 
     boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
diff --git a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
index 5c178503fa8..005f0ddf5f3 100644
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Parameter.java
@@ -205,7 +205,7 @@ public final class Parameter implements AnnotatedElement {
         return tmp;
     }
 
-    private transient volatile Type parameterTypeCache = null;
+    private transient volatile Type parameterTypeCache;
 
     /**
      * Returns a {@code Class} object that identifies the
@@ -237,7 +237,7 @@ public final class Parameter implements AnnotatedElement {
         return executable.getAnnotatedParameterTypes()[index];
     }
 
-    private transient volatile Class<?> parameterClassCache = null;
+    private transient volatile Class<?> parameterClassCache;
 
     /**
      * Returns {@code true} if this parameter is implicitly declared
diff --git a/jdk/src/java.base/share/classes/java/net/URI.java b/jdk/src/java.base/share/classes/java/net/URI.java
index 134a8b4380f..93fb98d906c 100644
--- a/jdk/src/java.base/share/classes/java/net/URI.java
+++ b/jdk/src/java.base/share/classes/java/net/URI.java
@@ -33,7 +33,6 @@ import java.io.Serializable;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 import java.nio.charset.CharacterCodingException;
@@ -495,12 +494,12 @@ public final class URI
     private transient volatile String schemeSpecificPart;
     private transient volatile int hash;        // Zero ==> undefined
 
-    private transient volatile String decodedUserInfo = null;
-    private transient volatile String decodedAuthority = null;
-    private transient volatile String decodedPath = null;
-    private transient volatile String decodedQuery = null;
-    private transient volatile String decodedFragment = null;
-    private transient volatile String decodedSchemeSpecificPart = null;
+    private transient volatile String decodedUserInfo;
+    private transient volatile String decodedAuthority;
+    private transient volatile String decodedPath;
+    private transient volatile String decodedQuery;
+    private transient volatile String decodedFragment;
+    private transient volatile String decodedSchemeSpecificPart;
 
     /**
      * The string form of this URI.
diff --git a/jdk/src/java.base/share/classes/java/nio/Bits.java b/jdk/src/java.base/share/classes/java/nio/Bits.java
index 526c71d3f8b..724fb0c01f5 100644
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java
@@ -25,9 +25,7 @@
 
 package java.nio;
 
-import java.security.AccessController;
 import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.LongAdder;
 
 import jdk.internal.misc.JavaNioAccess;
 import jdk.internal.misc.JavaLangRefAccess;
@@ -603,7 +601,8 @@ class Bits {                            // package-private
     private static final AtomicLong reservedMemory = new AtomicLong();
     private static final AtomicLong totalCapacity = new AtomicLong();
     private static final AtomicLong count = new AtomicLong();
-    private static volatile boolean memoryLimitSet = false;
+    private static volatile boolean memoryLimitSet;
+
     // max. number of sleeps during try-reserving with exponentially
     // increasing delay before throwing OutOfMemoryError:
     // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
diff --git a/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java b/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java
index 86c133d192f..bd7c74de52a 100644
--- a/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java
+++ b/jdk/src/java.base/share/classes/java/nio/channels/SelectionKey.java
@@ -26,8 +26,6 @@
 package java.nio.channels;
 
 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import java.io.IOException;
-
 
 /**
  * A token representing the registration of a {@link SelectableChannel} with a
@@ -363,7 +361,7 @@ public abstract class SelectionKey {
 
     // -- Attachments --
 
-    private volatile Object attachment = null;
+    private volatile Object attachment;
 
     private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
         attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
diff --git a/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java b/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
index dcf54cb7d0c..cc82cb7a83c 100644
--- a/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
+++ b/jdk/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -29,11 +29,7 @@
 package java.nio.channels.spi;
 
 import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 import java.nio.channels.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import jdk.internal.misc.SharedSecrets;
 import sun.nio.ch.Interruptible;
 
@@ -90,7 +86,7 @@ public abstract class AbstractInterruptibleChannel
 {
 
     private final Object closeLock = new Object();
-    private volatile boolean open = true;
+    private volatile boolean closed;
 
     /**
      * Initializes a new instance of this class.
@@ -110,9 +106,9 @@ public abstract class AbstractInterruptibleChannel
      */
     public final void close() throws IOException {
         synchronized (closeLock) {
-            if (!open)
+            if (closed)
                 return;
-            open = false;
+            closed = true;
             implCloseChannel();
         }
     }
@@ -136,7 +132,7 @@ public abstract class AbstractInterruptibleChannel
     protected abstract void implCloseChannel() throws IOException;
 
     public final boolean isOpen() {
-        return open;
+        return !closed;
     }
 
 
@@ -158,9 +154,9 @@ public abstract class AbstractInterruptibleChannel
             interruptor = new Interruptible() {
                     public void interrupt(Thread target) {
                         synchronized (closeLock) {
-                            if (!open)
+                            if (closed)
                                 return;
-                            open = false;
+                            closed = true;
                             interrupted = target;
                             try {
                                 AbstractInterruptibleChannel.this.implCloseChannel();
@@ -202,7 +198,7 @@ public abstract class AbstractInterruptibleChannel
             this.interrupted = null;
             throw new ClosedByInterruptException();
         }
-        if (!completed && !open)
+        if (!completed && closed)
             throw new AsynchronousCloseException();
     }
 
diff --git a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java
index 498ed365213..d48f5a972db 100644
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java
@@ -276,7 +276,7 @@ public abstract class Charset
 
     /* -- Static methods -- */
 
-    private static volatile String bugLevel = null;
+    private static volatile String bugLevel;
 
     static boolean atBugLevel(String bl) {              // package-private
         String level = bugLevel;
@@ -324,8 +324,8 @@ public abstract class Charset
     // Cache of the most-recently-returned charsets,
     // along with the names that were used to find them
     //
-    private static volatile Object[] cache1 = null; // "Level 1" cache
-    private static volatile Object[] cache2 = null; // "Level 2" cache
+    private static volatile Object[] cache1; // "Level 1" cache
+    private static volatile Object[] cache2; // "Level 2" cache
 
     private static void cache(String charsetName, Charset cs) {
         cache2 = cache1;
diff --git a/jdk/src/java.base/share/classes/java/security/SecureRandom.java b/jdk/src/java.base/share/classes/java/security/SecureRandom.java
index a2a246f4a14..543b7abd98f 100644
--- a/jdk/src/java.base/share/classes/java/security/SecureRandom.java
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandom.java
@@ -124,7 +124,7 @@ public class SecureRandom extends java.util.Random {
     private String algorithm;
 
     // Seed Generator
-    private static volatile SecureRandom seedGenerator = null;
+    private static volatile SecureRandom seedGenerator;
 
     /**
      * Constructs a secure random number generator (RNG) implementing the
@@ -522,10 +522,12 @@ public class SecureRandom extends java.util.Random {
      * @see #setSeed
      */
     public static byte[] getSeed(int numBytes) {
-        if (seedGenerator == null) {
-            seedGenerator = new SecureRandom();
+        SecureRandom seedGen = seedGenerator;
+        if (seedGen == null) {
+            seedGen = new SecureRandom();
+            seedGenerator = seedGen;
         }
-        return seedGenerator.generateSeed(numBytes);
+        return seedGen.generateSeed(numBytes);
     }
 
     /**
diff --git a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java
index c1f951d5bf8..955415af8b6 100644
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java
+++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java
@@ -630,7 +630,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
             hashCode = 11 * hashCode + Arrays.hashCode(ampms);
             hashCode = 11 * hashCode + Arrays.deepHashCode(getZoneStringsWrapper());
             hashCode = 11 * hashCode + Objects.hashCode(localPatternChars);
-            cachedHashCode = hashCode;
+            if (hashCode != 0) {
+                cachedHashCode = hashCode;
+            }
         }
 
         return hashCode;
@@ -670,12 +672,12 @@ public class DateFormatSymbols implements Serializable, Cloneable {
     private static final ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> cachedInstances
         = new ConcurrentHashMap<>(3);
 
-    private transient int lastZoneIndex = 0;
+    private transient int lastZoneIndex;
 
     /**
      * Cached hash code
      */
-    transient volatile int cachedHashCode = 0;
+    transient volatile int cachedHashCode;
 
     private void initializeData(Locale desiredLocale) {
         locale = desiredLocale;
diff --git a/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java b/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
index 6727197ef81..cf7e7e5ffc7 100644
--- a/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
+++ b/jdk/src/java.base/share/classes/java/text/DecimalFormatSymbols.java
@@ -42,14 +42,8 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.Serializable;
 import java.text.spi.DecimalFormatSymbolsProvider;
-import java.util.ArrayList;
 import java.util.Currency;
-import java.util.List;
 import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleServiceProviderPool;
 import sun.util.locale.provider.ResourceBundleBasedAdapter;
@@ -875,7 +869,7 @@ public class DecimalFormatSymbols implements Cloneable, Serializable {
 
     // currency; only the ISO code is serialized.
     private transient Currency currency;
-    private transient volatile boolean currencyInitialized = false;
+    private transient volatile boolean currencyInitialized;
 
     // Proclaim JDK 1.1 FCS compatibility
     static final long serialVersionUID = 5772796243397350300L;
diff --git a/jdk/src/java.base/share/classes/java/util/Locale.java b/jdk/src/java.base/share/classes/java/util/Locale.java
index d01891be0c5..25697ca0c9d 100644
--- a/jdk/src/java.base/share/classes/java/util/Locale.java
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java
@@ -62,7 +62,6 @@ import sun.util.locale.ParseStatus;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleResources;
 import sun.util.locale.provider.LocaleServiceProviderPool;
-import sun.util.locale.provider.ResourceBundleBasedAdapter;
 
 /**
  * A <code>Locale</code> object represents a specific geographical, political,
@@ -2016,11 +2015,11 @@ public final class Locale implements Cloneable, Serializable {
     /**
      * Calculated hashcode
      */
-    private transient volatile int hashCodeValue = 0;
+    private transient volatile int hashCodeValue;
 
     private static volatile Locale defaultLocale = initDefault();
-    private static volatile Locale defaultDisplayLocale = null;
-    private static volatile Locale defaultFormatLocale = null;
+    private static volatile Locale defaultDisplayLocale;
+    private static volatile Locale defaultFormatLocale;
 
     private transient volatile String languageTag;
 
@@ -2207,9 +2206,9 @@ public final class Locale implements Cloneable, Serializable {
                 baseLocale.getRegion(), baseLocale.getVariant(), localeExtensions);
     }
 
-    private static volatile String[] isoLanguages = null;
+    private static volatile String[] isoLanguages;
 
-    private static volatile String[] isoCountries = null;
+    private static volatile String[] isoCountries;
 
     private static String convertOldISOCodes(String language) {
         // we accept both the old and the new ISO codes for the languages whose ISO
@@ -2851,7 +2850,7 @@ public final class Locale implements Cloneable, Serializable {
         private final String range;
         private final double weight;
 
-        private volatile int hash = 0;
+        private volatile int hash;
 
         /**
          * Constructs a {@code LanguageRange} using the given {@code range}.
@@ -3108,14 +3107,17 @@ public final class Locale implements Cloneable, Serializable {
          */
         @Override
         public int hashCode() {
-            if (hash == 0) {
-                int result = 17;
-                result = 37*result + range.hashCode();
+            int h = hash;
+            if (h == 0) {
+                h = 17;
+                h = 37*h + range.hashCode();
                 long bitsWeight = Double.doubleToLongBits(weight);
-                result = 37*result + (int)(bitsWeight ^ (bitsWeight >>> 32));
-                hash = result;
+                h = 37*h + (int)(bitsWeight ^ (bitsWeight >>> 32));
+                if (h != 0) {
+                    hash = h;
+                }
             }
-            return hash;
+            return h;
         }
 
         /**
diff --git a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java
index 3a6ac6f56a8..511611f574b 100644
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java
+++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java
@@ -950,7 +950,7 @@ public final class Pattern
      * Boolean indicating this Pattern is compiled; this is necessary in order
      * to lazily compile deserialized Patterns.
      */
-    private transient volatile boolean compiled = false;
+    private transient volatile boolean compiled;
 
     /**
      * The normalized pattern string.
@@ -1332,7 +1332,6 @@ public final class Pattern
         localCount = 0;
 
         // if length > 0, the Pattern is lazily compiled
-        compiled = false;
         if (pattern.length() == 0) {
             root = new Start(lastAccept);
             matchRoot = lastAccept;
@@ -1377,7 +1376,6 @@ public final class Pattern
      * equivalences of the characters.
      */
     private void normalize() {
-        boolean inCharClass = false;
         int lastCodePoint = -1;
 
         // Convert pattern into normalized form
@@ -1551,7 +1549,6 @@ public final class Pattern
         // offset maintains the index in code units.
 loop:   for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
             len = countChars(input, offset, 1);
-            boolean skip = false;
             for(int y=x-1; y>=0; y--) {
                 if (combClass[y] == combClass[x]) {
                     continue loop;
@@ -1566,8 +1563,7 @@ loop:   for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
                 temp[index++] = prefix + sre;
         }
         String[] result = new String[index];
-        for (int x=0; x<index; x++)
-            result[x] = temp[x];
+        System.arraycopy(temp, 0, result, 0, index);
         return result;
     }
 
@@ -1742,9 +1738,11 @@ loop:   for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
     }
 
     Map<String, Integer> namedGroups() {
-        if (namedGroups == null)
-            namedGroups = new HashMap<>(2);
-        return namedGroups;
+        Map<String, Integer> groups = namedGroups;
+        if (groups == null) {
+            namedGroups = groups = new HashMap<>(2);
+        }
+        return groups;
     }
 
     /**
diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
index a25db018b78..9d9a776a010 100644
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
@@ -72,7 +72,7 @@ public
 class ZipFile implements ZipConstants, Closeable {
 
     private final String name;     // zip file name
-    private volatile boolean closeRequested = false;
+    private volatile boolean closeRequested;
     private Source zsrc;
     private ZipCoder zc;
 
@@ -366,7 +366,7 @@ class ZipFile implements ZipConstants, Closeable {
     }
 
     private class ZipFileInflaterInputStream extends InflaterInputStream {
-        private volatile boolean closeRequested = false;
+        private volatile boolean closeRequested;
         private boolean eof = false;
         private final ZipFileInputStream zfin;
 
@@ -653,7 +653,7 @@ class ZipFile implements ZipConstants, Closeable {
      * (possibly compressed) zip file entry.
      */
    private class ZipFileInputStream extends InputStream {
-        private volatile boolean closeRequested = false;
+        private volatile boolean closeRequested;
         private   long pos;     // current position within entry data
         protected long rem;     // number of remaining bytes within entry
         protected long size;    // uncompressed size of this entry
diff --git a/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java b/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
index c59ff195cc4..c54fc1a55ff 100644
--- a/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java
@@ -326,20 +326,22 @@ public final class LazyLoggers {
     }
 
     // Do not expose this outside of this package.
-    private static volatile LoggerFinder provider = null;
+    private static volatile LoggerFinder provider;
     private static LoggerFinder accessLoggerFinder() {
-        if (provider == null) {
+        LoggerFinder prov = provider;
+        if (prov == null) {
             // no need to lock: it doesn't matter if we call
             // getLoggerFinder() twice - since LoggerFinder already caches
             // the result.
             // This is just an optimization to avoid the cost of calling
             // doPrivileged every time.
             final SecurityManager sm = System.getSecurityManager();
-            provider = sm == null ? LoggerFinder.getLoggerFinder() :
+            prov = sm == null ? LoggerFinder.getLoggerFinder() :
                 AccessController.doPrivileged(
                         (PrivilegedAction<LoggerFinder>)LoggerFinder::getLoggerFinder);
+            provider = prov;
         }
-        return provider;
+        return prov;
     }
 
     // Avoid using lambda here as lazy loggers could be created early
diff --git a/jdk/src/java.base/share/classes/sun/misc/VM.java b/jdk/src/java.base/share/classes/sun/misc/VM.java
index 37dc3b38fa1..4c83dfaf049 100644
--- a/jdk/src/java.base/share/classes/sun/misc/VM.java
+++ b/jdk/src/java.base/share/classes/sun/misc/VM.java
@@ -27,9 +27,6 @@ package sun.misc;
 
 import static java.lang.Thread.State.*;
 import java.util.Properties;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
 
 public class VM {
 
@@ -288,10 +285,10 @@ public class VM {
     }
 
     /* Current count of objects pending for finalization */
-    private static volatile int finalRefCount = 0;
+    private static volatile int finalRefCount;
 
     /* Peak count of objects pending for finalization */
-    private static volatile int peakFinalRefCount = 0;
+    private static volatile int peakFinalRefCount;
 
     /*
      * Gets the number of objects pending for finalization.
diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java b/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
index 43eff0435f4..13ede95ac41 100644
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpCapture.java
@@ -54,12 +54,12 @@ import sun.util.logging.PlatformLogger;
  * @author jccollet
  */
 public class HttpCapture {
-    private File file = null;
+    private File file;
     private boolean incoming = true;
-    private BufferedWriter out = null;
-    private static boolean initialized = false;
-    private static volatile ArrayList<Pattern> patterns = null;
-    private static volatile ArrayList<String> capFiles = null;
+    private BufferedWriter out;
+    private static boolean initialized;
+    private static volatile ArrayList<Pattern> patterns;
+    private static volatile ArrayList<String> capFiles;
 
     private static synchronized void init() {
         initialized = true;
diff --git a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
index c0b0d629d42..920b48d4b64 100644
--- a/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
+++ b/jdk/src/java.base/share/classes/sun/net/www/http/HttpClient.java
@@ -98,7 +98,7 @@ public class HttpClient extends NetworkClient {
     // from previous releases.
     private static boolean retryPostProp = true;
 
-    volatile boolean keepingAlive = false;     /* this is a keep-alive connection */
+    volatile boolean keepingAlive;    /* this is a keep-alive connection */
     int keepAliveConnections = -1;    /* number of keep-alives left */
 
     /**Idle timeout value, in milliseconds. Zero means infinity,
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
index 2d0ef217e3c..8ed2c9f1317 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java
@@ -51,14 +51,14 @@ abstract class AsynchronousServerSocketChannelImpl
     protected final FileDescriptor fd;
 
     // the local address to which the channel's socket is bound
-    protected volatile InetSocketAddress localAddress = null;
+    protected volatile InetSocketAddress localAddress;
 
     // need this lock to set local address
     private final Object stateLock = new Object();
 
     // close support
     private ReadWriteLock closeLock = new ReentrantReadWriteLock();
-    private volatile boolean open = true;
+    private volatile boolean closed;
 
     // set true when accept operation is cancelled
     private volatile boolean acceptKilled;
@@ -73,7 +73,7 @@ abstract class AsynchronousServerSocketChannelImpl
 
     @Override
     public final boolean isOpen() {
-        return open;
+        return !closed;
     }
 
     /**
@@ -102,9 +102,9 @@ abstract class AsynchronousServerSocketChannelImpl
         // synchronize with any threads using file descriptor/handle
         closeLock.writeLock().lock();
         try {
-            if (!open)
+            if (closed)
                 return;     // already closed
-            open = false;
+            closed = true;
         } finally {
             closeLock.writeLock().unlock();
         }
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
index 16a4d391881..3122b96a29f 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
@@ -54,8 +54,8 @@ abstract class AsynchronousSocketChannelImpl
     // protects state, localAddress, and remoteAddress
     protected final Object stateLock = new Object();
 
-    protected volatile InetSocketAddress localAddress = null;
-    protected volatile InetSocketAddress remoteAddress = null;
+    protected volatile InetSocketAddress localAddress;
+    protected volatile InetSocketAddress remoteAddress;
 
     // State, increases monotonically
     static final int ST_UNINITIALIZED = -1;
@@ -78,7 +78,7 @@ abstract class AsynchronousSocketChannelImpl
 
     // close support
     private final ReadWriteLock closeLock = new ReentrantReadWriteLock();
-    private volatile boolean open = true;
+    private volatile boolean closed;
 
     // set true when exclusive binding is on and SO_REUSEADDR is emulated
     private boolean isReuseAddress;
@@ -106,7 +106,7 @@ abstract class AsynchronousSocketChannelImpl
 
     @Override
     public final boolean isOpen() {
-        return open;
+        return !closed;
     }
 
     /**
@@ -135,9 +135,9 @@ abstract class AsynchronousSocketChannelImpl
         // synchronize with any threads initiating asynchronous operations
         closeLock.writeLock().lock();
         try {
-            if (!open)
+            if (closed)
                 return;     // already closed
-            open = false;
+            closed = true;
         } finally {
             closeLock.writeLock().unlock();
         }
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
index 9d4a2e828c1..7eb987991c9 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -58,8 +58,8 @@ class DatagramChannelImpl
     private final ProtocolFamily family;
 
     // IDs of native threads doing reads and writes, for signalling
-    private volatile long readerThread = 0;
-    private volatile long writerThread = 0;
+    private volatile long readerThread;
+    private volatile long writerThread;
 
     // Cached InetAddress and port for unconnected DatagramChannels
     // used by receive0
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
index fe2ed230002..fa1eae73d59 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java
@@ -46,7 +46,7 @@ public class DatagramSocketAdaptor
     private final DatagramChannelImpl dc;
 
     // Timeout "option" value for receives
-    private volatile int timeout = 0;
+    private volatile int timeout;
 
     // ## super will create a useless impl
     private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException {
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java
index 05bc5764062..1b00761f9f2 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileLockImpl.java
@@ -31,7 +31,7 @@ import java.nio.channels.*;
 public class FileLockImpl
     extends FileLock
 {
-    private volatile boolean valid = true;
+    private volatile boolean invalid;
 
     FileLockImpl(FileChannel channel, long position, long size, boolean shared)
     {
@@ -44,25 +44,25 @@ public class FileLockImpl
     }
 
     public boolean isValid() {
-        return valid;
+        return !invalid;
     }
 
     void invalidate() {
         assert Thread.holdsLock(this);
-        valid = false;
+        invalid = true;
     }
 
     public synchronized void release() throws IOException {
         Channel ch = acquiredBy();
         if (!ch.isOpen())
             throw new ClosedChannelException();
-        if (valid) {
+        if (isValid()) {
             if (ch instanceof FileChannelImpl)
                 ((FileChannelImpl)ch).release(this);
             else if (ch instanceof AsynchronousFileChannelImpl)
                 ((AsynchronousFileChannelImpl)ch).release(this);
             else throw new AssertionError();
-            valid = false;
+            invalidate();
         }
     }
 }
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
index 4d47b41ad9b..abe0e7ad277 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/MembershipKeyImpl.java
@@ -43,8 +43,7 @@ class MembershipKeyImpl
     private final NetworkInterface interf;
     private final InetAddress source;
 
-    // true when key is valid
-    private volatile boolean valid = true;
+    private volatile boolean invalid;
 
     // lock used when creating or accessing blockedSet
     private Object stateLock = new Object();
@@ -134,12 +133,12 @@ class MembershipKeyImpl
     }
 
     public boolean isValid() {
-        return valid;
+        return !invalid;
     }
 
     // package-private
     void invalidate() {
-        valid = false;
+        invalid = true;
     }
 
     public void drop() {
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java
index 525d3a1224c..27c46a9ca2c 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Net.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Net.java
@@ -32,7 +32,6 @@ import java.nio.channels.*;
 import java.util.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
 import sun.net.ExtendedOptionsImpl;
 
 
@@ -55,7 +54,7 @@ public class Net {
 
     // -- Miscellaneous utilities --
 
-    private static volatile boolean checkedIPv6 = false;
+    private static volatile boolean checkedIPv6;
     private static volatile boolean isIPv6Available;
 
     /**
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
index e7a2cbb73be..11d16b6068f 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java
@@ -45,7 +45,7 @@ public class ServerSocketAdaptor                        // package-private
     private final ServerSocketChannelImpl ssc;
 
     // Timeout "option" value for accepts
-    private volatile int timeout = 0;
+    private volatile int timeout;
 
     public static ServerSocket create(ServerSocketChannelImpl ssc) {
         try {
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
index 0274c2e0753..2a427f1a352 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
@@ -54,7 +54,7 @@ class ServerSocketChannelImpl
     private int fdVal;
 
     // ID of native thread currently blocked in this channel, for signalling
-    private volatile long thread = 0;
+    private volatile long thread;
 
     // Lock held by thread currently blocked in this channel
     private final Object lock = new Object();
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java
index d115b7aaf60..bf43c8b2317 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java
@@ -26,13 +26,11 @@
 package sun.nio.ch;
 
 import java.io.*;
-import java.lang.ref.*;
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
-import java.util.*;
 
 
 // Make a socket channel look like a socket.
@@ -55,7 +53,7 @@ public class SocketAdaptor
     private final SocketChannelImpl sc;
 
     // Timeout "option" value for reads
-    private volatile int timeout = 0;
+    private volatile int timeout;
 
     private SocketAdaptor(SocketChannelImpl sc) throws SocketException {
         super((SocketImpl) null);
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
index 0b3a3828ef3..c4965e1111b 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -56,8 +56,8 @@ class SocketChannelImpl
     private final int fdVal;
 
     // IDs of native threads doing reads and writes, for signalling
-    private volatile long readerThread = 0;
-    private volatile long writerThread = 0;
+    private volatile long readerThread;
+    private volatile long writerThread;
 
     // Lock held by current reading or connecting thread
     private final Object readLock = new Object();
diff --git a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java
index fd428149999..bb8df722927 100644
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java
@@ -25,13 +25,10 @@
 
 package sun.nio.ch;
 
-import java.lang.ref.SoftReference;
 import java.lang.reflect.*;
-import java.io.IOException;
 import java.io.FileDescriptor;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
-import java.nio.channels.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.*;
@@ -295,7 +292,7 @@ public class Util {
         return pageSize;
     }
 
-    private static volatile Constructor<?> directByteBufferConstructor = null;
+    private static volatile Constructor<?> directByteBufferConstructor;
 
     private static void initDBBConstructor() {
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
@@ -340,7 +337,7 @@ public class Util {
         return dbb;
     }
 
-    private static volatile Constructor<?> directByteBufferRConstructor = null;
+    private static volatile Constructor<?> directByteBufferRConstructor;
 
     private static void initDBBRConstructor() {
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
@@ -388,7 +385,7 @@ public class Util {
 
     // -- Bug compatibility --
 
-    private static volatile String bugLevel = null;
+    private static volatile String bugLevel;
 
     static boolean atBugLevel(String bl) {              // package-private
         if (bugLevel == null) {
diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java b/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
index e878d6d4891..eedf00480aa 100644
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
@@ -39,10 +39,10 @@ public class StreamDecoder extends Reader
     private static final int MIN_BYTE_BUFFER_SIZE = 32;
     private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
 
-    private volatile boolean isOpen = true;
+    private volatile boolean closed;
 
     private void ensureOpen() throws IOException {
-        if (!isOpen)
+        if (closed)
             throw new IOException("Stream closed");
     }
 
@@ -188,15 +188,15 @@ public class StreamDecoder extends Reader
 
     public void close() throws IOException {
         synchronized (lock) {
-            if (!isOpen)
+            if (closed)
                 return;
             implClose();
-            isOpen = false;
+            closed = true;
         }
     }
 
     private boolean isOpen() {
-        return isOpen;
+        return !closed;
     }
 
 
diff --git a/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java b/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java
index b41f93c038c..ccf3c63dbd0 100644
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java
@@ -38,10 +38,10 @@ public class StreamEncoder extends Writer
 
     private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
 
-    private volatile boolean isOpen = true;
+    private volatile boolean closed;
 
     private void ensureOpen() throws IOException {
-        if (!isOpen)
+        if (closed)
             throw new IOException("Stream closed");
     }
 
@@ -156,15 +156,15 @@ public class StreamEncoder extends Writer
 
     public void close() throws IOException {
         synchronized (lock) {
-            if (!isOpen)
+            if (closed)
                 return;
             implClose();
-            isOpen = false;
+            closed = true;
         }
     }
 
     private boolean isOpen() {
-        return isOpen;
+        return !closed;
     }
 
 
diff --git a/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java b/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java
index dfecd17423e..68e1a7c0c43 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/MethodAccessorGenerator.java
@@ -44,9 +44,9 @@ class MethodAccessorGenerator extends AccessorGenerator {
     // Only used if forSerialization is true
     private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;
 
-    private static volatile int methodSymnum = 0;
-    private static volatile int constructorSymnum = 0;
-    private static volatile int serializationConstructorSymnum = 0;
+    private static volatile int methodSymnum;
+    private static volatile int constructorSymnum;
+    private static volatile int serializationConstructorSymnum;
 
     private Class<?>   declaringClass;
     private Class<?>[] parameterTypes;
diff --git a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
index da509b6081a..2f6bdee2f93 100644
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
@@ -299,7 +299,7 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable {
                 }});
     }
 
-    private transient volatile Method[] memberMethods = null;
+    private transient volatile Method[] memberMethods;
 
     /**
      * Validates that a method is structurally appropriate for an
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
index d021ec17ef4..b566b892eb9 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
@@ -130,7 +130,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
      * also since counters make shorter debugging IDs than the big ones
      * we use in the protocol for uniqueness-over-time.
      */
-    private static volatile int counter = 0;
+    private static volatile int counter;
 
     /*
      * Use of session caches is globally enabled/disabled.
diff --git a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
index 8b716798f64..812778c02c0 100644
--- a/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java
@@ -1290,7 +1290,7 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
             implements Comparable<X509IssuerSerial> {
         final X500Principal issuer;
         final BigInteger serial;
-        volatile int hashcode = 0;
+        volatile int hashcode;
 
         /**
          * Create an X509IssuerSerial.
@@ -1358,13 +1358,16 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
          * @return the hash code value
          */
         public int hashCode() {
-            if (hashcode == 0) {
-                int result = 17;
-                result = 37*result + issuer.hashCode();
-                result = 37*result + serial.hashCode();
-                hashcode = result;
+            int h = hashcode;
+            if (h == 0) {
+                h = 17;
+                h = 37*h + issuer.hashCode();
+                h = 37*h + serial.hashCode();
+                if (h != 0) {
+                    hashcode = h;
+                }
             }
-            return hashcode;
+            return h;
         }
 
         @Override
diff --git a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
index 535f9159293..59fae3b7c0e 100644
--- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
@@ -25,13 +25,6 @@
 
 package sun.util.calendar;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Properties;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -76,7 +69,7 @@ public abstract class CalendarSystem {
 
     /////////////////////// Calendar Factory Methods /////////////////////////
 
-    private static volatile boolean initialized = false;
+    private static volatile boolean initialized;
 
     // Map of calendar names and calendar class names
     private static ConcurrentMap<String, String> names;
diff --git a/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java b/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java
index 2f4da3d5960..62420d23351 100644
--- a/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java
+++ b/jdk/src/java.base/share/classes/sun/util/locale/BaseLocale.java
@@ -46,7 +46,7 @@ public final class BaseLocale {
     private final String region;
     private final String variant;
 
-    private volatile int hash = 0;
+    private volatile int hash;
 
     // This method must be called only when creating the Locale.* constants.
     private BaseLocale(String language, String region) {
@@ -147,7 +147,9 @@ public final class BaseLocale {
             h = 31 * h + script.hashCode();
             h = 31 * h + region.hashCode();
             h = 31 * h + variant.hashCode();
-            hash = h;
+            if (h != 0) {
+                hash = h;
+            }
         }
         return h;
     }
diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
index 5cb48a97d36..c9cdba78edc 100644
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java
@@ -114,20 +114,20 @@ public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements R
         }
     }
 
-    private volatile BreakIteratorProvider breakIteratorProvider = null;
-    private volatile CollatorProvider collatorProvider = null;
-    private volatile DateFormatProvider dateFormatProvider = null;
-    private volatile DateFormatSymbolsProvider dateFormatSymbolsProvider = null;
-    private volatile DecimalFormatSymbolsProvider decimalFormatSymbolsProvider = null;
-    private volatile NumberFormatProvider numberFormatProvider = null;
+    private volatile BreakIteratorProvider breakIteratorProvider;
+    private volatile CollatorProvider collatorProvider;
+    private volatile DateFormatProvider dateFormatProvider;
+    private volatile DateFormatSymbolsProvider dateFormatSymbolsProvider;
+    private volatile DecimalFormatSymbolsProvider decimalFormatSymbolsProvider;
+    private volatile NumberFormatProvider numberFormatProvider;
 
-    private volatile CurrencyNameProvider currencyNameProvider = null;
-    private volatile LocaleNameProvider localeNameProvider = null;
-    private volatile TimeZoneNameProvider timeZoneNameProvider = null;
-    private volatile CalendarDataProvider calendarDataProvider = null;
-    private volatile CalendarNameProvider calendarNameProvider = null;
+    private volatile CurrencyNameProvider currencyNameProvider;
+    private volatile LocaleNameProvider localeNameProvider;
+    private volatile TimeZoneNameProvider timeZoneNameProvider;
+    private volatile CalendarDataProvider calendarDataProvider;
+    private volatile CalendarNameProvider calendarNameProvider;
 
-    private volatile CalendarProvider calendarProvider = null;
+    private volatile CalendarProvider calendarProvider;
 
     /*
      * Getter methods for java.text.spi.* providers
diff --git a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
index c17856ffe9a..e19a6c8c531 100644
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
@@ -107,7 +107,7 @@ public abstract class LocaleProviderAdapter {
      * Default fallback adapter type, which should return something meaningful in any case.
      * This is either CLDR or FALLBACK.
      */
-    static volatile LocaleProviderAdapter.Type defaultLocaleProviderAdapter = null;
+    static volatile LocaleProviderAdapter.Type defaultLocaleProviderAdapter;
 
     /**
      * Adapter lookup cache.
diff --git a/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java b/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java
index ae1dce93f6b..4d31cf2834d 100644
--- a/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java
+++ b/jdk/src/java.base/share/classes/sun/util/resources/OpenListResourceBundle.java
@@ -164,6 +164,6 @@ public abstract class OpenListResourceBundle extends ResourceBundle {
         return new HashSet<>();
     }
 
-    private volatile Map<String, Object> lookup = null;
+    private volatile Map<String, Object> lookup;
     private volatile Set<String> keyset;
 }
diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
index 8e437684f33..69e71c05f57 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java
@@ -47,7 +47,7 @@ class SinkChannelImpl
     int fdVal;
 
     // ID of native thread doing write, for signalling
-    private volatile long thread = 0;
+    private volatile long thread;
 
     // Lock held by current reading thread
     private final Object lock = new Object();
diff --git a/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java b/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
index b1b4f9e36f0..7eea3ca0b72 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java
@@ -47,7 +47,7 @@ class SourceChannelImpl
     int fdVal;
 
     // ID of native thread doing read, for signalling
-    private volatile long thread = 0;
+    private volatile long thread;
 
     // Lock held by current reading thread
     private final Object lock = new Object();
diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java b/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java
index 9eb683b2bd7..d58677502d2 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java
@@ -52,7 +52,7 @@ class MimeTypesFileTypeDetector extends AbstractFileTypeDetector {
     private Map<String,String> mimeTypeMap;
 
     // set to true when file loaded
-    private volatile boolean loaded = false;
+    private volatile boolean loaded;
 
     public MimeTypesFileTypeDetector(Path filePath) {
         mimeTypesFile = filePath;
diff --git a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
index 6fa5efb1cbd..cb74298d3dc 100644
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
@@ -119,7 +119,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
 
     // Lock for interrupt triggering and clearing
     private final Object interruptLock = new Object();
-    private volatile boolean interruptTriggered = false;
+    private volatile boolean interruptTriggered;
 
     WindowsSelectorImpl(SelectorProvider sp) throws IOException {
         super(sp);

From aebd8a6c3256786598c53e0626fc303542194819 Mon Sep 17 00:00:00 2001
From: Roger Riggs <rriggs@openjdk.org>
Date: Mon, 21 Dec 2015 15:26:56 -0500
Subject: [PATCH 51/62] 8136597: java/lang/ProcessHandle/InfoTest.java fails

Correct for truncated command line

Reviewed-by: redestad
---
 jdk/test/java/lang/ProcessHandle/InfoTest.java | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/jdk/test/java/lang/ProcessHandle/InfoTest.java b/jdk/test/java/lang/ProcessHandle/InfoTest.java
index e3182edb3f7..38b1546acc0 100644
--- a/jdk/test/java/lang/ProcessHandle/InfoTest.java
+++ b/jdk/test/java/lang/ProcessHandle/InfoTest.java
@@ -49,7 +49,7 @@ import org.testng.TestNG;
 
 /*
  * @test
- * @bug 8077350 8081566 8081567 8098852
+ * @bug 8077350 8081566 8081567 8098852 8136597
  * @build jdk.testlibrary.*
  * @library /lib/testlibrary
  * @summary Functions of ProcessHandle.Info
@@ -210,10 +210,12 @@ public class InfoTest {
                             Assert.assertTrue(commandLine.contains(allArgs.get(i)),
                                               "commandLine() must contain argument: " + allArgs.get(i));
                         }
-                    } else if (info.commandLine().isPresent()) {
+                    } else if (info.commandLine().isPresent() &&
+                            command.isPresent() &&
+                            command.get().length() < info.commandLine().get().length()) {
                         // If we only have the commandLine() we can only do some basic checks...
                         String commandLine = info.commandLine().get();
-                        String javaExe = "java" + (Platform.isWindows() ? ".exe": "");
+                        String javaExe = "java" + (Platform.isWindows() ? ".exe" : "");
                         int pos = commandLine.indexOf(javaExe);
                         Assert.assertTrue(pos > 0, "commandLine() should at least contain 'java'");
 

From 69bd68385cc378fea9d913eff9dab68a4ea9cbc7 Mon Sep 17 00:00:00 2001
From: Amy Lu <amlu@openjdk.org>
Date: Tue, 22 Dec 2015 11:07:17 +0800
Subject: [PATCH 52/62] 8145869: Mark test JMXStartStopTest.java and
 TestJstatdServer.java as intermittently failing

Reviewed-by: darcy
---
 .../sun/management/jmxremote/startstop/JMXStartStopTest.java    | 2 +-
 jdk/test/sun/tools/jstatd/TestJstatdServer.java                 | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java
index ca988cdea47..6348de21ef7 100644
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java
@@ -58,7 +58,7 @@ import sun.management.AgentConfigurationError;
  * @run main/othervm/timeout=600 -XX:+UsePerfData JMXStartStopTest
  * @summary Makes sure that enabling/disabling the management agent through JCMD
  *          achieves the desired results
- * @key randomness
+ * @key randomness intermittent
  */
 public class JMXStartStopTest {
     private static final String TEST_APP_NAME = "TestApp";
diff --git a/jdk/test/sun/tools/jstatd/TestJstatdServer.java b/jdk/test/sun/tools/jstatd/TestJstatdServer.java
index 4622ea64a59..565f799765d 100644
--- a/jdk/test/sun/tools/jstatd/TestJstatdServer.java
+++ b/jdk/test/sun/tools/jstatd/TestJstatdServer.java
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 4990825
+ * @key intermittent
  * @library /lib/testlibrary
  * @modules java.management
  * @build jdk.testlibrary.* JstatdTest JstatGCUtilParser

From 7e4d56677d48e02d2df999ed6105cc7566c03455 Mon Sep 17 00:00:00 2001
From: Chris Hegarty <chegar@openjdk.org>
Date: Tue, 22 Dec 2015 12:17:25 +0000
Subject: [PATCH 53/62] 8145990: Move sun.misc math support classes to
 jdk.internal.math

Reviewed-by: bpb, darcy
---
 .../classes/java/lang/AbstractStringBuilder.java |  2 +-
 .../share/classes/java/lang/Double.java          |  4 ++--
 .../java.base/share/classes/java/lang/Float.java |  6 +++---
 .../java.base/share/classes/java/lang/Math.java  |  4 ++--
 .../share/classes/java/lang/StrictMath.java      |  2 +-
 .../share/classes/java/math/BigInteger.java      |  4 ++--
 .../share/classes/java/text/DigitList.java       |  2 +-
 .../share/classes/java/util/Formatter.java       |  4 ++--
 .../misc => jdk/internal/math}/DoubleConsts.java |  2 +-
 .../misc => jdk/internal/math}/FDBigInteger.java |  2 +-
 .../misc => jdk/internal/math}/FloatConsts.java  |  2 +-
 .../internal/math}/FloatingDecimal.java          |  2 +-
 .../internal/math}/FormattedFloatingDecimal.java |  2 +-
 .../classes/sun/java2d/marlin/FloatMath.java     |  4 ++--
 .../java/util/Formatter/Basic-X.java.template    |  2 +-
 jdk/test/java/util/Formatter/Basic.java          |  2 +-
 jdk/test/java/util/Formatter/BasicDouble.java    |  6 +++++-
 .../FloatingDecimal/OldFDBigIntForTest.java      |  2 +-
 .../OldFloatingDecimalForTest.java               |  2 +-
 .../math}/FloatingDecimal/TestFDBigInteger.java  |  6 +++---
 .../FloatingDecimal/TestFloatingDecimal.java     | 16 ++++++++--------
 21 files changed, 41 insertions(+), 37 deletions(-)
 rename jdk/src/java.base/share/classes/{sun/misc => jdk/internal/math}/DoubleConsts.java (99%)
 rename jdk/src/java.base/share/classes/{sun/misc => jdk/internal/math}/FDBigInteger.java (99%)
 rename jdk/src/java.base/share/classes/{sun/misc => jdk/internal/math}/FloatConsts.java (99%)
 rename jdk/src/java.base/share/classes/{sun/misc => jdk/internal/math}/FloatingDecimal.java (99%)
 rename jdk/src/java.base/share/classes/{sun/misc => jdk/internal/math}/FormattedFloatingDecimal.java (99%)
 rename jdk/test/{sun/misc => jdk/internal/math}/FloatingDecimal/OldFDBigIntForTest.java (99%)
 rename jdk/test/{sun/misc => jdk/internal/math}/FloatingDecimal/OldFloatingDecimalForTest.java (99%)
 rename jdk/test/{sun/misc => jdk/internal/math}/FloatingDecimal/TestFDBigInteger.java (99%)
 rename jdk/test/{sun/misc => jdk/internal/math}/FloatingDecimal/TestFloatingDecimal.java (96%)

diff --git a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
index 975c806bc81..619b7de278a 100644
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java
@@ -25,7 +25,7 @@
 
 package java.lang;
 
-import sun.misc.FloatingDecimal;
+import jdk.internal.math.FloatingDecimal;
 import java.util.Arrays;
 import java.util.Spliterator;
 import java.util.stream.IntStream;
diff --git a/jdk/src/java.base/share/classes/java/lang/Double.java b/jdk/src/java.base/share/classes/java/lang/Double.java
index 88201873c36..f1389ebe0f8 100644
--- a/jdk/src/java.base/share/classes/java/lang/Double.java
+++ b/jdk/src/java.base/share/classes/java/lang/Double.java
@@ -25,8 +25,8 @@
 
 package java.lang;
 
-import sun.misc.FloatingDecimal;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.FloatingDecimal;
+import jdk.internal.math.DoubleConsts;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
 /**
diff --git a/jdk/src/java.base/share/classes/java/lang/Float.java b/jdk/src/java.base/share/classes/java/lang/Float.java
index f9d3f9ef325..09eb63527ab 100644
--- a/jdk/src/java.base/share/classes/java/lang/Float.java
+++ b/jdk/src/java.base/share/classes/java/lang/Float.java
@@ -25,9 +25,9 @@
 
 package java.lang;
 
-import sun.misc.FloatingDecimal;
-import sun.misc.FloatConsts;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.FloatingDecimal;
+import jdk.internal.math.FloatConsts;
+import jdk.internal.math.DoubleConsts;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
 /**
diff --git a/jdk/src/java.base/share/classes/java/lang/Math.java b/jdk/src/java.base/share/classes/java/lang/Math.java
index 1cd32bd3839..ddb953225a8 100644
--- a/jdk/src/java.base/share/classes/java/lang/Math.java
+++ b/jdk/src/java.base/share/classes/java/lang/Math.java
@@ -26,8 +26,8 @@
 package java.lang;
 
 import java.util.Random;
-import sun.misc.FloatConsts;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.FloatConsts;
+import jdk.internal.math.DoubleConsts;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
 /**
diff --git a/jdk/src/java.base/share/classes/java/lang/StrictMath.java b/jdk/src/java.base/share/classes/java/lang/StrictMath.java
index 68bba059786..0c82f6afbf5 100644
--- a/jdk/src/java.base/share/classes/java/lang/StrictMath.java
+++ b/jdk/src/java.base/share/classes/java/lang/StrictMath.java
@@ -26,7 +26,7 @@
 package java.lang;
 
 import java.util.Random;
-import sun.misc.DoubleConsts;
+import jdk.internal.math.DoubleConsts;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
 /**
diff --git a/jdk/src/java.base/share/classes/java/math/BigInteger.java b/jdk/src/java.base/share/classes/java/math/BigInteger.java
index 1c44659daf4..c77731b2418 100644
--- a/jdk/src/java.base/share/classes/java/math/BigInteger.java
+++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java
@@ -38,8 +38,8 @@ import java.util.Objects;
 import java.util.Random;
 import java.util.concurrent.ThreadLocalRandom;
 
-import sun.misc.DoubleConsts;
-import sun.misc.FloatConsts;
+import jdk.internal.math.DoubleConsts;
+import jdk.internal.math.FloatConsts;
 import jdk.internal.HotSpotIntrinsicCandidate;
 
 /**
diff --git a/jdk/src/java.base/share/classes/java/text/DigitList.java b/jdk/src/java.base/share/classes/java/text/DigitList.java
index 0b73543a9d4..708e3e64575 100644
--- a/jdk/src/java.base/share/classes/java/text/DigitList.java
+++ b/jdk/src/java.base/share/classes/java/text/DigitList.java
@@ -41,7 +41,7 @@ package java.text;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.math.RoundingMode;
-import sun.misc.FloatingDecimal;
+import jdk.internal.math.FloatingDecimal;
 
 /**
  * Digit List. Private to DecimalFormat.
diff --git a/jdk/src/java.base/share/classes/java/util/Formatter.java b/jdk/src/java.base/share/classes/java/util/Formatter.java
index 0a3b50b6a13..c771ac1ba0c 100644
--- a/jdk/src/java.base/share/classes/java/util/Formatter.java
+++ b/jdk/src/java.base/share/classes/java/util/Formatter.java
@@ -60,8 +60,8 @@ import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalQueries;
 import java.time.temporal.UnsupportedTemporalTypeException;
 
-import sun.misc.DoubleConsts;
-import sun.misc.FormattedFloatingDecimal;
+import jdk.internal.math.DoubleConsts;
+import jdk.internal.math.FormattedFloatingDecimal;
 
 /**
  * An interpreter for printf-style format strings.  This class provides support
diff --git a/jdk/src/java.base/share/classes/sun/misc/DoubleConsts.java b/jdk/src/java.base/share/classes/jdk/internal/math/DoubleConsts.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/DoubleConsts.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/DoubleConsts.java
index 6ee80490102..c0480e9d497 100644
--- a/jdk/src/java.base/share/classes/sun/misc/DoubleConsts.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/DoubleConsts.java
@@ -23,7 +23,7 @@
  * questions.
  */
 
-package sun.misc;
+package jdk.internal.math;
 
 /**
  * This class contains additional constants documenting limits of the
diff --git a/jdk/src/java.base/share/classes/sun/misc/FDBigInteger.java b/jdk/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FDBigInteger.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
index d25f2017f6a..ba3ce9b8287 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FDBigInteger.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
@@ -22,7 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package sun.misc;
+package jdk.internal.math;
 
 import java.math.BigInteger;
 import java.util.Arrays;
diff --git a/jdk/src/java.base/share/classes/sun/misc/FloatConsts.java b/jdk/src/java.base/share/classes/jdk/internal/math/FloatConsts.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FloatConsts.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FloatConsts.java
index 07396f8bca9..977a222278b 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FloatConsts.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FloatConsts.java
@@ -23,7 +23,7 @@
  * questions.
  */
 
-package sun.misc;
+package jdk.internal.math;
 
 /**
  * This class contains additional constants documenting limits of the
diff --git a/jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java b/jdk/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java
index 0c07520f13e..575255eb174 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java
@@ -23,7 +23,7 @@
  * questions.
  */
 
-package sun.misc;
+package jdk.internal.math;
 
 import java.util.Arrays;
 import java.util.regex.*;
diff --git a/jdk/src/java.base/share/classes/sun/misc/FormattedFloatingDecimal.java b/jdk/src/java.base/share/classes/jdk/internal/math/FormattedFloatingDecimal.java
similarity index 99%
rename from jdk/src/java.base/share/classes/sun/misc/FormattedFloatingDecimal.java
rename to jdk/src/java.base/share/classes/jdk/internal/math/FormattedFloatingDecimal.java
index fc53920e398..0a560dc11e5 100644
--- a/jdk/src/java.base/share/classes/sun/misc/FormattedFloatingDecimal.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/math/FormattedFloatingDecimal.java
@@ -23,7 +23,7 @@
  * questions.
  */
 
-package sun.misc;
+package jdk.internal.math;
 
 import java.util.Arrays;
 
diff --git a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
index d1ffc04b786..df6af52438c 100644
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/FloatMath.java
@@ -24,8 +24,8 @@
  */
 package sun.java2d.marlin;
 
-import sun.misc.DoubleConsts;
-import sun.misc.FloatConsts;
+import jdk.internal.math.DoubleConsts;
+import jdk.internal.math.FloatConsts;
 
 /**
  * Faster Math ceil / floor routines derived from StrictMath
diff --git a/jdk/test/java/util/Formatter/Basic-X.java.template b/jdk/test/java/util/Formatter/Basic-X.java.template
index 57d77ae887d..206c3e0d27f 100644
--- a/jdk/test/java/util/Formatter/Basic-X.java.template
+++ b/jdk/test/java/util/Formatter/Basic-X.java.template
@@ -36,7 +36,7 @@ import java.math.BigInteger;
 import java.text.DateFormatSymbols;
 import java.util.*;
 #if[double]
-import sun.misc.DoubleConsts;
+import jdk.internal.math.DoubleConsts;
 #end[double]
 
 import static java.util.Calendar.*;
diff --git a/jdk/test/java/util/Formatter/Basic.java b/jdk/test/java/util/Formatter/Basic.java
index 4287f1bc2d8..8fb2e1de3a1 100644
--- a/jdk/test/java/util/Formatter/Basic.java
+++ b/jdk/test/java/util/Formatter/Basic.java
@@ -28,7 +28,7 @@
  *      6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 6476168
  *      8059175
  *
- * @modules java.base/sun.misc
+ * @modules java.base/jdk.internal.math
  * @run shell/timeout=240 Basic.sh
  */
 
diff --git a/jdk/test/java/util/Formatter/BasicDouble.java b/jdk/test/java/util/Formatter/BasicDouble.java
index 11760f17f7f..ba54d46be36 100644
--- a/jdk/test/java/util/Formatter/BasicDouble.java
+++ b/jdk/test/java/util/Formatter/BasicDouble.java
@@ -36,7 +36,7 @@ import java.math.BigInteger;
 import java.text.DateFormatSymbols;
 import java.util.*;
 
-import sun.misc.DoubleConsts;
+import jdk.internal.math.DoubleConsts;
 
 
 import static java.util.Calendar.*;
@@ -1169,6 +1169,10 @@ public class BasicDouble extends Basic {
 
 
 
+
+
+
+
 
 
 
diff --git a/jdk/test/sun/misc/FloatingDecimal/OldFDBigIntForTest.java b/jdk/test/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java
similarity index 99%
rename from jdk/test/sun/misc/FloatingDecimal/OldFDBigIntForTest.java
rename to jdk/test/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java
index a7082ba76bc..f500040a922 100644
--- a/jdk/test/sun/misc/FloatingDecimal/OldFDBigIntForTest.java
+++ b/jdk/test/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java
@@ -21,7 +21,7 @@
  * questions.
  */
 
-//package sun.misc;
+//package jdk.internal.math;
 
 /*
  * A really, really simple bigint package
diff --git a/jdk/test/sun/misc/FloatingDecimal/OldFloatingDecimalForTest.java b/jdk/test/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java
similarity index 99%
rename from jdk/test/sun/misc/FloatingDecimal/OldFloatingDecimalForTest.java
rename to jdk/test/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java
index 63bbbf5eb14..073f2655e3a 100644
--- a/jdk/test/sun/misc/FloatingDecimal/OldFloatingDecimalForTest.java
+++ b/jdk/test/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java
@@ -21,7 +21,7 @@
  * questions.
  */
 
-//package sun.misc;
+//package jdk.internal.math;
 
 import java.util.regex.*;
 
diff --git a/jdk/test/sun/misc/FloatingDecimal/TestFDBigInteger.java b/jdk/test/jdk/internal/math/FloatingDecimal/TestFDBigInteger.java
similarity index 99%
rename from jdk/test/sun/misc/FloatingDecimal/TestFDBigInteger.java
rename to jdk/test/jdk/internal/math/FloatingDecimal/TestFDBigInteger.java
index 983f5d78cee..9eb8cfe7844 100644
--- a/jdk/test/sun/misc/FloatingDecimal/TestFDBigInteger.java
+++ b/jdk/test/jdk/internal/math/FloatingDecimal/TestFDBigInteger.java
@@ -23,13 +23,13 @@
 
 import java.math.BigInteger;
 import java.util.Random;
-import sun.misc.FDBigInteger;
+import jdk.internal.math.FDBigInteger;
 
 /**
  * @test
  * @bug 7032154
- * @summary unit testys of sun.misc.FDBigInteger
- * @modules java.base/sun.misc
+ * @summary unit testys of FDBigInteger
+ * @modules java.base/jdk.internal.math
  * @author Dmitry Nadezhin
  */
 public class TestFDBigInteger {
diff --git a/jdk/test/sun/misc/FloatingDecimal/TestFloatingDecimal.java b/jdk/test/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java
similarity index 96%
rename from jdk/test/sun/misc/FloatingDecimal/TestFloatingDecimal.java
rename to jdk/test/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java
index 96806a9b708..5fcb5b52b04 100644
--- a/jdk/test/sun/misc/FloatingDecimal/TestFloatingDecimal.java
+++ b/jdk/test/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java
@@ -22,7 +22,7 @@
  */
 
 import java.util.Random;
-import sun.misc.FloatingDecimal;
+import jdk.internal.math.FloatingDecimal;
 
 /*
 OldFloatingDecimalForTest
@@ -40,26 +40,26 @@ public class OldFloatingDecimalForTest {
   public strictfp float floatValue();
 }
 
-sun.misc.FloatingDecimal
+jdk.internal.math.FloatingDecimal
 
-public class sun.misc.FloatingDecimal {
-  public sun.misc.FloatingDecimal();
+public class jdk.internal.math.FloatingDecimal {
+  public jdk.internal.math.FloatingDecimal();
   public static java.lang.String toJavaFormatString(double);
   public static java.lang.String toJavaFormatString(float);
   public static void appendTo(double, java.lang.Appendable);
   public static void appendTo(float, java.lang.Appendable);
   public static double parseDouble(java.lang.String) throws java.lang.NumberFormatException;
   public static float parseFloat(java.lang.String) throws java.lang.NumberFormatException;
-  public static sun.misc.FloatingDecimal$AbstractD2ABuffer getD2ABuffer(double);
+  public static jdk.internal.math.FloatingDecimal$AbstractD2ABuffer getD2ABuffer(double);
 }
 */
 
 /**
  * @test
  * @bug 7032154
- * @summary unit tests of sun.misc.FloatingDecimal
- * @modules java.base/sun.misc
- * @library ../../../java/lang/Math
+ * @summary unit tests of FloatingDecimal
+ * @modules java.base/jdk.internal.math
+ * @library /java/lang/Math
  * @build DoubleConsts FloatConsts
  * @run main TestFloatingDecimal
  * @author Brian Burkhalter

From 22df7c453f8fd4497cc64960f073f1a4e66b4dce Mon Sep 17 00:00:00 2001
From: Claes Redestad <redestad@openjdk.org>
Date: Tue, 22 Dec 2015 16:42:16 +0100
Subject: [PATCH 54/62] 8145988: Use the raw methods of java.net.URI when
 possible

Reviewed-by: shade, chegar
---
 jdk/src/java.base/share/classes/java/io/File.java     |  6 +++---
 .../classes/sun/nio/fs/UnixFileSystemProvider.java    | 11 ++++++-----
 .../unix/classes/sun/nio/fs/UnixUriUtils.java         |  6 +++---
 .../classes/sun/nio/fs/WindowsFileSystemProvider.java | 11 ++++++-----
 .../windows/classes/sun/nio/fs/WindowsUriSupport.java |  6 +++---
 5 files changed, 21 insertions(+), 19 deletions(-)

diff --git a/jdk/src/java.base/share/classes/java/io/File.java b/jdk/src/java.base/share/classes/java/io/File.java
index 6137d0acd29..089171bab9e 100644
--- a/jdk/src/java.base/share/classes/java/io/File.java
+++ b/jdk/src/java.base/share/classes/java/io/File.java
@@ -420,11 +420,11 @@ public class File
         String scheme = uri.getScheme();
         if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
             throw new IllegalArgumentException("URI scheme is not \"file\"");
-        if (uri.getAuthority() != null)
+        if (uri.getRawAuthority() != null)
             throw new IllegalArgumentException("URI has an authority component");
-        if (uri.getFragment() != null)
+        if (uri.getRawFragment() != null)
             throw new IllegalArgumentException("URI has a fragment component");
-        if (uri.getQuery() != null)
+        if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("URI has a query component");
         String p = uri.getPath();
         if (p.equals(""))
diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
index 182a57b94c2..f161bd3e0bf 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java
@@ -69,15 +69,16 @@ public abstract class UnixFileSystemProvider
     private void checkUri(URI uri) {
         if (!uri.getScheme().equalsIgnoreCase(getScheme()))
             throw new IllegalArgumentException("URI does not match this provider");
-        if (uri.getAuthority() != null)
+        if (uri.getRawAuthority() != null)
             throw new IllegalArgumentException("Authority component present");
-        if (uri.getPath() == null)
+        String path = uri.getPath();
+        if (path == null)
             throw new IllegalArgumentException("Path component is undefined");
-        if (!uri.getPath().equals("/"))
+        if (!path.equals("/"))
             throw new IllegalArgumentException("Path component should be '/'");
-        if (uri.getQuery() != null)
+        if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("Query component present");
-        if (uri.getFragment() != null)
+        if (uri.getRawFragment() != null)
             throw new IllegalArgumentException("Fragment component present");
     }
 
diff --git a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java
index b59ab4275ce..a0df3e3102e 100644
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java
+++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java
@@ -49,11 +49,11 @@ class UnixUriUtils {
         String scheme = uri.getScheme();
         if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
             throw new IllegalArgumentException("URI scheme is not \"file\"");
-        if (uri.getAuthority() != null)
+        if (uri.getRawAuthority() != null)
             throw new IllegalArgumentException("URI has an authority component");
-        if (uri.getFragment() != null)
+        if (uri.getRawFragment() != null)
             throw new IllegalArgumentException("URI has a fragment component");
-        if (uri.getQuery() != null)
+        if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("URI has a query component");
 
         // compatibility with java.io.File
diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
index cf0d23fea2b..847ef1564b5 100644
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
@@ -61,15 +61,16 @@ public class WindowsFileSystemProvider
     private void checkUri(URI uri) {
         if (!uri.getScheme().equalsIgnoreCase(getScheme()))
             throw new IllegalArgumentException("URI does not match this provider");
-        if (uri.getAuthority() != null)
+        if (uri.getRawAuthority() != null)
             throw new IllegalArgumentException("Authority component present");
-        if (uri.getPath() == null)
+        String path = uri.getPath();
+        if (path == null)
             throw new IllegalArgumentException("Path component is undefined");
-        if (!uri.getPath().equals("/"))
+        if (!path.equals("/"))
             throw new IllegalArgumentException("Path component should be '/'");
-        if (uri.getQuery() != null)
+        if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("Query component present");
-        if (uri.getFragment() != null)
+        if (uri.getRawFragment() != null)
             throw new IllegalArgumentException("Fragment component present");
     }
 
diff --git a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java
index 5748bbb02af..f95a913f448 100644
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java
@@ -123,16 +123,16 @@ class WindowsUriSupport {
         String scheme = uri.getScheme();
         if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
             throw new IllegalArgumentException("URI scheme is not \"file\"");
-        if (uri.getFragment() != null)
+        if (uri.getRawFragment() != null)
             throw new IllegalArgumentException("URI has a fragment component");
-        if (uri.getQuery() != null)
+        if (uri.getRawQuery() != null)
             throw new IllegalArgumentException("URI has a query component");
         String path = uri.getPath();
         if (path.equals(""))
             throw new IllegalArgumentException("URI path component is empty");
 
         // UNC
-        String auth = uri.getAuthority();
+        String auth = uri.getRawAuthority();
         if (auth != null && !auth.equals("")) {
             String host = uri.getHost();
             if (host == null)

From c6afc47fc1a3793ed63c550af8742d6a88906da6 Mon Sep 17 00:00:00 2001
From: Claes Redestad <redestad@openjdk.org>
Date: Tue, 22 Dec 2015 19:14:47 +0100
Subject: [PATCH 55/62] 8145862: Improve lazy initialization of fields in
 java.net.URI

Reviewed-by: shade, chegar
---
 .../java.base/share/classes/java/net/URI.java | 257 +++++++++---------
 1 file changed, 134 insertions(+), 123 deletions(-)

diff --git a/jdk/src/java.base/share/classes/java/net/URI.java b/jdk/src/java.base/share/classes/java/net/URI.java
index 93fb98d906c..e896568c7a1 100644
--- a/jdk/src/java.base/share/classes/java/net/URI.java
+++ b/jdk/src/java.base/share/classes/java/net/URI.java
@@ -489,17 +489,17 @@ public final class URI
     private transient String path;              // null ==> opaque
     private transient String query;
 
-    // The remaining fields may be computed on demand
+    // The remaining fields may be computed on demand, which is safe even in
+    // the face of multiple threads racing to initialize them
+    private transient String schemeSpecificPart;
+    private transient int hash;        // Zero ==> undefined
 
-    private transient volatile String schemeSpecificPart;
-    private transient volatile int hash;        // Zero ==> undefined
-
-    private transient volatile String decodedUserInfo;
-    private transient volatile String decodedAuthority;
-    private transient volatile String decodedPath;
-    private transient volatile String decodedQuery;
-    private transient volatile String decodedFragment;
-    private transient volatile String decodedSchemeSpecificPart;
+    private transient String decodedUserInfo;
+    private transient String decodedAuthority;
+    private transient String decodedPath;
+    private transient String decodedQuery;
+    private transient String decodedFragment;
+    private transient String decodedSchemeSpecificPart;
 
     /**
      * The string form of this URI.
@@ -910,8 +910,7 @@ public final class URI
         // either more fields or a more-obscure representation.
         if ((host != null) || (authority == null))
             return this;
-        defineString();
-        new Parser(string).parse(true);
+        new Parser(toString()).parse(true);
         return this;
     }
 
@@ -1143,8 +1142,17 @@ public final class URI
      *          (never {@code null})
      */
     public String getRawSchemeSpecificPart() {
-        defineSchemeSpecificPart();
-        return schemeSpecificPart;
+        String part = schemeSpecificPart;
+        if (part != null) {
+            return part;
+        }
+        StringBuilder sb = new StringBuilder();
+        appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
+                                 host, port, getPath(), getQuery());
+        if (sb.length() == 0) {
+            return null;
+        }
+        return schemeSpecificPart = sb.toString();
     }
 
     /**
@@ -1159,9 +1167,11 @@ public final class URI
      *          (never {@code null})
      */
     public String getSchemeSpecificPart() {
-        if (decodedSchemeSpecificPart == null)
-            decodedSchemeSpecificPart = decode(getRawSchemeSpecificPart());
-        return decodedSchemeSpecificPart;
+        String part = decodedSchemeSpecificPart;
+        if (part == null) {
+            decodedSchemeSpecificPart = part = decode(getRawSchemeSpecificPart());
+        }
+        return part;
     }
 
     /**
@@ -1192,9 +1202,11 @@ public final class URI
      *          or {@code null} if the authority is undefined
      */
     public String getAuthority() {
-        if (decodedAuthority == null)
-            decodedAuthority = decode(authority);
-        return decodedAuthority;
+        String auth = decodedAuthority;
+        if ((auth == null) && (authority != null)) {
+            decodedAuthority = auth = decode(authority);
+        }
+        return auth;
     }
 
     /**
@@ -1222,9 +1234,11 @@ public final class URI
      *          or {@code null} if the user information is undefined
      */
     public String getUserInfo() {
-        if ((decodedUserInfo == null) && (userInfo != null))
-            decodedUserInfo = decode(userInfo);
-        return decodedUserInfo;
+        String user = decodedUserInfo;
+        if ((user == null) && (userInfo != null)) {
+            decodedUserInfo = user = decode(userInfo);
+        }
+        return user;
     }
 
     /**
@@ -1306,9 +1320,11 @@ public final class URI
      *          or {@code null} if the path is undefined
      */
     public String getPath() {
-        if ((decodedPath == null) && (path != null))
-            decodedPath = decode(path);
-        return decodedPath;
+        String decoded = decodedPath;
+        if ((decoded == null) && (path != null)) {
+            decodedPath = decoded = decode(path);
+        }
+        return decoded;
     }
 
     /**
@@ -1335,9 +1351,11 @@ public final class URI
      *          or {@code null} if the query is undefined
      */
     public String getQuery() {
-        if ((decodedQuery == null) && (query != null))
-            decodedQuery = decode(query, false);
-        return decodedQuery;
+        String decoded = decodedQuery;
+        if ((decoded == null) && (query != null)) {
+            decodedQuery = decoded = decode(query, false);
+        }
+        return decoded;
     }
 
     /**
@@ -1364,9 +1382,11 @@ public final class URI
      *          or {@code null} if the fragment is undefined
      */
     public String getFragment() {
-        if ((decodedFragment == null) && (fragment != null))
-            decodedFragment = decode(fragment, false);
-        return decodedFragment;
+        String decoded = decodedFragment;
+        if ((decoded == null) && (fragment != null)) {
+            decodedFragment = decoded = decode(fragment, false);
+        }
+        return decoded;
     }
 
 
@@ -1452,24 +1472,27 @@ public final class URI
      * @return  A hash-code value for this URI
      */
     public int hashCode() {
-        if (hash != 0)
-            return hash;
-        int h = hashIgnoringCase(0, scheme);
-        h = hash(h, fragment);
-        if (isOpaque()) {
-            h = hash(h, schemeSpecificPart);
-        } else {
-            h = hash(h, path);
-            h = hash(h, query);
-            if (host != null) {
-                h = hash(h, userInfo);
-                h = hashIgnoringCase(h, host);
-                h += 1949 * port;
+        int h = hash;
+        if (h == 0) {
+            h = hashIgnoringCase(0, scheme);
+            h = hash(h, fragment);
+            if (isOpaque()) {
+                h = hash(h, schemeSpecificPart);
             } else {
-                h = hash(h, authority);
+                h = hash(h, path);
+                h = hash(h, query);
+                if (host != null) {
+                    h = hash(h, userInfo);
+                    h = hashIgnoringCase(h, host);
+                    h += 1949 * port;
+                } else {
+                    h = hash(h, authority);
+                }
+            }
+            if (h != 0) {
+                hash = h;
             }
         }
-        hash = h;
         return h;
     }
 
@@ -1599,8 +1622,59 @@ public final class URI
      * @return  The string form of this URI
      */
     public String toString() {
-        defineString();
-        return string;
+        String s = string;
+        if (s == null) {
+            s = defineString();
+        }
+        return s;
+    }
+
+    private String defineString() {
+        String s = string;
+        if (s != null) {
+            return s;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        if (scheme != null) {
+            sb.append(scheme);
+            sb.append(':');
+        }
+        if (isOpaque()) {
+            sb.append(schemeSpecificPart);
+        } else {
+            if (host != null) {
+                sb.append("//");
+                if (userInfo != null) {
+                    sb.append(userInfo);
+                    sb.append('@');
+                }
+                boolean needBrackets = ((host.indexOf(':') >= 0)
+                        && !host.startsWith("[")
+                        && !host.endsWith("]"));
+                if (needBrackets) sb.append('[');
+                sb.append(host);
+                if (needBrackets) sb.append(']');
+                if (port != -1) {
+                    sb.append(':');
+                    sb.append(port);
+                }
+            } else if (authority != null) {
+                sb.append("//");
+                sb.append(authority);
+            }
+            if (path != null)
+                sb.append(path);
+            if (query != null) {
+                sb.append('?');
+                sb.append(query);
+            }
+        }
+        if (fragment != null) {
+            sb.append('#');
+            sb.append(fragment);
+        }
+        return string = sb.toString();
     }
 
     /**
@@ -1617,8 +1691,7 @@ public final class URI
      *          charset
      */
     public String toASCIIString() {
-        defineString();
-        return encode(string);
+        return encode(toString());
     }
 
 
@@ -1824,7 +1897,7 @@ public final class URI
         }
     }
 
-    private void appendAuthority(StringBuffer sb,
+    private void appendAuthority(StringBuilder sb,
                                  String authority,
                                  String userInfo,
                                  String host,
@@ -1874,7 +1947,7 @@ public final class URI
         }
     }
 
-    private void appendSchemeSpecificPart(StringBuffer sb,
+    private void appendSchemeSpecificPart(StringBuilder sb,
                                           String opaquePart,
                                           String authority,
                                           String userInfo,
@@ -1915,7 +1988,7 @@ public final class URI
         }
     }
 
-    private void appendFragment(StringBuffer sb, String fragment) {
+    private void appendFragment(StringBuilder sb, String fragment) {
         if (fragment != null) {
             sb.append('#');
             sb.append(quote(fragment, L_URIC, H_URIC));
@@ -1932,7 +2005,7 @@ public final class URI
                             String query,
                             String fragment)
     {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         if (scheme != null) {
             sb.append(scheme);
             sb.append(':');
@@ -1944,61 +2017,6 @@ public final class URI
         return sb.toString();
     }
 
-    private void defineSchemeSpecificPart() {
-        if (schemeSpecificPart != null) return;
-        StringBuffer sb = new StringBuffer();
-        appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
-                                 host, port, getPath(), getQuery());
-        if (sb.length() == 0) return;
-        schemeSpecificPart = sb.toString();
-    }
-
-    private void defineString() {
-        if (string != null) return;
-
-        StringBuilder sb = new StringBuilder();
-        if (scheme != null) {
-            sb.append(scheme);
-            sb.append(':');
-        }
-        if (isOpaque()) {
-            sb.append(schemeSpecificPart);
-        } else {
-            if (host != null) {
-                sb.append("//");
-                if (userInfo != null) {
-                    sb.append(userInfo);
-                    sb.append('@');
-                }
-                boolean needBrackets = ((host.indexOf(':') >= 0)
-                                    && !host.startsWith("[")
-                                    && !host.endsWith("]"));
-                if (needBrackets) sb.append('[');
-                sb.append(host);
-                if (needBrackets) sb.append(']');
-                if (port != -1) {
-                    sb.append(':');
-                    sb.append(port);
-                }
-            } else if (authority != null) {
-                sb.append("//");
-                sb.append(authority);
-            }
-            if (path != null)
-                sb.append(path);
-            if (query != null) {
-                sb.append('?');
-                sb.append(query);
-            }
-        }
-        if (fragment != null) {
-            sb.append('#');
-            sb.append(fragment);
-        }
-        string = sb.toString();
-    }
-
-
     // -- Normalization, resolution, and relativization --
 
     // RFC2396 5.2 (6)
@@ -2649,13 +2667,13 @@ public final class URI
         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
     };
 
-    private static void appendEscape(StringBuffer sb, byte b) {
+    private static void appendEscape(StringBuilder sb, byte b) {
         sb.append('%');
         sb.append(hexDigits[(b >> 4) & 0x0f]);
         sb.append(hexDigits[(b >> 0) & 0x0f]);
     }
 
-    private static void appendEncoded(StringBuffer sb, char c) {
+    private static void appendEncoded(StringBuilder sb, char c) {
         ByteBuffer bb = null;
         try {
             bb = ThreadLocalCoders.encoderFor("UTF-8")
@@ -2676,15 +2694,14 @@ public final class URI
     // by the given mask pair
     //
     private static String quote(String s, long lowMask, long highMask) {
-        int n = s.length();
-        StringBuffer sb = null;
+        StringBuilder sb = null;
         boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
         for (int i = 0; i < s.length(); i++) {
             char c = s.charAt(i);
             if (c < '\u0080') {
                 if (!match(c, lowMask, highMask)) {
                     if (sb == null) {
-                        sb = new StringBuffer();
+                        sb = new StringBuilder();
                         sb.append(s, 0, i);
                     }
                     appendEscape(sb, (byte)c);
@@ -2696,7 +2713,7 @@ public final class URI
                        && (Character.isSpaceChar(c)
                            || Character.isISOControl(c))) {
                 if (sb == null) {
-                    sb = new StringBuffer();
+                    sb = new StringBuilder();
                     sb.append(s, 0, i);
                 }
                 appendEncoded(sb, c);
@@ -2733,7 +2750,7 @@ public final class URI
             assert false;
         }
 
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         while (bb.hasRemaining()) {
             int b = bb.get() & 0xff;
             if (b >= 0x80)
@@ -2864,12 +2881,6 @@ public final class URI
             fail("Expected " + expected, p);
         }
 
-        private void failExpecting(String expected, String prior, int p)
-            throws URISyntaxException
-        {
-            fail("Expected " + expected + " following " + prior, p);
-        }
-
 
         // -- Simple access to the input string --
 

From 042d41828fbe611a22de368f597bbd85c92b3079 Mon Sep 17 00:00:00 2001
From: Roger Riggs <rriggs@openjdk.org>
Date: Tue, 22 Dec 2015 14:12:55 -0500
Subject: [PATCH 56/62] 8146012: CleanerTest fails: Cleanable should have been
 freed

Simplify cleanables being called and use WhiteBox to trigger GC

Reviewed-by: chegar
---
 jdk/test/java/lang/ref/CleanerTest.java | 86 ++++++++-----------------
 1 file changed, 28 insertions(+), 58 deletions(-)

diff --git a/jdk/test/java/lang/ref/CleanerTest.java b/jdk/test/java/lang/ref/CleanerTest.java
index 8d3862ed713..deaadbdc2f2 100644
--- a/jdk/test/java/lang/ref/CleanerTest.java
+++ b/jdk/test/java/lang/ref/CleanerTest.java
@@ -28,9 +28,9 @@ import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
 import java.util.Objects;
-import java.util.Vector;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
@@ -38,15 +38,21 @@ import jdk.internal.misc.CleanerImpl.PhantomCleanable;
 import jdk.internal.misc.CleanerImpl.WeakCleanable;
 import jdk.internal.misc.CleanerImpl.SoftCleanable;
 
+import sun.hotspot.WhiteBox;
+
 import org.testng.Assert;
 import org.testng.TestNG;
 import org.testng.annotations.Test;
 
 /*
  * @test
- * @library /lib/testlibrary
+ * @library /lib/testlibrary /test/lib
+ * @build sun.hotspot.WhiteBox
  * @modules java.base/jdk.internal.misc
- * @run testng/othervm -Xmx4m CleanerTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run testng/othervm
+ *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *      -verbose:gc -Xmx4m CleanerTest
  */
 
 @Test
@@ -54,6 +60,9 @@ public class CleanerTest {
     // A common CleaningService used by the test for notifications
     static final Cleaner COMMON = Cleaner.create();
 
+    // Access to WhiteBox utilities
+    static final WhiteBox whitebox = WhiteBox.getWhiteBox();
+
     /**
      * Test that sequences of the various actions on a Reference
      * and on the Cleanable instance have the desired result.
@@ -265,50 +274,29 @@ public class CleanerTest {
     }
 
     /**
-     * Check a set of semaphores having been released by cleanup handlers.
+     * Check a semaphore having been released by cleanup handler.
      * Force a number of GC cycles to give the GC a chance to process
-     * all the References and for the cleanup actions to be run.
+     * the Reference and for the cleanup action to be run.
      *
-     * @param semaphore a varargs list of Semaphores
-     * @return true if all of the semaphores have at least 1 permit,
-     *      false otherwise.
+     * @param semaphore a Semaphore
+     * @return true if the semaphores has 1 permit, false otherwise.
      */
-    static boolean checkCleaned(Semaphore... semaphore) {
-        long[] cycles = new long[semaphore.length];
-        long total = 0;
-        for (int cycle = 0; cycle < 20; cycle++) {
-            for (int i = 0; i < semaphore.length; i++) {
-                long count = semaphore[i].availablePermits();
-                if (count > 0 && cycles[i] == 0) {
-                    System.out.printf(" Cleanable[%d] cleaned in cycle: %d%n", i, cycle);
-                    cycles[i] = cycle;
-                    total += 1;
+    static boolean checkCleaned(Semaphore semaphore) {
+        int cycle = 0;
+        for (; cycle < 3; cycle++) {
+            try {
+                if (semaphore.tryAcquire(10L, TimeUnit.MILLISECONDS)) {
+                    System.out.printf(" Cleanable cleaned in cycle: %d%n", cycle);
+                    return true;
                 }
-            }
-
-            if (total == semaphore.length) {
-                System.out.printf(" All cleanups done in cycle: %d, total: %d%n",
-                        cycle, total);
-                for (int i = 0; i < semaphore.length; i++) {
-                    long count = semaphore[i].availablePermits();
-                    Assert.assertEquals(count, 1,
-                            "Cleanable invoked more than once, semaphore " + i);
-                }
-                return true;          // all references freed
+            } catch (InterruptedException ie) {
+                // retry in outer loop
             }
             // Force GC
-            memoryPressure();
+            whitebox.fullGC();
         }
-        // Not all objects have been cleaned
-
-        for (int i = 0; i < semaphore.length; i++) {
-            if (cycles[i] != 0) {
-                System.out.printf(" Cleanable[%d] cleaned in cycle: %d%n", i, cycles[i]);
-            } else {
-                System.out.printf(" Cleanable[%d] not cleaned%n", i);
-            }
-        }
-
+        // Object has not been cleaned
+        System.out.printf(" Cleanable not cleaned%n");
         return false;   // Failing result
     }
 
@@ -456,24 +444,6 @@ public class CleanerTest {
         return new CleanableCase(new SoftReference<>(obj, null), c1, s1, true);
     }
 
-    /**
-     * MemoryPressure allocates memory to force a gc and to clear SoftReferences.
-     */
-    static void memoryPressure() {
-        SoftReference<Object> soft = new SoftReference<>(new Object(), null);
-        Vector<Object> root = new Vector<>();
-        try {
-            long free = 0;
-            while (soft.get() != null) {
-                long[] extra = new long[50_000];
-                root.addElement(extra);
-            }
-        } catch (OutOfMemoryError mem) {
-            // ignore
-            root = null;
-        }
-    }
-
     /**
      * CleanableCase encapsulates the objects used for a test.
      * The reference to the object is not held directly,

From 626fc9bc75f654497d1be747649aae5508374123 Mon Sep 17 00:00:00 2001
From: Chris Hegarty <chegar@openjdk.org>
Date: Tue, 22 Dec 2015 21:30:48 +0000
Subject: [PATCH 57/62] 8146038: CleanerImpl should not depend on
 ManagedLocalsThread

Reviewed-by: rriggs
---
 .../share/classes/jdk/internal/misc/CleanerImpl.java        | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java b/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java
index cec14ba5b42..4ce835f9a39 100644
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/CleanerImpl.java
@@ -39,7 +39,6 @@ import java.util.concurrent.ThreadFactory;
 import java.util.function.Function;
 
 import sun.misc.InnocuousThread;
-import sun.misc.ManagedLocalsThread;
 
 /**
  * CleanerImpl manages a set of object references and corresponding cleaning actions.
@@ -130,8 +129,8 @@ public final class CleanerImpl implements Runnable {
      */
     public void run() {
         Thread t = Thread.currentThread();
-        ManagedLocalsThread mlThread = (t instanceof ManagedLocalsThread)
-                ? (ManagedLocalsThread) t
+        InnocuousThread mlThread = (t instanceof InnocuousThread)
+                ? (InnocuousThread) t
                 : null;
         while (!phantomCleanableList.isListEmpty() ||
                 !weakCleanableList.isListEmpty() ||
@@ -787,4 +786,3 @@ public final class CleanerImpl implements Runnable {
     }
 
 }
-

From 7f221493d8c4f959ec27f8db0d59360880a817d1 Mon Sep 17 00:00:00 2001
From: Chris Hegarty <chegar@openjdk.org>
Date: Tue, 22 Dec 2015 21:32:29 +0000
Subject: [PATCH 58/62] 8146000: Remove sun.mics.CompoundEnumeration

Reviewed-by: coffeys, shade
---
 .../share/classes/java/lang/ClassLoader.java  | 35 ++++++++++-
 .../classes/sun/misc/CompoundEnumeration.java | 63 -------------------
 2 files changed, 34 insertions(+), 64 deletions(-)
 delete mode 100644 jdk/src/java.base/share/classes/sun/misc/CompoundEnumeration.java

diff --git a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
index a3009062c2d..76cdd25dcd7 100644
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -45,11 +45,11 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.Stack;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Vector;
 import java.util.Hashtable;
 import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
-import sun.misc.CompoundEnumeration;
 import sun.misc.Resource;
 import sun.misc.URLClassPath;
 import sun.reflect.CallerSensitive;
@@ -2206,3 +2206,36 @@ class SystemClassLoaderAction
         return sys;
     }
 }
+
+/*
+ * A utility class that will enumerate over an array of enumerations.
+ */
+final class CompoundEnumeration<E> implements Enumeration<E> {
+    private final Enumeration<E>[] enums;
+    private int index;
+
+    public CompoundEnumeration(Enumeration<E>[] enums) {
+        this.enums = enums;
+    }
+
+    private boolean next() {
+        while (index < enums.length) {
+            if (enums[index] != null && enums[index].hasMoreElements()) {
+                return true;
+            }
+            index++;
+        }
+        return false;
+    }
+
+    public boolean hasMoreElements() {
+        return next();
+    }
+
+    public E nextElement() {
+        if (!next()) {
+            throw new NoSuchElementException();
+        }
+        return enums[index].nextElement();
+    }
+}
diff --git a/jdk/src/java.base/share/classes/sun/misc/CompoundEnumeration.java b/jdk/src/java.base/share/classes/sun/misc/CompoundEnumeration.java
deleted file mode 100644
index a89ec5f59c4..00000000000
--- a/jdk/src/java.base/share/classes/sun/misc/CompoundEnumeration.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 1998, 2011, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.misc;
-
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-/*
- * A useful utility class that will enumerate over an array of
- * enumerations.
- */
-public class CompoundEnumeration<E> implements Enumeration<E> {
-    private Enumeration<E>[] enums;
-    private int index = 0;
-
-    public CompoundEnumeration(Enumeration<E>[] enums) {
-        this.enums = enums;
-    }
-
-    private boolean next() {
-        while (index < enums.length) {
-            if (enums[index] != null && enums[index].hasMoreElements()) {
-                return true;
-            }
-            index++;
-        }
-        return false;
-    }
-
-    public boolean hasMoreElements() {
-        return next();
-    }
-
-    public E nextElement() {
-        if (!next()) {
-            throw new NoSuchElementException();
-        }
-        return enums[index].nextElement();
-    }
-}

From 80015b758637d83b02e125139b53e18328ccaf8d Mon Sep 17 00:00:00 2001
From: Xue-Lei Andrew Fan <xuelei@openjdk.org>
Date: Wed, 23 Dec 2015 03:51:35 +0000
Subject: [PATCH 59/62] 8133070: Hot lock on BulkCipher.isAvailable

Reviewed-by: mullan
---
 .../classes/sun/security/ssl/CipherBox.java   |  35 --
 .../classes/sun/security/ssl/CipherSuite.java | 127 ++--
 .../sun/security/ssl/CipherSuiteList.java     |  30 +-
 .../classes/sun/security/ssl/JsseJce.java     |  48 +-
 .../sun/security/ssl/SSLContextImpl.java      | 548 ++++++++++--------
 5 files changed, 366 insertions(+), 422 deletions(-)

diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
index 9f76d19792f..57a3e1e8aa6 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java
@@ -1105,41 +1105,6 @@ final class CipherBox {
         return fragLen;
     }
 
-
-    /*
-     * Is this cipher available?
-     *
-     * This method can only be called by CipherSuite.BulkCipher.isAvailable()
-     * to test the availability of a cipher suites.  Please DON'T use it in
-     * other places, otherwise, the behavior may be unexpected because we may
-     * initialize AEAD cipher improperly in the method.
-     */
-    Boolean isAvailable() {
-        // We won't know whether a cipher for a particular key size is
-        // available until the cipher is successfully initialized.
-        //
-        // We do not initialize AEAD cipher in the constructor.  Need to
-        // initialize the cipher to ensure that the AEAD mode for a
-        // particular key size is supported.
-        if (cipherType == AEAD_CIPHER) {
-            try {
-                Authenticator authenticator =
-                    new Authenticator(protocolVersion);
-                byte[] nonce = authenticator.sequenceNumber();
-                byte[] iv = Arrays.copyOf(fixedIv,
-                                            fixedIv.length + nonce.length);
-                System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length);
-                GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv);
-
-                cipher.init(mode, key, spec, random);
-            } catch (Exception e) {
-                return Boolean.FALSE;
-            }
-        }   // Otherwise, we have initialized the cipher in the constructor.
-
-        return Boolean.TRUE;
-    }
-
     /**
      * Sanity check the length of a fragment before decryption.
      *
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
index 65a110b479e..fa6c5ad34bb 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuite.java
@@ -77,12 +77,6 @@ final class CipherSuite implements Comparable<CipherSuite> {
     // minimum priority for default enabled CipherSuites
     static final int DEFAULT_SUITES_PRIORITY = 300;
 
-    // Flag indicating if CipherSuite availability can change dynamically.
-    // This is the case when we rely on a JCE cipher implementation that
-    // may not be available in the installed JCE providers.
-    // It is true because we might not have an ECC implementation.
-    static final boolean DYNAMIC_AVAILABILITY = true;
-
     private static final boolean ALLOW_ECC = Debug.getBooleanProperty
         ("com.sun.net.ssl.enableECC", true);
 
@@ -176,9 +170,6 @@ final class CipherSuite implements Comparable<CipherSuite> {
      * Return whether this CipherSuite is available for use. A
      * CipherSuite may be unavailable even if it is supported
      * (i.e. allowed == true) if the required JCE cipher is not installed.
-     * In some configuration, this situation may change over time, call
-     * CipherSuiteList.clearAvailableCache() before this method to obtain
-     * the most current status.
      */
     boolean isAvailable() {
         return allowed && keyExchange.isAvailable() && cipher.isAvailable();
@@ -471,10 +462,6 @@ final class CipherSuite implements Comparable<CipherSuite> {
         B_AES_128_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 16, 12, 4, true),
         B_AES_256_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 32, 12, 4, true);
 
-        // Map BulkCipher -> Boolean(available)
-        private static final Map<BulkCipher,Boolean> availableCache =
-                                            new HashMap<>(8);
-
         // descriptive name including key size, e.g. AES/128
         final String description;
 
@@ -518,6 +505,9 @@ final class CipherSuite implements Comparable<CipherSuite> {
         // The secure random used to detect the cipher availability.
         private static final SecureRandom secureRandom;
 
+        // runtime availability
+        private final boolean isAvailable;
+
         static {
             try {
                 secureRandom = JsseJce.getSecureRandom();
@@ -542,6 +532,17 @@ final class CipherSuite implements Comparable<CipherSuite> {
 
             this.expandedKeySize = expandedKeySize;
             this.exportable = true;
+
+            // availability of this bulk cipher
+            //
+            // Currently all supported ciphers except AES are always available
+            // via the JSSE internal implementations. We also assume AES/128 of
+            // CBC mode is always available since it is shipped with the SunJCE
+            // provider.  However, AES/256 is unavailable when the default JCE
+            // policy jurisdiction files are installed because of key length
+            // restrictions.
+            this.isAvailable =
+                    allowed ? isUnlimited(keySize, transformation) : false;
         }
 
         BulkCipher(String transformation, CipherType cipherType, int keySize,
@@ -558,6 +559,17 @@ final class CipherSuite implements Comparable<CipherSuite> {
 
             this.expandedKeySize = keySize;
             this.exportable = false;
+
+            // availability of this bulk cipher
+            //
+            // Currently all supported ciphers except AES are always available
+            // via the JSSE internal implementations. We also assume AES/128 of
+            // CBC mode is always available since it is shipped with the SunJCE
+            // provider.  However, AES/256 is unavailable when the default JCE
+            // policy jurisdiction files are installed because of key length
+            // restrictions.
+            this.isAvailable =
+                    allowed ? isUnlimited(keySize, transformation) : false;
         }
 
         /**
@@ -575,86 +587,29 @@ final class CipherSuite implements Comparable<CipherSuite> {
 
         /**
          * Test if this bulk cipher is available. For use by CipherSuite.
-         *
-         * Currently all supported ciphers except AES are always available
-         * via the JSSE internal implementations. We also assume AES/128 of
-         * CBC mode is always available since it is shipped with the SunJCE
-         * provider.  However, AES/256 is unavailable when the default JCE
-         * policy jurisdiction files are installed because of key length
-         * restrictions, and AEAD is unavailable when the underlying providers
-         * do not support AEAD/GCM mode.
          */
         boolean isAvailable() {
-            if (allowed == false) {
-                return false;
+            return this.isAvailable;
+        }
+
+        private static boolean isUnlimited(int keySize, String transformation) {
+            int keySizeInBits = keySize * 8;
+            if (keySizeInBits > 128) {    // need the JCE unlimited
+                                          // strength jurisdiction policy
+                try {
+                    if (Cipher.getMaxAllowedKeyLength(
+                            transformation) < keySizeInBits) {
+
+                        return false;
+                    }
+                } catch (Exception e) {
+                    return false;
+                }
             }
 
-            if ((this == B_AES_256) ||
-                    (this.cipherType == CipherType.AEAD_CIPHER)) {
-                return isAvailable(this);
-            }
-
-            // always available
             return true;
         }
 
-        // for use by CipherSuiteList.clearAvailableCache();
-        static synchronized void clearAvailableCache() {
-            if (DYNAMIC_AVAILABILITY) {
-                availableCache.clear();
-            }
-        }
-
-        private static synchronized boolean isAvailable(BulkCipher cipher) {
-            Boolean b = availableCache.get(cipher);
-            if (b == null) {
-                int keySizeInBits = cipher.keySize * 8;
-                if (keySizeInBits > 128) {    // need the JCE unlimited
-                                               // strength jurisdiction policy
-                    try {
-                        if (Cipher.getMaxAllowedKeyLength(
-                                cipher.transformation) < keySizeInBits) {
-                            b = Boolean.FALSE;
-                        }
-                    } catch (Exception e) {
-                        b = Boolean.FALSE;
-                    }
-                }
-
-                if (b == null) {
-                    b = Boolean.FALSE;          // may be reset to TRUE if
-                                                // the cipher is available
-                    CipherBox temporary = null;
-                    try {
-                        SecretKey key = new SecretKeySpec(
-                                            new byte[cipher.expandedKeySize],
-                                            cipher.algorithm);
-                        IvParameterSpec iv;
-                        if (cipher.cipherType == CipherType.AEAD_CIPHER) {
-                            iv = new IvParameterSpec(
-                                            new byte[cipher.fixedIvSize]);
-                        } else {
-                            iv = new IvParameterSpec(new byte[cipher.ivSize]);
-                        }
-                        temporary = cipher.newCipher(
-                                            ProtocolVersion.DEFAULT_TLS,
-                                            key, iv, secureRandom, true);
-                        b = temporary.isAvailable();
-                    } catch (NoSuchAlgorithmException e) {
-                        // not available
-                    } finally {
-                        if (temporary != null) {
-                            temporary.dispose();
-                        }
-                    }
-                }
-
-                availableCache.put(cipher, b);
-            }
-
-            return b.booleanValue();
-        }
-
         @Override
         public String toString() {
             return description;
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java
index 19dc90fa4c5..491bffa85ba 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherSuiteList.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -74,24 +74,12 @@ final class CipherSuiteList {
             throw new IllegalArgumentException("CipherSuites may not be null");
         }
         cipherSuites = new ArrayList<CipherSuite>(names.length);
-        // refresh available cache once if a CipherSuite is not available
-        // (maybe new JCE providers have been installed)
-        boolean refreshed = false;
         for (int i = 0; i < names.length; i++) {
             String suiteName = names[i];
             CipherSuite suite = CipherSuite.valueOf(suiteName);
             if (suite.isAvailable() == false) {
-                if (refreshed == false) {
-                    // clear the cache so that the isAvailable() call below
-                    // does a full check
-                    clearAvailableCache();
-                    refreshed = true;
-                }
-                // still missing?
-                if (suite.isAvailable() == false) {
-                    throw new IllegalArgumentException("Cannot support "
-                        + suiteName + " with currently installed providers");
-                }
+                throw new IllegalArgumentException("Cannot support "
+                    + suiteName + " with currently installed providers");
             }
             cipherSuites.add(suite);
         }
@@ -195,16 +183,4 @@ final class CipherSuiteList {
         }
         s.putBytes16(suiteBytes);
     }
-
-    /**
-     * Clear cache of available ciphersuites. If we support all ciphers
-     * internally, there is no need to clear the cache and calling this
-     * method has no effect.
-     */
-    static synchronized void clearAvailableCache() {
-        if (CipherSuite.DYNAMIC_AVAILABILITY) {
-            CipherSuite.BulkCipher.clearAvailableCache();
-            JsseJce.clearEcAvailable();
-        }
-    }
 }
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java
index 43d62b60152..aebc7c09c08 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/JsseJce.java
@@ -55,11 +55,6 @@ final class JsseJce {
 
     private static final ProviderList fipsProviderList;
 
-    // Flag indicating whether EC crypto is available.
-    // If null, then we have not checked yet.
-    // If yes, then all the EC based crypto we need is available.
-    private static Boolean ecAvailable;
-
     // Flag indicating whether Kerberos crypto is available.
     // If true, then all the Kerberos-based crypto we need is available.
     private static final boolean kerberosAvailable;
@@ -180,24 +175,8 @@ final class JsseJce {
         // no instantiation of this class
     }
 
-    static synchronized boolean isEcAvailable() {
-        if (ecAvailable == null) {
-            try {
-                JsseJce.getSignature(SIGNATURE_ECDSA);
-                JsseJce.getSignature(SIGNATURE_RAWECDSA);
-                JsseJce.getKeyAgreement("ECDH");
-                JsseJce.getKeyFactory("EC");
-                JsseJce.getKeyPairGenerator("EC");
-                ecAvailable = true;
-            } catch (Exception e) {
-                ecAvailable = false;
-            }
-        }
-        return ecAvailable;
-    }
-
-    static synchronized void clearEcAvailable() {
-        ecAvailable = null;
+    static boolean isEcAvailable() {
+        return EcAvailability.isAvailable;
     }
 
     static boolean isKerberosAvailable() {
@@ -399,4 +378,27 @@ final class JsseJce {
         }
     }
 
+
+    // lazy initialization holder class idiom for static default parameters
+    //
+    // See Effective Java Second Edition: Item 71.
+    private static class EcAvailability {
+        // Is EC crypto available?
+        private final static boolean isAvailable;
+
+        static {
+            boolean mediator = true;
+            try {
+                JsseJce.getSignature(SIGNATURE_ECDSA);
+                JsseJce.getSignature(SIGNATURE_RAWECDSA);
+                JsseJce.getKeyAgreement("ECDH");
+                JsseJce.getKeyFactory("EC");
+                JsseJce.getKeyPairGenerator("EC");
+            } catch (Exception e) {
+                mediator = false;
+            }
+
+            isAvailable = mediator;
+        }
+    }
 }
diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
index cac13df0184..15b420da172 100644
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -52,18 +52,8 @@ public abstract class SSLContextImpl extends SSLContextSpi {
     private X509TrustManager trustManager;
     private SecureRandom secureRandom;
 
-    // supported and default protocols
-    private ProtocolList defaultServerProtocolList;
-    private ProtocolList defaultClientProtocolList;
-    private ProtocolList supportedProtocolList;
-
-    // supported and default cipher suites
-    private CipherSuiteList defaultServerCipherSuiteList;
-    private CipherSuiteList defaultClientCipherSuiteList;
-    private CipherSuiteList supportedCipherSuiteList;
-
     // DTLS cookie exchange manager
-    private HelloCookieManager helloCookieManager;
+    private volatile HelloCookieManager helloCookieManager;
 
     private StatusResponseManager statusResponseManager;
 
@@ -117,6 +107,7 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         if (debug != null && Debug.isOn("sslctx")) {
             System.out.println("done seeding SecureRandom");
         }
+
         isInitialized = true;
     }
 
@@ -242,13 +233,20 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         return ephemeralKeyManager;
     }
 
+    // Used for DTLS in server mode only, see ServerHandshaker.
     HelloCookieManager getHelloCookieManager() {
         if (!isInitialized) {
             throw new IllegalStateException("SSLContext is not initialized");
         }
 
-        if (helloCookieManager == null) {
-            helloCookieManager = getHelloCookieManager(secureRandom);
+        if (helloCookieManager != null) {
+            return helloCookieManager;
+        }
+
+        synchronized (this) {
+            if (helloCookieManager == null) {
+                helloCookieManager = getHelloCookieManager(secureRandom);
+            }
         }
 
         return helloCookieManager;
@@ -263,78 +261,34 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         return statusResponseManager;
     }
 
-    abstract SSLParameters getDefaultServerSSLParams();
-    abstract SSLParameters getDefaultClientSSLParams();
-    abstract SSLParameters getSupportedSSLParams();
-
     // Get supported ProtocolList.
-    ProtocolList getSuportedProtocolList() {
-        if (supportedProtocolList == null) {
-            supportedProtocolList =
-                new ProtocolList(getSupportedSSLParams().getProtocols());
-        }
+    abstract ProtocolList getSuportedProtocolList();
 
-        return supportedProtocolList;
-    }
+    // Get default ProtocolList for server mode.
+    abstract ProtocolList getServerDefaultProtocolList();
+
+    // Get default ProtocolList for client mode.
+    abstract ProtocolList getClientDefaultProtocolList();
+
+    // Get supported CipherSuiteList.
+    abstract CipherSuiteList getSupportedCipherSuiteList();
+
+    // Get default CipherSuiteList for server mode.
+    abstract CipherSuiteList getServerDefaultCipherSuiteList();
+
+    // Get default CipherSuiteList for client mode.
+    abstract CipherSuiteList getClientDefaultCipherSuiteList();
 
     // Get default ProtocolList.
     ProtocolList getDefaultProtocolList(boolean roleIsServer) {
-        if (roleIsServer) {
-            if (defaultServerProtocolList == null) {
-                defaultServerProtocolList = new ProtocolList(
-                        getDefaultServerSSLParams().getProtocols());
-            }
-
-            return defaultServerProtocolList;
-        } else {
-            if (defaultClientProtocolList == null) {
-                defaultClientProtocolList = new ProtocolList(
-                        getDefaultClientSSLParams().getProtocols());
-            }
-
-            return defaultClientProtocolList;
-        }
-    }
-
-    // Get supported CipherSuiteList.
-    CipherSuiteList getSupportedCipherSuiteList() {
-        // The maintenance of cipher suites needs to be synchronized.
-        synchronized (this) {
-            // Clear cache of available ciphersuites.
-            clearAvailableCache();
-
-            if (supportedCipherSuiteList == null) {
-                supportedCipherSuiteList = getApplicableCipherSuiteList(
-                        getSuportedProtocolList(), false);
-            }
-
-            return supportedCipherSuiteList;
-        }
+        return roleIsServer ? getServerDefaultProtocolList()
+                            : getClientDefaultProtocolList();
     }
 
     // Get default CipherSuiteList.
     CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
-        // The maintenance of cipher suites needs to be synchronized.
-        synchronized (this) {
-            // Clear cache of available ciphersuites.
-            clearAvailableCache();
-
-            if (roleIsServer) {
-                if (defaultServerCipherSuiteList == null) {
-                    defaultServerCipherSuiteList = getApplicableCipherSuiteList(
-                        getDefaultProtocolList(true), true);
-                }
-
-                return defaultServerCipherSuiteList;
-            } else {
-                if (defaultClientCipherSuiteList == null) {
-                    defaultClientCipherSuiteList = getApplicableCipherSuiteList(
-                        getDefaultProtocolList(false), true);
-                }
-
-                return defaultClientCipherSuiteList;
-            }
-        }
+        return roleIsServer ? getServerDefaultCipherSuiteList()
+                            : getClientDefaultCipherSuiteList();
     }
 
     /**
@@ -342,8 +296,8 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
      */
     boolean isDefaultProtocolList(ProtocolList protocols) {
-        return (protocols == defaultServerProtocolList) ||
-               (protocols == defaultClientProtocolList);
+        return (protocols == getServerDefaultProtocolList()) ||
+               (protocols == getClientDefaultProtocolList());
     }
 
     /**
@@ -351,8 +305,8 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
      */
     boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
-        return (cipherSuites == defaultClientCipherSuiteList) ||
-               (cipherSuites == defaultServerCipherSuiteList);
+        return (cipherSuites == getServerDefaultCipherSuiteList()) ||
+               (cipherSuites == getClientDefaultCipherSuiteList());
     }
 
     /*
@@ -405,24 +359,6 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         return new CipherSuiteList(suites);
     }
 
-    /**
-     * Clear cache of available ciphersuites. If we support all ciphers
-     * internally, there is no need to clear the cache and calling this
-     * method has no effect.
-     *
-     * Note that every call to clearAvailableCache() and the maintenance of
-     * cipher suites need to be synchronized with this instance.
-     */
-    private void clearAvailableCache() {
-        if (CipherSuite.DYNAMIC_AVAILABILITY) {
-            supportedCipherSuiteList = null;
-            defaultServerCipherSuiteList = null;
-            defaultClientCipherSuiteList = null;
-            CipherSuite.BulkCipher.clearAvailableCache();
-            JsseJce.clearEcAvailable();
-        }
-    }
-
     private static String[] getAvailableProtocols(
             ProtocolVersion[] protocolCandidates) {
 
@@ -479,31 +415,28 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     private abstract static class AbstractTLSContext extends SSLContextImpl {
-        // parameters
-        private static final SSLParameters defaultServerSSLParams;
-        private static final SSLParameters supportedSSLParams;
+        private static final ProtocolList supportedProtocolList;
+        private static final ProtocolList serverDefaultProtocolList;
+
+        private static final CipherSuiteList supportedCipherSuiteList;
+        private static final CipherSuiteList serverDefaultCipherSuiteList;
 
         static {
-            // supported SSL parameters
-            supportedSSLParams = new SSLParameters();
-
-            // candidates for available protocols
-            ProtocolVersion[] candidates;
-
             if (SunJSSE.isFIPS()) {
-                supportedSSLParams.setProtocols(new String[] {
+                supportedProtocolList = new ProtocolList(new String[] {
                     ProtocolVersion.TLS10.name,
                     ProtocolVersion.TLS11.name,
                     ProtocolVersion.TLS12.name
                 });
 
-                candidates = new ProtocolVersion[] {
+                serverDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.TLS10,
                     ProtocolVersion.TLS11,
                     ProtocolVersion.TLS12
-                };
+                }));
             } else {
-                supportedSSLParams.setProtocols(new String[] {
+                supportedProtocolList = new ProtocolList(new String[] {
                     ProtocolVersion.SSL20Hello.name,
                     ProtocolVersion.SSL30.name,
                     ProtocolVersion.TLS10.name,
@@ -511,28 +444,40 @@ public abstract class SSLContextImpl extends SSLContextSpi {
                     ProtocolVersion.TLS12.name
                 });
 
-                candidates = new ProtocolVersion[] {
+                serverDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.SSL20Hello,
                     ProtocolVersion.SSL30,
                     ProtocolVersion.TLS10,
                     ProtocolVersion.TLS11,
                     ProtocolVersion.TLS12
-                };
+                }));
             }
 
-            defaultServerSSLParams = new SSLParameters();
-            defaultServerSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            supportedCipherSuiteList = getApplicableCipherSuiteList(
+                    supportedProtocolList, false);          // all supported
+            serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    serverDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultServerSSLParams() {
-            return defaultServerSSLParams;
+        ProtocolList getSuportedProtocolList() {
+            return supportedProtocolList;
         }
 
         @Override
-        SSLParameters getSupportedSSLParams() {
-            return supportedSSLParams;
+        CipherSuiteList getSupportedCipherSuiteList() {
+            return supportedCipherSuiteList;
+        }
+
+        @Override
+        ProtocolList getServerDefaultProtocolList() {
+            return serverDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getServerDefaultCipherSuiteList() {
+            return serverDefaultCipherSuiteList;
         }
 
         @Override
@@ -552,30 +497,35 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     public static final class TLS10Context extends AbstractTLSContext {
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
 
         static {
-            // candidates for available protocols
-            ProtocolVersion[] candidates;
             if (SunJSSE.isFIPS()) {
-                candidates = new ProtocolVersion[] {
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.TLS10
-                };
+                }));
             } else {
-                candidates = new ProtocolVersion[] {
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.SSL30,
                     ProtocolVersion.TLS10
-                };
+                }));
             }
 
-            defaultClientSSLParams = new SSLParameters();
-            defaultClientSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -585,32 +535,37 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     public static final class TLS11Context extends AbstractTLSContext {
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
 
         static {
-            // candidates for available protocols
-            ProtocolVersion[] candidates;
             if (SunJSSE.isFIPS()) {
-                candidates = new ProtocolVersion[] {
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.TLS10,
                     ProtocolVersion.TLS11
-                };
+                }));
             } else {
-                candidates = new ProtocolVersion[] {
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.SSL30,
                     ProtocolVersion.TLS10,
                     ProtocolVersion.TLS11
-                };
+                }));
             }
 
-            defaultClientSSLParams = new SSLParameters();
-            defaultClientSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -620,34 +575,39 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     public static final class TLS12Context extends AbstractTLSContext {
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
 
         static {
-            // candidates for available protocols
-            ProtocolVersion[] candidates;
             if (SunJSSE.isFIPS()) {
-                candidates = new ProtocolVersion[] {
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.TLS10,
                     ProtocolVersion.TLS11,
                     ProtocolVersion.TLS12
-                };
+                }));
             } else {
-                candidates = new ProtocolVersion[] {
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(new ProtocolVersion[] {
                     ProtocolVersion.SSL30,
                     ProtocolVersion.TLS10,
                     ProtocolVersion.TLS11,
                     ProtocolVersion.TLS12
-                };
+                }));
             }
 
-            defaultClientSSLParams = new SSLParameters();
-            defaultClientSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -719,7 +679,9 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      */
     private static class CustomizedTLSContext extends AbstractTLSContext {
 
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
+
         private static IllegalArgumentException reservedException = null;
 
         // Don't want a java.lang.LinkageError for illegal system property.
@@ -766,11 +728,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
                     candidates = customizedTLSProtocols.toArray(candidates);
                 }
 
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(
+                clientDefaultProtocolList = new ProtocolList(
                         getAvailableProtocols(candidates));
+                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);   // enabled only
             } else {
-                defaultClientSSLParams = null;  // unlikely to be used
+                clientDefaultProtocolList = null;       // unlikely to be used
+                clientDefaultCipherSuiteList = null;    // unlikely to be used
             }
         }
 
@@ -781,8 +745,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -795,71 +764,53 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         // use the default constructor and methods
     }
 
-    /*
-     * The SSLContext implementation for default "Default" algorithm
-     *
-     * @see SSLContext
-     */
-    public static final class DefaultSSLContext extends CustomizedTLSContext {
+    // lazy initialization holder class idiom for static default parameters
+    //
+    // See Effective Java Second Edition: Item 71.
+    private static final class DefaultManagersHolder {
         private static final String NONE = "NONE";
         private static final String P11KEYSTORE = "PKCS11";
 
-        private static volatile SSLContextImpl defaultImpl;
+        private static final TrustManager[] trustManagers;
+        private static final KeyManager[] keyManagers;
 
-        private static TrustManager[] defaultTrustManagers;
-        private static KeyManager[] defaultKeyManagers;
+        static Exception reservedException = null;
 
-        public DefaultSSLContext() throws Exception {
+        static {
+            TrustManager[] tmMediator;
             try {
-                super.engineInit(getDefaultKeyManager(),
-                        getDefaultTrustManager(), null);
+                tmMediator = getTrustManagers();
             } catch (Exception e) {
-                if (debug != null && Debug.isOn("defaultctx")) {
-                    System.out.println("default context init failed: " + e);
+                reservedException = e;
+                tmMediator = new TrustManager[0];
+            }
+            trustManagers = tmMediator;
+
+            if (reservedException == null) {
+                KeyManager[] kmMediator;
+                try {
+                    kmMediator = getKeyManagers();
+                } catch (Exception e) {
+                    reservedException = e;
+                    kmMediator = new KeyManager[0];
                 }
-                throw e;
-            }
-
-            if (defaultImpl == null) {
-                defaultImpl = this;
+                keyManagers = kmMediator;
+            } else {
+                keyManagers = new KeyManager[0];
             }
         }
 
-        @Override
-        protected void engineInit(KeyManager[] km, TrustManager[] tm,
-            SecureRandom sr) throws KeyManagementException {
-            throw new KeyManagementException
-                ("Default SSLContext is initialized automatically");
-        }
-
-        static synchronized SSLContextImpl getDefaultImpl() throws Exception {
-            if (defaultImpl == null) {
-                new DefaultSSLContext();
-            }
-            return defaultImpl;
-        }
-
-        private static synchronized TrustManager[] getDefaultTrustManager()
-                throws Exception {
-            if (defaultTrustManagers != null) {
-                return defaultTrustManagers;
-            }
-
+        private static TrustManager[] getTrustManagers() throws Exception {
             KeyStore ks =
                 TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
 
             TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                 TrustManagerFactory.getDefaultAlgorithm());
             tmf.init(ks);
-            defaultTrustManagers = tmf.getTrustManagers();
-            return defaultTrustManagers;
+            return tmf.getTrustManagers();
         }
 
-        private static synchronized KeyManager[] getDefaultKeyManager()
-                throws Exception {
-            if (defaultKeyManagers != null) {
-                return defaultKeyManagers;
-            }
+        private static KeyManager[] getKeyManagers() throws Exception {
 
             final Map<String,String> props = new HashMap<>();
             AccessController.doPrivileged(
@@ -956,8 +907,71 @@ public abstract class SSLContextImpl extends SSLContextSpi {
                 kmf.init(ks, passwd);
             }
 
-            defaultKeyManagers = kmf.getKeyManagers();
-            return defaultKeyManagers;
+            return kmf.getKeyManagers();
+        }
+    }
+
+    // lazy initialization holder class idiom for static default parameters
+    //
+    // See Effective Java Second Edition: Item 71.
+    private static final class DefaultSSLContextHolder {
+
+        private static final SSLContextImpl sslContext;
+        static Exception reservedException = null;
+
+        static {
+            SSLContextImpl mediator = null;
+            if (DefaultManagersHolder.reservedException != null) {
+                reservedException = DefaultManagersHolder.reservedException;
+            } else {
+                try {
+                    mediator = new DefaultSSLContext();
+                } catch (Exception e) {
+                    reservedException = e;
+                }
+            }
+
+            sslContext = mediator;
+        }
+    }
+
+    /*
+     * The SSLContext implementation for default "Default" algorithm
+     *
+     * @see SSLContext
+     */
+    public static final class DefaultSSLContext extends CustomizedTLSContext {
+
+        // public constructor for SSLContext.getInstance("Default")
+        public DefaultSSLContext() throws Exception {
+            if (DefaultManagersHolder.reservedException != null) {
+                throw DefaultManagersHolder.reservedException;
+            }
+
+            try {
+                super.engineInit(DefaultManagersHolder.keyManagers,
+                        DefaultManagersHolder.trustManagers, null);
+            } catch (Exception e) {
+                if (debug != null && Debug.isOn("defaultctx")) {
+                    System.out.println("default context init failed: " + e);
+                }
+                throw e;
+            }
+        }
+
+        @Override
+        protected void engineInit(KeyManager[] km, TrustManager[] tm,
+            SecureRandom sr) throws KeyManagementException {
+            throw new KeyManagementException
+                ("Default SSLContext is initialized automatically");
+        }
+
+        static SSLContextImpl getDefaultImpl() throws Exception {
+            if (DefaultSSLContextHolder.reservedException != null) {
+                throw DefaultSSLContextHolder.reservedException;
+            }
+
+            return DefaultSSLContextHolder.sslContext;
         }
     }
 
@@ -971,39 +985,50 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     private abstract static class AbstractDTLSContext extends SSLContextImpl {
-        // parameters
-        private static final SSLParameters defaultServerSSLParams;
-        private static final SSLParameters supportedSSLParams;
+        private static final ProtocolList supportedProtocolList;
+        private static final ProtocolList serverDefaultProtocolList;
+
+        private static final CipherSuiteList supportedCipherSuiteList;
+        private static final CipherSuiteList serverDefaultCipherSuiteList;
 
         static {
-            // supported SSL parameters
-            supportedSSLParams = new SSLParameters();
-
             // Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
-            supportedSSLParams.setProtocols(new String[] {
+            supportedProtocolList = new ProtocolList(new String[] {
                 ProtocolVersion.DTLS10.name,
                 ProtocolVersion.DTLS12.name
             });
 
-            // candidates for available protocols
-            ProtocolVersion[] candidates = new ProtocolVersion[] {
+            // available protocols for server mode
+            serverDefaultProtocolList = new ProtocolList(
+                    getAvailableProtocols(new ProtocolVersion[] {
                 ProtocolVersion.DTLS10,
                 ProtocolVersion.DTLS12
-            };
+            }));
 
-            defaultServerSSLParams = new SSLParameters();
-            defaultServerSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            supportedCipherSuiteList = getApplicableCipherSuiteList(
+                    supportedProtocolList, false);          // all supported
+            serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    serverDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultServerSSLParams() {
-            return defaultServerSSLParams;
+        ProtocolList getSuportedProtocolList() {
+            return supportedProtocolList;
         }
 
         @Override
-        SSLParameters getSupportedSSLParams() {
-            return supportedSSLParams;
+        CipherSuiteList getSupportedCipherSuiteList() {
+            return supportedCipherSuiteList;
+        }
+
+        @Override
+        ProtocolList getServerDefaultProtocolList() {
+            return serverDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getServerDefaultCipherSuiteList() {
+            return serverDefaultCipherSuiteList;
         }
 
         @Override
@@ -1028,22 +1053,28 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     public static final class DTLS10Context extends AbstractDTLSContext {
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
 
         static {
-            // candidates for available protocols
-            ProtocolVersion[] candidates = new ProtocolVersion[] {
+            // available protocols for client mode
+            clientDefaultProtocolList = new ProtocolList(
+                    getAvailableProtocols(new ProtocolVersion[] {
                 ProtocolVersion.DTLS10
-            };
+            }));
 
-            defaultClientSSLParams = new SSLParameters();
-            defaultClientSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -1053,23 +1084,29 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     public static final class DTLS12Context extends AbstractDTLSContext {
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
 
         static {
-            // candidates for available protocols
-            ProtocolVersion[] candidates = new ProtocolVersion[] {
+            // available protocols for client mode
+            clientDefaultProtocolList = new ProtocolList(
+                    getAvailableProtocols(new ProtocolVersion[] {
                 ProtocolVersion.DTLS10,
                 ProtocolVersion.DTLS12
-            };
+            }));
 
-            defaultClientSSLParams = new SSLParameters();
-            defaultClientSSLParams.setProtocols(
-                    getAvailableProtocols(candidates));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -1079,7 +1116,9 @@ public abstract class SSLContextImpl extends SSLContextSpi {
      * @see SSLContext
      */
     private static class CustomizedDTLSContext extends AbstractDTLSContext {
-        private static final SSLParameters defaultClientSSLParams;
+        private static final ProtocolList clientDefaultProtocolList;
+        private static final CipherSuiteList clientDefaultCipherSuiteList;
+
         private static IllegalArgumentException reservedException = null;
 
         // Don't want a java.lang.LinkageError for illegal system property.
@@ -1119,11 +1158,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
                     candidates = customizedDTLSProtocols.toArray(candidates);
                 }
 
-                defaultClientSSLParams = new SSLParameters();
-                defaultClientSSLParams.setProtocols(
+                clientDefaultProtocolList = new ProtocolList(
                         getAvailableProtocols(candidates));
+                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);   // enabled only
             } else {
-                defaultClientSSLParams = null;   // unlikely to be used
+                clientDefaultProtocolList = null;       // unlikely to be used
+                clientDefaultCipherSuiteList = null;    // unlikely to be used
             }
         }
 
@@ -1134,8 +1175,13 @@ public abstract class SSLContextImpl extends SSLContextSpi {
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 

From 1a8918d371b0bdc7765a203a097edf6af88f0e1d Mon Sep 17 00:00:00 2001
From: Olivier Lagneau <olagneau@openjdk.org>
Date: Fri, 18 Dec 2015 17:42:06 +0100
Subject: [PATCH 60/62] 8058865: JMX Test Refactoring

Reviewed-by: jbachorik
---
 .../MBeanServer/ExceptionFactory.java         | 131 +++
 .../management/MBeanServer/ExceptionTest.java | 372 ++++++++
 .../MBeanServer/ExceptionThrower.java         |  35 +
 .../MBeanServer/ExceptionThrowerMBean.java    |  29 +
 jdk/test/javax/management/mxbean/Basic.java   | 530 ++++++++++++
 .../javax/management/mxbean/BasicMXBean.java  | 203 +++++
 .../mxbean/MXBeanExceptionHandlingTest.java   | 245 ++++++
 .../management/mxbean/MXBeanInteropTest1.java | 638 ++++++++++++++
 .../management/mxbean/MXBeanInteropTest2.java | 217 +++++
 .../management/mxbean/MXBeanLoadingTest1.java | 329 +++++++
 .../management/mxbean/MXBeanNotifTest.java    | 385 +++++++++
 .../mxbean/MXBeanWeirdParamTest.java          | 277 ++++++
 .../management/mxbean/SqeDescriptorKey.java   |  49 ++
 .../management/mxbean/SqeNotification.java    |  54 ++
 .../javax/management/mxbean/SqeParameter.java |  63 ++
 jdk/test/javax/management/mxbean/Utils.java   | 241 ++++++
 .../javax/management/query/QueryData.java     |  32 +
 .../javax/management/query/QueryFactory.java  | 328 +++++++
 .../management/query/ServerDelegate.java      | 177 ++++
 .../management/query/ServerDelegateMBean.java |  67 ++
 .../management/query/SqeDescriptorKey.java    |  49 ++
 .../query/SupportedQueryTypesTest.java        | 471 +++++++++++
 .../javax/management/query/TestQuery.java     | 167 ++++
 .../management/query/TestQueryMBean.java      | 101 +++
 .../security/AuthorizationTest.java           | 613 ++++++++++++++
 .../javax/management/security/MBS_Light.java  | 213 +++++
 .../management/security/MBS_LightMBean.java   | 108 +++
 .../security/RjmxMBeanParameter.java          |  47 +
 .../management/security/SecurityTest.java     | 800 ++++++++++++++++++
 .../management/security/ServerDelegate.java   | 177 ++++
 .../security/ServerDelegateMBean.java         |  67 ++
 .../javax/management/security/Simple.java     |  75 ++
 .../management/security/SimpleListener.java   | 131 +++
 .../management/security/SimpleMBean.java      |  58 ++
 .../management/security/SqeDescriptorKey.java |  49 ++
 .../security/TestJMXAuthenticator.java        | 107 +++
 .../security/TestSampleLoginModule.java       | 115 +++
 jdk/test/javax/management/security/Utils.java | 424 ++++++++++
 .../management/security/access.properties     |  11 +
 .../security/java.policy.authorization        |  98 +++
 .../javax/management/security/keystoreAgent   | Bin 0 -> 1325 bytes
 .../javax/management/security/keystoreClient  | Bin 0 -> 1327 bytes
 .../javax/management/security/login.config    |   8 +
 .../management/security/password.properties   |  12 +
 .../javax/management/security/truststoreAgent | Bin 0 -> 619 bytes
 .../management/security/truststoreClient      | Bin 0 -> 618 bytes
 46 files changed, 8303 insertions(+)
 create mode 100644 jdk/test/javax/management/MBeanServer/ExceptionFactory.java
 create mode 100644 jdk/test/javax/management/MBeanServer/ExceptionTest.java
 create mode 100644 jdk/test/javax/management/MBeanServer/ExceptionThrower.java
 create mode 100644 jdk/test/javax/management/MBeanServer/ExceptionThrowerMBean.java
 create mode 100644 jdk/test/javax/management/mxbean/Basic.java
 create mode 100644 jdk/test/javax/management/mxbean/BasicMXBean.java
 create mode 100644 jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java
 create mode 100644 jdk/test/javax/management/mxbean/MXBeanInteropTest1.java
 create mode 100644 jdk/test/javax/management/mxbean/MXBeanInteropTest2.java
 create mode 100644 jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java
 create mode 100644 jdk/test/javax/management/mxbean/MXBeanNotifTest.java
 create mode 100644 jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java
 create mode 100644 jdk/test/javax/management/mxbean/SqeDescriptorKey.java
 create mode 100644 jdk/test/javax/management/mxbean/SqeNotification.java
 create mode 100644 jdk/test/javax/management/mxbean/SqeParameter.java
 create mode 100644 jdk/test/javax/management/mxbean/Utils.java
 create mode 100644 jdk/test/javax/management/query/QueryData.java
 create mode 100644 jdk/test/javax/management/query/QueryFactory.java
 create mode 100644 jdk/test/javax/management/query/ServerDelegate.java
 create mode 100644 jdk/test/javax/management/query/ServerDelegateMBean.java
 create mode 100644 jdk/test/javax/management/query/SqeDescriptorKey.java
 create mode 100644 jdk/test/javax/management/query/SupportedQueryTypesTest.java
 create mode 100644 jdk/test/javax/management/query/TestQuery.java
 create mode 100644 jdk/test/javax/management/query/TestQueryMBean.java
 create mode 100644 jdk/test/javax/management/security/AuthorizationTest.java
 create mode 100644 jdk/test/javax/management/security/MBS_Light.java
 create mode 100644 jdk/test/javax/management/security/MBS_LightMBean.java
 create mode 100644 jdk/test/javax/management/security/RjmxMBeanParameter.java
 create mode 100644 jdk/test/javax/management/security/SecurityTest.java
 create mode 100644 jdk/test/javax/management/security/ServerDelegate.java
 create mode 100644 jdk/test/javax/management/security/ServerDelegateMBean.java
 create mode 100644 jdk/test/javax/management/security/Simple.java
 create mode 100644 jdk/test/javax/management/security/SimpleListener.java
 create mode 100644 jdk/test/javax/management/security/SimpleMBean.java
 create mode 100644 jdk/test/javax/management/security/SqeDescriptorKey.java
 create mode 100644 jdk/test/javax/management/security/TestJMXAuthenticator.java
 create mode 100644 jdk/test/javax/management/security/TestSampleLoginModule.java
 create mode 100644 jdk/test/javax/management/security/Utils.java
 create mode 100644 jdk/test/javax/management/security/access.properties
 create mode 100644 jdk/test/javax/management/security/java.policy.authorization
 create mode 100644 jdk/test/javax/management/security/keystoreAgent
 create mode 100644 jdk/test/javax/management/security/keystoreClient
 create mode 100644 jdk/test/javax/management/security/login.config
 create mode 100644 jdk/test/javax/management/security/password.properties
 create mode 100644 jdk/test/javax/management/security/truststoreAgent
 create mode 100644 jdk/test/javax/management/security/truststoreClient

diff --git a/jdk/test/javax/management/MBeanServer/ExceptionFactory.java b/jdk/test/javax/management/MBeanServer/ExceptionFactory.java
new file mode 100644
index 00000000000..2315edff3fc
--- /dev/null
+++ b/jdk/test/javax/management/MBeanServer/ExceptionFactory.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2008, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import javax.management.AttributeNotFoundException;
+import javax.management.BadAttributeValueExpException;
+import javax.management.BadBinaryOpValueExpException;
+import javax.management.BadStringOperationException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidApplicationException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMException;
+import javax.management.JMRuntimeException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.OperationsException;
+import javax.management.ReflectionException;
+import javax.management.RuntimeErrorException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
+import javax.management.ServiceNotFoundException;
+import javax.management.StringValueExp;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.XMLParseException;
+import javax.management.monitor.MonitorSettingException;
+import javax.management.openmbean.InvalidKeyException;
+import javax.management.openmbean.InvalidOpenTypeException;
+import javax.management.openmbean.KeyAlreadyExistsException;
+import javax.management.openmbean.OpenDataException;
+import javax.management.relation.InvalidRelationIdException;
+import javax.management.relation.InvalidRelationServiceException;
+import javax.management.relation.InvalidRelationTypeException;
+import javax.management.relation.InvalidRoleInfoException;
+import javax.management.relation.InvalidRoleValueException;
+import javax.management.relation.RelationException;
+import javax.management.relation.RelationNotFoundException;
+import javax.management.relation.RelationServiceNotRegisteredException;
+import javax.management.relation.RelationTypeNotFoundException;
+import javax.management.relation.RoleInfoNotFoundException;
+import javax.management.relation.RoleNotFoundException;
+import javax.management.remote.JMXProviderException;
+import javax.management.remote.JMXServerErrorException;
+
+/**
+ *  |----- Original Description Coming From Tonga Original Source Code -------|
+ *  |                                                                         |
+ *  | That class creates an ArrayList and fill it with an instance of each of |
+ *  | the Exception class of the JMX API.                                     |
+ *  | It's dedicated to use by ExceptionTest.                                 |
+ *  |-------------------------------------------------------------------------|
+ */
+public class ExceptionFactory {
+
+    public static final ArrayList<Exception> exceptions =
+            new ArrayList<Exception>();
+
+    static {
+        String mes = "SQE";
+        exceptions.add(new AttributeNotFoundException());
+        exceptions.add(new BadAttributeValueExpException(mes));
+        exceptions.add(new BadBinaryOpValueExpException(new StringValueExp(mes)));
+        exceptions.add(new BadStringOperationException(mes));
+        exceptions.add(new InstanceAlreadyExistsException());
+        exceptions.add(new InstanceNotFoundException());
+        exceptions.add(new IntrospectionException());
+        exceptions.add(new InvalidApplicationException(mes));
+        exceptions.add(new InvalidAttributeValueException());
+        exceptions.add(new JMException());
+        exceptions.add(new JMRuntimeException());
+        exceptions.add(new ListenerNotFoundException());
+        exceptions.add(new MalformedObjectNameException());
+        exceptions.add(new MBeanException(new Exception(mes), mes));
+        exceptions.add(new MBeanRegistrationException(new Exception(mes), mes));
+        exceptions.add(new NotCompliantMBeanException());
+        exceptions.add(new OperationsException());
+        exceptions.add(new ReflectionException(new Exception(mes), mes));
+        exceptions.add(new RuntimeErrorException(new Error(mes), mes));
+        exceptions.add(new RuntimeMBeanException(new RuntimeException(mes), mes));
+        exceptions.add(new RuntimeOperationsException(new RuntimeException(mes), mes));
+        exceptions.add(new ServiceNotFoundException());
+        exceptions.add(new InvalidTargetObjectTypeException());
+        exceptions.add(new XMLParseException());
+        exceptions.add(new MonitorSettingException());
+        exceptions.add(new InvalidKeyException());
+        exceptions.add(new InvalidOpenTypeException());
+        exceptions.add(new KeyAlreadyExistsException());
+        exceptions.add(new OpenDataException());
+        exceptions.add(new InvalidRelationIdException());
+        exceptions.add(new InvalidRelationServiceException());
+        exceptions.add(new InvalidRelationTypeException());
+        exceptions.add(new InvalidRoleInfoException());
+        exceptions.add(new InvalidRoleValueException());
+        exceptions.add(new RelationException());
+        exceptions.add(new RelationNotFoundException());
+        exceptions.add(new RelationServiceNotRegisteredException());
+        exceptions.add(new RelationTypeNotFoundException());
+        exceptions.add(new RoleInfoNotFoundException());
+        exceptions.add(new RoleNotFoundException());
+        exceptions.add(new JMXProviderException());
+        exceptions.add(new JMXServerErrorException(mes, new Error(mes)));
+        ExceptionTest.Utils.debug(ExceptionTest.Utils.DEBUG_STANDARD,
+                "DataFactory::updateMap: Initialized" +
+                " an ArrayList with the " +
+                exceptions.size() + " exceptions of the JMX API");
+    }
+}
diff --git a/jdk/test/javax/management/MBeanServer/ExceptionTest.java b/jdk/test/javax/management/MBeanServer/ExceptionTest.java
new file mode 100644
index 00000000000..571e43d3a03
--- /dev/null
+++ b/jdk/test/javax/management/MBeanServer/ExceptionTest.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2008, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks that exceptions are correctly wired (compared to reference).
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD ExceptionTest
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import java.lang.management.ManagementFactory;
+import javax.management.ObjectName;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+
+public class ExceptionTest {
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        ExceptionTest test = new ExceptionTest();
+        test.run(map);
+
+    }
+
+    public void run(Map<String, Object> args) {
+
+        System.out.println("ExceptionTest::run: Start");
+        int errorCount = 0;
+
+        JMXConnectorServer cs = null;
+        JMXConnector cc = null;
+
+        try {
+            // JMX MbeanServer used inside single VM as if remote.
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+            JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+            cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+            cs.start();
+
+            JMXServiceURL addr = cs.getAddress();
+            cc = JMXConnectorFactory.connect(addr);
+            MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+            // ----
+            ObjectName objName =
+                new ObjectName(ExceptionThrower.EXCEPTION_THROWER_NAME);
+            System.out.println("ExceptionTest::run: Create and register MBean " + objName);
+            mbsc.createMBean("ExceptionThrower", objName);
+            System.out.println("---- OK\n");
+
+            // ----
+            System.out.println("ExceptionTest::run: Ask for exception(s)");
+            Object[] throwExceptionParam = new Object[1];
+            String[] throwExceptionSig = new String[]{"int"};
+
+            for (int i = 0; i < ExceptionFactory.exceptions.size(); i++) {
+                throwExceptionParam[0] = new Integer(i);
+
+                Exception ex =
+                    (Exception)mbsc.invoke(objName,
+                        "throwException", throwExceptionParam, throwExceptionSig);
+
+                if ( ! matches(ex, ExceptionFactory.exceptions.get(i)) ) {
+                    errorCount++;
+                    System.out.println("ExceptionTest::run: (ERROR) Received \n["
+                            + ex + "]\nin place of\n["
+                            + ExceptionFactory.exceptions.get(i) + "]");
+                } else {
+                    System.out.println("OK [" + ex + "]");
+                }
+            }
+
+            System.out.println("---- DONE\n");
+
+        } catch (Exception e) {
+            Utils.printThrowable(e, true);
+            throw new RuntimeException();
+        } finally {
+            try {
+                // Close JMX Connector Client
+                cc.close();
+                // Stop connertor server
+                cs.stop();
+
+            } catch (Exception e) {
+                Utils.printThrowable(e, true);
+                throw new RuntimeException(
+                    "Unable to either close connector client or stop connector server");
+            }
+        }
+
+        if (errorCount == 0) {
+            System.out.println("ExceptionTest::run: Done without any error");
+        } else {
+            System.out.println("ExceptionTest::run: Done with " + errorCount
+                    + " error(s)");
+            throw new RuntimeException("errorCount = " + errorCount);
+        }
+
+        System.out.println("ExceptionTest::run: Done");
+    }
+
+    // Check both Exception are identical.
+    // That means:
+    // - none is null.
+    // - they are of the same Class.
+    // - if their respective messages aren't null they're equal.
+    // - if the message of one is null the message of the other is null too.
+    private boolean matches(Exception ex, Exception refex) {
+        if ( ex == null || refex == null ) {
+            System.out.println("(ERROR) Called with one or more null parameter; check "
+                    + ex + " against " + refex);
+            return false;
+        }
+
+        String exClass = ex.getClass().getName();
+        String refexClass = refex.getClass().getName();
+
+        if ( ! exClass.equals(refexClass) ) {
+            System.out.println("(ERROR) Class names don't match; check ["
+                        + exClass + "] against [" + refexClass + "]");
+            return false;
+        }
+
+        String exMes = ex.getMessage();
+        String refexMes = refex.getMessage();
+
+        if ( exMes != null && refexMes != null ) {
+            if ( ! exMes.equals(refexMes) ) {
+                System.out.println("(ERROR) Non null messages don't match; check ["
+                        + exMes + "] against [" + refexMes + "]");
+                return false;
+            }
+        } else if ( (exMes == null && refexMes != null)
+                || (exMes != null && refexMes == null) ) {
+                System.out.println("(ERROR) Messages don't match; check [" + exMes
+                        + "] against [" + refexMes + "]");
+        }
+
+        return true;
+    }
+
+    // Utility inner class coming from JMX Tonga test suite.
+    // Also used by ExceptionFactory.
+    static class Utils {
+
+        // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+        static final String DEBUG_HEADER = "[debug] ";
+
+        // DEBUG levels
+        static int selectedDebugLevel = 0;
+        static final int DEBUG_STANDARD = 1;
+        static final int DEBUG_VERBOSE = 2;  // Mainly used for stress tests
+        static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+        static void parseDebugProperties() {
+            int level = 0;
+            Properties p = System.getProperties();
+
+            // get selected levels
+            if (p.getProperty("DEBUG_STANDARD") != null) {
+                level |= DEBUG_STANDARD;
+            }
+
+            if (p.getProperty("DEBUG_VERBOSE") != null) {
+                level |= DEBUG_VERBOSE;
+            }
+
+            if (p.getProperty("DEBUG_ALL") != null) {
+                level |= DEBUG_ALL;
+            }
+
+            selectedDebugLevel = level;
+        }
+
+        /**
+         * Reproduces the original parsing and collection of test parameters
+         * from the DTonga JMX test suite.
+         *
+         * Collects passed args and returns them in a map(argname, value) structure,
+         * which will be then propagated as necessary to various called methods.
+         */
+        static Map<String, Object> parseParameters(String args[])
+        throws Exception {
+            debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+            HashMap<String, Object> map = new HashMap<>();
+
+            for ( int i = 0; i < args.length; i++ ) {
+                if ( args[i].trim().startsWith("-") ) {
+                    if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+                        debug(DEBUG_STANDARD,
+                            "TestRoot::parseParameters: added in map = " +
+                            args[i] +
+                            " with value " +
+                            args[i+1]) ;
+                        map.put(args[i].trim(), args[i+1].trim()) ;
+                    } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+                               (i+1) == args.length ) {
+                        debug(DEBUG_STANDARD,
+                                "TestRoot::parseParameters: added in map = " +
+                                args[i] +
+                                " with null value") ;
+                        map.put(args[i].trim(), null) ;
+                    } else {
+                        System.out.println(
+                            "TestRoot::parseParameters: (WARNING) not added in map = " +
+                            args[i]) ;
+                    }
+                }
+            }
+
+            debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+            return map ;
+        }
+
+        /**
+         * This method is to be used in all tests to print anything
+         * that is temporary.
+         * Printing is done only when debug is activated by the property DEBUG.
+         * Printing depends also on the DEBUG_LEVEL property.
+         * Here it encapsulates a System.out.println.
+         */
+        static void debug(int level, String line) {
+            if ((selectedDebugLevel & level) != 0) {
+                System.out.println(DEBUG_HEADER + line);
+            }
+        }
+
+        /**
+         * Do print stack trace when withStack is true.
+         * Does try to call getTargetException() and getTargetError() then
+         * print embedded stacks in the case of an Exception wrapping
+         * another Exception or an Error. Recurse until no more wrapping
+         * is found.
+         */
+        static void printThrowable(Throwable theThro, boolean withStack) {
+            try {
+                if (withStack) {
+                    theThro.printStackTrace(System.out);
+                }
+                if (theThro instanceof Exception) {
+                    Exception t = (Exception) theThro;
+                    Method target = null;
+                    String blank = " ";
+                    try {
+                        target = t.getClass().getMethod("getTargetException",
+                                (java.lang.Class<?>[]) null);
+                    } catch (Exception ee) {
+                    // OK: getTargetException method could be there or not
+                    }
+                    System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+                    while (target != null) {
+                        try {
+                            t = (Exception) target.invoke(t,
+                                    (java.lang.Object[]) null);
+                        } catch (Exception ee) {
+                            t = null;
+                        }
+                        try {
+                            if (t != null) {
+                                blank = blank + "  ";
+                                System.out.println(blank + t.getClass() + "==>" +
+                                        t.getMessage());
+                                try {
+                                    target =
+                                            t.getClass().getMethod("getTargetException",
+                                            (java.lang.Class<?>[]) null);
+                                } catch (Exception ee) {
+                                // OK: getTargetException method could be there or not                            }
+                                }
+                            } else {
+                                target = null;
+                            }
+                        } catch (Exception ee) {
+                            target = null;
+                        }
+                    }
+
+                    // We may have exceptions wrapping an Error then it is
+                    // getTargetError that is likely to be called
+                    try {
+                        target = ((Exception) theThro).getClass().getMethod("getTargetError",
+                                (java.lang.Class<?>[]) null);
+                    } catch (Exception ee) {
+                    // OK: getTargetError method could be there or not
+                    }
+                    Throwable err = theThro;
+                    while (target != null) {
+                        try {
+                            err = (Error) target.invoke(err,
+                                    (java.lang.Object[]) null);
+                        } catch (Exception ee) {
+                            err = null;
+                        }
+                        try {
+                            if (err != null) {
+                                blank = blank + "  ";
+                                System.out.println(blank + err.getClass() + "==>" +
+                                        err.getMessage());
+                                if (withStack) {
+                                    err.printStackTrace(System.out);
+                                }
+                                try {
+                                    target = err.getClass().getMethod("getTargetError",
+                                            (java.lang.Class<?>[]) null);
+                                } catch (Exception ee) {
+                                // OK: getTargetError method could be there or not
+                                }
+                            } else {
+                                target = null;
+                            }
+                        } catch (Exception ee) {
+                            target = null;
+                        }
+                    }
+                } else {
+                    System.out.println("Throwable is : " + theThro);
+                }
+            } catch (Throwable x) {
+                System.out.println("Exception : raised in printException : " + x);
+            }
+        }
+    }
+
+}
+
+
diff --git a/jdk/test/javax/management/MBeanServer/ExceptionThrower.java b/jdk/test/javax/management/MBeanServer/ExceptionThrower.java
new file mode 100644
index 00000000000..37d661eaca6
--- /dev/null
+++ b/jdk/test/javax/management/MBeanServer/ExceptionThrower.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This class defines a simple standard MBean.
+ */
+public class ExceptionThrower implements ExceptionThrowerMBean {
+
+    public static final String EXCEPTION_THROWER_NAME
+            = "sqe:type=ExceptionThrower";
+
+    public Exception throwException(int exceptionIndex) {
+        return ExceptionFactory.exceptions.get(exceptionIndex);
+    }
+}
diff --git a/jdk/test/javax/management/MBeanServer/ExceptionThrowerMBean.java b/jdk/test/javax/management/MBeanServer/ExceptionThrowerMBean.java
new file mode 100644
index 00000000000..d5485d30e67
--- /dev/null
+++ b/jdk/test/javax/management/MBeanServer/ExceptionThrowerMBean.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This interface defines a simple standard MBean.
+ */
+public interface ExceptionThrowerMBean {
+    public Exception throwException(int exceptionIndex);
+}
diff --git a/jdk/test/javax/management/mxbean/Basic.java b/jdk/test/javax/management/mxbean/Basic.java
new file mode 100644
index 00000000000..3f32af666b9
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/Basic.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+
+/**
+ * Class Basic
+ * Basic Description
+ */
+public class Basic implements BasicMXBean, NotificationEmitter,
+                              MBeanRegistration {
+
+    public static final String EXCEPTION_MESSAGE = "from Basic";
+    public static final String NOTIFICATION_MESSAGE = "from Basic";
+    /** Attribute : IntAtt */
+    private int intAtt = 0;
+    /** Attribute : IntegerAtt */
+    private Integer integerAtt = 0;
+    /** Attribute : BoolAtt */
+    private boolean boolAtt = false;
+    /** Attribute : BooleanAtt */
+    private Boolean booleanAtt = false;
+    /** Attribute : StringAtt */
+    private String stringAtt = null;
+    /** Attribute : DateAtt */
+    private Date dateAtt = null;
+    /** Attribute : ObjectNameAtt */
+    private ObjectName objectNameAtt = null;
+    /** Attribute : NotifDescriptorAsMapAtt */
+    private Map<String, String> notifDescriptorAsMapAtt = null;
+    /** Attribute : NotifDescriptorAtt */
+    private Descriptor notifDescriptorAtt = null;
+    /** Attribute : SqeParameter */
+    private SqeParameter sqeParameterAtt = null;
+
+    /* Creates a new instance of Basic */
+    @SqeDescriptorKey("CONSTRUCTOR Basic")
+    public Basic() {
+    }
+
+    /* Creates a new instance of Basic */
+    @SqeDescriptorKey("CONSTRUCTOR Basic")
+    public Basic(
+            @SqeDescriptorKey("CONSTRUCTOR PARAMETER SqeParameter") SqeParameter param) {
+    }
+
+    /**
+     * Get int attribute
+     */
+    public int getIntAtt() {
+        return intAtt;
+    }
+
+    /**
+     * Set int attribute
+     */
+    public void setIntAtt(int value) {
+        intAtt = value;
+    }
+
+    /**
+     * Get Integer attribute
+     */
+    public Integer getIntegerAtt() {
+        return integerAtt;
+    }
+
+    /**
+     * Set Integer attribute
+     */
+    public void setIntegerAtt(Integer value) {
+        integerAtt = value;
+    }
+
+    /**
+     * Get boolean attribute
+     */
+    public boolean getBoolAtt() {
+        return boolAtt;
+    }
+
+    /**
+     * Set boolean attribute
+     */
+    public void setBoolAtt(boolean value) {
+        boolAtt = value;
+    }
+
+    /**
+     * Get Boolean attribute
+     */
+    public Boolean getBooleanAtt() {
+        return booleanAtt;
+    }
+
+    /**
+     * Set Boolean attribute
+     */
+    public void setBooleanAtt(Boolean value) {
+        booleanAtt = value;
+    }
+
+    /**
+     * Get String attribute
+     */
+    public String getStringAtt() {
+        return stringAtt;
+    }
+
+    /**
+     * Set String attribute
+     */
+    public void setStringAtt(String value) {
+        stringAtt = value;
+    }
+
+    /**
+     * Get Date attribute
+     */
+    public Date getDateAtt() {
+        return dateAtt;
+    }
+
+    /**
+     * Set Date attribute
+     */
+    public void setDateAtt(Date value) {
+        dateAtt = value;
+    }
+
+    /**
+     * Get ObjectName attribute
+     */
+    public ObjectName getObjectNameAtt() {
+        return objectNameAtt;
+    }
+
+    /**
+     * Set ObjectName attribute
+     */
+    public void setObjectNameAtt(ObjectName value) {
+        objectNameAtt = value;
+    }
+
+    /**
+     * Get SqeParameter attribute
+     */
+    public SqeParameter getSqeParameterAtt() throws Exception {
+        if (sqeParameterAtt == null) {
+            sqeParameterAtt = new SqeParameter();
+            sqeParameterAtt.setGlop("INITIALIZED");
+        }
+
+        return sqeParameterAtt;
+    }
+
+    /**
+     * Set SqeParameter attribute
+     */
+    public void setSqeParameterAtt(SqeParameter value) {
+        sqeParameterAtt = value;
+    }
+
+    /**
+     * Get the Descriptor used to build the NotificationInfo
+     * of emitted notifications.
+     */
+    public Map<String, String> getNotifDescriptorAsMapAtt() {
+        if (notifDescriptorAsMapAtt == null) {
+            initNotifDescriptorAtt();
+        }
+
+        return notifDescriptorAsMapAtt;
+    }
+
+    /**
+     * Set the Descriptor used to build the NotificationInfo
+     * of emitted notifications.
+     * <br>A Map<String, Object> would better fit Descriptor needs but then
+     * it is not convertible according the MXBean specification so the MBean
+     * registration fails.
+     * As we plan to test our custom Descriptor finds its way into
+     * the metadata of emitted notifications, String is good enough.
+     */
+    public void setNotifDescriptorAsMapAtt(Map<String, String> value) {
+        notifDescriptorAsMapAtt = new HashMap<String, String>(value);
+        notifDescriptorAtt = new ImmutableDescriptor(value);
+    }
+
+    /**
+     * Do nothing
+     */
+    public void doNothing() {
+        // I said NOTHING !
+    }
+
+    /**
+     * Do take SqeParameter as a parameter
+     */
+    public void doWeird(SqeParameter param) {
+    }
+
+    /**
+     * Throw an Exception
+     */
+    public void throwException() throws Exception {
+        throw new Exception(EXCEPTION_MESSAGE);
+    }
+
+    /**
+     * Throw an Error
+     */
+    public void throwError() {
+        throw new InternalError(EXCEPTION_MESSAGE);
+    }
+
+    /**
+     * Reset all attributes
+     */
+    public void reset() {
+        intAtt = 0;
+        integerAtt = 0;
+        boolAtt = false;
+        booleanAtt = Boolean.FALSE;
+        stringAtt = null;
+        dateAtt = null;
+        objectNameAtt = null;
+    }
+
+    /**
+     * Returns the weather for the coming days
+     * @param verbose <code>boolean</code> verbosity
+     * @throws java.lang.Exception <code>storm</code>
+     * @return <code>ObjectName</code>
+     */
+    public Weather getWeather(boolean verbose)
+            throws java.lang.Exception {
+        return Weather.SUNNY;
+    }
+
+    // Starting here are the 4 methods of MBeanRegistration interface.
+    // We use that to grab the ObjectName the MBean is registered with.
+    //
+    public ObjectName preRegister(MBeanServer server, ObjectName name)
+            throws Exception {
+        // Grab a reference on the MBeanServer we're registered in.
+        mbs = server;
+        // Compute the name we're registered with.
+        if (name != null) {
+            mbeanName = name;
+            return name;
+        } else {
+            mbeanName =
+                new ObjectName("sqe:type=" + Basic.class.getName());
+            return mbeanName;
+        }
+    }
+
+    public void postRegister(Boolean registrationDone) {
+        // Do nothing
+    }
+
+    public void preDeregister() throws Exception {
+        // Do nothing
+    }
+
+    public void postDeregister() {
+        // Do nothing
+    }
+
+    /**
+     * Send one Notification of the provided notifType type.
+     */
+    public void sendNotification(String notifType) {
+        Notification notification = null;
+
+        if (notifType.equals(NOTIF_TYPE_0)) {
+            notification = new Notification(NOTIF_TYPE_0,
+                    mbeanName,
+                    seqNumber,
+                    NOTIFICATION_MESSAGE);
+        } else if (notifType.equals(NOTIF_TYPE_1)) {
+            notification = new SqeNotification(NOTIF_TYPE_1,
+                    mbeanName,
+                    seqNumber,
+                    NOTIFICATION_MESSAGE);
+        }
+
+        seqNumber++;
+        broadcaster.sendNotification(notification);
+    }
+
+    /**
+     * That method starts a set of threads, each thread sends a given number of
+     * notifications.
+     * The number of threads can be set via the attribute numOfNotificationSenders.
+     * The number of notification sent by each thread can be set via
+     * the attribute numOfNotificationSenderLoops.
+     * Depending on the parameter customNotification we send either custom
+     * notification(s) or MBeanServer registration and unregistration notification(s).
+     * When customNotification=true the total number of notification(s) sent is
+     * (numOfNotificationSenders * numOfNotificationSenderLoops). They are
+     * sequentially of type NOTIF_TYPE_0 then NOTIF_TYPE_1 and so on.
+     *
+     * When customNotification=false the total number of notification(s) sent is
+     * (numOfNotificationSenders * numOfNotificationSenderLoops) registration
+     * notification(s)
+     * +
+     * (numOfNotificationSenders * numOfNotificationSenderLoops) unregistration
+     * notification(s)
+     *
+     * @throws java.lang.Exception
+     */
+    public void sendNotificationWave(boolean customNotification) throws
+            Exception {
+        // Build the set of notification sender.
+        Collection<Callable<Integer>> tasks =
+                new HashSet<Callable<Integer>>(numOfNotificationSenders);
+
+        for (int i = 1; i <= numOfNotificationSenders; i++) {
+            tasks.add(new NotifSender(numOfNotificationSenderLoops,
+                    customNotification, i));
+        }
+
+        // Start all notification sender in parallel.
+        ExecutorService execServ = null;
+        try {
+            execServ = Executors.newFixedThreadPool(numOfNotificationSenders);
+            List<Future<Integer>> taskHandlers = execServ.invokeAll(tasks);
+            checkNotifSenderThreadStatus(taskHandlers);
+        } finally {
+            if (!execServ.isShutdown()) {
+                execServ.shutdown();
+            }
+        }
+    }
+
+    public void setNumOfNotificationSenders(int value) {
+        numOfNotificationSenders = value;
+    }
+
+    public void setNumOfNotificationSenderLoops(int value) {
+        numOfNotificationSenderLoops = value;
+    }
+
+    /**
+     * MBean Notification support
+     * You shouldn't update these methods
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">
+    public void addNotificationListener(NotificationListener listener,
+                                        NotificationFilter filter,
+                                        Object handback)
+            throws IllegalArgumentException {
+        broadcaster.addNotificationListener(listener, filter, handback);
+    }
+
+    public MBeanNotificationInfo[] getNotificationInfo() {
+        if (notifDescriptorAtt == null) {
+            initNotifDescriptorAtt();
+        }
+
+        return new MBeanNotificationInfo[]{
+                    new MBeanNotificationInfo(new String[]{
+                        NOTIF_TYPE_0
+                    },
+                    javax.management.Notification.class.getName(),
+                    "Standard JMX Notification",
+                    notifDescriptorAtt),
+                    new MBeanNotificationInfo(new String[]{
+                        NOTIF_TYPE_1
+                    },
+                    SqeNotification.class.getName(),
+                    "SQE Notification",
+                    notifDescriptorAtt)
+                };
+    }
+
+    public void removeNotificationListener(NotificationListener listener)
+            throws ListenerNotFoundException {
+        broadcaster.removeNotificationListener(listener);
+    }
+
+    public void removeNotificationListener(NotificationListener listener,
+                                           NotificationFilter filter,
+                                           Object handback)
+            throws ListenerNotFoundException {
+        broadcaster.removeNotificationListener(listener, filter, handback);
+    }
+    // </editor-fold>
+    private synchronized long getNextSeqNumber() {
+        return seqNumber++;
+    }
+
+    private void initNotifDescriptorAtt() {
+        String key = "CRABE";
+        String value = "TAMBOUR";
+        notifDescriptorAtt =
+                new ImmutableDescriptor(new String[]{key + "=" + value});
+        notifDescriptorAsMapAtt =
+                new HashMap<String, String>();
+        notifDescriptorAsMapAtt.put(key, value);
+    }
+
+    private void checkNotifSenderThreadStatus(
+            List<Future<Integer>> taskHandlers)
+            throws Exception {
+        String msgTag = "Basic::checkNotifSenderThreadStatus: ";
+        // Grab back status of each notification sender.
+        for (Future<Integer> f : taskHandlers) {
+            if (f.isCancelled()) {
+                String message = msgTag +
+                        "---- ERROR : One thread has been cancelled";
+                System.out.println(message);
+                throw new RuntimeException(message);
+            } else {
+                Integer effectiveNumOfLoops = f.get();
+
+                if (effectiveNumOfLoops != numOfNotificationSenderLoops) {
+                    String message = msgTag + "---- ERROR : One thread did " +
+                            effectiveNumOfLoops + " loops in place of " +
+                            numOfNotificationSenderLoops;
+                    System.out.println(message);
+                    throw new RuntimeException(message);
+                }
+            }
+        }
+    }
+    //
+    private int numOfNotificationSenderLoops = 2;
+    private int numOfNotificationSenders = 13;
+
+    private class NotifSender implements Callable<Integer> {
+
+        private int cycles;
+        private boolean customNotification;
+        private int senderID;
+
+        public NotifSender(int cycles, boolean customNotification, int id) {
+            this.cycles = cycles;
+            this.customNotification = customNotification;
+            this.senderID = id;
+        }
+
+        public Integer call() throws Exception {
+            int callsDone = 0;
+
+            try {
+                for (int i = 1; i <= cycles; i++) {
+                    if (customNotification) {
+                        if (i % 2 == 0) {
+                            sendNotification(NOTIF_TYPE_0);
+                        } else {
+                            sendNotification(NOTIF_TYPE_1);
+                        }
+                    } else {
+                        ObjectName mbeanName = new ObjectName("SQE:type=" +
+                                mbeanClassName + ",senderID=" + senderID);
+                        mbs.createMBean(mbeanClassName, mbeanName);
+                        mbs.unregisterMBean(mbeanName);
+                    }
+                    callsDone++;
+                }
+            } catch (Exception e) {
+                System.out.println("NotifSender::call: (ERROR) Thread [" + senderID +
+                        "] failed after " + callsDone + " cycles");
+                throw e;
+            }
+
+            return Integer.valueOf(callsDone);
+        }
+    }
+
+    //
+    private long seqNumber;
+    private final NotificationBroadcasterSupport broadcaster =
+            new NotificationBroadcasterSupport();
+    private ObjectName mbeanName;
+    private MBeanServer mbs;
+    private String mbeanClassName = "Simple";
+
+    /**
+     * Notification types definitions. To use when creating JMX Notifications.
+     */
+    public static final String NOTIF_TYPE_0 =
+            "sqe.notification.a.type";
+    public static final String NOTIF_TYPE_1 =
+            "sqe.notification.b.type";
+}
diff --git a/jdk/test/javax/management/mxbean/BasicMXBean.java b/jdk/test/javax/management/mxbean/BasicMXBean.java
new file mode 100644
index 00000000000..7693be90c9f
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/BasicMXBean.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Date;
+import java.util.Map;
+
+import javax.management.ObjectName;
+
+/**
+ * Interface BasicMBean
+ * Basic Description
+ */
+@SqeDescriptorKey("INTERFACE BasicMXBean")
+public interface BasicMXBean
+{
+   /**
+    * Get int attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE intAtt")
+    public int getIntAtt();
+
+   /**
+    * Set int attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE intAtt")
+    public void setIntAtt(int value);
+
+   /**
+    * Get Integer attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE integerAtt")
+    public Integer getIntegerAtt();
+
+   /**
+    * Set Integer attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE integerAtt")
+    public void setIntegerAtt(Integer value);
+
+   /**
+    * Get boolean attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE boolAtt")
+    public boolean getBoolAtt();
+
+   /**
+    * Set boolean attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE boolAtt")
+    public void setBoolAtt(boolean value);
+
+   /**
+    * Get Boolean attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE booleanAtt")
+    public Boolean getBooleanAtt();
+
+   /**
+    * Set Boolean attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE booleanAtt")
+    public void setBooleanAtt(Boolean value);
+
+   /**
+    * Get String attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE stringAtt")
+    public String getStringAtt();
+
+   /**
+    * Set String attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE stringAtt")
+    public void setStringAtt(String value);
+
+   /**
+    * Get Date attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE dateAtt")
+    public Date getDateAtt();
+
+   /**
+    * Set Date attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE dateAtt")
+    public void setDateAtt(Date value);
+
+   /**
+    * Get ObjectName attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE objectNameAtt")
+    public ObjectName getObjectNameAtt();
+
+   /**
+    * Set ObjectName attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE objectNameAtt")
+    public void setObjectNameAtt(ObjectName value);
+
+   /**
+    * Get SqeParameter attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
+    public SqeParameter getSqeParameterAtt() throws Exception;
+
+   /**
+    * Set SqeParameter attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
+    public void setSqeParameterAtt(SqeParameter value);
+
+   /**
+    * Set NumOfNotificationSenders attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenders")
+    public void setNumOfNotificationSenders(int value);
+
+   /**
+    * Set NumOfNotificationSenderLoops attribute
+    */
+    @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenderLoops")
+    public void setNumOfNotificationSenderLoops(int value);
+
+   /**
+    * do nothing
+    *
+    */
+    @SqeDescriptorKey("OPERATION doNothing")
+    public void doNothing();
+
+   /**
+    * Do take SqeParameter as a parameter
+    */
+    @SqeDescriptorKey("OPERATION doWeird")
+    public void doWeird(@SqeDescriptorKey("METHOD PARAMETER")SqeParameter param);
+
+    /**
+    * throw an Exception
+    *
+    */
+    @SqeDescriptorKey("OPERATION throwException")
+    public void throwException() throws Exception;
+
+   /**
+    * throw an Error
+    *
+    */
+    @SqeDescriptorKey("OPERATION throwError")
+    public void throwError();
+
+   /**
+    * reset all attributes
+    *
+    */
+    @SqeDescriptorKey("OPERATION reset")
+    public void reset();
+
+   /**
+    * returns the weather for the coming days
+    *
+    * @param verbose <code>boolean</code> verbosity
+    * @return <code>ObjectName</code>
+    */
+    @SqeDescriptorKey("OPERATION getWeather")
+    public Weather getWeather(@SqeDescriptorKey("METHOD PARAMETER")boolean verbose)
+        throws java.lang.Exception;
+
+    public enum Weather {
+        CLOUDY, SUNNY
+    }
+
+    @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
+    public Map<String, String> getNotifDescriptorAsMapAtt();
+
+    @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
+    public void setNotifDescriptorAsMapAtt(Map<String, String> value);
+
+    @SqeDescriptorKey("OPERATION sendNotification")
+    public void sendNotification(@SqeDescriptorKey("METHOD PARAMETER")String notifType);
+
+    @SqeDescriptorKey("OPERATION sendNotificationWave")
+    public void sendNotificationWave(boolean customNotification) throws Exception;
+}
diff --git a/jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java b/jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java
new file mode 100644
index 00000000000..96071980c1e
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks correct exception and error events from NotificationListener
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3
+ */
+
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.MBeanException;
+import javax.management.MBeanServerDelegate;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.RuntimeErrorException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanExceptionHandlingTest implements NotificationListener {
+
+    private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+    private long timeForNotificationInSeconds = 3L;
+    private int numOfNotifications = 2;
+    private BlockingQueue<Notification> notifList = null;
+
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        MXBeanExceptionHandlingTest test = new MXBeanExceptionHandlingTest();
+        test.run(map);
+
+    }
+
+    protected void parseArgs(Map<String, Object> args) throws Exception {
+
+        String arg = null;
+
+        // Init timeForNotificationInSeconds
+        // It is the maximum time in seconds we wait for a notification.
+        arg = (String)args.get("-timeForNotificationInSeconds") ;
+        if (arg != null) {
+            timeForNotificationInSeconds = (new Long(arg)).longValue();
+        }
+
+    }
+
+    public void run(Map<String, Object> args) {
+
+        System.out.println("MXBeanExceptionHandlingTest::run: Start") ;
+        int errorCount = 0 ;
+
+        try {
+            parseArgs(args);
+            notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
+
+            // JMX MbeanServer used inside single VM as if remote.
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+            JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+            JMXConnectorServer cs =
+                JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+            cs.start();
+
+            JMXServiceURL addr = cs.getAddress();
+            JMXConnector cc = JMXConnectorFactory.connect(addr);
+            MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+            // ----
+            System.out.println("Add me as notification listener");
+            mbsc.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
+                    this, null, null);
+            System.out.println("---- OK\n") ;
+
+            // ----
+            System.out.println("Create and register the MBean");
+            ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+            mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+            System.out.println("---- OK\n") ;
+
+            // ----
+            System.out.println("Call method throwException on our MXBean");
+
+            try {
+                mbsc.invoke(objName, "throwException", null, null);
+                errorCount++;
+                System.out.println("(ERROR) Did not get awaited MBeanException") ;
+            } catch (MBeanException mbe) {
+                System.out.println("(OK) Got awaited MBeanException") ;
+                Throwable cause = mbe.getCause();
+
+                if ( cause instanceof java.lang.Exception ) {
+                    System.out.println("(OK) Cause is of the right class") ;
+                    String mess = cause.getMessage();
+
+                    if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
+                        System.out.println("(OK) Cause message is fine") ;
+                    } else {
+                        errorCount++;
+                        System.out.println("(ERROR) Cause has message "
+                                + cause.getMessage()
+                                + " as we expect "
+                                + Basic.EXCEPTION_MESSAGE) ;
+                    }
+                } else {
+                    errorCount++;
+                    System.out.println("(ERROR) Cause is of  class "
+                            + cause.getClass().getName()
+                            + " as we expect java.lang.Exception") ;
+                }
+            } catch (Exception e) {
+                errorCount++;
+                System.out.println("(ERROR) Did not get awaited MBeanException but "
+                        + e) ;
+                Utils.printThrowable(e, true);
+            }
+            System.out.println("---- DONE\n") ;
+
+            // ----
+            System.out.println("Call method throwError on our MXBean");
+
+            try {
+                mbsc.invoke(objName, "throwError", null, null);
+                errorCount++;
+                System.out.println("(ERROR) Did not get awaited RuntimeErrorException") ;
+            } catch (RuntimeErrorException ree) {
+                System.out.println("(OK) Got awaited RuntimeErrorException") ;
+                Throwable cause = ree.getCause();
+
+                if ( cause instanceof java.lang.InternalError ) {
+                    System.out.println("(OK) Cause is of the right class") ;
+                    String mess = cause.getMessage();
+
+                    if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
+                        System.out.println("(OK) Cause message is fine") ;
+                    } else {
+                        errorCount++;
+                        System.out.println("(ERROR) Cause has message "
+                                + cause.getMessage()
+                                + " as we expect "
+                                + Basic.EXCEPTION_MESSAGE) ;
+                    }
+                } else {
+                    errorCount++;
+                    System.out.println("(ERROR) Cause is of  class "
+                            + cause.getClass().getName()
+                            + " as we expect java.lang.InternalError") ;
+                }
+            } catch (Exception e) {
+                errorCount++;
+                System.out.println("(ERROR) Did not get awaited RuntimeErrorException but "
+                        + e) ;
+                Utils.printThrowable(e, true);
+            }
+            System.out.println("---- DONE\n") ;
+
+            // ----
+            System.out.println("Unregister the MBean");
+            mbsc.unregisterMBean(objName);
+            System.out.println("---- OK\n") ;
+
+            Thread.sleep(timeForNotificationInSeconds * 1000);
+            int numOfReceivedNotif = notifList.size();
+
+            if ( numOfReceivedNotif == numOfNotifications ) {
+                System.out.println("(OK) We received "
+                        + numOfNotifications
+                        + " Notifications") ;
+            } else {
+                errorCount++;
+                System.out.println("(ERROR) We received "
+                        + numOfReceivedNotif
+                        + " Notifications in place of "
+                        + numOfNotifications) ;
+            }
+        } catch(Exception e) {
+            Utils.printThrowable(e, true) ;
+            throw new RuntimeException(e);
+        }
+
+        if ( errorCount == 0 ) {
+            System.out.println("MXBeanExceptionHandlingTest::run: Done without any error") ;
+        } else {
+            System.out.println("MXBeanExceptionHandlingTest::run: Done with "
+                    + errorCount
+                    + " error(s)") ;
+            throw new RuntimeException("errorCount = " + errorCount);
+        }
+    }
+
+    public void handleNotification(Notification notification, Object handback) {
+        System.out.println("MXBeanExceptionHandlingTest::handleNotification: Received "
+                + notification);
+        notifList.add(notification);
+    }
+
+}
diff --git a/jdk/test/javax/management/mxbean/MXBeanInteropTest1.java b/jdk/test/javax/management/mxbean/MXBeanInteropTest1.java
new file mode 100644
index 00000000000..5f0e834a72e
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/MXBeanInteropTest1.java
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Test all MXBeans available by default on the platform
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest1
+ */
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.CompilationMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanInteropTest1 {
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        MXBeanInteropTest1 test = new MXBeanInteropTest1();
+        test.run(map);
+
+    }
+
+    public void run(Map<String, Object> args) {
+
+        System.out.println("MXBeanInteropTest1::run: Start") ;
+        int errorCount = 0 ;
+
+        try {
+            // JMX MbeanServer used inside single VM as if remote.
+            // MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+            JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+            JMXConnectorServer cs =
+                JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+            cs.start();
+
+            JMXServiceURL addr = cs.getAddress();
+            JMXConnector cc = JMXConnectorFactory.connect(addr);
+            MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+            // Print out registered java.lang.management MXBeans found
+            // in the remote jvm.
+            printMBeans(mbsc) ;
+
+            // For each possible kind of JDK 5 defined MXBean, we retrieve its
+            // MBeanInfo and print it and we call all getters and print
+            // their output.
+            errorCount += doClassLoadingMXBeanTest(mbsc) ;
+            errorCount += doMemoryMXBeanTest(mbsc) ;
+            errorCount += doThreadMXBeanTest(mbsc) ;
+            errorCount += doRuntimeMXBeanTest(mbsc) ;
+            errorCount += doOperatingSystemMXBeanTest(mbsc) ;
+            errorCount += doCompilationMXBeanTest(mbsc) ;
+            errorCount += doGarbageCollectorMXBeanTest(mbsc) ;
+            errorCount += doMemoryManagerMXBeanTest(mbsc) ;
+            errorCount += doMemoryPoolMXBeanTest(mbsc) ;
+
+            // Terminate the JMX Client
+            cc.close();
+
+        } catch(Exception e) {
+            Utils.printThrowable(e, true) ;
+            throw new RuntimeException(e);
+        }
+
+        if ( errorCount == 0 ) {
+            System.out.println("MXBeanInteropTest1::run: Done without any error") ;
+        } else {
+            System.out.println("MXBeanInteropTest1::run: Done with "
+                    + errorCount
+                    + " error(s)") ;
+            throw new RuntimeException("errorCount = " + errorCount);
+        }
+    }
+
+    /**
+     * Prints all MBeans of domain java.lang.
+     * They are MBeans related to the JSR 174 that defines
+     * package java.lang.management.
+     */
+    private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
+        ObjectName filterName = new ObjectName("java.lang:*");
+        Set<ObjectName> set = mbsc.queryNames(filterName, null);
+
+        if ( set.size() == 0 ) {
+            throw new RuntimeException("(ERROR) No MBean found with filter "
+                    + filterName);
+        }
+
+        System.out.println("---- MBeans found in domain java.lang :");
+
+        for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
+            System.out.println(iter.next().toString());
+        }
+
+        System.out.println("\n") ;
+    }
+
+
+    private final int doClassLoadingMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- ClassLoadingMXBean") ;
+
+        try {
+            ObjectName classLoadingName =
+                    new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME) ;
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(classLoadingName);
+            errorCount += checkNonEmpty(mbInfo);
+            System.out.println("getMBeanInfo\t\t"
+                    + mbInfo);
+            ClassLoadingMXBean classLoading = null;
+
+            classLoading = JMX.newMXBeanProxy(mbsc,
+                    classLoadingName,
+                    ClassLoadingMXBean.class) ;
+            System.out.println("getLoadedClassCount\t\t"
+                    + classLoading.getLoadedClassCount());
+            System.out.println("getTotalLoadedClassCount\t\t"
+                    + classLoading.getTotalLoadedClassCount());
+            System.out.println("getUnloadedClassCount\t\t"
+                    + classLoading.getUnloadedClassCount());
+            System.out.println("isVerbose\t\t"
+                    + classLoading.isVerbose());
+
+            System.out.println("---- OK\n") ;
+
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doMemoryMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- MemoryMXBean") ;
+
+        try {
+            ObjectName memoryName =
+                    new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME) ;
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryName);
+            errorCount += checkNonEmpty(mbInfo);
+            System.out.println("getMBeanInfo\t\t"
+                    + mbInfo);
+            MemoryMXBean memory = null ;
+
+            memory =
+                    JMX.newMXBeanProxy(mbsc,
+                    memoryName,
+                    MemoryMXBean.class,
+                    true) ;
+            System.out.println("getMemoryHeapUsage\t\t"
+                    + memory.getHeapMemoryUsage());
+            System.out.println("getNonHeapMemoryHeapUsage\t\t"
+                    + memory.getNonHeapMemoryUsage());
+            System.out.println("getObjectPendingFinalizationCount\t\t"
+                    + memory.getObjectPendingFinalizationCount());
+            System.out.println("isVerbose\t\t"
+                    + memory.isVerbose());
+
+            System.out.println("---- OK\n") ;
+
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doThreadMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- ThreadMXBean") ;
+
+        try {
+            ObjectName threadName =
+                    new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME) ;
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(threadName);
+            errorCount += checkNonEmpty(mbInfo);
+            System.out.println("getMBeanInfo\t\t" + mbInfo);
+            ThreadMXBean thread = null ;
+
+            thread =
+                    JMX.newMXBeanProxy(mbsc,
+                    threadName,
+                    ThreadMXBean.class) ;
+            System.out.println("findMonitorDeadlockedThreads\t\t"
+                    + thread.findMonitorDeadlockedThreads());
+            long[] threadIDs = thread.getAllThreadIds() ;
+            System.out.println("getAllThreadIds\t\t"
+                    + threadIDs);
+
+            for ( long threadID : threadIDs ) {
+                System.out.println("getThreadInfo long\t\t"
+                        + thread.getThreadInfo(threadID));
+                System.out.println("getThreadInfo long, int\t\t"
+                        + thread.getThreadInfo(threadID, 2));
+            }
+
+            System.out.println("getThreadInfo long[]\t\t"
+                    + thread.getThreadInfo(threadIDs));
+            System.out.println("getThreadInfo long[], int\t\t"
+                    + thread.getThreadInfo(threadIDs, 2));
+            System.out.println("getDaemonThreadCount\t\t"
+                    + thread.getDaemonThreadCount());
+            System.out.println("getPeakThreadCount\t\t"
+                    + thread.getPeakThreadCount());
+            System.out.println("getThreadCount\t\t"
+                    + thread.getThreadCount());
+            System.out.println("getTotalStartedThreadCount\t\t"
+                    + thread.getTotalStartedThreadCount());
+            boolean supported = thread.isThreadContentionMonitoringSupported() ;
+            System.out.println("isThreadContentionMonitoringSupported\t\t"
+                    + supported);
+
+            if ( supported ) {
+                System.out.println("isThreadContentionMonitoringEnabled\t\t"
+                        + thread.isThreadContentionMonitoringEnabled());
+            }
+
+            supported = thread.isThreadCpuTimeSupported() ;
+            System.out.println("isThreadCpuTimeSupported\t\t"
+                    + supported);
+
+            if ( supported ) {
+                System.out.println("isThreadCpuTimeEnabled\t\t"
+                        + thread.isThreadCpuTimeEnabled());
+
+                for (long id : threadIDs) {
+                    System.out.println("getThreadCpuTime(" + id + ")\t\t"
+                            + thread.getThreadCpuTime(id));
+                    System.out.println("getThreadUserTime(" + id + ")\t\t"
+                            + thread.getThreadUserTime(id));
+                }
+            }
+
+            supported = thread.isCurrentThreadCpuTimeSupported() ;
+            System.out.println("isCurrentThreadCpuTimeSupported\t\t"
+                    + supported);
+
+            if ( supported ) {
+                System.out.println("getCurrentThreadCpuTime\t\t"
+                        + thread.getCurrentThreadCpuTime());
+                System.out.println("getCurrentThreadUserTime\t\t"
+                        + thread.getCurrentThreadUserTime());
+            }
+
+            thread.resetPeakThreadCount() ;
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doRuntimeMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- RuntimeMXBean") ;
+
+        try {
+            ObjectName runtimeName =
+                    new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME) ;
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(runtimeName);
+            errorCount += checkNonEmpty(mbInfo);
+            System.out.println("getMBeanInfo\t\t" + mbInfo);
+            RuntimeMXBean runtime = null;
+
+            runtime =
+                    JMX.newMXBeanProxy(mbsc,
+                    runtimeName,
+                    RuntimeMXBean.class) ;
+            System.out.println("getClassPath\t\t"
+                    + runtime.getClassPath());
+            System.out.println("getInputArguments\t\t"
+                    + runtime.getInputArguments());
+            System.out.println("getLibraryPath\t\t"
+                    + runtime.getLibraryPath());
+            System.out.println("getManagementSpecVersion\t\t"
+                    + runtime.getManagementSpecVersion());
+            System.out.println("getName\t\t"
+                    + runtime.getName());
+            System.out.println("getSpecName\t\t"
+                    + runtime.getSpecName());
+            System.out.println("getSpecVendor\t\t"
+                    + runtime.getSpecVendor());
+            System.out.println("getSpecVersion\t\t"
+                    + runtime.getSpecVersion());
+            System.out.println("getStartTime\t\t"
+                    + runtime.getStartTime());
+            System.out.println("getSystemProperties\t\t"
+                    + runtime.getSystemProperties());
+            System.out.println("getUptime\t\t"
+                    + runtime.getUptime());
+            System.out.println("getVmName\t\t"
+                    + runtime.getVmName());
+            System.out.println("getVmVendor\t\t"
+                    + runtime.getVmVendor());
+            System.out.println("getVmVersion\t\t"
+                    + runtime.getVmVersion());
+            boolean supported = runtime.isBootClassPathSupported() ;
+            System.out.println("isBootClassPathSupported\t\t"
+                    + supported);
+
+            if ( supported ) {
+                System.out.println("getBootClassPath\t\t"
+                        + runtime.getBootClassPath());
+            }
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doOperatingSystemMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- OperatingSystemMXBean") ;
+
+        try {
+            ObjectName operationName =
+                    new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME) ;
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(operationName);
+            errorCount += checkNonEmpty(mbInfo);
+            System.out.println("getMBeanInfo\t\t" + mbInfo);
+            OperatingSystemMXBean operation = null ;
+
+            operation =
+                    JMX.newMXBeanProxy(mbsc,
+                    operationName,
+                    OperatingSystemMXBean.class) ;
+            System.out.println("getArch\t\t"
+                    + operation.getArch());
+            System.out.println("getAvailableProcessors\t\t"
+                    + operation.getAvailableProcessors());
+            System.out.println("getName\t\t"
+                    + operation.getName());
+            System.out.println("getVersion\t\t"
+                    + operation.getVersion());
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doCompilationMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- CompilationMXBean") ;
+
+        try {
+            ObjectName compilationName =
+                    new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
+
+            if ( mbsc.isRegistered(compilationName) ) {
+                MBeanInfo mbInfo = mbsc.getMBeanInfo(compilationName);
+                errorCount += checkNonEmpty(mbInfo);
+                System.out.println("getMBeanInfo\t\t" + mbInfo);
+                CompilationMXBean compilation = null ;
+
+                compilation =
+                        JMX.newMXBeanProxy(mbsc,
+                        compilationName,
+                        CompilationMXBean.class) ;
+                System.out.println("getName\t\t"
+                        + compilation.getName());
+                boolean supported =
+                        compilation.isCompilationTimeMonitoringSupported() ;
+                System.out.println("isCompilationTimeMonitoringSupported\t\t"
+                        + supported);
+
+                if ( supported ) {
+                    System.out.println("getTotalCompilationTime\t\t"
+                            + compilation.getTotalCompilationTime());
+                }
+            }
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doGarbageCollectorMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- GarbageCollectorMXBean") ;
+
+        try {
+            ObjectName filterName =
+                    new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE
+                    + ",*");
+            Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+            for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+                ObjectName garbageName = iter.next() ;
+                System.out.println("-------- " + garbageName) ;
+                MBeanInfo mbInfo = mbsc.getMBeanInfo(garbageName);
+                errorCount += checkNonEmpty(mbInfo);
+                System.out.println("getMBeanInfo\t\t" + mbInfo);
+                GarbageCollectorMXBean garbage = null ;
+
+                garbage =
+                        JMX.newMXBeanProxy(mbsc,
+                        garbageName,
+                        GarbageCollectorMXBean.class) ;
+                System.out.println("getCollectionCount\t\t"
+                        + garbage.getCollectionCount());
+                System.out.println("getCollectionTime\t\t"
+                        + garbage.getCollectionTime());
+            }
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doMemoryManagerMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- MemoryManagerMXBean") ;
+
+        try {
+            ObjectName filterName =
+                    new ObjectName(ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE
+                    + ",*");
+            Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+            for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+                ObjectName memoryManagerName = iter.next() ;
+                System.out.println("-------- " + memoryManagerName) ;
+                MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryManagerName);
+                System.out.println("getMBeanInfo\t\t" + mbInfo);
+                errorCount += checkNonEmpty(mbInfo);
+                MemoryManagerMXBean memoryManager = null;
+
+                memoryManager =
+                        JMX.newMXBeanProxy(mbsc,
+                        memoryManagerName,
+                        MemoryManagerMXBean.class) ;
+                System.out.println("getMemoryPoolNames\t\t"
+                        + Arrays.deepToString(memoryManager.getMemoryPoolNames()));
+                System.out.println("getName\t\t"
+                        + memoryManager.getName());
+                System.out.println("isValid\t\t"
+                        + memoryManager.isValid());
+            }
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private final int doMemoryPoolMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- MemoryPoolMXBean") ;
+
+        try {
+            ObjectName filterName =
+                    new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE
+                    + ",*");
+            Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+            for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+                ObjectName memoryPoolName = iter.next() ;
+                System.out.println("-------- " + memoryPoolName) ;
+                MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryPoolName);
+                errorCount += checkNonEmpty(mbInfo);
+                System.out.println("getMBeanInfo\t\t" + mbInfo);
+                MemoryPoolMXBean memoryPool = null;
+
+                memoryPool =
+                        JMX.newMXBeanProxy(mbsc,
+                        memoryPoolName,
+                        MemoryPoolMXBean.class,
+                        true) ;
+                System.out.println("getCollectionUsage\t\t"
+                        + memoryPool.getCollectionUsage());
+                System.out.println("getMemoryManagerNames\t\t"
+                        + Arrays.deepToString(memoryPool.getMemoryManagerNames()));
+                System.out.println("getName\t\t"
+                        + memoryPool.getName());
+                System.out.println("getPeakUsage\t\t"
+                        + memoryPool.getPeakUsage());
+                System.out.println("getType\t\t"
+                        + memoryPool.getType());
+                System.out.println("getUsage\t\t"
+                        + memoryPool.getUsage());
+                System.out.println("isValid\t\t"
+                        + memoryPool.isValid());
+                boolean supported = memoryPool.isUsageThresholdSupported() ;
+                System.out.println("isUsageThresholdSupported\t\t"
+                        + supported);
+
+                if ( supported ) {
+                    System.out.println("getUsageThreshold\t\t"
+                            + memoryPool.getUsageThreshold());
+                    System.out.println("isUsageThresholdExceeded\t\t"
+                            + memoryPool.isUsageThresholdExceeded());
+                    System.out.println("getUsageThresholdCount\t\t"
+                            + memoryPool.getUsageThresholdCount());
+                }
+
+                supported = memoryPool.isCollectionUsageThresholdSupported() ;
+                System.out.println("isCollectionUsageThresholdSupported\t\t"
+                        + supported);
+
+                if ( supported ) {
+                    System.out.println("getCollectionUsageThreshold\t\t"
+                            + memoryPool.getCollectionUsageThreshold());
+                    System.out.println("getCollectionUsageThresholdCount\t\t"
+                            + memoryPool.getCollectionUsageThresholdCount());
+                    System.out.println("isCollectionUsageThresholdExceeded\t\t"
+                            + memoryPool.isCollectionUsageThresholdExceeded());
+                }
+
+                memoryPool.resetPeakUsage();
+            }
+
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+
+    private int checkNonEmpty(MBeanInfo mbi) {
+        if ( mbi.toString().length() == 0 ) {
+            System.out.println("(ERROR) MBeanInfo is empty !");
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+}
diff --git a/jdk/test/javax/management/mxbean/MXBeanInteropTest2.java b/jdk/test/javax/management/mxbean/MXBeanInteropTest2.java
new file mode 100644
index 00000000000..4c713574100
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/MXBeanInteropTest2.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks access to test MXBean
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest2
+ */
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanServer;
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanInteropTest2 {
+
+    private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        MXBeanInteropTest2 test = new MXBeanInteropTest2();
+        test.run(map);
+
+    }
+
+    public void run(Map<String, Object> args) {
+
+        System.out.println("MXBeanInteropTest2::run: Start") ;
+        int errorCount = 0 ;
+
+        try {
+            // JMX MbeanServer used inside single VM as if remote.
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+            JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+            JMXConnectorServer cs =
+                JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+            cs.start();
+
+            JMXServiceURL addr = cs.getAddress();
+            JMXConnector cc = JMXConnectorFactory.connect(addr);
+            MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+            // Prints all MBeans whatever the domain is.
+            printMBeans(mbsc) ;
+
+            // Call test body
+            errorCount += doBasicMXBeanTest(mbsc) ;
+
+            // Terminate the JMX Client
+            cc.close();
+
+        } catch(Exception e) {
+            Utils.printThrowable(e, true) ;
+            throw new RuntimeException(e);
+        }
+
+        if ( errorCount == 0 ) {
+            System.out.println("MXBeanInteropTest2::run: Done without any error") ;
+        } else {
+            System.out.println("MXBeanInteropTest2::run: Done with "
+                    + errorCount
+                    + " error(s)") ;
+            throw new RuntimeException("errorCount = " + errorCount);
+        }
+    }
+
+
+    /**
+     * Prints all MBeans whatever the domain is.
+     */
+    private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
+        Set<ObjectName> set = mbsc.queryNames(null, null);
+        System.out.println("---- MBeans found :");
+
+        for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
+            System.out.println(iter.next().toString());
+        }
+
+        System.out.println("\n") ;
+    }
+
+
+    private final int doBasicMXBeanTest(MBeanServerConnection mbsc) {
+        int errorCount = 0 ;
+        System.out.println("---- doBasicMXBeanTest") ;
+
+        try {
+            ObjectName objName =
+                    new ObjectName("sqe:type=BasicMXBean") ;
+            mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
+            printMBeanInfo(mbInfo);
+            System.out.println("---- OK\n") ;
+            System.out.println("getMBeanInfo\t\t"
+                    + mbInfo);
+            System.out.println("---- OK\n") ;
+
+            System.out.println("Check mxbean field in the MBeanInfo");
+            String mxbeanField =
+                    (String)mbInfo.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
+
+            if ( mxbeanField == null || ! mxbeanField.equals("true")) {
+                System.out.println("---- ERROR : Improper mxbean field value "
+                        + mxbeanField);
+                errorCount++;
+            }
+            System.out.println("---- OK\n") ;
+
+            System.out.println("Set attribute ObjectNameAtt");
+            Attribute att = new Attribute("ObjectNameAtt", objName);
+            mbsc.setAttribute(objName, att);
+            ObjectName value =
+                    (ObjectName)mbsc.getAttribute(objName, "ObjectNameAtt");
+
+            if ( ! value.equals(objName) ) {
+                errorCount++;
+                System.out.println("---- ERROR : setAttribute failed, got "
+                        + value
+                        + " while expecting "
+                        + objName);
+            }
+            System.out.println("---- OK\n") ;
+
+            System.out.println("Call operation doNothing");
+            mbsc.invoke(objName,  "doNothing", null, null);
+            System.out.println("---- OK\n") ;
+
+            System.out.println("Call operation getWeather");
+            Object weather = mbsc.invoke(objName,
+                    "getWeather",
+                    new Object[]{Boolean.TRUE},
+                    new String[]{"boolean"});
+            System.out.println("Weather is " + weather);
+            System.out.println("---- OK\n") ;
+        } catch (Exception e) {
+            Utils.printThrowable(e, true) ;
+            errorCount++ ;
+            System.out.println("---- ERROR\n") ;
+        }
+
+        return errorCount ;
+    }
+
+    private void printMBeanInfo(MBeanInfo mbInfo) {
+        System.out.println("Description " + mbInfo.getDescription());
+
+        for (MBeanConstructorInfo ctor : mbInfo.getConstructors()) {
+            System.out.println("Constructor " + ctor.getName());
+        }
+
+        for (MBeanAttributeInfo att : mbInfo.getAttributes()) {
+            System.out.println("Attribute " + att.getName()
+            + " [" + att.getType() + "]");
+        }
+
+        for (MBeanOperationInfo oper : mbInfo.getOperations()) {
+            System.out.println("Operation " + oper.getName());
+        }
+
+        for (MBeanNotificationInfo notif : mbInfo.getNotifications()) {
+            System.out.println("Notification " + notif.getName());
+        }
+    }
+}
diff --git a/jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java b/jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java
new file mode 100644
index 00000000000..699260777d1
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/MXBeanLoadingTest1.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks correct collection of MXBean's class after unregistration
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @run main/othervm/timeout=300 MXBeanLoadingTest1
+ */
+
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Map;
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MXBean;
+import javax.management.ObjectName;
+import javax.management.loading.PrivateMLet;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+public class MXBeanLoadingTest1 {
+
+    public static void main(String[] args) throws Exception {
+        MXBeanLoadingTest1 test = new MXBeanLoadingTest1();
+        test.run((Map<String, Object>)null);
+    }
+
+
+    public void run(Map<String, Object> args) {
+
+        System.out.println("MXBeanLoadingTest1::run: Start") ;
+
+        try {
+            System.out.println("We ensure no reference is retained on MXBean class"
+                    + " after it is unregistered. We take time to perform"
+                    + " some little extra check of Descriptors, MBean*Info.");
+
+            ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader();
+
+            if (!(myClassLoader instanceof URLClassLoader)) {
+                String message = "(ERROR) Test's class loader is not " +
+                        "a URLClassLoader";
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            URLClassLoader myURLClassLoader = (URLClassLoader) myClassLoader;
+            URL[] urls = myURLClassLoader.getURLs();
+            PrivateMLet mlet = new PrivateMLet(urls, null, false);
+            Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName());
+
+            if (shadowClass == TestMXBean.class) {
+                String message = "(ERROR) MLet got original TestMXBean, not shadow";
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+            shadowClass = null;
+
+            MBeanServer mbs = MBeanServerFactory.createMBeanServer();
+            ObjectName mletName = new ObjectName("x:type=mlet");
+            mbs.registerMBean(mlet, mletName);
+
+            ObjectName testName = new ObjectName("x:type=test");
+            mbs.createMBean(Test.class.getName(), testName, mletName);
+
+            // That test fails because the MXBean instance is accessed via
+            // a delegate OpenMBean which has
+            ClassLoader testLoader = mbs.getClassLoaderFor(testName);
+
+            if (testLoader != mlet) {
+                System.out.println("MLet " + mlet);
+                String message = "(ERROR) MXBean's class loader is not MLet: "
+                        + testLoader;
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+            testLoader = null;
+
+
+            // Cycle get/set/get of the attribute of type Luis.
+            // We check the set is effective.
+            CompositeData cd_B = (CompositeData)mbs.getAttribute(testName, "B");
+            CompositeType compType_B = cd_B.getCompositeType();
+
+            CompositeDataSupport cds_B =
+                    new CompositeDataSupport(compType_B,
+                    new String[]{"something"},
+                    new Object[]{Integer.valueOf(13)});
+            Attribute myAtt = new Attribute("B",  cds_B);
+            mbs.setAttribute(testName, myAtt);
+
+            CompositeData cd_B2 = (CompositeData)mbs.getAttribute(testName, "B");
+
+            if ( ((Integer)cd_B2.get("something")).intValue() != 13 ) {
+                String message = "(ERROR) The setAttribute of att B did not work;"
+                        + " expect Luis.something = 13 but got "
+                        + cd_B2.get("something");
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            MBeanInfo info = mbs.getMBeanInfo(testName);
+            String mxbeanField =
+                    (String)info.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
+
+            if ( mxbeanField == null || ! mxbeanField.equals("true")) {
+                String message = "(ERROR) Improper mxbean field value "
+                        + mxbeanField;
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            // Check the 2 attributes.
+            MBeanAttributeInfo[] attrs = info.getAttributes();
+
+            if ( attrs.length == 2 ) {
+                for (MBeanAttributeInfo mbai : attrs) {
+                    String originalTypeFieldValue =
+                            (String)mbai.getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
+                    OpenType<?> openTypeFieldValue =
+                            (OpenType<?>)mbai.getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
+
+                    if ( mbai.getName().equals("A") ) {
+                        if ( !mbai.isReadable() || !mbai.isWritable()
+                        || mbai.isIs()
+                        || !mbai.getType().equals("int") ) {
+                            String message = "(ERROR) Unexpected MBeanAttributeInfo for A "
+                                    + mbai;
+                            System.out.println(message);
+                            throw new RuntimeException(message);
+                        }
+
+                        if ( ! originalTypeFieldValue.equals("int") ) {
+                            String message = "(ERROR) Unexpected originalType in Descriptor for A "
+                                    + originalTypeFieldValue;
+                            System.out.println(message);
+                            throw new RuntimeException(message);
+                        }
+
+                        if ( ! openTypeFieldValue.equals(SimpleType.INTEGER) ) {
+                            String message = "(ERROR) Unexpected openType in Descriptor for A "
+                                    + originalTypeFieldValue;
+                            System.out.println(message);
+                            throw new RuntimeException(message);
+                        }
+                    } else if ( mbai.getName().equals("B") ) {
+                        if ( !mbai.isReadable() || !mbai.isWritable()
+                        || mbai.isIs()
+                        || !mbai.getType().equals("javax.management.openmbean.CompositeData") ) {
+                            String message = "(ERROR) Unexpected MBeanAttributeInfo for B "
+                                    + mbai;
+                            System.out.println(message);
+                            throw new RuntimeException(message);
+                        }
+
+                        if ( ! originalTypeFieldValue.equals(Luis.class.getName()) ) {
+                            String message = "(ERROR) Unexpected originalType in Descriptor for B "
+                                    + originalTypeFieldValue;
+                            System.out.println(message);
+                            throw new RuntimeException(message);
+                        }
+
+                        if ( ! openTypeFieldValue.equals(compType_B) ) {
+                            String message = "(ERROR) Unexpected openType in Descriptor for B "
+                                    + compType_B;
+                            System.out.println(message);
+                            throw new RuntimeException(message);
+                        }
+                    } else {
+                        String message = "(ERROR) Unknown attribute name";
+                        System.out.println(message);
+                        throw new RuntimeException(message);
+                    }
+                }
+            } else {
+                String message = "(ERROR) Unexpected MBeanAttributeInfo array"
+                        + Arrays.deepToString(attrs);
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            // Check the MXBean operation.
+            MBeanOperationInfo[] ops = info.getOperations();
+            // The impact is ACTION_INFO as for a standard MBean it is UNKNOWN,
+            // logged 6320104.
+            if (ops.length != 1 || !ops[0].getName().equals("bogus")
+            || ops[0].getSignature().length > 0
+                    || !ops[0].getReturnType().equals("void")) {
+                String message = "(ERROR) Unexpected MBeanOperationInfo array "
+                        + Arrays.deepToString(ops);
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            String originalTypeFieldValue =
+                    (String)ops[0].getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
+            OpenType<?> openTypeFieldValue =
+                    (OpenType<?>)ops[0].getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
+
+            if ( ! originalTypeFieldValue.equals("void") ) {
+                String message = "(ERROR) Unexpected originalType in Descriptor for bogus "
+                        + originalTypeFieldValue;
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            if ( ! openTypeFieldValue.equals(SimpleType.VOID) ) {
+                String message = "(ERROR) Unexpected openType in Descriptor for bogus "
+                        + originalTypeFieldValue;
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            // Check there is 2 constructors.
+            if (info.getConstructors().length != 2) {
+                String message = "(ERROR) Wrong number of constructors " +
+                        "in introspected bean: " +
+                        Arrays.asList(info.getConstructors());
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            // Check MXBean class name.
+            if (!info.getClassName().endsWith("Test")) {
+                String message = "(ERROR) Wrong info class name: " +
+                        info.getClassName();
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+
+            mbs.unregisterMBean(testName);
+            mbs.unregisterMBean(mletName);
+
+            WeakReference<PrivateMLet> mletRef =
+                    new WeakReference<PrivateMLet>(mlet);
+            mlet = null;
+
+            System.out.println("MXBean registered and unregistered, waiting for " +
+                    "garbage collector to collect class loader");
+
+            for (int i = 0; i < 10000 && mletRef.get() != null; i++) {
+                System.gc();
+                Thread.sleep(1);
+            }
+
+            if (mletRef.get() == null)
+                System.out.println("(OK) class loader was GC'd");
+            else {
+                String message = "(ERROR) Class loader was not GC'd";
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+        } catch(Exception e) {
+            Utils.printThrowable(e, true) ;
+            throw new RuntimeException(e);
+        }
+
+        System.out.println("MXBeanLoadingTest1::run: Done without any error") ;
+    }
+
+
+    // I agree the use of the MXBean annotation and the MXBean suffix for the
+    // interface name are redundant but however harmless.
+    //
+    @MXBean(true)
+    public static interface TestMXBean {
+        public void bogus();
+        public int getA();
+        public void setA(int a);
+        public Luis getB();
+        public void setB(Luis mi);
+    }
+
+
+    public static class Test implements TestMXBean {
+        private Luis luis = new Luis() ;
+        public Test() {}
+        public Test(int x) {}
+
+        public void bogus() {}
+        public int getA() {return 0;}
+        public void setA(int a) {}
+        public Luis getB() {return this.luis;}
+        public void setB(Luis luis) {this.luis = luis;}
+    }
+
+
+    public static class Luis {
+        private int something = 0;
+        public Luis() {}
+        public int getSomething() {return something;}
+        public void setSomething(int v) {something = v;}
+        public void doNothing() {}
+    }
+}
diff --git a/jdk/test/javax/management/mxbean/MXBeanNotifTest.java b/jdk/test/javax/management/mxbean/MXBeanNotifTest.java
new file mode 100644
index 00000000000..021731e4fa7
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/MXBeanNotifTest.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks MXBean proper registration both as its implementation class and interface
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanNotifTest -numOfNotifications 239 -timeForNotificationInSeconds 4
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.Attribute;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.MBeanServer;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+public class MXBeanNotifTest implements NotificationListener {
+
+    private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+    private static String BASIC_MXBEAN_INTERFACE_NAME = "BasicMXBean";
+
+    private long timeForNotificationInSeconds = 3L;
+    private int numOfNotifications = 1;
+    private BlockingQueue<Notification> notifList = null;
+    private int numOfNotifDescriptorElements = 13;
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        MXBeanNotifTest test = new MXBeanNotifTest();
+        test.run(map);
+
+    }
+
+    protected void parseArgs(Map<String, Object> args) throws Exception {
+
+        String arg = null;
+
+        // Init numOfNotifications
+        // It is the number of notifications we should trigger and check.
+        arg = (String)args.get("-numOfNotifications") ;
+        if (arg != null) {
+            numOfNotifications = (new Integer(arg)).intValue();
+        }
+
+        // Init timeForNotificationInSeconds
+        // It is the maximum time in seconds we wait for each notification.
+        arg = (String)args.get("-timeForEachNotificationInSeconds") ;
+        if (arg != null) {
+            timeForNotificationInSeconds = (new Long(arg)).longValue();
+        }
+
+    }
+
+    public void run(Map<String, Object> args) {
+
+        System.out.println("MXBeanNotifTest::run: Start") ;
+        int errorCount = 0 ;
+
+        try {
+            parseArgs(args);
+            notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
+
+            // JMX MbeanServer used inside single VM as if remote.
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+            JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+            JMXConnectorServer cs =
+                JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+            cs.start();
+
+            JMXServiceURL addr = cs.getAddress();
+            JMXConnector cc = JMXConnectorFactory.connect(addr);
+            MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+            // ----
+            System.out.println("MXBeanNotifTest::run: Create and register the MBean");
+            ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+            mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+            System.out.println("---- OK\n") ;
+
+            // ----
+            System.out.println("MXBeanNotifTest::run: Add me as notification listener");
+            mbsc.addNotificationListener(objName, this, null, null);
+
+            // ----
+            System.out.println("MXBeanNotifTest::run: Retrieve the Descriptor"
+                    + " that should be in MBeanNotificationInfo");
+            TabularData tabData =
+                (TabularData)mbsc.getAttribute(objName, "NotifDescriptorAsMapAtt");
+            Map<String, String> descrMap = new HashMap<>();
+
+            for (Iterator<?> it = tabData.values().iterator(); it.hasNext(); ) {
+                CompositeData compData = (CompositeData)it.next();
+                descrMap.put((String)compData.get("key"),
+                        (String)compData.get("value"));
+            }
+
+            Descriptor refNotifDescriptor = new ImmutableDescriptor(descrMap);
+            System.out.println("---- OK\n") ;
+
+            // ----
+            // Because the MBean holding the targeted attribute is MXBean, we
+            // should use for the setAttribute a converted form for the
+            // attribute value as described by the MXBean mapping rules.
+            // This explains all that lovely stuff for creating a
+            // TabularDataSupport.
+            //
+            // WARNING : the MBeanInfo of the MXBean used on opposite side
+            // is computed when the MBean is registered.
+            // It means the Descriptor considered for the MBeanNotificationInfo
+            // is not the one we set in the lines below, it is too late.
+            // However, we check that set is harmless when we check
+            // the MBeanNotificationInfo.
+            //
+            System.out.println("MXBeanNotifTest::run: Set a Map<String, String>"
+                    + " attribute");
+            String typeName =
+                    "java.util.Map<java.lang.String,java.lang.String>";
+            String[] keyValue = new String[] {"key", "value"};
+            OpenType<?>[] openTypes =
+                    new OpenType<?>[] {SimpleType.STRING, SimpleType.STRING};
+            CompositeType rowType = new CompositeType(typeName, typeName,
+                    keyValue, keyValue, openTypes);
+            TabularType tabType = new TabularType(typeName, typeName,
+                    rowType, new String[]{"key"});
+            TabularDataSupport convertedDescrMap =
+                    new TabularDataSupport(tabType);
+
+            for (int i = 0; i < numOfNotifDescriptorElements; i++) {
+                Object[] descrValue = {"field" + i, "value" + i};
+                CompositeData data =
+                        new CompositeDataSupport(rowType, keyValue, descrValue);
+                convertedDescrMap.put(data);
+            }
+
+            Attribute descrAtt =
+                    new Attribute("NotifDescriptorAsMapAtt", convertedDescrMap);
+            mbsc.setAttribute(objName, descrAtt);
+            System.out.println("---- OK\n") ;
+
+            // ----
+            System.out.println("MXBeanNotifTest::run: Compare the Descriptor from"
+                    + " the MBeanNotificationInfo against a reference");
+            MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
+            errorCount += checkMBeanInfo(mbInfo, refNotifDescriptor);
+            System.out.println("---- DONE\n") ;
+
+            // ----
+            System.out.println("Check isInstanceOf(Basic)");
+
+            if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_CLASS_NAME) ) {
+                errorCount++;
+                System.out.println("---- ERROR isInstanceOf returned false\n") ;
+            } else {
+                System.out.println("---- OK\n") ;
+            }
+
+            // ----
+            System.out.println("Check isInstanceOf(BasicMXBean)");
+
+            if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_INTERFACE_NAME) ) {
+                errorCount++;
+                System.out.println("---- ERROR isInstanceOf returned false\n") ;
+            } else {
+                System.out.println("---- OK\n") ;
+            }
+
+            // ----
+            System.out.println("MXBeanNotifTest::run: Ask for "
+                    + numOfNotifications + " notification(s)");
+            Object[] sendNotifParam = new Object[1];
+            String[] sendNotifSig = new String[]{"java.lang.String"};
+
+            for (int i = 0; i < numOfNotifications; i++) {
+                // Select which type of notification we ask for
+                if ( i % 2 == 0 ) {
+                    sendNotifParam[0] = Basic.NOTIF_TYPE_0;
+                } else {
+                    sendNotifParam[0] = Basic.NOTIF_TYPE_1;
+                }
+
+                // Trigger notification emission
+                mbsc.invoke(objName,
+                        "sendNotification",
+                        sendNotifParam,
+                        sendNotifSig);
+
+                // Wait for it then check it when it comes early enough
+                Notification notif =
+                        notifList.poll(timeForNotificationInSeconds,
+                        TimeUnit.SECONDS) ;
+                // The very first notification is likely to come in slower than
+                // all the others. Because that test isn't targeting the speed
+                // notifications are delivered with, we prefer to secure it.
+                if (i == 0 && notif == null) {
+                    System.out.println("MXBeanNotifTest::run: Wait extra "
+                            + timeForNotificationInSeconds + " second(s) the "
+                            + " very first notification");
+                    notif = notifList.poll(timeForNotificationInSeconds,
+                            TimeUnit.SECONDS);
+                }
+
+                if ( notif == null ) {
+                    errorCount++;
+                    System.out.println("---- ERROR No notification received"
+                            + " within allocated " + timeForNotificationInSeconds
+                            + " second(s) !");
+                } else {
+                    errorCount +=
+                            checkNotification(notif,
+                            (String)sendNotifParam[0],
+                            Basic.NOTIFICATION_MESSAGE,
+                            objName);
+                }
+            }
+
+            int toc = 0;
+            while ( notifList.size() < 2 && toc < 10 ) {
+                Thread.sleep(499);
+                toc++;
+            }
+            System.out.println("---- DONE\n") ;
+        } catch(Exception e) {
+            Utils.printThrowable(e, true) ;
+            throw new RuntimeException(e);
+        }
+
+        if ( errorCount == 0 ) {
+            System.out.println("MXBeanNotifTest::run: Done without any error") ;
+        } else {
+            System.out.println("MXBeanNotifTest::run: Done with "
+                    + errorCount
+                    + " error(s)") ;
+            throw new RuntimeException("errorCount = " + errorCount);
+        }
+    }
+
+
+    private int checkMBeanInfo(MBeanInfo mbi, Descriptor refDescr) {
+        MBeanNotificationInfo[] notifsInfo = mbi.getNotifications();
+        int res = 0;
+
+        for (MBeanNotificationInfo mbni : notifsInfo) {
+            if ( mbni.getDescriptor().equals(refDescr) ) {
+                System.out.println("(OK)");
+            } else {
+                System.out.println("(ERROR) Descriptor of the notification is "
+                        + mbni.getDescriptor()
+                        + " as we expect "
+                        + refDescr);
+                res++;
+            }
+        }
+
+        return res;
+    }
+
+
+    private int checkNotification(Notification notif,
+            String refType,
+            String refMessage,
+            ObjectName refSource) {
+        int res = 0;
+
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "\t getSource " + notif.getSource());
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "\t getMessage " + notif.getMessage());
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "\t getSequenceNumber " + notif.getSequenceNumber());
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "\t getTimeStamp " + notif.getTimeStamp());
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "\t getType " + notif.getType());
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "\t getUserData " + notif.getUserData());
+
+        if ( ! notif.getType().equals(refType) ) {
+            res++;
+            System.out.println("(ERROR) Type is not "
+                    + refType + " in notification\n" + notif);
+        } else {
+            if ( notif.getType().equals(Basic.NOTIF_TYPE_0)
+            && ! (notif instanceof javax.management.Notification) ) {
+                res++;
+                System.out.println("(ERROR) Notification is not instance of "
+                        + " javax.management.Notification but rather "
+                        + notif.getClass().getName());
+            } else if ( notif.getType().equals(Basic.NOTIF_TYPE_1)
+            && ! (notif instanceof SqeNotification) ) {
+                res++;
+                System.out.println("(ERROR) Notification is not instance of "
+                        + " javasoft.sqe.jmx.share.SqeNotification but rather "
+                        + notif.getClass().getName());
+            }
+        }
+
+        if ( ! notif.getMessage().equals(refMessage) ) {
+            res++;
+            System.out.println("(ERROR) Message is not "
+                    + refMessage + " in notification\n" + notif);
+        }
+
+        if ( ! notif.getSource().equals(refSource) ) {
+            res++;
+            System.out.println("(ERROR) Source is not "
+                    + refSource + " in notification\n" + notif);
+        }
+
+        return res;
+    }
+
+    public void handleNotification(Notification notification, Object handback) {
+        Utils.debug(Utils.DEBUG_VERBOSE,
+                "MXBeanNotifTest::handleNotification: Received "
+                + notification);
+        notifList.add(notification);
+    }
+
+}
diff --git a/jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java b/jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java
new file mode 100644
index 00000000000..358233f79a3
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks that a serialized instance is not transmitted from an MXBean.
+ * All the communication should be done via Open Types
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest
+ */
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.lang.Process;
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class MXBeanWeirdParamTest {
+
+    private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+    private static final String CLIENT_CLASS_MAIN =
+        "MXBeanWeirdParamTest$ClientSide";
+
+    private JMXConnectorServer cs;
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        MXBeanWeirdParamTest test = new MXBeanWeirdParamTest();
+        test.run(map);
+
+    }
+
+    /*
+     * Create the MBeansServe side of the test and returns its address
+     */
+    private JMXServiceURL createServerSide() throws Exception {
+        final int NINETY_SECONDS = 90;
+
+        // We will use the platform mbean server
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+        JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+        cs.start();
+
+        Utils.waitReady(cs, NINETY_SECONDS);
+
+        JMXServiceURL addr = cs.getAddress();
+        return addr;
+    }
+
+
+    /*
+     * Creating command-line for running subprocess JVM:
+     *
+     * JVM command line is like:
+     * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+     *
+     * {defaultopts} are the default java options set by the framework.
+     *
+     */
+    private List<String> buildCommandLine() {
+        List<String> opts = new ArrayList<>();
+        opts.add(JDKToolFinder.getJDKTool("java"));
+        opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+        // We need to set WEIRD_PARAM propertty on the client-side
+        opts.add("-DWEIRD_PARAM");
+        opts.add("-cp");
+        opts.add(System.getProperty("test.class.path", "test.class.path"));
+        opts.add(CLIENT_CLASS_MAIN);
+
+        return opts;
+    }
+
+    /**
+     * Runs MXBeanWeirdParamTest$ClientSide with the passed options and redirects
+     * subprocess standard I/O to the current (parent) process. This provides a
+     * trace of what happens in the subprocess while it is runnning (and before
+     * it terminates).
+     *
+     * @param serviceUrlStr string representing the JMX service Url to connect to.
+     */
+    private int runClientSide(String serviceUrlStr) throws Exception {
+
+        // Building command-line
+        List<String> opts = buildCommandLine();
+        opts.add(serviceUrlStr);
+
+        // Launch separate JVM subprocess
+        int exitCode = 0;
+        String[] optsArray = opts.toArray(new String[0]);
+        ProcessBuilder pb = new ProcessBuilder(optsArray);
+        Process p = ProcessTools.startProcess("MXBeanWeirdParamTest$ClientSide", pb);
+
+        // Handling end of subprocess
+        try {
+            exitCode = p.waitFor();
+            if (exitCode != 0) {
+                System.out.println(
+                    "Subprocess unexpected exit value of [" + exitCode +
+                    "]. Expected 0.\n");
+            }
+        } catch (InterruptedException e) {
+            System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+            // Parent thread unknown state, killing subprocess.
+            p.destroyForcibly();
+
+            throw new RuntimeException(
+                "Parent process interrupted with exception : \n " + e + " :" );
+        } finally {
+            return exitCode;
+        }
+
+     }
+
+    public void run(Map<String, Object> args) throws Exception {
+
+        System.out.println("MXBeanWeirdParamTest::run: Start") ;
+        int errorCount = 0;
+
+        try {
+            // Initialise the server side
+            JMXServiceURL urlToUse = createServerSide();
+
+            // Run client side
+            errorCount = runClientSide(urlToUse.toString());
+
+            if ( errorCount == 0 ) {
+                System.out.println("MXBeanWeirdParamTest::run: Done without any error") ;
+            } else {
+                System.out.println("MXBeanWeirdParamTest::run: Done with "
+                        + errorCount
+                        + " error(s)") ;
+                throw new RuntimeException("errorCount = " + errorCount);
+            }
+
+            cs.stop();
+
+        } catch(Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    private static class ClientSide {
+        public static void main(String args[]) throws Exception {
+
+            int errorCount = 0 ;
+            String msgTag = "ClientSide::main: ";
+
+            try {
+
+                // Get a connection to remote mbean server
+                JMXServiceURL addr = new JMXServiceURL(args[0]);
+                JMXConnector cc = JMXConnectorFactory.connect(addr);
+                MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+                // ----
+                System.out.println(msgTag + "Create and register the MBean");
+                ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+                mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+                System.out.println(msgTag +"---- OK\n") ;
+
+                // ----
+                System.out.println(msgTag +"Get attribute SqeParameterAtt on our MXBean");
+                Object result = mbsc.getAttribute(objName, "SqeParameterAtt");
+                System.out.println(msgTag +"(OK) Got result of class "
+                        + result.getClass().getName());
+                System.out.println(msgTag +"Received CompositeData is " + result);
+                System.out.println(msgTag +"---- OK\n") ;
+
+                // ----
+                // We use the value returned by getAttribute to perform the invoke.
+                System.out.println(msgTag +"Call operation doWeird on our MXBean [1]");
+                mbsc.invoke(objName, "doWeird",
+                        new Object[]{result},
+                        new String[]{"javax.management.openmbean.CompositeData"});
+                System.out.println(msgTag +"---- OK\n") ;
+
+                // ----
+                // We build the CompositeData ourselves that time.
+                System.out.println(msgTag +"Call operation doWeird on our MXBean [2]");
+                String typeName = "SqeParameter";
+                String[] itemNames = new String[] {"glop"};
+                OpenType<?>[] openTypes = new OpenType<?>[] {SimpleType.STRING};
+                CompositeType rowType = new CompositeType(typeName, typeName,
+                        itemNames, itemNames, openTypes);
+                Object[] itemValues = {"HECTOR"};
+                CompositeData data =
+                        new CompositeDataSupport(rowType, itemNames, itemValues);
+                TabularType tabType = new TabularType(typeName, typeName,
+                        rowType, new String[]{"glop"});
+                TabularDataSupport tds = new TabularDataSupport(tabType);
+                tds.put(data);
+                System.out.println(msgTag +"Source CompositeData is " + data);
+                mbsc.invoke(objName, "doWeird",
+                        new Object[]{data},
+                        new String[]{"javax.management.openmbean.CompositeData"});
+                System.out.println(msgTag +"---- OK\n") ;
+
+                // ----
+                System.out.println(msgTag +"Unregister the MBean");
+                mbsc.unregisterMBean(objName);
+                System.out.println(msgTag +"---- OK\n") ;
+
+                // Terminate the JMX Client
+                cc.close();
+
+            } catch(Exception e) {
+                Utils.printThrowable(e, true) ;
+                errorCount++;
+                throw new RuntimeException(e);
+            } finally {
+                System.exit(errorCount);
+            }
+        }
+    }
+}
diff --git a/jdk/test/javax/management/mxbean/SqeDescriptorKey.java b/jdk/test/javax/management/mxbean/SqeDescriptorKey.java
new file mode 100644
index 00000000000..60e4926218b
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/SqeDescriptorKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+    @DescriptorKey("sqeDescriptorKey")
+    String value();
+
+    // List descriptor fields that may be added or may be updated
+    // when retrieving an MBeanInfo using a JMXWS connection compared to the
+    // MBeanInfo returned by a local MBeanServer.
+    // The annotation format is :
+    //   <descriptorFieldName>=<descriptorFieldValue>
+    // The values actually handled by the test suite are :
+    //   openType=SimpleType.VOID
+    @DescriptorKey("descriptorFields")
+    String[] descriptorFields() default {};
+}
diff --git a/jdk/test/javax/management/mxbean/SqeNotification.java b/jdk/test/javax/management/mxbean/SqeNotification.java
new file mode 100644
index 00000000000..7d0130ea902
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/SqeNotification.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.management.Notification;
+
+/**
+ * Could hold someday a specific semantic.
+ * For now it is used to have a Notification which of another class, no more.
+ */
+public class SqeNotification extends Notification {
+
+    /** Creates a new instance of SqeNotification */
+    public SqeNotification(String type, Object source, long sequenceNumber) {
+        super(type, source, sequenceNumber);
+    }
+
+    /** Creates a new instance of SqeNotification */
+    public SqeNotification(String type, Object source, long sequenceNumber,
+            long timeStamp) {
+        super(type, source, sequenceNumber, timeStamp);
+    }
+
+    /** Creates a new instance of SqeNotification */
+    public SqeNotification(String type, Object source, long sequenceNumber,
+            long timeStamp, String message) {
+        super(type, source, sequenceNumber, timeStamp, message);
+    }
+
+    /** Creates a new instance of SqeNotification */
+    public SqeNotification(String type, Object source, long sequenceNumber,
+            String message) {
+        super(type, source, sequenceNumber, message);
+    }
+}
diff --git a/jdk/test/javax/management/mxbean/SqeParameter.java b/jdk/test/javax/management/mxbean/SqeParameter.java
new file mode 100644
index 00000000000..35a6ff0d897
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/SqeParameter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable;
+
+/**
+ * That class is to use as an MBean operation parameter or returned value.
+ * The property Glop with its public getter + setter is only there to be
+ * reconstructible following MXBean specification, so that SqeParameter can be
+ * used for what it is designed to.
+ */
+public class SqeParameter implements Serializable {
+
+    private static boolean weird;
+    private String glop;
+
+    static {
+        if ( System.getProperty("WEIRD_PARAM") != null ) {
+            weird = true;
+        }
+    }
+
+    /**
+     * Creates a new instance of SqeParameter.
+     * <br>When the Java property WEIRD_PARAM is set, that constructor
+     * throws an exception.
+     * <br>That can be used to ensure the class is instantiated on server side
+     * but never on client side.
+     */
+    public SqeParameter() throws Exception {
+        if ( weird ) {
+            throw new Exception();
+        }
+    }
+
+    public String getGlop() {
+        return glop;
+    }
+
+    public void setGlop(String value) {
+        glop = value;
+    }
+}
diff --git a/jdk/test/javax/management/mxbean/Utils.java b/jdk/test/javax/management/mxbean/Utils.java
new file mode 100644
index 00000000000..f77196baa2c
--- /dev/null
+++ b/jdk/test/javax/management/mxbean/Utils.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+import javax.management.remote.JMXConnectorServerMBean;
+
+// utility class for MXBean* tests coming from JMX Tonga test suite
+class Utils {
+
+    // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+    private static final String DEBUG_HEADER = "[debug] ";
+
+    // DEBUG levels
+    private static int selectedDebugLevel = 0;
+    static final int DEBUG_STANDARD = 1;
+    static final int DEBUG_VERBOSE = 2;  // Mainly used for stress tests
+    static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+    static void parseDebugProperties() {
+        int level = 0;
+        Properties p = System.getProperties();
+
+        // get selected levels
+        if (p.getProperty("DEBUG_STANDARD") != null) {
+            level |= DEBUG_STANDARD;
+        }
+
+        if (p.getProperty("DEBUG_VERBOSE") != null) {
+            level |= DEBUG_VERBOSE;
+        }
+
+        if (p.getProperty("DEBUG_ALL") != null) {
+            level |= DEBUG_ALL;
+        }
+
+        selectedDebugLevel = level;
+    }
+
+    /**
+     * Reproduces the original parsing and collection of test parameters
+     * from the DTonga JMX test suite.
+     *
+     * Collects passed args and returns them in a map(argname, value) structure,
+     * which will be then propagated as necessary to various called methods.
+     */
+    static Map<String, Object> parseParameters(String args[])
+    throws Exception {
+        Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+        HashMap<String, Object> map = new HashMap<>();
+
+        for ( int i = 0; i < args.length; i++ ) {
+            if ( args[i].trim().startsWith("-") ) {
+                if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+                    Utils.debug(DEBUG_STANDARD,
+                        "TestRoot::parseParameters: added in map = " +
+                        args[i] +
+                        " with value " +
+                        args[i+1]) ;
+                    map.put(args[i].trim(), args[i+1].trim()) ;
+                } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+                           (i+1) == args.length ) {
+                    Utils.debug(DEBUG_STANDARD,
+                            "TestRoot::parseParameters: added in map = " +
+                            args[i] +
+                            " with null value") ;
+                    map.put(args[i].trim(), null) ;
+                } else {
+                    System.out.println(
+                        "TestRoot::parseParameters: (WARNING) not added in map = " +
+                        args[i]) ;
+                }
+            }
+        }
+
+        Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+        return map ;
+    }
+
+    /**
+     * This method is to be used in all tests to print anything
+     * that is temporary.
+     * Printing is done only when debug is activated by the property DEBUG.
+     * Printing depends also on the DEBUG_LEVEL property.
+     * Here it encapsulates a System.out.println.
+     */
+    public static void debug(int level, String line) {
+        if ((selectedDebugLevel & level) != 0) {
+            System.out.println(DEBUG_HEADER + line);
+        }
+    }
+
+    /**
+     * Do print stack trace when withStack is true.
+     * Does try to call getTargetException() and getTargetError() then
+     * print embedded stacks in the case of an Exception wrapping
+     * another Exception or an Error. Recurse until no more wrapping
+     * is found.
+     */
+    public static void printThrowable(Throwable theThro, boolean withStack) {
+        try {
+            if (withStack) {
+                theThro.printStackTrace(System.out);
+            }
+            if (theThro instanceof Exception) {
+                Exception t = (Exception) theThro;
+                Method target = null;
+                String blank = " ";
+                try {
+                    target = t.getClass().getMethod("getTargetException",
+                            (java.lang.Class<?>[]) null);
+                } catch (Exception ee) {
+                // OK: getTargetException method could be there or not
+                }
+                System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+                while (target != null) {
+                    try {
+                        t = (Exception) target.invoke(t,
+                                (java.lang.Object[]) null);
+                    } catch (Exception ee) {
+                        t = null;
+                    }
+                    try {
+                        if (t != null) {
+                            blank = blank + "  ";
+                            System.out.println(blank + t.getClass() + "==>" +
+                                    t.getMessage());
+                            try {
+                                target =
+                                        t.getClass().getMethod("getTargetException",
+                                        (java.lang.Class<?>[]) null);
+                            } catch (Exception ee) {
+                            // OK: getTargetException method could be there or not                            }
+                            }
+                        } else {
+                            target = null;
+                        }
+                    } catch (Exception ee) {
+                        target = null;
+                    }
+                }
+
+                // We may have exceptions wrapping an Error then it is
+                // getTargetError that is likely to be called
+                try {
+                    target = ((Exception) theThro).getClass().getMethod("getTargetError",
+                            (java.lang.Class<?>[]) null);
+                } catch (Exception ee) {
+                // OK: getTargetError method could be there or not
+                }
+                Throwable err = theThro;
+                while (target != null) {
+                    try {
+                        err = (Error) target.invoke(err,
+                                (java.lang.Object[]) null);
+                    } catch (Exception ee) {
+                        err = null;
+                    }
+                    try {
+                        if (err != null) {
+                            blank = blank + "  ";
+                            System.out.println(blank + err.getClass() + "==>" +
+                                    err.getMessage());
+                            if (withStack) {
+                                err.printStackTrace(System.out);
+                            }
+                            try {
+                                target = err.getClass().getMethod("getTargetError",
+                                        (java.lang.Class<?>[]) null);
+                            } catch (Exception ee) {
+                            // OK: getTargetError method could be there or not
+                            }
+                        } else {
+                            target = null;
+                        }
+                    } catch (Exception ee) {
+                        target = null;
+                    }
+                }
+            } else {
+                System.out.println("Throwable is : " + theThro);
+            }
+        } catch (Throwable x) {
+            System.out.println("Exception : raised in printException : " + x);
+        }
+    }
+
+    /**
+     * Wait up to maxTimeInSeconds second(s) the given JMX connector server
+     * comes up (which means isActive returns true).
+     * If it fails to do so we throw a RunTime exception.
+     */
+    public static void waitReady(JMXConnectorServerMBean server,
+                                 int maxTimeInSeconds) throws Exception {
+        int elapsed = 0;
+
+        while (!server.isActive() && elapsed < maxTimeInSeconds) {
+            Thread.sleep(1000);
+            elapsed++;
+        }
+
+        if (server.isActive()) {
+            String message = "Utils::waitReady: JMX connector server came up";
+            if ( elapsed == 0) {
+                message += " immediately";
+            } else {
+                message += " after " + elapsed + " seconds";
+            }
+            message += " [" + server.getAddress() + "]";
+            Utils.debug(DEBUG_STANDARD, message);
+        } else {
+            String message = "Utils::waitReady: (ERROR) JMX connector" +
+                    " server didn't come up after " + elapsed + " seconds [" +
+                    server.getAddress() + "]";
+            System.out.println(message);
+            throw new RuntimeException(message);
+        }
+    }
+}
diff --git a/jdk/test/javax/management/query/QueryData.java b/jdk/test/javax/management/query/QueryData.java
new file mode 100644
index 00000000000..fadc6d386ee
--- /dev/null
+++ b/jdk/test/javax/management/query/QueryData.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public abstract class QueryData {
+    protected int intValue = 9;
+    protected long longValue = 9L;
+    protected Integer integerValue = Integer.valueOf(9);
+    protected boolean booleanValue = true;
+    protected double doubleValue = 9D;
+    protected float floatValue = 9.0F;
+    protected String stringValue = "9";
+}
diff --git a/jdk/test/javax/management/query/QueryFactory.java b/jdk/test/javax/management/query/QueryFactory.java
new file mode 100644
index 00000000000..96394996d46
--- /dev/null
+++ b/jdk/test/javax/management/query/QueryFactory.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+
+import javax.management.Query;
+import javax.management.QueryExp;
+import javax.management.ValueExp;
+
+/**
+ * Class used for building QueryExp instances of all every possible type
+ * in terms of JMX API members; note that several JMX classes are private
+ * and appears in the JDK API only by their serial form.
+ * Comments in each case of the big switch in method getQuery() details which
+ * API member we cover with a given query.
+ */
+public class QueryFactory extends QueryData {
+
+    private String mbeanClassName = "";
+    private String primitiveIntAttName = "IntAtt";
+    private String primitiveLongAttName = "LongAtt";
+    private String integerAttName = "IntegerAtt";
+    private String primitiveBooleanAttName = "BooleanAtt";
+    private String primitiveDoubleAttName = "DoubleAtt";
+    private String primitiveFloatAttName = "FloatAtt";
+    private String stringAttName = "StringAtt";
+    private ArrayList<QueryExp> queries = new ArrayList<QueryExp>();
+
+    /**
+     * Creates a new instance of QueryFactory.
+     * The name is the fully qualified class name of an MBean.
+     * There is severe constraints on that MBean that must:
+     * <ul>
+     * <li>extend QueryData in order to inherit attribute values.
+     * <li>define a RW attribute IntAtt of type int
+     * initialized to QueryData.longValue
+     * <li>define a RW attribute LongAtt of type long
+     * initialized to QueryData.intValue
+     * <li>define a RW attribute IntegerAtt of type Integer
+     * initialized to QueryData.integerValue
+     * <li>define a RW attribute BooleanAtt of type boolean
+     * initialized to QueryData.booleanValue
+     * <li>define a RW attribute DoubleAtt of type double
+     * initialized to QueryData.doubleValue
+     * <li>define a RW attribute FloatAtt of type float
+     * initialized to QueryData.floatValue
+     * <li>define a RW attribute StringAtt of type String
+     * initialized to QueryData.stringValue
+     * </ul>
+     */
+    public QueryFactory(String name) {
+        this.mbeanClassName = name;
+    }
+
+    /**
+     * Returns the highest index value the method getQuery supports.
+     * WARNING : returns 0 if buildQueries haven't been called first !
+     */
+    public int getSize() {
+        return queries.size();
+    }
+
+    /**
+     * Populates an ArrayList of QueryExp.
+     * Lowest index is 1.
+     * Highest index is returned by getSize().
+     * <br>The queries numbered 1 to 23 allow to cover all the underlying
+     * Java classes of the JMX API used to build queries.
+     */
+    public void buildQueries() {
+        if ( queries.size() == 0 ) {
+            int smallerIntValue = intValue - 1;
+            int biggerIntValue = intValue + 1;
+
+            // case 1:
+            // True if the MBean is of class mbeanClassName
+            // We cover javax.management.InstanceOfQueryExp
+            queries.add(Query.isInstanceOf(Query.value(mbeanClassName)));
+
+            // case 2:
+            // True if the MBean is of class mbeanClassName
+            // We cover javax.management.MatchQueryExp and
+            // javax.management.ClassAttributeValueExp
+            queries.add(Query.match(Query.classattr(),
+                    Query.value(mbeanClassName)));
+
+            // case 3:
+            // True if an attribute named primitiveIntAttName of type int has
+            // the value intValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.NumericValueExp
+            queries.add(Query.eq(Query.attr(primitiveIntAttName),
+                    Query.value(intValue)));
+
+            // case 4:
+            // True if an attribute named primitiveLongAttName of type long has
+            // the value longValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.NumericValueExp
+            queries.add(Query.eq(Query.attr(primitiveLongAttName),
+                    Query.value(longValue)));
+
+            // case 5:
+            // True if an attribute named primitiveDoubleAttName of type double
+            // has the value doubleValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.NumericValueExp
+            queries.add(Query.eq(Query.attr(primitiveDoubleAttName),
+                    Query.value(doubleValue)));
+
+            // case 6:
+            // True if an attribute named primitiveFloatAttName of type float
+            // has the value floatValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.NumericValueExp
+            queries.add(Query.eq(Query.attr(primitiveFloatAttName),
+                    Query.value(floatValue)));
+
+            // case 7:
+            // True if an attribute named primitiveIntAttName of type int is
+            // hold by an MBean of class mbeanClassName and has
+            // the value intValue
+            // We cover javax.management.QualifiedAttributeValueExp
+            queries.add(Query.eq(Query.attr(mbeanClassName, primitiveIntAttName),
+                    Query.value(intValue)));
+
+            // case 8:
+            // True if an attribute named stringAttName of type String has
+            // the value stringValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.StringValueExp
+            queries.add(Query.eq(Query.attr(stringAttName),
+                    Query.value(stringValue)));
+
+            // case 9:
+            // True if an attribute named integerAttName of type Integer has
+            // the value integerValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.NumericValueExp
+            queries.add(Query.eq(Query.attr(integerAttName),
+                    Query.value(integerValue)));
+
+            // case 10:
+            // True if an attribute named primitiveBooleanAttName of type boolean
+            // has the value booleanValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to EQ and javax.management.BooleanValueExp
+            queries.add(Query.eq(Query.attr(primitiveBooleanAttName),
+                    Query.value(booleanValue)));
+
+            // case 11:
+            // True if an attribute named primitiveIntAttName of type int has
+            // not the value smallerIntValue
+            // We cover javax.management.NotQueryExp
+            queries.add(Query.not(Query.eq(Query.attr(primitiveIntAttName),
+                    Query.value(smallerIntValue))));
+
+            // case 12:
+            // True if either
+            // an attribute named primitiveIntAttName of type int has
+            // the value intValue
+            // or
+            // an attribute named primitiveLongAttName of type long has
+            // the value longValue
+            // We cover javax.management.OrQueryExp
+            queries.add(Query.or(
+                    Query.eq(Query.attr(primitiveIntAttName),
+                    Query.value(intValue)),
+                    Query.eq(Query.attr(primitiveLongAttName),
+                    Query.value(longValue))));
+
+            // case 13:
+            // True if
+            // an attribute named primitiveIntAttName of type int has
+            // the value intValue
+            // and
+            // an attribute named primitiveLongAttName of type long has
+            // the value longValue
+            // We cover javax.management.AndQueryExp
+            queries.add(Query.and(
+                    Query.eq(Query.attr(primitiveIntAttName),
+                    Query.value(intValue)),
+                    Query.eq(Query.attr(primitiveLongAttName),
+                    Query.value(longValue))));
+
+            // case 14:
+            // True if an attribute named primitiveIntAttName of type int has
+            // the value intValue
+            // We cover javax.management.InQueryExp
+            ValueExp[] inArray = {Query.value(intValue)};
+            queries.add(Query.in(Query.attr(primitiveIntAttName), inArray));
+
+            // case 15:
+            // True if an attribute named primitiveIntAttName of type int has
+            // its value in between smallerIntValue and biggerIntValue
+            // We cover javax.management.BetweenRelQueryExp
+            queries.add(Query.between(Query.attr(primitiveIntAttName),
+                    Query.value(smallerIntValue),
+                    Query.value(biggerIntValue)));
+
+            // case 16:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value greater than smallerIntValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to GT
+            queries.add(Query.gt(Query.attr(primitiveIntAttName),
+                    Query.value(smallerIntValue)));
+
+            // case 17:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value greater or equal to smallerIntValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to GE
+            queries.add(Query.geq(Query.attr(primitiveIntAttName),
+                    Query.value(smallerIntValue)));
+
+            // case 18:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value smaller than biggerIntValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to LT
+            queries.add(Query.lt(Query.attr(primitiveIntAttName),
+                    Query.value(biggerIntValue)));
+
+            // case 19:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value smaller or equal to biggerIntValue
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to LE
+            queries.add(Query.leq(Query.attr(primitiveIntAttName),
+                    Query.value(biggerIntValue)));
+
+            // case 20:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value equal to intValue minus zero
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to MINUS
+            queries.add(Query.eq(Query.attr(primitiveIntAttName),
+                    Query.minus(Query.value(intValue), Query.value(0))));
+
+            // case 21:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value equal to intValue plus zero
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to PLUS
+            queries.add(Query.eq(Query.attr(primitiveIntAttName),
+                    Query.plus(Query.value(intValue), Query.value(0))));
+
+            // case 22:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value equal to intValue divided by one
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to DIV
+            queries.add(Query.eq(Query.attr(primitiveIntAttName),
+                    Query.div(Query.value(intValue), Query.value(1))));
+
+            // case 23:
+            // True if an attribute named primitiveIntAttName of type int has
+            // a value equal to intValue multiplicated by one
+            // We cover javax.management.BinaryRelQueryExp with
+            // a relOp equal to TIMES
+            queries.add(Query.eq(Query.attr(primitiveIntAttName),
+                    Query.times(Query.value(intValue), Query.value(1))));
+
+            // case 24:
+            // That query is a complex one that combines within a big AND
+            // queries with index 2 to 23 inclusive. But because a List is
+            // zero based, we must decrement all indexes by 1 when retrieving
+            // any previously stored query.
+            QueryExp q2_3 = Query.and(queries.get(2-1), queries.get(3-1));
+            QueryExp q4_5 = Query.and(queries.get(4-1), queries.get(5-1));
+            QueryExp q6_7 = Query.and(queries.get(6-1), queries.get(7-1));
+            QueryExp q8_9 = Query.and(queries.get(8-1), queries.get(9-1));
+            QueryExp q10_11 = Query.and(queries.get(10-1), queries.get(11-1));
+            QueryExp q12_13 = Query.and(queries.get(12-1), queries.get(13-1));
+            QueryExp q14_15 = Query.and(queries.get(14-1), queries.get(15-1));
+            QueryExp q16_17 = Query.and(queries.get(16-1), queries.get(17-1));
+            QueryExp q18_19 = Query.and(queries.get(18-1), queries.get(19-1));
+            QueryExp q20_21 = Query.and(queries.get(20-1), queries.get(21-1));
+            QueryExp q22_23 = Query.and(queries.get(22-1), queries.get(23-1));
+            QueryExp q2_5 = Query.and(q2_3, q4_5);
+            QueryExp q6_9 = Query.and(q6_7, q8_9);
+            QueryExp q10_13 = Query.and(q10_11, q12_13);
+            QueryExp q14_17 = Query.and(q14_15, q16_17);
+            QueryExp q18_21 = Query.and(q18_19, q20_21);
+            QueryExp q2_9 = Query.and(q2_5, q6_9);
+            QueryExp q10_17 = Query.and(q10_13, q14_17);
+            QueryExp q18_23 = Query.and(q18_21, q22_23);
+            QueryExp q2_17 = Query.and(q2_9, q10_17);
+            queries.add(Query.and(q2_17, q18_23));
+
+            // case 25:
+            // Complex query mixing AND and OR.
+            queries.add(Query.or(q6_9, q18_23));
+        }
+    }
+
+    /**
+     * Returns a QueryExp taken is the ArrayList populated by buildQueries().
+     * Lowest index is 1.
+     * Highest index is returned by getSize().
+     * <br>The queries numbered 1 to 23 allow to cover all the underlying
+     * Java classes of the JMX API used to build queries.
+     */
+    public QueryExp getQuery(int index) {
+        return queries.get(index - 1);
+    }
+}
diff --git a/jdk/test/javax/management/query/ServerDelegate.java b/jdk/test/javax/management/query/ServerDelegate.java
new file mode 100644
index 00000000000..6ce5face871
--- /dev/null
+++ b/jdk/test/javax/management/query/ServerDelegate.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * This class defines an MBean that can be registered and used on client side
+ * to handle informations or properties of the remote server.
+ *
+ * For example, this MBean can store IOR addresses
+ * of RMI/IIOP connector(s) used in a test.
+ *
+ * That MBean might not be used for testing purpose itself.
+ */
+public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
+
+    private MBeanServer mbeanServer = null;
+    private List<JMXServiceURL> addresses  = null;
+    private String port;
+    private static String javaVersion = System.getProperty("java.version");
+    private int sqeJmxwsCredentialsProviderCallCount = 0;
+    private String jmxwsCredentialsProviderUrl = null;
+    private int testJMXAuthenticatorCallCount = 0;
+    private Principal testJMXAuthenticatorPrincipal = null;
+
+    @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
+    public ServerDelegate() {
+        addresses = new ArrayList<JMXServiceURL>();
+    }
+
+    public ObjectName preRegister(MBeanServer server, ObjectName name)
+    throws Exception {
+        // Initialize MBeanServer attribute
+        mbeanServer = server;
+        return name;
+    }
+    public void postRegister(Boolean registrationDone) {
+    }
+    public void preDeregister() throws Exception {
+    }
+    public void postDeregister() {
+    }
+
+    public void addAddress(JMXServiceURL url) {
+        addresses.add(url) ;
+    }
+
+    public List<JMXServiceURL> getAddresses() {
+        return addresses ;
+    }
+
+    public void setPort(String p) {
+        port = p ;
+    }
+
+    public String getPort() {
+        return port ;
+    }
+
+    public String getJavaVersion() {
+        return javaVersion;
+    }
+
+    public void sqeJmxwsCredentialsProviderCalled() {
+        sqeJmxwsCredentialsProviderCallCount++;
+    }
+
+    public int getSqeJmxwsCredentialsProviderCallCount() {
+        return sqeJmxwsCredentialsProviderCallCount;
+    }
+
+    public void setJmxwsCredentialsProviderUrl(String url) {
+        jmxwsCredentialsProviderUrl = url;
+    }
+
+    public String getJmxwsCredentialsProviderUrl() {
+        return jmxwsCredentialsProviderUrl;
+    }
+
+    public void testJMXAuthenticatorCalled() {
+        testJMXAuthenticatorCallCount++;
+    }
+
+    public int getTestJMXAuthenticatorCallCount() {
+        return testJMXAuthenticatorCallCount;
+    }
+
+    public void setTestJMXAuthenticatorPrincipal(Principal principal) {
+        testJMXAuthenticatorPrincipal = principal;
+    }
+
+    public String getTestJMXAuthenticatorPrincipalString() {
+        if ( testJMXAuthenticatorPrincipal != null ) {
+            return testJMXAuthenticatorPrincipal.toString();
+        }
+
+        return null;
+    }
+
+   /**
+     * Instantiates and registers a StandardMBean in the MBean server.
+     *
+     * @param implementationClassName
+     *      The implementation class name of the MBean.
+     * @param interfaceClassName
+     *      The management interface class name of the MBean.
+     * @param isMXBean
+     *      If true, the resultant MBean is an MXBean.
+     * @param name
+     *      The object name of the StandardMBean.
+     */
+    @SuppressWarnings("unchecked")
+    public void createStandardMBean(
+            String implementationClassName,
+            String interfaceClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception {
+
+        Object implementation =
+                Class.forName(implementationClassName).newInstance();
+        Class<Object> interfaceClass = interfaceClassName == null ? null :
+            (Class<Object>)Class.forName(interfaceClassName);
+
+        // Create the StandardMBean
+        StandardMBean standardMBean = new StandardMBean(
+                implementation,
+                interfaceClass,
+                isMXBean);
+
+        // Register the StandardMBean
+        mbeanServer.registerMBean(standardMBean, name);
+    }
+
+    /**
+     * Instantiates and registers a StandardMBean in the MBean server.
+     * The object will use standard JMX design pattern to determine
+     * the management interface associated with the given implementation.
+     */
+    @SuppressWarnings("unchecked")
+    public void createStandardMBean(
+            String implementationClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception {
+
+        createStandardMBean(implementationClassName, null, isMXBean, name);
+    }
+}
diff --git a/jdk/test/javax/management/query/ServerDelegateMBean.java b/jdk/test/javax/management/query/ServerDelegateMBean.java
new file mode 100644
index 00000000000..88f0b3f5675
--- /dev/null
+++ b/jdk/test/javax/management/query/ServerDelegateMBean.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.ObjectName;
+
+@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
+public interface ServerDelegateMBean {
+    @SqeDescriptorKey("ATTRIBUTE Address")
+    public void addAddress(JMXServiceURL url);
+
+    @SqeDescriptorKey("ATTRIBUTE Address")
+    public List<JMXServiceURL> getAddresses();
+
+    public String getPort();
+    public void setPort(String p);
+
+    public String getJavaVersion();
+
+    public void sqeJmxwsCredentialsProviderCalled();
+    public int getSqeJmxwsCredentialsProviderCallCount();
+
+    public void setJmxwsCredentialsProviderUrl(String url);
+    public String getJmxwsCredentialsProviderUrl();
+
+    public void testJMXAuthenticatorCalled();
+    public int getTestJMXAuthenticatorCallCount();
+
+    public void setTestJMXAuthenticatorPrincipal(Principal principal);
+    public String getTestJMXAuthenticatorPrincipalString();
+
+    public void createStandardMBean(
+            String implementationClassName,
+            String interfaceClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception;
+
+    public void createStandardMBean(
+            String implementationClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception;
+}
diff --git a/jdk/test/javax/management/query/SqeDescriptorKey.java b/jdk/test/javax/management/query/SqeDescriptorKey.java
new file mode 100644
index 00000000000..60e4926218b
--- /dev/null
+++ b/jdk/test/javax/management/query/SqeDescriptorKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+    @DescriptorKey("sqeDescriptorKey")
+    String value();
+
+    // List descriptor fields that may be added or may be updated
+    // when retrieving an MBeanInfo using a JMXWS connection compared to the
+    // MBeanInfo returned by a local MBeanServer.
+    // The annotation format is :
+    //   <descriptorFieldName>=<descriptorFieldValue>
+    // The values actually handled by the test suite are :
+    //   openType=SimpleType.VOID
+    @DescriptorKey("descriptorFields")
+    String[] descriptorFields() default {};
+}
diff --git a/jdk/test/javax/management/query/SupportedQueryTypesTest.java b/jdk/test/javax/management/query/SupportedQueryTypesTest.java
new file mode 100644
index 00000000000..fab8128a317
--- /dev/null
+++ b/jdk/test/javax/management/query/SupportedQueryTypesTest.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Tests most of the existing query types.
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @compile TestQuery.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SupportedQueryTypesTest -mbeanClassName TestQuery
+ */
+
+import java.util.Map ;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName ;
+import javax.management.QueryExp;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class SupportedQueryTypesTest {
+
+    protected String mbeanClassName = null;
+
+    private MBeanServerConnection mbsc = null;
+
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+        Map<String, Object> map = Utils.parseParameters(args) ;
+
+        // Run test
+        SupportedQueryTypesTest test = new SupportedQueryTypesTest();
+        test.run(map);
+
+    }
+
+    public void run(Map<String, Object> args) {
+        int errorCount = 0;
+
+        ObjectName on = null;
+        ObjectName serverDelegateObjectName = null;
+
+        JMXConnectorServer cs = null;
+        JMXConnector cc = null;
+
+        System.out.println("SupportedQueryTypesTest::run: Start") ;
+        try {
+            // JMX MbeanServer used inside single VM as if remote.
+            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+            JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+            cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+            cs.start();
+
+            JMXServiceURL addr = cs.getAddress();
+            cc = JMXConnectorFactory.connect(addr);
+            mbsc = cc.getMBeanServerConnection();
+
+
+            // Create and register the ServerDelegate MBean on the remote MBeanServer
+            String serverDelegateClassName = ServerDelegate.class.getName();
+            serverDelegateObjectName =
+                    new ObjectName("defaultDomain:class=" + serverDelegateClassName);
+            mbsc.createMBean(serverDelegateClassName, serverDelegateObjectName);
+
+            // Retrieve the MBean class name
+            mbeanClassName = (String) args.get("-mbeanClassName") ;
+            on = new ObjectName("defaultDomain:class=" + mbeanClassName);
+
+            // Create and register the MBean on the remote MBeanServer
+            System.out.println("SupportedQueryTypesTest::run: CREATE " +
+                    mbeanClassName + " on the remote MBeanServer with name "
+                    + on);
+            mbsc.createMBean(mbeanClassName, on);
+
+            // Create a QueryFactory and setup which query we'll use.
+            QueryFactory queries = new QueryFactory(mbeanClassName);
+            queries.buildQueries();
+            int maxIndex = queries.getSize();
+            int minIndex = 1;
+
+            // Create a reference Set<ObjectName> to check later on
+            // the queryNames() results
+            Set<ObjectName> referenceNameSet = new HashSet<ObjectName>();
+            referenceNameSet.add(on);
+
+            // Create a reference Set<ObjectInstance> to check later on
+            // the queryMBeans() results
+            ObjectInstance oi = new ObjectInstance(on, mbeanClassName);
+            Set<ObjectInstance> referenceInstanceSet =
+                    new HashSet<ObjectInstance>();
+            referenceInstanceSet.add(oi);
+
+            // Perform the queryNames and queryMBeans requests
+            for (int i = minIndex; i <= maxIndex; i++ ) {
+                QueryExp query = queries.getQuery(i);
+                System.out.println("----");
+                System.out.println("SupportedQueryTypesTest::run: Query # " + i);
+                System.out.println("query " + query);
+                errorCount +=
+                    doQueryNames(query, referenceNameSet);
+                errorCount +=
+                    doQueryMBeans(query, referenceInstanceSet);
+            }
+
+        } catch(Exception e) {
+            Utils.printThrowable(e, true);
+            errorCount++;
+
+        } finally {
+            // Do unregister the MBean
+            try {
+                if (mbsc.isRegistered(on)) {
+                    mbsc.unregisterMBean(on);
+                }
+                if (mbsc.isRegistered(serverDelegateObjectName)) {
+                    mbsc.unregisterMBean(serverDelegateObjectName);
+                }
+            } catch (Exception e) {
+                Utils.printThrowable(e, true) ;
+                errorCount++;
+            }
+
+            try {
+                // Close JMX Connector Client
+                cc.close();
+                // Stop connertor server
+                cs.stop();
+
+            } catch (Exception e) {
+                Utils.printThrowable(e, true) ;
+                errorCount++;
+            }
+        }
+
+        System.out.println("");
+        System.out.println("SupportedQueryTypesTest::run: Done") ;
+
+        // Handle result
+        if (errorCount == 0) {
+            System.out.println("SupportedQueryTypesTest::run: (OK)");
+        } else {
+            String message = "SupportedQueryTypesTest::run: (ERROR) Got " +
+                    + errorCount + " error(s)";
+            System.out.println(message);
+            throw new RuntimeException(message);
+        }
+    }
+
+
+    private int doQueryNames(QueryExp query, Set<ObjectName> referenceSet) {
+        int errorCount = 0;
+        System.out.println(" <*> Perform queryNames call ");
+
+        try {
+            // Call queryNames on the remote MBeanServer
+            Set<ObjectName> remoteSet =  mbsc.queryNames(null, query);
+
+            // Compare the 2 Set<ObjectName>
+            errorCount += checkSet(remoteSet, referenceSet);
+
+            // Cleaning
+            remoteSet.clear();
+
+        } catch (Exception e) {
+            Utils.printThrowable(e, true);
+            errorCount++;
+        }
+
+        if ( errorCount == 0 ) {
+            System.out.println("\t(OK)");
+        } else {
+            System.out.println("\t(ERROR) Query failed");
+        }
+
+        return errorCount;
+    }
+
+
+    private int doQueryMBeans(QueryExp query, Set<ObjectInstance> referenceSet) {
+        int errorCount = 0;
+        System.out.println(" <*> Perform queryMBeans call ");
+
+        try {
+            // Call queryMBeans on the remote MBeanServer
+            Set<ObjectInstance> remoteSet =  mbsc.queryMBeans(null, query);
+
+            // Compare the 2 Set<ObjectInstance>
+            errorCount += checkSet(remoteSet, referenceSet);
+
+            // Cleaning
+            remoteSet.clear();
+
+        } catch (Exception e) {
+            Utils.printThrowable(e, true);
+            errorCount++;
+        }
+
+        if ( errorCount == 0 ) {
+            System.out.println("\t(OK)");
+        } else {
+            System.out.println("\t(ERROR) Query failed");
+        }
+
+        return errorCount;
+    }
+
+    /**
+     * Pretty print of a Set content.
+     * When the Set isn't empty, toString() is called on each element.
+     * <br>The variable's name used to hold that Set is given via the setName
+     * parameter and used in the output.
+     */
+    private static void printSet(Set<?> printableSet, String setName) {
+        if ( printableSet.size() == 0 ) {
+            System.out.println("The Set " + setName + " is empty");
+        } else {
+            System.out.println("The Set " + setName + " contains :");
+
+            for (Iterator<?> it = printableSet.iterator(); it.hasNext();) {
+                Object elem = it.next();
+                System.out.println("\t" + elem.toString());
+            }
+        }
+    }
+
+
+    /**
+     * This method check the Set remoteSet is equal to
+     * the reference Set referenceSet,
+     * which means same size and content (order doesn't matter).
+     * <br>It returns 0 when the check is fine, otherwise 1.
+     */
+    private int checkSet(Set<?> remoteSet, Set<?> referenceSet) {
+        if ( !  remoteSet.equals(referenceSet) ) {
+            System.out.println("SupportedQueryTypesTest::checkSet:"
+                    + " (ERROR) Set aren't as expected");
+            printSet(remoteSet, "remoteSet");
+            printSet(referenceSet, "referenceSet");
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    // Utility inner class coming from JMX Tonga test suite.
+    private static class Utils {
+
+        // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+        static final String DEBUG_HEADER = "[debug] ";
+
+        // DEBUG levels
+        static int selectedDebugLevel = 0;
+        static final int DEBUG_STANDARD = 1;
+        static final int DEBUG_VERBOSE = 2;  // Mainly used for stress tests
+        static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+        static void parseDebugProperties() {
+            int level = 0;
+            Properties p = System.getProperties();
+
+            // get selected levels
+            if (p.getProperty("DEBUG_STANDARD") != null) {
+                level |= DEBUG_STANDARD;
+            }
+
+            if (p.getProperty("DEBUG_VERBOSE") != null) {
+                level |= DEBUG_VERBOSE;
+            }
+
+            if (p.getProperty("DEBUG_ALL") != null) {
+                level |= DEBUG_ALL;
+            }
+
+            selectedDebugLevel = level;
+        }
+
+        /**
+         * Reproduces the original parsing and collection of test parameters
+         * from the DTonga JMX test suite.
+         *
+         * Collects passed args and returns them in a map(argname, value) structure,
+         * which will be then propagated as necessary to various called methods.
+         */
+        static Map<String, Object> parseParameters(String args[])
+        throws Exception {
+            debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+            HashMap<String, Object> map = new HashMap<>();
+
+            for ( int i = 0; i < args.length; i++ ) {
+                if ( args[i].trim().startsWith("-") ) {
+                    if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+                        debug(DEBUG_STANDARD,
+                            "TestRoot::parseParameters: added in map = " +
+                            args[i] +
+                            " with value " +
+                            args[i+1]) ;
+                        map.put(args[i].trim(), args[i+1].trim()) ;
+                    } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+                               (i+1) == args.length ) {
+                        debug(DEBUG_STANDARD,
+                                "TestRoot::parseParameters: added in map = " +
+                                args[i] +
+                                " with null value") ;
+                        map.put(args[i].trim(), null) ;
+                    } else {
+                        System.out.println(
+                            "TestRoot::parseParameters: (WARNING) not added in map = " +
+                            args[i]) ;
+                    }
+                }
+            }
+
+            debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+            return map ;
+        }
+
+        /**
+         * This method is to be used in all tests to print anything
+         * that is temporary.
+         * Printing is done only when debug is activated by the property DEBUG.
+         * Printing depends also on the DEBUG_LEVEL property.
+         * Here it encapsulates a System.out.println.
+         */
+        static void debug(int level, String line) {
+            if ((selectedDebugLevel & level) != 0) {
+                System.out.println(DEBUG_HEADER + line);
+            }
+        }
+
+        /**
+         * Do print stack trace when withStack is true.
+         * Does try to call getTargetException() and getTargetError() then
+         * print embedded stacks in the case of an Exception wrapping
+         * another Exception or an Error. Recurse until no more wrapping
+         * is found.
+         */
+        static void printThrowable(Throwable theThro, boolean withStack) {
+            try {
+                if (withStack) {
+                    theThro.printStackTrace(System.out);
+                }
+                if (theThro instanceof Exception) {
+                    Exception t = (Exception) theThro;
+                    Method target = null;
+                    String blank = " ";
+                    try {
+                        target = t.getClass().getMethod("getTargetException",
+                                (java.lang.Class<?>[]) null);
+                    } catch (Exception ee) {
+                    // OK: getTargetException method could be there or not
+                    }
+                    System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+                    while (target != null) {
+                        try {
+                            t = (Exception) target.invoke(t,
+                                    (java.lang.Object[]) null);
+                        } catch (Exception ee) {
+                            t = null;
+                        }
+                        try {
+                            if (t != null) {
+                                blank = blank + "  ";
+                                System.out.println(blank + t.getClass() + "==>" +
+                                        t.getMessage());
+                                try {
+                                    target =
+                                            t.getClass().getMethod("getTargetException",
+                                            (java.lang.Class<?>[]) null);
+                                } catch (Exception ee) {
+                                // OK: getTargetException method could be there or not                            }
+                                }
+                            } else {
+                                target = null;
+                            }
+                        } catch (Exception ee) {
+                            target = null;
+                        }
+                    }
+
+                    // We may have exceptions wrapping an Error then it is
+                    // getTargetError that is likely to be called
+                    try {
+                        target = ((Exception) theThro).getClass().getMethod("getTargetError",
+                                (java.lang.Class<?>[]) null);
+                    } catch (Exception ee) {
+                    // OK: getTargetError method could be there or not
+                    }
+                    Throwable err = theThro;
+                    while (target != null) {
+                        try {
+                            err = (Error) target.invoke(err,
+                                    (java.lang.Object[]) null);
+                        } catch (Exception ee) {
+                            err = null;
+                        }
+                        try {
+                            if (err != null) {
+                                blank = blank + "  ";
+                                System.out.println(blank + err.getClass() + "==>" +
+                                        err.getMessage());
+                                if (withStack) {
+                                    err.printStackTrace(System.out);
+                                }
+                                try {
+                                    target = err.getClass().getMethod("getTargetError",
+                                            (java.lang.Class<?>[]) null);
+                                } catch (Exception ee) {
+                                // OK: getTargetError method could be there or not
+                                }
+                            } else {
+                                target = null;
+                            }
+                        } catch (Exception ee) {
+                            target = null;
+                        }
+                    }
+                } else {
+                    System.out.println("Throwable is : " + theThro);
+                }
+            } catch (Throwable x) {
+                System.out.println("Exception : raised in printException : " + x);
+            }
+        }
+    }
+
+}
diff --git a/jdk/test/javax/management/query/TestQuery.java b/jdk/test/javax/management/query/TestQuery.java
new file mode 100644
index 00000000000..31b896ed7ff
--- /dev/null
+++ b/jdk/test/javax/management/query/TestQuery.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Class TestQuery
+ * MBean used for testing the types wired when using QueryExp.
+ * It is heavily linked to QueryFactory.
+ */
+public class TestQuery extends QueryData implements TestQueryMBean {
+
+    /**
+     * Attribute : BooleanAtt
+     */
+    private boolean booleanAtt = booleanValue;
+
+    /**
+     * Attribute : DoubleAtt
+     */
+    private double doubleAtt = doubleValue;
+
+    /**
+     * Attribute : FloatAtt
+     */
+    private float floatAtt = floatValue;
+
+    /**
+     * Attribute : IntAtt
+     */
+    private int intAtt = intValue;
+
+    /**
+     * Attribute : IntegerAtt
+     */
+    private Integer integerAtt = integerValue;
+
+    /**
+     * Attribute : LongAtt
+     */
+    private long longAtt = longValue;
+
+    /**
+     * Attribute : StringAtt
+     */
+    private String stringAtt = stringValue;
+
+    public TestQuery() {
+    }
+
+    /**
+     * Get Att of type boolean
+     */
+    public boolean getBooleanAtt() {
+        return booleanAtt;
+    }
+
+    /**
+     * Set Att of type boolean
+     */
+    public void setBooleanAtt(boolean value) {
+        booleanAtt = value;
+    }
+
+    /**
+     * Get Att of type double
+     */
+    public double getDoubleAtt() {
+        return doubleAtt;
+    }
+
+    /**
+     * Set Att of type double
+     */
+    public void setDoubleAtt(double value) {
+        doubleAtt = value;
+    }
+
+    /**
+     * Get Att of type float
+     */
+    public float getFloatAtt() {
+        return floatAtt;
+    }
+
+    /**
+     * Set Att of type float
+     */
+    public void setFloatAtt(float value) {
+        floatAtt = value;
+    }
+
+    /**
+     * Get Att of type int
+     */
+    public int getIntAtt() {
+        return intAtt;
+    }
+
+    /**
+     * Set Att of type int
+     */
+    public void setIntAtt(int value) {
+        intAtt = value;
+    }
+
+    /**
+     * Get Att of type Integer
+     */
+    public Integer getIntegerAtt() {
+        return integerAtt;
+    }
+
+    /**
+     * Set Att of type Integer
+     */
+    public void setIntegerAtt(Integer value) {
+        integerAtt = value;
+    }
+
+    /**
+     * Get Att of type long
+     */
+    public long getLongAtt() {
+        return longAtt;
+    }
+
+    /**
+     * Set Att of type long
+     */
+    public void setLongAtt(long value) {
+        longAtt = value;
+    }
+
+    /**
+     * Get Att of type String
+     */
+    public String getStringAtt() {
+        return stringAtt;
+    }
+
+    /**
+     * Set Att of type String
+     */
+    public void setStringAtt(String value) {
+        stringAtt = value;
+    }
+
+}
diff --git a/jdk/test/javax/management/query/TestQueryMBean.java b/jdk/test/javax/management/query/TestQueryMBean.java
new file mode 100644
index 00000000000..9cf321f9030
--- /dev/null
+++ b/jdk/test/javax/management/query/TestQueryMBean.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Interface TestQueryMBean
+ * MBean used for testing the types wired when using QueryExp.
+ * It is heavily linked to QueryFactory.
+ */
+public interface TestQueryMBean
+{
+    /**
+     * Get Att of type boolean
+     */
+    public boolean getBooleanAtt();
+
+    /**
+     * Set Att of type boolean
+     */
+    public void setBooleanAtt(boolean value);
+
+    /**
+     * Get Att of type double
+     */
+    public double getDoubleAtt();
+
+    /**
+     * Set Att of type double
+     */
+    public void setDoubleAtt(double value);
+
+    /**
+     * Get Att of type float
+     */
+    public float getFloatAtt();
+
+    /**
+     * Set Att of type float
+     */
+    public void setFloatAtt(float value);
+
+    /**
+     * Get Att of type int
+     */
+    public int getIntAtt();
+
+    /**
+     * Set Att of type int
+     */
+    public void setIntAtt(int value);
+
+    /**
+     * Get Att of type Integer
+     */
+    public Integer getIntegerAtt();
+
+    /**
+     * Set Att of type Integer
+     */
+    public void setIntegerAtt(Integer value);
+
+    /**
+     * Get Att of type long
+     */
+    public long getLongAtt();
+
+    /**
+     * Set Att of type long
+     */
+    public void setLongAtt(long value);
+
+    /**
+     * Get Att of type String
+     */
+    public String getStringAtt();
+
+    /**
+     * Set Att of type String
+     */
+    public void setStringAtt(String value);
+
+}
diff --git a/jdk/test/javax/management/security/AuthorizationTest.java b/jdk/test/javax/management/security/AuthorizationTest.java
new file mode 100644
index 00000000000..54309ab059b
--- /dev/null
+++ b/jdk/test/javax/management/security/AuthorizationTest.java
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks various authentication behavior from remote jmx client
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Simple.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username4 -Dpassword=password4 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedGetException -expectedSetException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ */
+
+import java.io.File;
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory ;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.Attribute ;
+import javax.management.ObjectName ;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class AuthorizationTest {
+
+    static final String SERVER_CLASS_NAME = "AuthorizationTest";
+    static final String CLIENT_CLASS_NAME = "AuthorizationTest$ClientSide";
+    static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
+
+    static final String USERNAME_PROPERTY = "username";
+    static final String PASSWORD_PROPERTY = "password";
+
+    private JMXConnectorServer cs;
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+
+        // Supported parameters list format is :
+        // "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
+        // with <param-spec> either "-parami valuei" or "-parami"
+        HashMap<String, Object> serverMap = new HashMap<>() ;
+        int clientArgsIndex =
+            Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
+
+        // Extract and records client params
+        String[] clientParams = null;
+        if (clientArgsIndex < args.length) {
+            int clientParamsSize = args.length - clientArgsIndex;
+            clientParams = new String[clientParamsSize];
+            System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
+        } else {
+            clientParams = new String[0];
+        }
+
+        // Run test
+        AuthorizationTest test = new AuthorizationTest();
+        test.run(serverMap, clientParams);
+
+    }
+
+    /*
+     * Create the MBeansServer side of the test and returns its address
+     */
+    private JMXServiceURL createServerSide(Map<String, Object> serverMap)
+    throws Exception {
+        final int NINETY_SECONDS = 90;
+
+        System.out.println("AuthorizationTest::createServerSide: Start") ;
+
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+
+        // Creates connection environment from server side params
+        HashMap<String, Object> env = new HashMap<>();
+        String value = null;
+
+        if ((value = (String)serverMap.get("-mapType")) != null) {
+            if (value.contains("x.access.file")) {
+                String accessFileStr = System.getProperty("test.src") +
+                    File.separator + "access.properties";
+                env.put("jmx.remote.x.access.file", accessFileStr);
+                System.out.println("Added " + accessFileStr + " file as jmx.remote.x.access.file");
+            }
+            if (value.contains("x.password.file")) {
+                String passwordFileStr = System.getProperty("test.src") +
+                    File.separator + "password.properties";
+                env.put("jmx.remote.x.password.file", passwordFileStr);
+                System.out.println("Added " + passwordFileStr + " file as jmx.remote.x.password.file");
+            }
+        }
+
+        if (serverMap.containsKey("-populate")) {
+            String populateClassName = "Simple";
+            ObjectName on =
+                new ObjectName("defaultDomain:class=Simple");
+
+            Utils.debug(Utils.DEBUG_STANDARD, "create and register Simple MBean") ;
+            mbs.createMBean(populateClassName, on);
+        }
+
+        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+        cs.start();
+
+        Utils.waitReady(cs, NINETY_SECONDS);
+
+        JMXServiceURL addr = cs.getAddress();
+
+        System.out.println("AuthorizationTest::createServerSide: Done.") ;
+
+        return addr;
+    }
+
+    /*
+     * Creating command-line for running subprocess JVM:
+     *
+     * JVM command line is like:
+     * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+     *
+     * {defaultopts} are the default java options set by the framework.
+     *
+     */
+    private List<String> buildCommandLine(String args[]) {
+        List<String> opts = new ArrayList<>();
+        opts.add(JDKToolFinder.getJDKTool("java"));
+        opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+
+        String usernameValue = System.getProperty(USERNAME_PROPERTY);
+        if (usernameValue != null) {
+            opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
+        }
+        String passwordValue = System.getProperty(PASSWORD_PROPERTY);
+        if (passwordValue != null) {
+            opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
+        }
+
+        opts.add("-cp");
+        opts.add(System.getProperty("test.class.path", "test.class.path"));
+        opts.add(CLIENT_CLASS_MAIN);
+        opts.addAll(Arrays.asList(args));
+        return opts;
+    }
+
+    /**
+     * Runs AuthorizationTest$ClientSide with the passed options and redirects
+     * subprocess standard I/O to the current (parent) process. This provides a
+     * trace of what happens in the subprocess while it is runnning (and before
+     * it terminates).
+     *
+     * @param serviceUrlStr string representing the JMX service Url to connect to.
+     */
+    private int runClientSide(String args[], String serviceUrlStr) throws Exception {
+
+        // Building command-line
+        List<String> opts = buildCommandLine(args);
+        opts.add("-serviceUrl");
+        opts.add(serviceUrlStr);
+
+        // Launch separate JVM subprocess
+        int exitCode = 0;
+        String[] optsArray = opts.toArray(new String[0]);
+        ProcessBuilder pb = new ProcessBuilder(optsArray);
+        Process p = ProcessTools.startProcess("AuthorizationTest$ClientSide", pb);
+
+        // Handling end of subprocess
+        try {
+            exitCode = p.waitFor();
+            if (exitCode != 0) {
+                System.out.println(
+                    "Subprocess unexpected exit value of [" + exitCode +
+                    "]. Expected 0.\n");
+            }
+        } catch (InterruptedException e) {
+            System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+            // Parent thread unknown state, killing subprocess.
+            p.destroyForcibly();
+
+            throw new RuntimeException(
+                "Parent process interrupted with exception : \n " + e + " :" );
+
+        } finally {
+            if (p.isAlive()) {
+                p.destroyForcibly();
+            }
+            return exitCode;
+        }
+
+     }
+
+    public void run(Map<String, Object> serverArgs, String clientArgs[]) {
+
+        System.out.println("AuthorizationTest::run: Start") ;
+        int errorCount = 0;
+
+        try {
+            // Initialise the server side
+            JMXServiceURL urlToUse = createServerSide(serverArgs);
+
+            // Run client side
+            errorCount = runClientSide(clientArgs, urlToUse.toString());
+
+            if ( errorCount == 0 ) {
+                System.out.println("AuthorizationTest::run: Done without any error") ;
+            } else {
+                System.out.println("AuthorizationTest::run: Done with "
+                        + errorCount
+                        + " error(s)") ;
+                throw new RuntimeException("errorCount = " + errorCount);
+            }
+
+            cs.stop();
+
+        } catch(Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    private static class ClientSide {
+
+        private JMXConnector cc = null;
+        private MBeanServerConnection mbsc = null;
+
+        public static void main(String args[]) throws Exception {
+
+            // Parses parameters
+            Utils.parseDebugProperties();
+
+            // Supported parameters list format is : "MainClass [-client <param-spec> ...]
+            // with <param-spec> either "-parami valuei" or "-parami"
+            HashMap<String, Object> clientMap = new HashMap<>() ;
+            Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
+
+            // Run test
+            ClientSide test = new ClientSide();
+            test.run(clientMap);
+
+        }
+
+        public void run(Map<String, Object> args) {
+
+            int errorCount = 0 ;
+
+            try {
+                boolean expectedCreateException =
+                        (args.containsKey("-expectedCreateException")) ? true : false ;
+                boolean expectedGetException =
+                        (args.containsKey("-expectedGetException")) ? true : false ;
+                boolean expectedSetException =
+                        (args.containsKey("-expectedSetException")) ? true : false ;
+                boolean expectedInvokeException =
+                        (args.containsKey("-expectedInvokeException")) ? true : false ;
+                // JSR262 (see bug 6440374)
+                // There is no special JSR262 protocol operation for connect.
+                // The first request sent initiate the connection.
+                // In the JSR262 current implementation, getDefaultDomain is sent to
+                // the server in order to get the server part of the connection ID.
+                // => the connection may fail if no access permission on get requests.
+                boolean expectedConnectException =
+                        (args.containsKey("-expectedConnectException")) ? true : false ;
+                // Before connection,
+                // remove the element of the Map with null values (not supported by RMI)
+                // See bug 4982668
+                args.remove("-expectedCreateException");
+                args.remove("-expectedGetException");
+                args.remove("-expectedSetException");
+                args.remove("-expectedInvokeException");
+                args.remove("-expectedConnectException");
+
+
+                // Here do connect to the JMX Server
+                String username = System.getProperty("username");
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "ClientSide::run: CONNECT on behalf of \"" + username + "\"");
+                doConnect(args, expectedConnectException);
+
+                // If the connection did not fail, perform some requests.
+                // At this stage the mbeanserver connection is up and running
+                if (mbsc != null) {
+                    ObjectName on = new ObjectName("defaultDomain:class=Simple");
+
+                    // Create request
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        "ClientSide::run: CREATE on behalf of \"" +
+                        username + "\"");
+                    errorCount += doCreateRequest(mbsc,
+                        new ObjectName("defaultDomain:class=Simple,user=" + username),
+                        expectedCreateException);
+
+                    // Get request
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        "ClientSide::run: GET on behalf of \"" +
+                        username + "\"");
+                    errorCount += doGetRequest(mbsc, on, expectedGetException);
+
+                    // Set request
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        "ClientSide::run: SET on behalf of \"" +
+                        username + "\"");
+                    errorCount += doSetRequest(mbsc, on, expectedSetException);
+
+                    // Invoke request
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        "ClientSide::run: INVOKE on behalf of \"" +
+                        username + "\"");
+                    errorCount += doInvokeRequest(mbsc, on, expectedInvokeException);
+                }
+
+            } catch(Exception e) {
+                Utils.printThrowable(e, true) ;
+                errorCount++;
+            } finally {
+                // Terminate the JMX Client
+                try {
+                    cc.close();
+                } catch (Exception e) {
+                    Utils.printThrowable(e, true) ;
+                    errorCount++;
+                }
+            }
+
+            System.out.println("ClientSide::run: Done") ;
+
+            // Handle result
+            if (errorCount == 0) {
+                System.out.println("ClientSide::run: (OK) authorization test succeeded.");
+            } else {
+                String message = "AuthorizationTest$ClientSide::run: (ERROR) " +
+                        " authorization test failed with " +
+                        errorCount + " error(s)";
+                System.out.println(message);
+                throw new RuntimeException(message);
+            }
+        }
+
+        protected void doConnect(Map<String, Object> args,
+                                 boolean expectedException) {
+
+            String msgTag = "ClientSide::doConnect";
+            boolean throwRuntimeException = false;
+            String message = "";
+
+            try {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "ClientSide::doConnect: Connect the client");
+
+                // Collect connection environment
+                HashMap<String, Object> env = new HashMap<>();
+
+                Object value = args.get("-mapType");
+                if (value != null) {
+                    String username = System.getProperty("username");
+                    String password = System.getProperty("password");
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        msgTag + "add \"jmx.remote.credentials\" = \"" +
+                        username + "\", \"" + password + "\"");
+                    env.put("jmx.remote.credentials",
+                        new String[] { username , password });
+                }
+
+                // Get a connection to remote mbean server
+                JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
+                cc = JMXConnectorFactory.connect(addr,env);
+                mbsc = cc.getMBeanServerConnection();
+
+                if (expectedException) {
+                    message = "ClientSide::doConnect: (ERROR) " +
+                        "Connect did not fail with expected SecurityException";
+                    System.out.println(message);
+                    throwRuntimeException = true;
+                } else {
+                    System.out.println("ClientSide::doConnect: (OK) Connect succeed");
+                }
+            } catch(Exception e) {
+                Utils.printThrowable(e, true);
+                if (expectedException) {
+                    if (e instanceof java.lang.SecurityException) {
+                        System.out.println("ClientSide::doConnect: (OK) " +
+                            "Connect failed with expected SecurityException");
+                    } else {
+                        message = "ClientSide::doConnect: (ERROR) " +
+                            "Create failed with " + e.getClass() +
+                            " instead of expected SecurityException";
+                        System.out.println(message);
+                        throwRuntimeException = true;
+                    }
+                } else {
+                    message = "ClientSide::doConnect: (ERROR) " +
+                        "Connect failed";
+                    System.out.println(message);
+                    throwRuntimeException = true;
+                }
+            }
+
+            // If the connection failed, or if the connection succeeded but should not,
+            // no need to go further => throw RuntimeException and exit the test
+            if (throwRuntimeException) {
+                throw new RuntimeException(message);
+            }
+        }
+
+        protected int doCreateRequest(MBeanServerConnection mbsc,
+                                      ObjectName on,
+                                      boolean expectedException) {
+            int errorCount = 0;
+
+            try {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "ClientSide::doCreateRequest: Create and register the MBean") ;
+
+                mbsc.createMBean("Simple", on) ;
+
+                if (expectedException) {
+                    System.out.println("ClientSide::doCreateRequest: " +
+                        "(ERROR) Create did not fail with expected SecurityException");
+                    errorCount++;
+                } else {
+                    System.out.println("ClientSide::doCreateRequest: (OK) Create succeed") ;
+                }
+            } catch(Exception e) {
+                Utils.printThrowable(e, true) ;
+                if (expectedException) {
+                    if (e instanceof java.lang.SecurityException) {
+                        System.out.println("ClientSide::doCreateRequest: " +
+                            "(OK) Create failed with expected SecurityException") ;
+                    } else {
+                        System.out.println("ClientSide::doCreateRequest: " +
+                            "(ERROR) Create failed with " +
+                            e.getClass() + " instead of expected SecurityException");
+                        errorCount++;
+                    }
+                } else {
+                    System.out.println("ClientSide::doCreateRequest: " +
+                        "(ERROR) Create failed");
+                    errorCount++;
+                }
+            }
+            return errorCount;
+        }
+
+        protected int doGetRequest(MBeanServerConnection mbsc,
+                                   ObjectName on,
+                                   boolean expectedException) {
+            int errorCount = 0;
+
+            try {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "ClientSide::doGetRequest: Get attributes of the MBean") ;
+
+                mbsc.getAttribute(on, "Attribute");
+
+                if (expectedException) {
+                    System.out.println("ClientSide::doGetRequest: " +
+                        "(ERROR) Get did not fail with expected SecurityException");
+                    errorCount++;
+                } else {
+                    System.out.println("ClientSide::doGetRequest: (OK) Get succeed") ;
+                }
+            } catch(Exception e) {
+                Utils.printThrowable(e, true) ;
+                if (expectedException) {
+                    if (e instanceof java.lang.SecurityException) {
+                        System.out.println("ClientSide::doGetRequest: " +
+                            "(OK) Get failed with expected SecurityException") ;
+                    } else {
+                        System.out.println("ClientSide::doGetRequest: " +
+                            "(ERROR) Get failed with " +
+                            e.getClass() + " instead of expected SecurityException");
+                        errorCount++;
+                    }
+                } else {
+                    System.out.println("ClientSide::doGetRequest: (ERROR) Get failed");
+                    errorCount++;
+                }
+            }
+
+            return errorCount;
+        }
+
+        protected int doSetRequest(MBeanServerConnection mbsc,
+                                   ObjectName on,
+                                   boolean expectedException) {
+            int errorCount = 0;
+
+            try {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "ClientSide::doSetRequest: Set attributes of the MBean") ;
+
+                Attribute attribute = new Attribute("Attribute", "My value") ;
+                mbsc.setAttribute(on, attribute) ;
+
+                if (expectedException) {
+                    System.out.println("ClientSide::doSetRequest: " +
+                        "(ERROR) Set did not fail with expected SecurityException");
+                    errorCount++;
+                } else {
+                    System.out.println("ClientSide::doSetRequest: (OK) Set succeed") ;
+                }
+            } catch(Exception e) {
+                Utils.printThrowable(e, true) ;
+                if (expectedException) {
+                    if (e instanceof java.lang.SecurityException) {
+                        System.out.println("ClientSide::doSetRequest: " +
+                            "(OK) Set failed with expected SecurityException") ;
+                    } else {
+                        System.out.println("ClientSide::doSetRequest: " +
+                            "(ERROR) Set failed with " +
+                            e.getClass() + " instead of expected SecurityException");
+                        errorCount++;
+                    }
+                } else {
+                    System.out.println("ClientSide::doSetRequest: (ERROR) Set failed");
+                    errorCount++;
+                }
+            }
+            return errorCount;
+        }
+
+        protected int doInvokeRequest(MBeanServerConnection mbsc,
+                                      ObjectName on,
+                                      boolean expectedException) {
+            int errorCount = 0;
+
+            try {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "ClientSide::doInvokeRequest: Invoke operations on the MBean") ;
+
+                mbsc.invoke(on, "operation", null, null) ;
+
+                if (expectedException) {
+                    System.out.println("ClientSide::doInvokeRequest: " +
+                        "(ERROR) Invoke did not fail with expected SecurityException");
+                    errorCount++;
+                } else {
+                    System.out.println("ClientSide::doInvokeRequest: (OK) Invoke succeed") ;
+                }
+            } catch(Exception e) {
+                Utils.printThrowable(e, true) ;
+                if (expectedException) {
+                    if (e instanceof java.lang.SecurityException) {
+                        System.out.println("ClientSide::doInvokeRequest: " +
+                            "(OK) Invoke failed with expected SecurityException") ;
+                    } else {
+                        System.out.println("ClientSide::doInvokeRequest: " +
+                            " (ERROR) Invoke failed with " +
+                            e.getClass() + " instead of expected SecurityException");
+                        errorCount++;
+                    }
+                } else {
+                    System.out.println("ClientSide::doInvokeRequest: " +
+                        "(ERROR) Invoke failed");
+                    errorCount++;
+                }
+            }
+            return errorCount;
+        }
+
+    }
+}
diff --git a/jdk/test/javax/management/security/MBS_Light.java b/jdk/test/javax/management/security/MBS_Light.java
new file mode 100644
index 00000000000..1ed459eebcb
--- /dev/null
+++ b/jdk/test/javax/management/security/MBS_Light.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.management.MBeanRegistration ;
+import javax.management.MBeanServer ;
+import javax.management.ObjectName ;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+import javax.management.Notification;
+
+public class MBS_Light extends NotificationBroadcasterSupport
+    implements MBS_LightMBean, MBeanRegistration, NotificationListener
+{
+    private RjmxMBeanParameter param = null ;
+    private String aString = "notset" ;
+    private int anInt = 0 ;
+    private MBeanServer mbs = null ;
+    private ObjectName objname = null ;
+    private Exception anException = null ;
+    private Error anError = null ;
+    private int count = 0;
+    private SimpleListener listener = new SimpleListener();
+
+    @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR MBS_Light")
+    public MBS_Light() {
+    }
+
+    @SqeDescriptorKey("ONE RjmxMBeanParameter PARAMETER CONSTRUCTOR MBS_Light")
+    public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")
+                     RjmxMBeanParameter param) {
+        this.param = param ;
+    }
+
+    @SqeDescriptorKey("ONE String PARAMETER CONSTRUCTOR MBS_Light")
+    public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")String param) {
+        this.aString = param ;
+    }
+
+    // Getter for property param
+    public RjmxMBeanParameter getParam() {
+        return this.param ;
+    }
+
+    // Setter for property param
+    public void setParam(RjmxMBeanParameter param) {
+        this.param = param ;
+    }
+
+    // Getter for property aString
+    public String getAstring() {
+        return this.aString ;
+    }
+
+    // Setter for property aString
+    public void setAstring(String aString) {
+        this.aString = aString ;
+    }
+
+    // Getter for property anInt
+    public int getAnInt() {
+        return this.anInt ;
+    }
+
+    // Setter for property anInt
+    public void setAnInt(int anInt) {
+        this.anInt = anInt ;
+    }
+
+    // Getter for property anException
+    public Exception getAnException() {
+        return this.anException ;
+    }
+
+    // Setter for property anException
+    public void setAnException(Exception anException) {
+        this.anException = anException ;
+    }
+
+    // Getter for property anError
+    public Error getAnError() {
+        return this.anError ;
+    }
+
+    // Setter for property anError
+    public void setAnError(Error anError) {
+        this.anError = anError ;
+    }
+
+    // An operation
+    public RjmxMBeanParameter operate1(String name) {
+        return new RjmxMBeanParameter(name) ;
+    }
+
+    // An operation
+    public String operate2(RjmxMBeanParameter param) {
+        return param.name ;
+    }
+
+    // An operation
+    public void throwError() {
+        throw new Error("JSR-160-ERROR");
+    }
+
+    // An operation
+    public void throwException() throws Exception {
+        throw new Exception("JSR-160-EXCEPTION");
+    }
+
+    // MBeanRegistration method
+    public void postDeregister() {
+    }
+
+    // MBeanRegistration method
+    public void postRegister(Boolean registrationDone) {
+    }
+
+    // MBeanRegistration method
+    public void preDeregister()
+        throws Exception
+    {
+    }
+
+    // MBeanRegistration method
+    public ObjectName preRegister(MBeanServer server, ObjectName name)
+        throws Exception
+    {
+        this.mbs = server ;
+        if ( name == null ) {
+            this.objname = new ObjectName("protocol:class=MBS_Light") ;
+        }
+        else {
+            this.objname = name ;
+        }
+        return this.objname ;
+    }
+
+    public synchronized void handleNotification(Notification notification,
+                                                Object handback) {
+        Utils.debug(Utils.DEBUG_STANDARD,
+            "MBS_Light::handleNotification: " + notification);
+        listener.handleNotification(notification, handback);
+    }
+
+    // Send a notification
+    public void sendNotification() {
+        Notification notification =
+            new Notification("JSR160-TCK-NOTIFICATION", this, count++);
+        sendNotification(notification);
+    }
+
+    public Object waitForNotificationHB() {
+        return listener.waitForNotificationHB();
+    }
+
+    // Receive multi notifications and send back handbacks
+    public synchronized Object[] waitForMultiNotifications(String nb) {
+        return listener.waitForMultiNotifications(Integer.valueOf(nb).intValue());
+    }
+
+    // Receive a notification
+    public synchronized String waitForNotification() {
+        return listener.waitForNotification();
+    }
+
+    // Is the notification received
+    public synchronized Boolean notificationReceived() {
+        return Boolean.valueOf(listener.isNotificationReceived());
+    }
+
+    // The authorization Id
+    public String getAuthorizationId() {
+        AccessControlContext acc = AccessController.getContext();
+        Subject subject = Subject.getSubject(acc);
+        Set<Principal> principals = subject.getPrincipals();
+        Iterator<Principal> i = principals.iterator();
+        StringBuffer buffer = new StringBuffer();
+        while(i.hasNext()) {
+            Principal p = i.next();
+            buffer.append(p.getName());
+            if(i.hasNext())
+                buffer.append(" ");
+        }
+
+        return buffer.toString();
+    }
+}
diff --git a/jdk/test/javax/management/security/MBS_LightMBean.java b/jdk/test/javax/management/security/MBS_LightMBean.java
new file mode 100644
index 00000000000..a380af9dcff
--- /dev/null
+++ b/jdk/test/javax/management/security/MBS_LightMBean.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+@SqeDescriptorKey("INTERFACE MBS_LightMBean")
+public interface MBS_LightMBean {
+    // Getter for property param
+    @SqeDescriptorKey("ATTRIBUTE Param")
+    public RjmxMBeanParameter getParam() ;
+
+    // Setter for property param
+    @SqeDescriptorKey("ATTRIBUTE Param")
+    public void setParam(RjmxMBeanParameter param) ;
+
+    // Getter for property aString
+    @SqeDescriptorKey("ATTRIBUTE Astring")
+    public String getAstring() ;
+
+    // Setter for property aString
+    @SqeDescriptorKey("ATTRIBUTE Astring")
+    public void setAstring(String aString) ;
+
+    // Getter for property anInt
+    @SqeDescriptorKey("ATTRIBUTE AnInt")
+    public int getAnInt() ;
+
+    // Setter for property anInt
+    @SqeDescriptorKey("ATTRIBUTE AnInt")
+    public void setAnInt(int anInt) ;
+
+    // Getter for property anException
+    @SqeDescriptorKey("ATTRIBUTE AnException")
+    public Exception getAnException() ;
+
+    // Setter for property anException
+    @SqeDescriptorKey("ATTRIBUTE AnException")
+    public void setAnException(Exception anException) ;
+
+    // Getter for property anError
+    @SqeDescriptorKey("ATTRIBUTE AnError")
+    public Error getAnError() ;
+
+    // Setter for property anError
+    @SqeDescriptorKey("ATTRIBUTE AnError")
+    public void setAnError(Error anError) ;
+
+    // An operation
+    @SqeDescriptorKey("OPERATION operate1")
+    public RjmxMBeanParameter operate1(
+            @SqeDescriptorKey("OPERATION PARAMETER name")String name) ;
+
+    // An operation
+    @SqeDescriptorKey("OPERATION operate2")
+    public String operate2(
+            @SqeDescriptorKey("OPERATION PARAMETER param")RjmxMBeanParameter param) ;
+
+    // Throws an error
+    @SqeDescriptorKey("OPERATION throwError")
+    public void throwError();
+
+    // Throws an exception
+    @SqeDescriptorKey("OPERATION throwException")
+    public void throwException() throws Exception;
+
+    // Send a notification
+    @SqeDescriptorKey("OPERATION sendNotification")
+    public void sendNotification();
+
+    // Receive a notification and return the type
+    @SqeDescriptorKey("OPERATION waitForNotification")
+    public String waitForNotification();
+
+    // Receive a notification and return the HandBack
+    @SqeDescriptorKey("OPERATION waitForNotificationHB")
+    public Object waitForNotificationHB();
+
+    // Receive multi notifications and return the HandBacks
+    @SqeDescriptorKey("OPERATION waitForMultiNotifications")
+    public Object[] waitForMultiNotifications(
+            @SqeDescriptorKey("OPERATION PARAMETER nb")String nb);
+
+    // Is the notification received
+    @SqeDescriptorKey("OPERATION notificationReceived")
+    public Boolean notificationReceived();
+
+    // Return the current authorization Id
+    @SqeDescriptorKey("OPERATION getAuthorizationId")
+    public String getAuthorizationId();
+}
diff --git a/jdk/test/javax/management/security/RjmxMBeanParameter.java b/jdk/test/javax/management/security/RjmxMBeanParameter.java
new file mode 100644
index 00000000000..c96e9a12e97
--- /dev/null
+++ b/jdk/test/javax/management/security/RjmxMBeanParameter.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable ;
+
+/**
+ * That class is used to modelize a parameter to be used as MBean property
+ * value or MBean operation parameter or returned value.
+ */
+public class RjmxMBeanParameter implements Serializable {
+    public String name = "unset" ;
+
+    public RjmxMBeanParameter() {
+    }
+
+    public RjmxMBeanParameter(String name) {
+        this.name = name ;
+    }
+
+    public boolean equals(Object obj) {
+        if ( this.name.equals(((RjmxMBeanParameter)obj).name) ) {
+            return true ;
+        } else {
+            return false ;
+        }
+    }
+}
diff --git a/jdk/test/javax/management/security/SecurityTest.java b/jdk/test/javax/management/security/SecurityTest.java
new file mode 100644
index 00000000000..6d245bd6ab4
--- /dev/null
+++ b/jdk/test/javax/management/security/SecurityTest.java
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks various secure ways of connecting from remote jmx client
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile MBS_Light.java ServerDelegate.java TestSampleLoginModule.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=UNKNOWN_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=WRONG_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=TestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=AnotherTestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config.UNKNOWN -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentialss -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.UnknownAuthentication -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=usernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=AnotherUsernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword WRONG_password -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client  -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword WRONG_password -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.sha -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=TLSv1 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.tlsv1 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ */
+
+import java.io.File;
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory ;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.Attribute ;
+import javax.management.ObjectName ;
+
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+
+import java.security.Security;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class SecurityTest {
+
+    static final String SERVER_CLASS_NAME = "SecurityTest";
+    static final String CLIENT_CLASS_NAME = "SecurityTest$ClientSide";
+    static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
+
+    static final String USERNAME_PROPERTY = "username";
+    static final String PASSWORD_PROPERTY = "password";
+
+    static final String SERVER_DELEGATE_MBEAN_NAME =
+        "defaultDomain:class=ServerDelegate";
+
+    static final String RMI_SERVER_SOCKET_FACTORY_SSL = "rmi.server.socket.factory.ssl";
+    static final String RMI_CLIENT_SOCKET_FACTORY_SSL = "rmi.client.socket.factory.ssl";
+    static final String KEYSTORE_PROPNAME = "javax.net.ssl.keyStore";
+    static final String KEYSTORE_PWD_PROPNAME = "javax.net.ssl.keyStorePassword";
+    static final String TRUSTSTORE_PROPNAME = "javax.net.ssl.trustStore";
+    static final String TRUSTSTORE_PWD_PROPNAME = "javax.net.ssl.trustStorePassword";
+
+    static final String RMI_SSL_CLIENT_ENABLEDCIPHERSUITES =
+        "javax.rmi.ssl.client.enabledCipherSuites";
+    static final String RMI_SSL_CLIENT_ENABLEDPROTOCOLS =
+        "javax.rmi.ssl.client.enabledProtocols";
+
+    private JMXConnectorServer cs;
+
+    // Construct and set keyStore properties from given map
+    static void setKeyStoreProperties(Map<String, Object> map) {
+
+        String keyStore = (String) map.get("-keystore");
+        keyStore = buildSourcePath(keyStore);
+        System.setProperty(KEYSTORE_PROPNAME, keyStore);
+        System.out.println("keyStore location = \"" + keyStore + "\"");
+
+        String password = (String) map.get("-keystorepassword");
+        System.setProperty(KEYSTORE_PWD_PROPNAME, password);
+        System.out.println("keyStore password = " + password);
+
+    }
+
+    // Construct and set trustStore properties from given map
+    static void setTrustStoreProperties(Map<String, Object> map) {
+
+        String trustStore = (String) map.get("-truststore");
+        trustStore = buildSourcePath(trustStore);
+        System.setProperty(TRUSTSTORE_PROPNAME, trustStore);
+        System.out.println("trustStore location = \"" + trustStore + "\"");
+
+        String password = (String) map.get("-truststorepassword");
+        System.setProperty(TRUSTSTORE_PWD_PROPNAME, password);
+        System.out.println("trustStore password = " + password);
+
+    }
+
+    /*
+     * First Debug properties and arguments are collect in expected
+     * map  (argName, value) format, then calls original test's run method.
+     */
+    public static void main(String args[]) throws Exception {
+
+        System.out.println("=================================================");
+
+        // Parses parameters
+        Utils.parseDebugProperties();
+
+        // Supported parameters list format is :
+        // "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
+        // with <param-spec> either "-parami valuei" or "-parami"
+        HashMap<String, Object> serverMap = new HashMap<>() ;
+        int clientArgsIndex =
+            Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
+
+        // Extract and records client params
+        String[] clientParams = null;
+        if (clientArgsIndex < args.length) {
+            int clientParamsSize = args.length - clientArgsIndex;
+            clientParams = new String[clientParamsSize];
+            System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
+        } else {
+            clientParams = new String[0];
+        }
+
+        // Run test
+        SecurityTest test = new SecurityTest();
+        test.run(serverMap, clientParams);
+
+    }
+
+    // Return full path of filename in the test sopurce directory
+    private static String buildSourcePath(String filename) {
+        return System.getProperty("test.src") + File.separator + filename;
+    }
+
+    /*
+     * Collects security run params for server side.
+     */
+    private HashMap<String, Object> setServerSecurityEnv(Map<String, Object> map)
+    throws Exception {
+
+        // Creates Authentication environment from server side params
+        HashMap<String, Object> env = new HashMap<>();
+
+        // Retrieve and set keystore and truststore config if any
+        if (map.containsKey("-keystore") &&
+            map.get("-keystore") != null) {
+            setKeyStoreProperties(map);
+        }
+        System.out.println("Done keystore properties");
+
+        if (map.containsKey("-truststore") &&
+            map.get("-truststore") != null) {
+            setTrustStoreProperties(map);
+        }
+        System.out.println("Done truststore properties");
+
+        String value = null;
+        if ((value = (String)map.get("-mapType")) != null) {
+
+            // Case of remote password file with all authorized credentials
+            if (value.contains("x.password.file")) {
+                String passwordFileStr = buildSourcePath("password.properties");
+                env.put("jmx.remote.x.password.file", passwordFileStr);
+                System.out.println("Added " + passwordFileStr +
+                    " file as jmx.remote.x.password.file");
+            }
+
+            // Case of dedicated authenticator class : TestJMXAuthenticator
+            if (value.contains("x.authenticator")) {
+                env.put("jmx.remote.authenticator", new TestJMXAuthenticator()) ;
+                System.out.println(
+                    "Added \"jmx.remote.authenticator\" = TestJMXAuthenticator");
+            }
+
+            // Case of security config file with standard Authentication
+            if (value.contains("x.login.config.PasswordFileAuthentication")) {
+                String loginConfig = System.getProperty("login.config.file");
+
+                // Override the default JAAS configuration
+                System.setProperty("java.security.auth.login.config",
+                    "file:" + loginConfig);
+                System.out.println("Overrided default JAAS configuration with " +
+                    "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+                env.put("jmx.remote.x.login.config", "PasswordFileAuthentication") ;
+                System.out.println(
+                    "Added \"jmx.remote.x.login.config\" = " +
+                    "\"PasswordFileAuthentication\"") ;
+
+                // redirects "password.file" property to file in ${test.src}
+                String passwordFileStr =
+                    buildSourcePath(System.getProperty("password.file"));
+                System.setProperty("password.file", passwordFileStr);
+                System.out.println(
+                    "Redirected \"password.file\" property value to = " +
+                    passwordFileStr) ;
+            }
+
+            // Case of security config file with unexisting athentication config
+            if (value.contains("x.login.config.UnknownAuthentication")) {
+                String loginConfig = System.getProperty("login.config.file");
+
+                // Override the default JAAS configuration
+                System.setProperty("java.security.auth.login.config",
+                        "file:" + loginConfig);
+                System.out.println("Overrided default JAAS configuration with " +
+                    "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+                env.put("jmx.remote.x.login.config", "UnknownAuthentication") ;
+                System.out.println(
+                    "Added \"jmx.remote.x.login.config\" = " +
+                    "\"UnknownAuthentication\"") ;
+
+                // redirects "password.file" property to file in ${test.src}
+                 String passwordFileStr =
+                   buildSourcePath(System.getProperty("password.file"));
+                System.setProperty("password.file", passwordFileStr);
+                System.out.println(
+                    "Redirected \"password.file\" property value to = " +
+                    passwordFileStr) ;
+            }
+
+            // Case of security config file with dedicated login module
+            if (value.contains("x.login.config.SampleLoginModule")) {
+                String loginConfig = System.getProperty("login.config.file");
+
+                // Override the default JAAS configuration
+                System.setProperty("java.security.auth.login.config",
+                        "file:" + loginConfig);
+                System.out.println("Overrided default JAAS configuration with " +
+                    "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+                env.put("jmx.remote.x.login.config", "SampleLoginModule") ;
+                System.out.println(
+                    "Added \"jmx.remote.x.login.config\" = " +
+                    "\"SampleLoginModule\"") ;
+            }
+
+            // Simple rmi ssl authentication
+            if (value.contains(RMI_CLIENT_SOCKET_FACTORY_SSL)) {
+                env.put("jmx.remote.rmi.client.socket.factory",
+                    new SslRMIClientSocketFactory()) ;
+                System.out.println(
+                     "Added \"jmx.remote.rmi.client.socket.factory\"" +
+                     " = SslRMIClientSocketFactory") ;
+            }
+
+            if (value.contains(RMI_SERVER_SOCKET_FACTORY_SSL)) {
+                if (value.contains(
+                        "rmi.server.socket.factory.ssl.need.client.authentication")) {
+                   // rmi ssl authentication with client authentication
+                   env.put("jmx.remote.rmi.server.socket.factory",
+                       new SslRMIServerSocketFactory(null, null, true)) ;
+                   System.out.println(
+                       "Added \"jmx.remote.rmi.server.socket.factory\"" +
+                       " = SslRMIServerSocketFactory with client authentication") ;
+
+                } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.md5")) {
+                    // Allows all ciphering and protocols for testing purpose
+                    Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+                    env.put("jmx.remote.rmi.server.socket.factory",
+                        new SslRMIServerSocketFactory(
+                            new String[] {"SSL_RSA_WITH_RC4_128_MD5"}, null, false));
+                    System.out.println(
+                        "Added \"jmx.remote.rmi.server.socket.factory\"" +
+                        " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_MD5 cipher suite");
+
+                } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.sha")) {
+                    // Allows all ciphering and protocols for testing purpose
+                    Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+                    env.put("jmx.remote.rmi.server.socket.factory",
+                        new SslRMIServerSocketFactory(
+                            new String[] { "SSL_RSA_WITH_RC4_128_SHA" }, null, false)) ;
+                    System.out.println(
+                        "Added \"jmx.remote.rmi.server.socket.factory\"" +
+                        " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_SHA cipher suite") ;
+
+                } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.sslv3")) {
+                    // Allows all ciphering and protocols for testing purpose
+                    Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+                    env.put("jmx.remote.rmi.server.socket.factory",
+                        new SslRMIServerSocketFactory(null, new String[] {"SSLv3"}, false)) ;
+                    System.out.println(
+                        "Added \"jmx.remote.rmi.server.socket.factory\"" +
+                        " = SslRMIServerSocketFactory with SSLv3 protocol") ;
+
+                } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.tlsv1")) {
+                    // Allows all ciphering and protocols for testing purpose
+                    Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+                    env.put("jmx.remote.rmi.server.socket.factory",
+                        new SslRMIServerSocketFactory(null, new String[] {"TLSv1"}, false)) ;
+                    System.out.println(
+                        "Added \"jmx.remote.rmi.server.socket.factory\"" +
+                        " = SslRMIServerSocketFactory with TLSv1 protocol") ;
+
+                } else {
+                    env.put("jmx.remote.rmi.server.socket.factory",
+                        new SslRMIServerSocketFactory());
+                    System.out.println(
+                        "Added \"jmx.remote.rmi.server.socket.factory\"" +
+                        " = SslRMIServerSocketFactory");
+                }
+            }
+        }
+
+        return env;
+    }
+
+    /*
+     * Create the MBeansServer side of the test and returns its address
+     */
+    private JMXServiceURL createServerSide(Map<String, Object> serverMap)
+    throws Exception {
+        final int NINETY_SECONDS = 90;
+
+        System.out.println("SecurityTest::createServerSide: Start") ;
+
+        // Prepare server side security env
+        HashMap<String, Object> env = setServerSecurityEnv(serverMap);
+
+        // Create and start mbean server and connector server
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+        cs.start();
+
+        // Waits availibility of connector server
+        Utils.waitReady(cs, NINETY_SECONDS);
+
+        JMXServiceURL addr = cs.getAddress();
+
+        System.out.println("SecurityTest::createServerSide: Done.") ;
+
+        return addr;
+    }
+
+    /*
+     * Creating command-line for running subprocess JVM:
+     *
+     * JVM command line is like:
+     * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+     *
+     * {defaultopts} are the default java options set by the framework.
+     *
+     */
+    private List<String> buildCommandLine(String args[]) {
+
+        System.out.println("SecurityTest::buildCommandLine: Start") ;
+
+        List<String> opts = new ArrayList<>();
+        opts.add(JDKToolFinder.getJDKTool("java"));
+        opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+
+        // We need to forward some properties to the client side
+        opts.add("-Dtest.src=" + System.getProperty("test.src"));
+
+        String usernameValue = System.getProperty(USERNAME_PROPERTY);
+        if (usernameValue != null) {
+            System.out.println("SecurityTest::buildCommandLine: "+
+                " forward username property to client side");
+            opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
+        }
+        String passwordValue = System.getProperty(PASSWORD_PROPERTY);
+        if (passwordValue != null) {
+            System.out.println("SecurityTest::buildCommandLine: "+
+                " forward password property to client side");
+            opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
+        }
+
+        String enabledCipherSuites =
+            System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES);
+        if (enabledCipherSuites != null) {
+            System.out.println("SecurityTest::buildCommandLine: "+
+                " forward enabledCipherSuites property to client side");
+            opts.add("-D" + RMI_SSL_CLIENT_ENABLEDCIPHERSUITES +
+                "=" + enabledCipherSuites);
+        }
+
+        String enabledProtocols =
+            System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS);
+        if (enabledProtocols != null) {
+            System.out.println("SecurityTest::buildCommandLine: "+
+                " forward enabledProtocols property to client side");
+            opts.add("-D" + RMI_SSL_CLIENT_ENABLEDPROTOCOLS +
+                "=" + enabledProtocols);
+        }
+
+        opts.add("-cp");
+        opts.add(System.getProperty("test.class.path", "test.class.path"));
+        opts.add(CLIENT_CLASS_MAIN);
+        opts.addAll(Arrays.asList(args));
+
+        System.out.println("SecurityTest::buildCommandLine: Done.") ;
+
+        return opts;
+    }
+
+    /**
+     * Runs SecurityTest$ClientSide with the passed options and redirects
+     * subprocess standard I/O to the current (parent) process. This provides a
+     * trace of what happens in the subprocess while it is runnning (and before
+     * it terminates).
+     *
+     * @param serviceUrlStr string representing the JMX service Url to connect to.
+     */
+    private int runClientSide(String args[], String serviceUrlStr) throws Exception {
+
+        System.out.println("SecurityTest::runClientSide: Start") ;
+
+        // Building command-line
+        List<String> opts = buildCommandLine(args);
+        opts.add("-serviceUrl");
+        opts.add(serviceUrlStr);
+
+        // Launch separate JVM subprocess
+        int exitCode = 0;
+        String[] optsArray = opts.toArray(new String[0]);
+        ProcessBuilder pb = new ProcessBuilder(optsArray);
+        Process p = ProcessTools.startProcess("SecurityTest$ClientSide", pb);
+
+        // Handling end of subprocess
+        try {
+            exitCode = p.waitFor();
+            if (exitCode != 0) {
+                System.out.println(
+                    "Subprocess unexpected exit value of [" + exitCode +
+                    "]. Expected 0.\n");
+            }
+        } catch (InterruptedException e) {
+            System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+            // Parent thread unknown state, killing subprocess.
+            p.destroyForcibly();
+
+            throw new RuntimeException(
+                "Parent process interrupted with exception : \n " + e + " :" );
+
+        } finally {
+            if (p.isAlive()) {
+                p.destroyForcibly();
+            }
+
+            System.out.println("SecurityTest::runClientSide: Done") ;
+
+            return exitCode;
+        }
+
+     }
+
+    public void run(Map<String, Object> serverArgs, String clientArgs[]) {
+
+        System.out.println("SecurityTest::run: Start") ;
+        int errorCount = 0;
+
+        try {
+            // Initialise the server side
+            JMXServiceURL urlToUse = createServerSide(serverArgs);
+
+            // Run client side
+            errorCount = runClientSide(clientArgs, urlToUse.toString());
+
+            if ( errorCount == 0 ) {
+                System.out.println("SecurityTest::run: Done without any error") ;
+            } else {
+                System.out.println(
+                    "SecurityTest::run: Done with " + errorCount + " error(s)");
+                throw new RuntimeException("errorCount = " + errorCount);
+            }
+
+            cs.stop();
+
+        } catch(Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    private static class ClientSide {
+
+        private JMXConnector cc = null;
+        private MBeanServerConnection mbsc = null;
+
+        public static void main(String args[]) throws Exception {
+
+            // Parses parameters
+            Utils.parseDebugProperties();
+
+            // Supported parameters list format is : "MainClass [-client <param-spec> ...]
+            // with <param-spec> either "-parami valuei" or "-parami"
+            HashMap<String, Object> clientMap = new HashMap<>() ;
+            Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
+
+            // Run test
+            ClientSide test = new ClientSide();
+            test.run(clientMap);
+        }
+
+        public void run(Map<String, Object> args) {
+
+            System.out.println("ClientSide::run: Start");
+            int errorCount = 0;
+
+            try {
+                // Setup client side parameters
+                HashMap<String, Object> env = new HashMap<>();
+
+                // If needed allows all ciphering and protocols for testing purpose
+                if (System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES) != null) {
+                    Security.setProperty("jdk.tls.disabledAlgorithms", "");
+                }
+
+                // If needed allows all ciphering and protocols for testing purpose
+                if (System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS) != null) {
+                    Security.setProperty("jdk.tls.disabledAlgorithms", "");
+                }
+
+                // Retrieve and set keystore and truststore config if any
+                if (args.containsKey("-keystore") &&
+                    args.get("-keystore") != null) {
+                    SecurityTest.setKeyStoreProperties(args);
+                }
+                if (args.containsKey("-truststore") &&
+                    args.get("-truststore") != null) {
+                    SecurityTest.setTrustStoreProperties(args);
+                }
+
+                Object value = args.get("-mapType");
+                if ((value != null) &&
+                    value.equals("credentials")) {
+                    String username = System.getProperty("username");
+                    String password = System.getProperty("password");
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        "add \"jmx.remote.credentials\" = \"" +
+                        username + "\", \"" + password + "\"");
+                    env.put("jmx.remote.credentials",
+                        new String[] { username , password });
+                }
+
+                String expectedThrowable = (String) args.get("-expectedThrowable");
+
+                String authCallCountName = "-expectedAuthenticatorCallCount";
+                int authCallCountValue = 0;
+                if (args.containsKey(authCallCountName)) {
+                    authCallCountValue =
+                        (new Integer((String) args.get(authCallCountName))).intValue();
+                }
+
+                try {
+                    // Get a connection to remote mbean server
+                    JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
+                    cc = JMXConnectorFactory.connect(addr,env);
+                    mbsc = cc.getMBeanServerConnection();
+
+                    // In case we should have got an exception
+                    if (expectedThrowable != null) {
+                        System.out.println("ClientSide::run: (ERROR) " +
+                            " Connect did not fail with expected " + expectedThrowable);
+                        errorCount++;
+                    } else {
+                        System.out.println("ClientSide::run: (OK) Connect succeed");
+                    }
+                } catch (Throwable e) {
+                    Utils.printThrowable(e, true);
+                    if (expectedThrowable != null) {
+                        if (Utils.compareThrowable(e, expectedThrowable)) {
+                            System.out.println("ClientSide::run: (OK) " +
+                                "Connect failed with expected " + expectedThrowable);
+                        } else {
+                            System.out.println("ClientSide::run: (ERROR) Connect failed with " +
+                                e.getClass() + " instead of expected " +
+                                expectedThrowable);
+                            errorCount++;
+                        }
+                    } else {
+                        System.out.println("ClientSide::run: (ERROR) " +
+                            "Connect failed with exception");
+                        errorCount++;
+                    }
+                }
+
+                // Depending on the client state,
+                // perform some requests
+                if (mbsc != null && errorCount == 0) {
+                    // Perform some little JMX requests
+                    System.out.println("ClientSide::run: Start sending requests");
+
+                    doRequests();
+
+                    // In case authentication has been used we check how it did.
+                    if (authCallCountValue != 0) {
+                        errorCount += checkAuthenticator(mbsc, authCallCountValue);
+                    }
+                }
+            } catch (Exception e) {
+                Utils.printThrowable(e, true);
+                errorCount++;
+            } finally {
+                // Terminate the JMX Client if any
+                if (cc != null) {
+                    try {
+                        cc.close();
+                    } catch (Exception e) {
+                        Utils.printThrowable(e, true) ;
+                        errorCount++;
+                    }
+                }
+            }
+
+            System.out.println("ClientSide::run: Done");
+
+            // Handle result
+            if (errorCount != 0) {
+                throw new RuntimeException();
+            }
+        }
+
+        private void doRequests() throws Exception {
+
+            // Send  some requests to the remote JMX server
+            ObjectName objName1 =
+                new ObjectName("TestDomain:class=MBS_Light,rank=1");
+            String mbeanClass = "MBS_Light";
+            Exception exception = new Exception("MY TEST EXCEPTION");
+            Attribute attException = new Attribute("AnException", exception);
+            Error error = new Error("MY TEST ERROR");
+            Attribute attError = new Attribute("AnError", error);
+            String opParamString = "TOTORO";
+            RjmxMBeanParameter opParam = new RjmxMBeanParameter(opParamString);
+            Object[] params1 = {opParamString};
+            String[] sig1 = {"java.lang.String"};
+            Object[] params2 = {opParam};
+            String[] sig2 = {"RjmxMBeanParameter"};
+
+            // Create and register the MBean
+            Utils.debug(Utils.DEBUG_STANDARD,
+                "ClientSide::doRequests: Create and register the MBean");
+            mbsc.createMBean(mbeanClass, objName1);
+            if (!mbsc.isRegistered(objName1)) {
+                throw new Exception("Unable to register an MBean");
+            }
+
+            // Set attributes of the MBean
+            Utils.debug(Utils.DEBUG_STANDARD,
+                "ClientSide::doRequests: Set attributes of the MBean");
+            mbsc.setAttribute(objName1, attException);
+            mbsc.setAttribute(objName1, attError);
+
+            // Get attributes of the MBean
+            Utils.debug(Utils.DEBUG_STANDARD,
+                "ClientSide::doRequests: Get attributes of the MBean");
+            Exception retException =
+                (Exception) mbsc.getAttribute(objName1,"AnException");
+            if (!retException.getMessage().equals(exception.getMessage())) {
+                System.out.println("Expected = " + exception);
+                System.out.println("Got = " + retException);
+                throw new Exception("Attribute AnException not as expected");
+            }
+            Error retError = (Error) mbsc.getAttribute(objName1, "AnError");
+            if (!retError.getMessage().equals(error.getMessage())) {
+                System.out.println("Expected = " + error);
+                System.out.println("Got = " + retError);
+                throw new Exception("Attribute AnError not as expected");
+            }
+
+            // Invoke operations on the MBean
+            Utils.debug(Utils.DEBUG_STANDARD,
+                "ClientSide::doRequests: Invoke operations on the MBean");
+            RjmxMBeanParameter res1 =
+                (RjmxMBeanParameter) mbsc.invoke(objName1, "operate1", params1, sig1);
+            if (!res1.equals(opParam)) {
+                System.out.println("Expected = " + opParam);
+                System.out.println("Got = " + res1);
+                throw new Exception("Operation operate1 behaved badly");
+            }
+            String res2 =
+                (String) mbsc.invoke(objName1, "operate2", params2, sig2);
+            if (!res2.equals(opParamString)) {
+                System.out.println("Expected = " + opParamString);
+                System.out.println("Got = " + res2);
+                throw new Exception("Operation operate2 behaved badly");
+            }
+
+            // Unregister the MBean
+            Utils.debug(Utils.DEBUG_STANDARD,
+                "ClientSide::doRequests: Unregister the MBean");
+            mbsc.unregisterMBean(objName1);
+            if (mbsc.isRegistered(objName1)) {
+                throw new Exception("Unable to unregister an MBean");
+            }
+        }
+
+        /**
+         * Make some check about the instance of TestJMXAuthenticator.
+         * The authenticator is supposed to have set some properties on
+         * a ServerDelegate MBean.
+         * We compare the number of times it has been called with the expected value.
+         * We also check the Principal that has been given to the authenticator
+         * was not null.
+         * That method is of use to authentication with the JSR 262.
+         * @param mbs
+         * @param expectedAuthenticatorCallCount
+         * @return The number of errors encountered.
+         * @throws java.lang.Exception
+         */
+        protected int checkAuthenticator(MBeanServerConnection mbs,
+                int expectedAuthenticatorCallCount) throws Exception {
+            int errorCount = 0;
+
+            // Ensure the authenticator has been called the right number
+            // of times.
+            int callCount =
+                    ((Integer) mbs.getAttribute(
+                    new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
+                    "TestJMXAuthenticatorCallCount")).intValue();
+
+            if (callCount == expectedAuthenticatorCallCount) {
+                System.out.println("---- OK Authenticator has been called "
+                        + expectedAuthenticatorCallCount + " time");
+            } else {
+                errorCount++;
+                System.out.println("---- ERROR Authenticator has been called " + callCount
+                        + " times in place of " + expectedAuthenticatorCallCount);
+            }
+
+            // Ensure the provider has been called with
+            // a non null Principal.
+            String principalString =
+                (String) mbs.getAttribute(
+                new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
+                "TestJMXAuthenticatorPrincipalString");
+
+            if (principalString == null) {
+                errorCount++;
+                System.out.println("---- ERROR Authenticator has been called"
+                        + " with a null Principal");
+            } else {
+                if (principalString.length() > 0) {
+                    System.out.println("---- OK Authenticator has been called"
+                            + " with the Principal " + principalString);
+                } else {
+                    errorCount++;
+                    System.out.println("---- ERROR Authenticator has been called"
+                            + " with an empty Principal");
+                }
+            }
+
+            return errorCount;
+        }
+
+    }
+
+}
diff --git a/jdk/test/javax/management/security/ServerDelegate.java b/jdk/test/javax/management/security/ServerDelegate.java
new file mode 100644
index 00000000000..6ce5face871
--- /dev/null
+++ b/jdk/test/javax/management/security/ServerDelegate.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * This class defines an MBean that can be registered and used on client side
+ * to handle informations or properties of the remote server.
+ *
+ * For example, this MBean can store IOR addresses
+ * of RMI/IIOP connector(s) used in a test.
+ *
+ * That MBean might not be used for testing purpose itself.
+ */
+public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
+
+    private MBeanServer mbeanServer = null;
+    private List<JMXServiceURL> addresses  = null;
+    private String port;
+    private static String javaVersion = System.getProperty("java.version");
+    private int sqeJmxwsCredentialsProviderCallCount = 0;
+    private String jmxwsCredentialsProviderUrl = null;
+    private int testJMXAuthenticatorCallCount = 0;
+    private Principal testJMXAuthenticatorPrincipal = null;
+
+    @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
+    public ServerDelegate() {
+        addresses = new ArrayList<JMXServiceURL>();
+    }
+
+    public ObjectName preRegister(MBeanServer server, ObjectName name)
+    throws Exception {
+        // Initialize MBeanServer attribute
+        mbeanServer = server;
+        return name;
+    }
+    public void postRegister(Boolean registrationDone) {
+    }
+    public void preDeregister() throws Exception {
+    }
+    public void postDeregister() {
+    }
+
+    public void addAddress(JMXServiceURL url) {
+        addresses.add(url) ;
+    }
+
+    public List<JMXServiceURL> getAddresses() {
+        return addresses ;
+    }
+
+    public void setPort(String p) {
+        port = p ;
+    }
+
+    public String getPort() {
+        return port ;
+    }
+
+    public String getJavaVersion() {
+        return javaVersion;
+    }
+
+    public void sqeJmxwsCredentialsProviderCalled() {
+        sqeJmxwsCredentialsProviderCallCount++;
+    }
+
+    public int getSqeJmxwsCredentialsProviderCallCount() {
+        return sqeJmxwsCredentialsProviderCallCount;
+    }
+
+    public void setJmxwsCredentialsProviderUrl(String url) {
+        jmxwsCredentialsProviderUrl = url;
+    }
+
+    public String getJmxwsCredentialsProviderUrl() {
+        return jmxwsCredentialsProviderUrl;
+    }
+
+    public void testJMXAuthenticatorCalled() {
+        testJMXAuthenticatorCallCount++;
+    }
+
+    public int getTestJMXAuthenticatorCallCount() {
+        return testJMXAuthenticatorCallCount;
+    }
+
+    public void setTestJMXAuthenticatorPrincipal(Principal principal) {
+        testJMXAuthenticatorPrincipal = principal;
+    }
+
+    public String getTestJMXAuthenticatorPrincipalString() {
+        if ( testJMXAuthenticatorPrincipal != null ) {
+            return testJMXAuthenticatorPrincipal.toString();
+        }
+
+        return null;
+    }
+
+   /**
+     * Instantiates and registers a StandardMBean in the MBean server.
+     *
+     * @param implementationClassName
+     *      The implementation class name of the MBean.
+     * @param interfaceClassName
+     *      The management interface class name of the MBean.
+     * @param isMXBean
+     *      If true, the resultant MBean is an MXBean.
+     * @param name
+     *      The object name of the StandardMBean.
+     */
+    @SuppressWarnings("unchecked")
+    public void createStandardMBean(
+            String implementationClassName,
+            String interfaceClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception {
+
+        Object implementation =
+                Class.forName(implementationClassName).newInstance();
+        Class<Object> interfaceClass = interfaceClassName == null ? null :
+            (Class<Object>)Class.forName(interfaceClassName);
+
+        // Create the StandardMBean
+        StandardMBean standardMBean = new StandardMBean(
+                implementation,
+                interfaceClass,
+                isMXBean);
+
+        // Register the StandardMBean
+        mbeanServer.registerMBean(standardMBean, name);
+    }
+
+    /**
+     * Instantiates and registers a StandardMBean in the MBean server.
+     * The object will use standard JMX design pattern to determine
+     * the management interface associated with the given implementation.
+     */
+    @SuppressWarnings("unchecked")
+    public void createStandardMBean(
+            String implementationClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception {
+
+        createStandardMBean(implementationClassName, null, isMXBean, name);
+    }
+}
diff --git a/jdk/test/javax/management/security/ServerDelegateMBean.java b/jdk/test/javax/management/security/ServerDelegateMBean.java
new file mode 100644
index 00000000000..88f0b3f5675
--- /dev/null
+++ b/jdk/test/javax/management/security/ServerDelegateMBean.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.ObjectName;
+
+@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
+public interface ServerDelegateMBean {
+    @SqeDescriptorKey("ATTRIBUTE Address")
+    public void addAddress(JMXServiceURL url);
+
+    @SqeDescriptorKey("ATTRIBUTE Address")
+    public List<JMXServiceURL> getAddresses();
+
+    public String getPort();
+    public void setPort(String p);
+
+    public String getJavaVersion();
+
+    public void sqeJmxwsCredentialsProviderCalled();
+    public int getSqeJmxwsCredentialsProviderCallCount();
+
+    public void setJmxwsCredentialsProviderUrl(String url);
+    public String getJmxwsCredentialsProviderUrl();
+
+    public void testJMXAuthenticatorCalled();
+    public int getTestJMXAuthenticatorCallCount();
+
+    public void setTestJMXAuthenticatorPrincipal(Principal principal);
+    public String getTestJMXAuthenticatorPrincipalString();
+
+    public void createStandardMBean(
+            String implementationClassName,
+            String interfaceClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception;
+
+    public void createStandardMBean(
+            String implementationClassName,
+            boolean isMXBean,
+            ObjectName name)
+            throws Exception;
+}
diff --git a/jdk/test/javax/management/security/Simple.java b/jdk/test/javax/management/security/Simple.java
new file mode 100644
index 00000000000..c41da3f435a
--- /dev/null
+++ b/jdk/test/javax/management/security/Simple.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2004, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+//import java.beans.ConstructorProperties;
+import javax.management.ConstructorParameters;
+
+/**
+ * This class defines a simple standard MBean.
+ */
+public class Simple implements SimpleMBean {
+
+    private String attribute = "initial_value";
+    private boolean operationInvoked = false;
+    private boolean operation2Invoked = false;
+
+    @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR Simple")
+    public Simple() {
+    }
+
+    @SqeDescriptorKey("TWO PARAMETERS CONSTRUCTOR Simple")
+    @ConstructorParameters({"unused1", "unused2"})
+    public Simple(@SqeDescriptorKey("CONSTRUCTOR PARAMETER unused1")int unused1,
+            @SqeDescriptorKey("CONSTRUCTOR PARAMETER unused2")int unused2) {
+    }
+
+    public String getAttribute() {
+        return attribute;
+    }
+    public void setAttribute(String s) {
+        attribute = s;
+    }
+    public boolean getOperationInvoked() {
+        return operationInvoked;
+    }
+    public boolean getOperation2Invoked() {
+        return operation2Invoked;
+    }
+
+    public void operation() {
+        operationInvoked = true;
+        return;
+    }
+
+    public String operation2(int i) {
+        operation2Invoked = true;
+        return String.valueOf(i);
+    }
+
+    public void reset() {
+        attribute = "initial_value";
+        operationInvoked = false;
+        operation2Invoked = false;
+    }
+}
diff --git a/jdk/test/javax/management/security/SimpleListener.java b/jdk/test/javax/management/security/SimpleListener.java
new file mode 100644
index 00000000000..0510150150a
--- /dev/null
+++ b/jdk/test/javax/management/security/SimpleListener.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// JDK
+import java.util.Vector;
+
+// JMX
+import javax.management.NotificationListener;
+import javax.management.Notification;
+
+public class SimpleListener implements NotificationListener {
+    private boolean received = false;
+    private String type = null;
+    private Object handback = null;
+    private Vector<Object> handbacks = new Vector<Object>();
+    private int nbrec = 0;
+
+    public synchronized void handleNotification(Notification notification,
+                                                Object handback) {
+        Utils.debug(Utils.DEBUG_STANDARD,
+            "SimpleListener::handleNotification :" + notification);
+        try {
+            received = true;
+            type = notification.getType();
+            this.handback = handback;
+            handbacks.add(handback);
+            nbrec++;
+            notify();
+        } catch(Exception e) {
+            System.out.println("(ERROR) SimpleListener::handleNotification :"
+                        + " Caught exception "
+                        + e) ;
+        }
+    }
+
+    public synchronized boolean isNotificationReceived() {
+        boolean ret = received;
+        reset();
+        return ret;
+    }
+
+    public synchronized Object[] waitForMultiNotifications(int nb) {
+        while(true) {
+            if(nbrec < nb) {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                            "SimpleListener::waitForMultiNotifications wait");
+                try {
+                    wait();
+                } catch(InterruptedException ie) {
+                    // OK : we wait for being interrupted
+                }
+                Utils.debug(Utils.DEBUG_STANDARD,
+                            "SimpleListener::waitForMultiNotifications wait over");
+            }
+            else
+            break;
+        }
+        Object[] ret = handbacks.toArray();
+        reset();
+        return ret;
+    }
+
+    private void reset() {
+        received = false;
+        handback = null;
+        handbacks.removeAllElements();
+        type = null;
+    }
+
+    public synchronized Object waitForNotificationHB() {
+        while(true) {
+            if(!received) {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "SimpleListener::waitForNotificationHB wait");
+                try {
+                    wait();
+                } catch(InterruptedException ie) {
+                    // OK : we wait for being interrupted
+                }
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "SimpleListener::waitForNotificationHB received");
+            }
+            else
+                break;
+        }
+        Object ret = handback;
+        reset();
+        return ret;
+    }
+
+    public synchronized String waitForNotification() {
+        while(true) {
+            if(!received) {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "SimpleListener::waitForNotification wait");
+                try {
+                    wait();
+                } catch(InterruptedException ie) {
+                    // OK : we wait for being interrupted
+                }
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "SimpleListener::waitForNotification received");
+            }
+            else
+                break;
+        }
+        String ret = type;
+        reset();
+        return ret;
+    }
+}
diff --git a/jdk/test/javax/management/security/SimpleMBean.java b/jdk/test/javax/management/security/SimpleMBean.java
new file mode 100644
index 00000000000..676ac4aaa2d
--- /dev/null
+++ b/jdk/test/javax/management/security/SimpleMBean.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This interface defines a simple standard MBean.
+ */
+@SqeDescriptorKey("INTERFACE SimpleMBean")
+public interface SimpleMBean {
+
+    @SqeDescriptorKey("ATTRIBUTE Attribute")
+    public String getAttribute();
+
+    @SqeDescriptorKey("ATTRIBUTE Attribute")
+    public void setAttribute(String s);
+
+    @SqeDescriptorKey("ATTRIBUTE OperationInvoked")
+    public boolean getOperationInvoked();
+
+    @SqeDescriptorKey("ATTRIBUTE Operation2Invoked")
+    public boolean getOperation2Invoked();
+
+    // Void operation
+    // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
+    // => openType is added to the descriptor
+    @SqeDescriptorKey(value = "OPERATION operation",
+    descriptorFields = {"openType=SimpleType.VOID"})
+    public void operation();
+
+    @SqeDescriptorKey("OPERATION operation2")
+    public String operation2(int i);
+
+    // Void operation
+    // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
+    // => openType is added to the descriptor
+    @SqeDescriptorKey(value = "OPERATION reset",
+    descriptorFields = {"openType=SimpleType.VOID"})
+    public void reset();
+}
diff --git a/jdk/test/javax/management/security/SqeDescriptorKey.java b/jdk/test/javax/management/security/SqeDescriptorKey.java
new file mode 100644
index 00000000000..60e4926218b
--- /dev/null
+++ b/jdk/test/javax/management/security/SqeDescriptorKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+    @DescriptorKey("sqeDescriptorKey")
+    String value();
+
+    // List descriptor fields that may be added or may be updated
+    // when retrieving an MBeanInfo using a JMXWS connection compared to the
+    // MBeanInfo returned by a local MBeanServer.
+    // The annotation format is :
+    //   <descriptorFieldName>=<descriptorFieldValue>
+    // The values actually handled by the test suite are :
+    //   openType=SimpleType.VOID
+    @DescriptorKey("descriptorFields")
+    String[] descriptorFields() default {};
+}
diff --git a/jdk/test/javax/management/security/TestJMXAuthenticator.java b/jdk/test/javax/management/security/TestJMXAuthenticator.java
new file mode 100644
index 00000000000..cdea05d3e43
--- /dev/null
+++ b/jdk/test/javax/management/security/TestJMXAuthenticator.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+
+public final class TestJMXAuthenticator implements JMXAuthenticator {
+
+    private String protocol = "";
+    private MBeanServer mbs = null;
+
+    public TestJMXAuthenticator() {
+    }
+
+    public TestJMXAuthenticator(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public TestJMXAuthenticator(String protocol, MBeanServer mbs) {
+        this.protocol = protocol;
+        this.mbs = mbs;
+    }
+
+    public Subject authenticate(Object credentials) {
+
+        String credentials_username = "";
+        String credentials_password = "";
+        Principal aPrincipal = null;
+
+        credentials_username = ((String[]) credentials)[0];
+        credentials_password = ((String[]) credentials)[1];
+
+        String authenticated_username = System.getProperty("susername");
+        String authenticated_password = System.getProperty("spassword");
+        String principal = System.getProperty("principal");
+
+        System.out.println("TestJMXAuthenticator::authenticate: Start");
+        System.out.println("TestJMXAuthenticator::authenticate: credentials username = " +
+                credentials_username);
+        System.out.println("TestJMXAuthenticator::authenticate: credentials password = " +
+                credentials_password);
+        System.out.println("TestJMXAuthenticator::authenticate: authenticated username = " +
+                authenticated_username);
+        System.out.println("TestJMXAuthenticator::authenticate: authenticated password = " +
+                authenticated_password);
+        System.out.println("TestJMXAuthenticator::authenticate: principal used for " +
+                "authorization = " + principal);
+
+        if (credentials_username.equals(authenticated_username) &&
+                credentials_password.equals(authenticated_password)) {
+            System.out.println("TestJMXAuthenticator::authenticate: " +
+                    "Authenticator should succeed");
+        } else {
+            System.out.println("TestJMXAuthenticator::authenticate: " +
+                    "Authenticator should reject");
+            throw new SecurityException("TestJMXAuthenticator throws EXCEPTION");
+        }
+
+        // At this point, authentication has succeeded
+        // (no SecurityException thrown).
+        //
+        // If no authorization is required, the returned subject (empty or not)
+        // is useless.
+        // Otherwise, the returned subject must define a principal
+        // and authorization will be performed against this principal.
+        //
+        // Note that this custom JMXAuthenticator is used for test purpose and
+        // the username used to perform authentication may be different from the
+        // username used to perform authorization.
+        //
+        Subject subject = new Subject();
+
+        if (principal != null) {
+            System.out.println("TestJMXAuthenticator::authenticate: " +
+                    "Add " + principal + " principal to the returned subject");
+            subject.getPrincipals().add(new JMXPrincipal(principal));
+        }
+
+        return subject;
+    }
+}
diff --git a/jdk/test/javax/management/security/TestSampleLoginModule.java b/jdk/test/javax/management/security/TestSampleLoginModule.java
new file mode 100644
index 00000000000..81d342d8704
--- /dev/null
+++ b/jdk/test/javax/management/security/TestSampleLoginModule.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+
+public final class TestSampleLoginModule implements LoginModule {
+
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private Map<String, ?> sharedState;
+    private Map<String, ?> options;
+
+    public TestSampleLoginModule() {
+    }
+
+    public void initialize(Subject subject,
+            CallbackHandler callbackHandler,
+            Map<String,?> sharedState,
+            Map<String,?> options) {
+
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        this.sharedState = sharedState;
+        this.options = options;
+    }
+
+  /*
+   * Authenticate the user by comparing the values of the java properties
+   * (username and password) against the values of the credentials.
+   * */
+    public boolean login() throws LoginException {
+
+        String credentials_username = null;
+        String credentials_password = null;
+        String authenticated_username = System.getProperty("susername");
+        String authenticated_password = System.getProperty("spassword");
+
+        System.out.println("TestSampleLoginModule::login: Start");
+
+        // First retreive the credentials {username, password} from
+        // the callback handler
+        Callback[] callbacks = new Callback[2];
+        callbacks[0] = new NameCallback("username");
+        callbacks[1] = new PasswordCallback("password", false);
+        try {
+            callbackHandler.handle(callbacks);
+            credentials_username = ((NameCallback)callbacks[0]).getName();
+            credentials_password = new String(((PasswordCallback)callbacks[1]).
+                    getPassword());
+        } catch (Exception e) {
+            throw new LoginException(e.toString());
+        }
+
+        System.out.println("TestSampleLoginModule::login: credentials username = " +
+                credentials_username);
+        System.out.println("TestSampleLoginModule::login: credentials password = " +
+                credentials_password);
+        System.out.println("TestSampleLoginModule::login: authenticated username = " +
+                authenticated_username);
+        System.out.println("TestSampleLoginModule::login: authenticated password = " +
+                authenticated_password);
+
+        if (credentials_username.equals(authenticated_username) &&
+                credentials_password.equals(authenticated_password)) {
+            System.out.println("TestSampleLoginModule::login: " +
+                    "Authentication should succeed");
+            return true;
+        } else {
+            System.out.println("TestSampleLoginModule::login: " +
+                    "Authentication should reject");
+            throw new LoginException("TestSampleLoginModule throws EXCEPTION");
+        }
+    }
+
+    public boolean commit() throws LoginException {
+        return true;
+    }
+
+    public boolean abort() throws LoginException {
+        return true;
+    }
+
+    public boolean logout() throws LoginException {
+        return true;
+    }
+}
diff --git a/jdk/test/javax/management/security/Utils.java b/jdk/test/javax/management/security/Utils.java
new file mode 100644
index 00000000000..c0af037a4d6
--- /dev/null
+++ b/jdk/test/javax/management/security/Utils.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2005, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.lang.reflect.Method;
+import javax.management.remote.JMXConnectorServerMBean;
+
+// utility class for MXBean* tests coming from JMX Tonga test suite
+class Utils {
+
+    private static final String SERVER_SIDE_NAME = "-server";
+    private static final String CLIENT_SIDE_NAME = "-client";
+
+    // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+    private static final String DEBUG_HEADER = "[debug] ";
+
+    // DEBUG levels
+    private static int selectedDebugLevel = 0;
+    static final int DEBUG_STANDARD = 1;
+    static final int DEBUG_VERBOSE = 2;  // Mainly used for stress tests
+    static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+    static void parseDebugProperties() {
+        int level = 0;
+        Properties p = System.getProperties();
+
+        // get selected levels
+        if (p.getProperty("DEBUG_STANDARD") != null) {
+            level |= DEBUG_STANDARD;
+        }
+
+        if (p.getProperty("DEBUG_VERBOSE") != null) {
+            level |= DEBUG_VERBOSE;
+        }
+
+        if (p.getProperty("DEBUG_ALL") != null) {
+            level |= DEBUG_ALL;
+        }
+
+        selectedDebugLevel = level;
+    }
+
+    /**
+     * Reproduces the original parsing and collection of test parameters
+     * from the DTonga JMX test suite.
+     *
+     * Collects passed args and returns them in a map(argname, value) structure,
+     * which will be then propagated as necessary to various called methods.
+     */
+    static Map<String, Object> parseParameters(String args[])
+    throws Exception {
+        Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+        HashMap<String, Object> map = new HashMap<>();
+
+        for ( int i = 0; i < args.length; i++ ) {
+            if ( args[i].trim().startsWith("-") ) {
+                if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+                    Utils.debug(DEBUG_STANDARD,
+                        "TestRoot::parseParameters: added in map = " +
+                        args[i] +
+                        " with value " +
+                        args[i+1]) ;
+                    map.put(args[i].trim(), args[i+1].trim()) ;
+                } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+                           (i+1) == args.length ) {
+                    Utils.debug(DEBUG_STANDARD,
+                            "TestRoot::parseParameters: added in map = " +
+                            args[i] +
+                            " with null value") ;
+                    map.put(args[i].trim(), null) ;
+                } else {
+                    System.out.println(
+                        "TestRoot::parseParameters: (WARNING) not added in map = " +
+                        args[i]) ;
+                }
+            }
+        }
+
+        Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+        return map ;
+    }
+
+    // Parse server parameters and put them in passed serverMap
+    static int parseServerParameters(String args[],
+                                     String serverSideName,
+                                     Map<String, Object> serverMap )
+    throws Exception {
+        Utils.debug(Utils.DEBUG_STANDARD,
+            serverSideName + "::parseServerParameters: Start");
+
+        int nextIndex = 0;
+        boolean seenServerFlag = false;
+
+        for ( int i = 0; i < args.length; i++ ) {
+            // Case of reaching "-server" flag parameter
+            if (args[i].equals(SERVER_SIDE_NAME)) {
+                if (!seenServerFlag) {
+                    seenServerFlag = true;
+                    continue;
+                } else {
+                    // Already parsing server params, invalid params list
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        serverSideName + "::parseParameters: Invalid " +
+                        args[i] + " parameter detected in " +
+                        SERVER_SIDE_NAME + " parameters list");
+                    nextIndex = -1;
+                    throw new RuntimeException("Invalid Parameter list");
+                }
+            }
+
+            // Case of reaching "-client" flag parameter
+            if (args[i].equals(CLIENT_SIDE_NAME)) {
+                // While parsing server parameters, then parsing is done.
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    serverSideName + "::parseServerParameters: Parsing of " +
+                    SERVER_SIDE_NAME + " parameters done.");
+                return i;
+            }
+
+            i = parseParamAtIndex(args, i, serverMap);
+            nextIndex = i;
+        }
+
+        Utils.debug(Utils.DEBUG_STANDARD,
+            serverSideName + "::parseServerParameters: Parsing of parameters done");
+
+        return nextIndex;
+    }
+
+    // Parse client parameters and put them in passed clientMap
+    static void parseClientParameters(String args[],
+                                      String clientSideName,
+                                      Map<String, Object> clientMap )
+    throws Exception {
+
+        Utils.debug(Utils.DEBUG_STANDARD,
+            clientSideName + "::parseClientParameters: Start");
+
+        boolean seenClientFlag = false;
+
+        for ( int i = 0; i < args.length; i++ ) {
+            // Case of reaching "-client" flag parameter
+            if (args[i].equals(CLIENT_SIDE_NAME)) {
+                if (!seenClientFlag) {
+                    seenClientFlag = true;
+                    continue;
+                } else {
+                    // Already parsing client params, invalid params list
+                    Utils.debug(Utils.DEBUG_STANDARD,
+                        clientSideName + "::parseClientParameters: Invalid " +
+                        CLIENT_SIDE_NAME + " parameter detected in " +
+                        CLIENT_SIDE_NAME + " parameters list.");
+                    throw new RuntimeException("Invalid parameter in " +
+                        clientSideName + " parameter list");
+                }
+            }
+
+            // Case of reaching "-server" flag parameter
+            if (args[i].equals(SERVER_SIDE_NAME)) {
+                // While parsing client parameters, invalid parameter list.
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    clientSideName + "::parseClientParameters: Invalid " +
+                    SERVER_SIDE_NAME + " parameter inside " +
+                    CLIENT_SIDE_NAME + " parameters list.");
+                throw new RuntimeException("Invalid parameter in " +
+                    clientSideName + " parameter list");
+            }
+
+            i = parseParamAtIndex(args, i, clientMap);
+        }
+
+        Utils.debug(Utils.DEBUG_STANDARD,
+            clientSideName + "::parseClientParameters: Parsing of parameters done.");
+    }
+
+    // Add param found at index to passed map
+    // We only accept either "-param value" or "-param" form.
+    // The "value" form is invalid but just ignored.
+    private static int parseParamAtIndex(String args[],
+                                         int index,
+                                         Map<String, Object> map) {
+
+        if (args[index].trim().startsWith("-") ) {
+            // Case of a "-param value" form
+            if ((index+1) < args.length && !args[index+1].startsWith("-") ) {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "TestRoot::parseParamAtIndex: added in map = "
+                    + args[index]
+                    + " with value "
+                    + args[index+1]) ;
+                // adding ("param", value) to the passed map
+                map.put(args[index].trim(), args[index+1].trim()) ;
+                // value should not be parsed a second time
+                return index+1;
+            }
+            // Case of a "-param" form (flag parameter)
+            else if (((index+1) < args.length && args[index+1].startsWith("-")) ||
+                     (index+1) == args.length ) {
+                Utils.debug(Utils.DEBUG_STANDARD,
+                    "TestRoot::parseParamAtIndex: added in map = "
+                    + args[index]
+                    + " with null value") ;
+                // adding ("param", null) to passed map
+                map.put(args[index].trim(), null) ;
+            }
+        } else {
+            // Unsupported "value" alone parameter
+            Utils.debug(Utils.DEBUG_STANDARD,
+                "TestRoot::parseParamAtIndex: invalid " +
+                " value-alone \"" + args[index] + "\" parameter." +
+                " Parameter ignored.");
+        }
+
+        return index;
+    }
+
+    /**
+     * This method is to be used in all tests to print anything
+     * that is temporary.
+     * Printing is done only when debug is activated by the property DEBUG.
+     * Printing depends also on the DEBUG_LEVEL property.
+     * Here it encapsulates a System.out.println.
+     */
+    static void debug(int level, String line) {
+        if ((selectedDebugLevel & level) != 0) {
+            System.out.println(DEBUG_HEADER + line);
+        }
+    }
+
+    /**
+     * Do print stack trace when withStack is true.
+     * Does try to call getTargetException() and getTargetError() then
+     * print embedded stacks in the case of an Exception wrapping
+     * another Exception or an Error. Recurse until no more wrapping
+     * is found.
+     */
+    static void printThrowable(Throwable theThro, boolean withStack) {
+        try {
+            if (withStack) {
+                theThro.printStackTrace(System.out);
+            }
+            if (theThro instanceof Exception) {
+                Exception t = (Exception) theThro;
+                Method target = null;
+                String blank = " ";
+                try {
+                    target = t.getClass().getMethod("getTargetException",
+                            (java.lang.Class<?>[]) null);
+                } catch (Exception ee) {
+                // OK: getTargetException method could be there or not
+                }
+                System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+                while (target != null) {
+                    try {
+                        t = (Exception) target.invoke(t,
+                                (java.lang.Object[]) null);
+                    } catch (Exception ee) {
+                        t = null;
+                    }
+                    try {
+                        if (t != null) {
+                            blank = blank + "  ";
+                            System.out.println(blank + t.getClass() + "==>" +
+                                    t.getMessage());
+                            try {
+                                target =
+                                        t.getClass().getMethod("getTargetException",
+                                        (java.lang.Class<?>[]) null);
+                            } catch (Exception ee) {
+                            // OK: getTargetException method could be there or not                            }
+                            }
+                        } else {
+                            target = null;
+                        }
+                    } catch (Exception ee) {
+                        target = null;
+                    }
+                }
+
+                // We may have exceptions wrapping an Error then it is
+                // getTargetError that is likely to be called
+                try {
+                    target = ((Exception) theThro).getClass().getMethod("getTargetError",
+                            (java.lang.Class<?>[]) null);
+                } catch (Exception ee) {
+                // OK: getTargetError method could be there or not
+                }
+                Throwable err = theThro;
+                while (target != null) {
+                    try {
+                        err = (Error) target.invoke(err,
+                                (java.lang.Object[]) null);
+                    } catch (Exception ee) {
+                        err = null;
+                    }
+                    try {
+                        if (err != null) {
+                            blank = blank + "  ";
+                            System.out.println(blank + err.getClass() + "==>" +
+                                    err.getMessage());
+                            if (withStack) {
+                                err.printStackTrace(System.out);
+                            }
+                            try {
+                                target = err.getClass().getMethod("getTargetError",
+                                        (java.lang.Class<?>[]) null);
+                            } catch (Exception ee) {
+                            // OK: getTargetError method could be there or not
+                            }
+                        } else {
+                            target = null;
+                        }
+                    } catch (Exception ee) {
+                        target = null;
+                    }
+                }
+            } else {
+                System.out.println("Throwable is : " + theThro);
+            }
+        } catch (Throwable x) {
+            System.out.println("Exception : raised in printException : " + x);
+        }
+    }
+
+    /**
+     * Wait up to maxTimeInSeconds second(s) the given JMX connector server
+     * comes up (which means isActive returns true).
+     * If it fails to do so we throw a RunTime exception.
+     */
+    static void waitReady(JMXConnectorServerMBean server,
+                                 int maxTimeInSeconds) throws Exception {
+        int elapsed = 0;
+
+        while (!server.isActive() && elapsed < maxTimeInSeconds) {
+            Thread.sleep(1000);
+            elapsed++;
+        }
+
+        if (server.isActive()) {
+            String message = "Utils::waitReady: JMX connector server came up";
+            if ( elapsed == 0) {
+                message += " immediately";
+            } else {
+                message += " after " + elapsed + " seconds";
+            }
+            message += " [" + server.getAddress() + "]";
+            Utils.debug(DEBUG_STANDARD, message);
+        } else {
+            String message = "Utils::waitReady: (ERROR) JMX connector" +
+                    " server didn't come up after " + elapsed + " seconds [" +
+                    server.getAddress() + "]";
+            System.out.println(message);
+            throw new RuntimeException(message);
+        }
+    }
+
+    /**
+     * This method is used to compare the specified Throwable and possibly
+     * the derived causes to the specified String argument.
+     * The expected String argument format is :
+     *      throwable_1;throwable_2;...;throwable_N
+     * where throwable_i can be :
+     *      - either a throwable class name
+     *      - or the "*" character meaning several unknown throwable class names
+     *      This character must be followed by a throwable class name
+     */
+    static boolean compareThrowable(
+            Throwable t,
+            String expectedThrowable) {
+
+        // First parse the expectedThrowable String
+        StringTokenizer tokenizer = new StringTokenizer(expectedThrowable, ";");
+        String token = null;
+
+        try {
+            while (tokenizer.hasMoreTokens()) {
+                token = tokenizer.nextToken();
+                if (!token.equals("*")) {
+                    if (!Class.forName(token).isInstance(t)) {
+                        return false;
+                    }
+                } else {
+                    token = tokenizer.nextToken();
+                    while (!Class.forName(token).isInstance(t)) {
+                        t = t.getCause();
+                        if (t == null) {
+                            return false;
+                        }
+                    }
+                }
+                t = t.getCause();
+            }
+        } catch (ClassNotFoundException cnfe) {
+            String msg = "Expected throwable class(es) " + expectedThrowable +
+                " cannot be located";
+            System.out.println(msg);
+            throw new IllegalArgumentException(msg);
+        }
+        return true;
+    }
+}
diff --git a/jdk/test/javax/management/security/access.properties b/jdk/test/javax/management/security/access.properties
new file mode 100644
index 00000000000..eaf89a8b143
--- /dev/null
+++ b/jdk/test/javax/management/security/access.properties
@@ -0,0 +1,11 @@
+# Access control file for SQE tests.
+
+# Default username
+SQE_username readwrite create Simple
+
+# Functional authorization tests
+username1 readwrite create Simple
+username2 readonly
+username3 readonly
+username4 readwrite create Simple
+username5 readwrite create Simple
diff --git a/jdk/test/javax/management/security/java.policy.authorization b/jdk/test/javax/management/security/java.policy.authorization
new file mode 100644
index 00000000000..8b712765fca
--- /dev/null
+++ b/jdk/test/javax/management/security/java.policy.authorization
@@ -0,0 +1,98 @@
+// Standard extensions get all permissions by default
+
+grant codeBase "file:${java.home}/lib/ext/*" {
+	permission java.security.AllPermission;
+};
+
+// default permissions granted to all domains
+grant { 
+	// Allows any thread to stop itself using the java.lang.Thread.stop()
+	// method that takes no argument.
+	// Note that this permission is granted by default only to remain
+	// backwards compatible.
+	// It is strongly recommended that you either remove this permission
+	// from this policy file or further restrict it to code sources
+	// that you specify, because Thread.stop() is potentially unsafe.
+	// See "http://java.sun.com/notes" for more information.
+	permission java.lang.RuntimePermission "stopThread";
+
+	// allows anyone to listen on un-privileged ports
+	permission java.net.SocketPermission "localhost:1024-", "listen";
+
+	// "standard" properies that can be read by anyone
+
+	permission java.util.PropertyPermission "java.version", "read";
+	permission java.util.PropertyPermission "java.vendor", "read";
+	permission java.util.PropertyPermission "java.vendor.url", "read";
+	permission java.util.PropertyPermission "java.class.version", "read";
+	permission java.util.PropertyPermission "os.name", "read";
+	permission java.util.PropertyPermission "os.version", "read";
+	permission java.util.PropertyPermission "os.arch", "read";
+	permission java.util.PropertyPermission "file.separator", "read";
+	permission java.util.PropertyPermission "path.separator", "read";
+	permission java.util.PropertyPermission "line.separator", "read";
+
+	permission java.util.PropertyPermission "java.specification.version", "read";
+	permission java.util.PropertyPermission "java.specification.vendor", "read";
+	permission java.util.PropertyPermission "java.specification.name", "read";
+
+	permission java.util.PropertyPermission "java.vm.specification.version", "read";
+	permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+	permission java.util.PropertyPermission "java.vm.specification.name", "read";
+	permission java.util.PropertyPermission "java.vm.version", "read";
+	permission java.util.PropertyPermission "java.vm.vendor", "read";
+	permission java.util.PropertyPermission "java.vm.name", "read";
+
+       permission java.io.FilePermission "*","read,write";
+
+};
+
+grant codeBase "file:/-" {
+	permission java.security.AllPermission;
+       permission java.io.FilePermission "*","read,write";
+};
+
+grant principal javax.management.remote.JMXPrincipal "SQE_username" {
+    permission javax.management.MBeanServerPermission "*";
+    permission javax.management.MBeanPermission "Simple", "instantiate";
+    permission javax.management.MBeanPermission "Simple", "registerMBean";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username1" {
+    //
+    // JMXPrincipals "username1" has all permissions.
+    //
+    permission java.security.AllPermission;
+};
+
+grant principal javax.management.remote.JMXPrincipal "username2" {
+    //
+    // JMXPrincipals "username2" has all permissions.
+    //
+    permission java.security.AllPermission;
+};
+
+grant principal javax.management.remote.JMXPrincipal "username3" {
+    //
+    // JMXPrincipals "username3" has some permissions.
+    //
+    permission javax.management.MBeanPermission "Simple", "instantiate";
+    permission javax.management.MBeanPermission "Simple", "registerMBean";
+    permission javax.management.MBeanPermission "Simple", "setAttribute";
+    permission javax.management.MBeanPermission "Simple", "invoke";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username4" {
+    //
+    // JMXPrincipals "username4" has all permissions.
+    //
+    permission javax.management.MBeanPermission "Simple", "instantiate";
+    permission javax.management.MBeanPermission "Simple", "registerMBean";
+    permission javax.management.MBeanPermission "Simple", "invoke";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username5" {
+    //
+    // JMXPrincipals "username5" has no permissions.
+    //
+};
diff --git a/jdk/test/javax/management/security/keystoreAgent b/jdk/test/javax/management/security/keystoreAgent
new file mode 100644
index 0000000000000000000000000000000000000000..cfb02e00c38b8e28e4dcf4b0fdc60b80bda58990
GIT binary patch
literal 1325
zcmezO_TO6u1_mY|W&~r_#Prm>5+L*M{3&VyK$+bJO-$Pj_}I9#*%(<EwU`7M8Ce-v
znwS=wNzZV8k>3A9Z;R-&Gn3BG43#*>V^m=g{dlEL;e)p}a%T$OS$go)pZYj?d8^K<
zIc^QA>1+9wt*(2Xm)U&v{ek0ApL?1sO1VyXnX%k2a&pQ0d-%#3;ZWfc9tn<x=~EXq
z<OfEFUpo85OJhaU``0I1>|>WNvHq77(l(VrM)ddOPoZTq=I=4;DssR6+(yX4A~kR6
zw69UtJHIK<2>rEt`oj;AZTGJ|+sn*p<#?z6*#1cMezDg3pP34jr=%5rsy^g>{91PK
zq76lQy@|)&<5OPf1?o%}|9j%yo?8X1`}e1A``kC3X)3!s2e0@ns|u&rFQlszbuu&B
z!izeu3(9lY^jQ3kRXeod;xFkP7Vfd_D{sCwlV6(j&O$*?ET64KVd?J2p*y}c?!J8b
zKx*gR<4h|%%uhWtO8BFYEV3v<GMG1dM^YGX>_XSmhGh=Ud-I<@G;iMU@9XLHKhD=Q
z-w3vPrX=jy;c<%d$>P)dmVKQy$?vOI+}U8gOHyxcN$$M+py<$>%|-9tPhxm;Prl+T
zr(Cll_c}glp5Ge03R|uo-<lQv==6b2A+j%zzPj~<Z_eHd?t7t5X=bSl5_{hKX;0l@
z-2W!PV_w*wx0`R-wyNd)YW)}gAf%RSci#LO%kammV`aj!9?sA`SC}Tw+h(BAef0V@
zjlUQ6{@B=1b)&g)quB)Yd(l&-PXE6*Y2zPXK2A%G3zycL=c`}2pvNn7Uorgc^i$Sf
z=e<rlEo|#!H~+qHa;W-FDWlf8kI%bVeo$D{af5Z4^5Ky729ff=OqVtU6-Fd8E}w8g
z&tT(}=SS)cHR9IS<p}mBN!dBiQF^!jKX=4`;SJ%wbIbPpU1RaxnrXg6{LaGYy!ar)
zzwHZN8oNB5!NeDOlrQzuvUxcd-^OocO=g?t!#w>g&(5hIvOgz4Qgno#sevUhCF=lF
zvW7tu<3uJFhqt9?40zc%wc0$|zVk9Nvam83L>qD&aI!Invaks=xdj>W8SsEO9Kx)g
z#i>Q9hJptCAU?Y=hkH?KUVc(esv(a77f6Upm^rvK&yd%E8^q%lX7Mr#c7;hY3p0E9
zMi|J6^BR~Km>XCani-jy8byio8e1Be85=;kw6(l(KC)kd*_XMom%*U1lc}+hVeYPp
z^7|)oO+Ikj)`~}m`CwS*EO*OUyy@`~f2KY=GRMrsYL9A)#FDPv<+HzY1eJv8zVc{X
z#ah1bK0{l-zTANmSsR4@a<8bky!b~#mE@vdO?wy2=E<;XDrvFP-B+&H@4``V-2R-x
z1PwK(HM@j9O}xHFNx5(C7kftDcMo?oMFnIsF*7nSB0CQl70f_)2`-+P{V34y%!Us^
z^{MiIuT{S@;M`Tbr_e7&XiB&BzqOW@3!k|=p5Jn^@TSq5%YiKmr&^!d*mPaev6gj(
z&&|esy?G|nisS{GpPJ2%R!x^PpR_Hz*Wtn}!&$F{Zr+G%HnUpZ$SgFA<)pGes_xC`
s1RYCmjWelRZulO{m{9H0U*5Di<--A8#+8qI>{e=jSUrVB$KkIw0BqD5(*OVf

literal 0
HcmV?d00001

diff --git a/jdk/test/javax/management/security/keystoreClient b/jdk/test/javax/management/security/keystoreClient
new file mode 100644
index 0000000000000000000000000000000000000000..f0e0b7f57187520d475f57004e05ab8418f308d4
GIT binary patch
literal 1327
zcmezO_TO6u1_mY|W&~rl<ebdZyb>V$@BAs&e}Pha44RmB81S)iX|pl1FlsRgGBUC<
zurx6(>Gsk;Sbn%ibz|G+b3czQnUma9n4fTi{d$GGnOoAbfE=z(YEH|V-QBqQb@r>N
zPcUo#X=u1lvGqW4=XH~nN=|XYIvpZ6%3d6ey5-+zwEe^nrxj6iuJAFY?RwbZZ`*k6
zqWOiyw{It$$#I=>)}X`3P0gnB+3CQy-)B9wn<J@z<mR*^=O68?=3TU;KPC0{L7ffx
z2Nv@?#>8Luv2$2(Vd^Toh1ZvOoPL{S9Vb!sR(;-_hMoFlbGdJ=W8P@u-NZR@<uln%
z&YDRco%$cQulQ!xlCb%!?`(U)SCY1i4>;V6wawl4@wFJA(Yexdr!3z_1^LQ4y2vOB
z@^7E4le*z<WV=?9k$~=9E#ut3vp)ack<_BQG)HOH(G3#U<aC3J-fjGqW8TB*_uJ{(
z1Cu}8Mfcx!J~}^F*=mk%<jmVQpWa$BYl`*n<o6ek-RsqxZ+4zrLFePlWgDaJyB>_c
zYQ1Bfo_<7-t6$fr=W(*XAFNn5{pU;ZyH;$f_CGr6roC6G-+s<$gT`j|^zQX}i+?tS
zuHpQco6Zq;`Oe{Z`M;B&dmenXWVNxNwnp}wD<WlU_e?Z6TJ!c*Qt4ZM+5hTB<v(gB
zaJ`Spu6${GWWvH77Z#ZNNnLz)TP(AwCFNY1%brL4PrH7Zah82FZ~7he+%+^t`o^V$
zmUe{;IQJJg{oNzloA4v^%ifb0f@kboVYpA_?7fM?-i2*)FSHAe_Bkwc>baeBf33X{
z^L?}UpAJiyB8|$qzNFdtZ+#OvdB579^E<b()XGhp^+G~Q&sRTom1)I)X6a=b_7Vx}
zE340aoaLbWK>OGu4n1FiI^{}xovLqo>PP#k&lT}a>a8jJn7Ko8X4(VSYm7JEJaJw(
zO=z*n`&6TKi#JbqZ8CdVH0$~6yIUqc7M-kJ)R5h}V$GqzybFQG2~prQ%^IO+YG4UW
z$~wTLtYOf^IFX6P;ce+f170>xtu~Lg@4SqREUXL$(T3axoNUaYENsF|Zb62820S1R
zhcK&WacWVjp`Zajh|ey};a-%Qm!FiAYRF^21rp*CW)3dRGvqbk2JyIsS-gybU15^U
z!pvU25e9PNyapx)<^~pqW=3YF=27Cj#+C+V#s*L>Z7pw{kL*`q{$+0LWiV*$WNK_=
z__FfU6roS@d?wSXCUu|u5~!fcQ?<KH@kzeW1oag$73EEBCTdpfjUNBxXZ#U+>FBa>
z)7%gK%SsPOr`BBg#3#;QePM@Jkb;Trl(lcH3|`cUzgSqnsk&#vXREg2lczuQT&%xQ
z6Cri5wQy;p@vkh!FOMT{rsTio`1<CqiG}T7&k6gPm>C%uk(~#O3TB|Y`fks?q-kzy
z!Fc?*!u*M@ZFR<%?=9TkIoH?Is>i)p(s<RowC1<Af6Zs@+^=6`{oRh4bN|r;3Ts5f
zU&-4jD9vXI<y={CJ|}-_bn+?Qj)O8zb6+YbU;jJVZLVI+`<9M8_f$@2GZD$J2M(wu
v<#$f$wQQ?#eqFfkdL?sh#mWOw?slmqU2KP}(^NNqu5c^<F0%OEbk;opG14Es

literal 0
HcmV?d00001

diff --git a/jdk/test/javax/management/security/login.config b/jdk/test/javax/management/security/login.config
new file mode 100644
index 00000000000..8cd15025ef8
--- /dev/null
+++ b/jdk/test/javax/management/security/login.config
@@ -0,0 +1,8 @@
+PasswordFileAuthentication {
+    com.sun.jmx.remote.security.FileLoginModule required
+	passwordFile="${password.file}";
+};
+
+SampleLoginModule {
+    TestSampleLoginModule required;
+};
diff --git a/jdk/test/javax/management/security/password.properties b/jdk/test/javax/management/security/password.properties
new file mode 100644
index 00000000000..755099bbddd
--- /dev/null
+++ b/jdk/test/javax/management/security/password.properties
@@ -0,0 +1,12 @@
+# Password file for default SQE username.
+SQE_username SQE_password
+
+# Functional authorization tests
+username1 password1
+username2 password2
+username3 password3
+username4 password4
+username5 password5
+username6 password6
+
+usernameFileLoginModule passwordFileLoginModule
diff --git a/jdk/test/javax/management/security/truststoreAgent b/jdk/test/javax/management/security/truststoreAgent
new file mode 100644
index 0000000000000000000000000000000000000000..5b5f698cb9788adac8266eadd48316742ddbd2f2
GIT binary patch
literal 619
zcmezO_TO6u1_mY|W(3o0$vK&+c_l#h-}zI*tQc4$^h^ybfhu$inwT^UniwZCu{gXf
zy=cJ8#;Mij(e|B}k&%U!!64d@+klgeIh2J>n8_{3kk5bz#NiNT^(;;;N;MQT;0N*9
zg*n`dQuFeYa#9U>47fl-T*A!3rFn+D2HYSXw=j#BQLrmal3AG9%QwP6PMp`k#K7FZ
z!qCjf%+x$eoY&aWz|7bH%B8L4jq{QH%E-#V+}O)t(Ade;*vRl@<*6w`pXB*Wrd3Vq
zKKUh3L6xU!cbVdoe4z>ID`G0jo7zm&tk@ep{>jhyBlgnKW#Oi|AN-e<9*|D0x$=om
zoWJ_Q4zC~u6Wb|k-&h&Es1tv&uz*u_&xFrbZN(=~f9Sbbf1@Ts>R@Z((njN7S&CmC
zN8U`yf6ejr&0P}<+rOR@_A@avGB6@L4;U59KzH@so_k5t+|+{c_;H2#6J6Wtj4$6?
zxV>|(ucuXyd$FYPs&{G4Z*BjY&)T_PzsUN#9W&?tqX!h$h={+Ew^2}<&lJkJvfzA9
z{?zE?Q@kAqWt`@|R8YSDce2}Dy_WYa9eM7loX%z<l3x!TP)o}1oYHIAR^$A-aNYGv
i=Guyt2cq2V`esc3npzgTuGK>5-lbNr`wu<x{{aBs-^cF&

literal 0
HcmV?d00001

diff --git a/jdk/test/javax/management/security/truststoreClient b/jdk/test/javax/management/security/truststoreClient
new file mode 100644
index 0000000000000000000000000000000000000000..f6a6a0098aaabfaf4fd8ac5b6509b7235eb60a2b
GIT binary patch
literal 618
zcmezO_TO6u1_mY|W(3o$iRr0%B|zri`BQw?Gq6VJnHpFE73df=F=-eyF-~M+ad=yL
z#(<ZNQ>)FR?K>|cBMU2oL9`*a0Vf-CC<~h~lUtA>p8*eu!y(M-S)5vwYA9&H58|^6
zbGR3!=H(~lq#E)VaDjxlgqed&^9*?nxIsK_VHPi=U{{zVvoN!lZ-jxIIIn?;fw_T&
zp_!4HsZo?Tud$_pnXv(sOIynu=Og=-k(GhDv6sQ1v6HE>kzwwxiSqj=aZNsO+t!Ll
zhxuSw=PY;2S-k1-5r3vWJ2J=2#A=Ufio}wx-Q}~ta|D%y>Av!4T*X?x@IFIZzrNgo
z6ImOC{&KIVxV-pBLY3sAUrl=#%;w3kYAR{5)7@9D*YCnnaNPc!!UPR9r!~8TK25y7
zMoGDE?iYJT-gggoG(`nuGBGnUFd{n-7!}MwcL^?@nEfcw@63h|LG`Kff3H=)GvM4+
zyr<AFMQBR5^}n^2mJ6S`JD%Tivhb$So6CVM3#VG2+Sqhm(y^9xh0o2#e7$)l(~9H;
zo1dD^j#f>VGoQ3AyVv2uEW=r^gl^u5Yc{i5-pDL8i{+%UK&tM|=mZ^0ZjCdkTW<Is
h%a~B@(_h{c@$4AGneF=-_dWdT+&I6*+D~K-Cjf`W!}9<D

literal 0
HcmV?d00001


From 6a9a5a80ead413c98ba5c22d4b7894d0a6addfd7 Mon Sep 17 00:00:00 2001
From: Nadeesh TV <ntv@openjdk.org>
Date: Wed, 23 Dec 2015 13:19:58 -0500
Subject: [PATCH 61/62] 8143413: add toEpochSecond methods for efficient access

Reviewed-by: rriggs, scolebourne
---
 .../share/classes/java/time/LocalDate.java    | 27 +++++++++++++++++++
 .../share/classes/java/time/LocalTime.java    | 24 +++++++++++++++++
 .../share/classes/java/time/OffsetTime.java   | 24 ++++++++++++++++-
 .../java/time/tck/java/time/TCKLocalDate.java | 25 +++++++++++++++++
 .../java/time/tck/java/time/TCKLocalTime.java | 26 ++++++++++++++++++
 .../time/tck/java/time/TCKOffsetTime.java     | 24 +++++++++++++++++
 6 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/jdk/src/java.base/share/classes/java/time/LocalDate.java b/jdk/src/java.base/share/classes/java/time/LocalDate.java
index 0d47deeac3a..0c6c755b813 100644
--- a/jdk/src/java.base/share/classes/java/time/LocalDate.java
+++ b/jdk/src/java.base/share/classes/java/time/LocalDate.java
@@ -147,6 +147,10 @@ public final class LocalDate
      * This could be used by an application as a "far future" date.
      */
     public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
+    /**
+     * The epoch year {@code LocalDate}, '1970-01-01'.
+     */
+    public static final LocalDate EPOCH = LocalDate.of(1970, 1, 1);
 
     /**
      * Serialization version.
@@ -1864,6 +1868,29 @@ public final class LocalDate
         return total - DAYS_0000_TO_1970;
     }
 
+    /**
+     * Converts this {@code LocalDate} to the number of seconds since the epoch
+     * of 1970-01-01T00:00:00Z.
+     * <p>
+     * This combines this local date with the specified time and
+     * offset to calculate the epoch-second value, which is the
+     * number of elapsed seconds from 1970-01-01T00:00:00Z.
+     * Instants on the time-line after the epoch are positive, earlier
+     * are negative.
+     *
+     * @param time the local time, not null
+     * @param offset the zone offset, not null
+     * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+     * @since 9
+     */
+    public long toEpochSecond(LocalTime time, ZoneOffset offset) {
+        Objects.requireNonNull(time, "time");
+        Objects.requireNonNull(offset, "offset");
+        long secs = toEpochDay() * SECONDS_PER_DAY + time.toSecondOfDay();
+        secs -= offset.getTotalSeconds();
+        return secs;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this date to another date.
diff --git a/jdk/src/java.base/share/classes/java/time/LocalTime.java b/jdk/src/java.base/share/classes/java/time/LocalTime.java
index 6b41e8579ad..7cd4adf693f 100644
--- a/jdk/src/java.base/share/classes/java/time/LocalTime.java
+++ b/jdk/src/java.base/share/classes/java/time/LocalTime.java
@@ -1490,6 +1490,30 @@ public final class LocalTime
         return total;
     }
 
+    /**
+     * Converts this {@code LocalTime} to the number of seconds since the epoch
+     * of 1970-01-01T00:00:00Z.
+     * <p>
+     * This combines this local time with the specified date and
+     * offset to calculate the epoch-second value, which is the
+     * number of elapsed seconds from 1970-01-01T00:00:00Z.
+     * Instants on the time-line after the epoch are positive, earlier
+     * are negative.
+     *
+     * @param date the local date, not null
+     * @param offset the zone offset, not null
+     * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+     * @since 9
+     */
+    public long toEpochSecond(LocalDate date, ZoneOffset offset) {
+        Objects.requireNonNull(date, "date");
+        Objects.requireNonNull(offset, "offset");
+        long epochDay = date.toEpochDay();
+        long secs = epochDay * 86400 + toSecondOfDay();
+        secs -= offset.getTotalSeconds();
+        return secs;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this time to another time.
diff --git a/jdk/src/java.base/share/classes/java/time/OffsetTime.java b/jdk/src/java.base/share/classes/java/time/OffsetTime.java
index fca51fd8941..1df445da650 100644
--- a/jdk/src/java.base/share/classes/java/time/OffsetTime.java
+++ b/jdk/src/java.base/share/classes/java/time/OffsetTime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -1232,6 +1232,28 @@ public final class OffsetTime
         return nod - offsetNanos;
     }
 
+    /**
+     * Converts this {@code OffsetTime} to the number of seconds since the epoch
+     * of 1970-01-01T00:00:00Z.
+     * <p>
+     * This combines this offset time with the specified date to calculate the
+     * epoch-second value, which is the number of elapsed seconds from
+     * 1970-01-01T00:00:00Z.
+     * Instants on the time-line after the epoch are positive, earlier
+     * are negative.
+     *
+     * @param date the localdate, not null
+     * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+     * @since 9
+     */
+    public long toEpochSecond(LocalDate date) {
+        Objects.requireNonNull(date, "date");
+        long epochDay = date.toEpochDay();
+        long secs = epochDay * 86400 + time.toSecondOfDay();
+        secs -= offset.getTotalSeconds();
+        return secs;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this {@code OffsetTime} to another time.
diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java
index 6218d150241..afe7ddcdb58 100644
--- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java
+++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java
@@ -2156,6 +2156,31 @@ public class TCKLocalDate extends AbstractDateTimeTest {
         assertEquals(LocalDate.of(-1, 12, 31).toEpochDay(), -678942 - 40587);
     }
 
+    //-----------------------------------------------------------------------
+    // toEpochSecond
+    //-----------------------------------------------------------------------
+    @DataProvider(name="epochSecond")
+    Object[][] provider_toEpochSecond() {
+        return new Object[][] {
+            {LocalDate.of(1858, 11, 17).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_PONE), -3506720400L},
+            {LocalDate.of(1, 1, 1).toEpochSecond(LocalTime.NOON, OFFSET_PONE), -62135557200L},
+            {LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.of(5, 30), OFFSET_PTWO), 812172600L},
+            {LocalDate.of(1970, 1, 1).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_MTWO), 7200L},
+            {LocalDate.of(-1, 12, 31).toEpochSecond(LocalTime.NOON, OFFSET_PONE), -62167266000L},
+            {LocalDate.of(1, 1, 1).toEpochSecond(LocalTime.MIDNIGHT, OFFSET_PONE),
+                    Instant.ofEpochSecond(-62135600400L).getEpochSecond()},
+            {LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.NOON, OFFSET_PTWO),
+                    Instant.ofEpochSecond(812196000L).getEpochSecond()},
+            {LocalDate.of(1995, 9, 27).toEpochSecond(LocalTime.of(5, 30), OFFSET_MTWO),
+                    LocalDateTime.of(1995, 9, 27, 5, 30).toEpochSecond(OFFSET_MTWO)},
+        };
+    }
+
+    @Test(dataProvider="epochSecond")
+    public void test_toEpochSecond(long actual, long expected) {
+        assertEquals(actual, expected);
+    }
+
     //-----------------------------------------------------------------------
     // compareTo()
     //-----------------------------------------------------------------------
diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java
index 1736aca7cc4..ff577095842 100644
--- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java
@@ -2433,6 +2433,32 @@ public class TCKLocalTime extends AbstractDateTimeTest {
         }
     }
 
+    //-----------------------------------------------------------------------
+    // toEpochSecond()
+    //--------------------------------------------------------------------------
+    @DataProvider(name="epochSecond")
+    Object[][] provider__toEpochSecond() {
+        return new Object[][] {
+        {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO), -7200L},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1965, 12, 31), OFFSET_PTWO), -126282600L},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1995, 5, 3), OFFSET_MTWO), 799507800L},
+        {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
+                Instant.ofEpochSecond(-7200).getEpochSecond()},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1969, 12, 31), OFFSET_MTWO),
+                Instant.ofEpochSecond(-37800L).getEpochSecond()},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
+                LocalDateTime.of(1970, 1, 1, 11, 30).toEpochSecond(OFFSET_PTWO)},
+        };
+    }
+
+    @Test(dataProvider="epochSecond")
+    public void test_toEpochSecond(long actual, long expected) {
+        assertEquals(actual, expected);
+    }
+
+    //-----------------------------------------------------------------------
+    // toSecondOfDay_fromNanoOfDay_symmetry()
+    //-----------------------------------------------------------------------
     @Test
     public void test_toSecondOfDay_fromNanoOfDay_symmetry() {
         LocalTime t = LocalTime.of(0, 0);
diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
index 0882dfcb19e..016cfc3e9d8 100644
--- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java
@@ -134,6 +134,7 @@ public class TCKOffsetTime extends AbstractDateTimeTest {
     private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
     private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
     private static final LocalDate DATE = LocalDate.of(2008, 12, 3);
     private OffsetTime TEST_11_30_59_500_PONE;
 
@@ -1148,6 +1149,29 @@ public class TCKOffsetTime extends AbstractDateTimeTest {
         OffsetTime.of(11, 30, 0, 0, OFFSET_PONE).format(null);
     }
 
+    //-----------------------------------------------------------------------
+    // toEpochSecond()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="epochSecond")
+    Object[][] provider_toEpochSecond() {
+        return new Object[][] {
+        {OffsetTime.of(0, 0, 0, 0, OFFSET_PTWO).toEpochSecond(LocalDate.of(1970, 1, 1)), -7200L},
+        {OffsetTime.of(11, 30, 0, 0, OFFSET_MTWO).toEpochSecond(LocalDate.of(1995, 9, 27)), 812208600L},
+        {OffsetTime.of(0, 0, 0, 0, OFFSET_PONE).toEpochSecond(LocalDate.of(1970, 1, 1)),
+                Instant.ofEpochSecond(-3600).getEpochSecond()},
+        {OffsetTime.of(11, 30, 0, 0, OFFSET_PTWO).toEpochSecond(LocalDate.of(1965, 12, 31)),
+                Instant.ofEpochSecond(-126282600L).getEpochSecond()},
+        {OffsetTime.of(11, 30, 0, 0, OFFSET_MTWO).toEpochSecond(LocalDate.of(1970, 1, 1)),
+                OffsetDateTime.of(LocalDate.of(1970, 1, 1), LocalTime.of(11, 30), OFFSET_MTWO)
+                              .toEpochSecond()},
+        };
+    }
+
+    @Test(dataProvider="epochSecond")
+    public void test_toEpochSecond(long actual, long expected) {
+        assertEquals(actual, expected);
+    }
+
     //-----------------------------------------------------------------------
     // compareTo()
     //-----------------------------------------------------------------------

From 37fa4dba28df7a2ee09cb7271307c48494eb6ab6 Mon Sep 17 00:00:00 2001
From: Xue-Lei Andrew Fan <xuelei@openjdk.org>
Date: Thu, 24 Dec 2015 15:22:04 +0000
Subject: [PATCH 62/62] 8146192: Add test for JDK-8049321

Reviewed-by: mullan
---
 .../net/ssl/TLSv12/SignatureAlgorithms.java   | 595 ++++++++++++++++++
 1 file changed, 595 insertions(+)
 create mode 100644 jdk/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java

diff --git a/jdk/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java b/jdk/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java
new file mode 100644
index 00000000000..cf5ba477324
--- /dev/null
+++ b/jdk/test/javax/net/ssl/TLSv12/SignatureAlgorithms.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 8049321
+ * @summary Support SHA256WithDSA in JSSE
+ * @modules java.base/sun.misc
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
+ *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
+ *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256"
+ *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
+ *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
+ *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-256"
+ *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import javax.net.ssl.*;
+import java.security.Security;
+import java.security.KeyStore;
+import java.security.KeyFactory;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import sun.misc.BASE64Decoder;
+
+
+public class SignatureAlgorithms {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    static boolean separateServerThread = true;
+
+    /*
+     * Where do we find the keystores?
+     */
+    // Certificates and key (DSA) used in the test.
+    static String trustedCertStr =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDYTCCAyGgAwIBAgIJAK8/gw6zg/DPMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+        "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+        "MB4XDTE1MTIwMzEzNTIyNVoXDTM2MTExMjEzNTIyNVowOzELMAkGA1UEBhMCVVMx\n" +
+        "DTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlMIIB\n" +
+        "uDCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG4X+uxu5V\n" +
+        "b3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2eBfUv/hJ\n" +
+        "cLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNAqAB9PO5Y\n" +
+        "zKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAaor8iURd82\n" +
+        "b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I81drnN0Y\n" +
+        "lyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVXW+SEGADC\n" +
+        "J1+z8uqP3lIB6ltdgOiV/GQDgYUAAoGBAOXRppuJSGdt6AiZkb81P1DCUgIUlZFI\n" +
+        "J9GxWrjbbHDmGllMwPNhK6dU7LJKJJuYVPW+95rUGlSJEjRqSlHuyHkNb6e3e7qx\n" +
+        "tmx1/oIyq+oLult50hBS7uBvLLR0JbIKjBzzkudL8Rjze4G/Wq7KDM2T1JOP49tW\n" +
+        "eocCvaC8h8uQo4GtMIGqMB0GA1UdDgQWBBT17HcqLllsqnZzP+kElcGcBGmubjBr\n" +
+        "BgNVHSMEZDBigBT17HcqLllsqnZzP+kElcGcBGmubqE/pD0wOzELMAkGA1UEBhMC\n" +
+        "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+        "ggkArz+DDrOD8M8wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwCQYHKoZI\n" +
+        "zjgEAwMvADAsAhQ6Y1I6LtIEBMqNo8o6GIe4LLEJuwIUbVQUKi8tvtWyRoxm8AFV\n" +
+        "0axJYUU=\n" +
+        "-----END CERTIFICATE-----";
+
+    static String[] targetCertStr = {
+        // DSA-SHA1
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDKTCCAumgAwIBAgIJAOy5c0b+8stFMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+        "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+        "MB4XDTE1MTIwMzEzNTIyNVoXDTM1MDgyMDEzNTIyNVowTzELMAkGA1UEBhMCVVMx\n" +
+        "DTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVzdCBTZXJpdmNlMRIw\n" +
+        "EAYDVQQDDAlsb2NhbGhvc3QwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA8f5v4ZIx\n" +
+        "fopLuNcNF6/NzjrgMUbhf67G7lVvdTjKGxTwDxy4fiDCKfov8gOSZlDs3TMLSNGy\n" +
+        "IZVIywURNOrXQXf2kfZ4F9S/+Elwt8GciMES1WpX90TErzwe6XaxniZCKFDiKyw+\n" +
+        "XuGyuhL0RZiJydfSg0CoAH087ljMpt+kvtMCFQDXdZbjyuWfZQ/8toCC2fMqGpw2\n" +
+        "0wKBgQDdG/QaKtNsBqivyJRF3zZvkWUNN684JO6rtkil9lVXfSd5LtwFg163qb/f\n" +
+        "/hx9SVtuuqFuognYj4jzV2uc3RiXI3gqS7ERwHo5PB9aQhSPqu89oJCsEfxDbXds\n" +
+        "Orcce1g1o/w6h5BTJVdb5IQYAMInX7Py6o/eUgHqW12A6JX8ZAOBhAACgYB+zYqn\n" +
+        "jJwG4GZpBIN/6qhzbp0flChsV+Trlu0SL0agAQzb6XdI/4JnO87Pgbxaxh3VNAj3\n" +
+        "3+Ghr1NLBuBfTKzJ4j9msWT3EpLupkMyNtXvBYM0iyMrll67lSjMdv++wLEw35Af\n" +
+        "/bzVcjGyA5Q0i0cuEzDmHTVfi0OydynbwSLxtKNjMGEwCwYDVR0PBAQDAgPoMB0G\n" +
+        "A1UdDgQWBBQXJI8AxM0qsYCbbkIMuI5zJ+nMEDAfBgNVHSMEGDAWgBT17HcqLlls\n" +
+        "qnZzP+kElcGcBGmubjASBgNVHREBAf8ECDAGhwR/AAABMAkGByqGSM44BAMDLwAw\n" +
+        "LAIUXgyJ0xll4FrZAKXi8bj7Kiz+SA4CFH9WCSZIBYA9lmJkiTgRS7iM/6IC\n" +
+        "-----END CERTIFICATE-----",
+
+        // DSA-SHA224
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDLzCCAuugAwIBAgIJAOy5c0b+8stGMAsGCWCGSAFlAwQDATA7MQswCQYDVQQG\n" +
+        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+        "Y2UwHhcNMTUxMjAzMTU0NDM5WhcNMzUwODIwMTU0NDM5WjBPMQswCQYDVQQGEwJV\n" +
+        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+        "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+        "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+        "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+        "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+        "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+        "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+        "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgA81\n" +
+        "CJKEv+pwiqYgxtw/9rkQ9748WP3mKrEC06kjUG+94/Z9dQloNFFfj6LiO1bymc5l\n" +
+        "6QIR8XCi4Po3N80K3+WxhBGFhY+RkVWTh43JV8epb41aH2qiWErarBwBGEh8LyGT\n" +
+        "i30db+Nkz2gfvyz9H/9T0jmYgfLEOlMCusali1qHo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+        "HQYDVR0OBBYEFBqSP0S4+X+zOCTEnlp2hbAjV/W5MB8GA1UdIwQYMBaAFPXsdyou\n" +
+        "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMB\n" +
+        "AzEAMC4CFQChiRaOnAnsCSJFwdpK22jSxU/mhQIVALgLbj/G39+1Ej8UuSWnEQyU\n" +
+        "4DA+\n" +
+        "-----END CERTIFICATE-----",
+
+        // DSA-SHA256
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDLTCCAuugAwIBAgIJAOy5c0b+8stHMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+        "Y2UwHhcNMTUxMjAzMTU0NjUxWhcNMzUwODIwMTU0NjUxWjBPMQswCQYDVQQGEwJV\n" +
+        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+        "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+        "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+        "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+        "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+        "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+        "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+        "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgEF7\n" +
+        "2qiYxGrjX4KCOy0k5nK/RYlgLy4gYDChihQpiaa+fbA5JOBOxPWsh7rdtmJuDrEJ\n" +
+        "keacU223+DIhOKC49fa+EvhLNqo6U1oPn8n/yvBsvvnWkcynw5KfNzaLlaPmzugh\n" +
+        "v9xl/GhyZNAXc1QUcW3C+ceHVNrKnkfbTKZz5eRSo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+        "HQYDVR0OBBYEFNMkPrt40oO9Dpy+bcbQdEvOlNlyMB8GA1UdIwQYMBaAFPXsdyou\n" +
+        "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMC\n" +
+        "Ay8AMCwCFCvA2QiKSe/n+6GqSYQwgQ/zL5M9AhQfSiuWdMJKWpgPJKakvzhBUbMb\n" +
+        "vA==\n" +
+        "-----END CERTIFICATE-----"};
+
+    // Private key in the format of PKCS#8, key size is 1024 bits.
+    static String[] targetPrivateKey = {
+        // For cert DSA-SHA1
+        "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+        "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+        "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+        "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+        "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+        "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+        "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOiB7J/lrFrNduQ8nDNTe8VspoAI=",
+
+        // For cert DSA-SHA224
+        "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+        "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+        "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+        "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+        "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+        "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+        "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOj9F5mxWd9W1tiLSdsOAt8BUBzE=",
+
+        // For cert DSA-SHA256
+        "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+        "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+        "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+        "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+        "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+        "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+        "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUQ2WGgg+OO39Aujj0e4lM4pP4/9g="};
+
+
+    static char passphrase[] = "passphrase".toCharArray();
+
+    /*
+     * Turn on SSL debugging?
+     */
+    static boolean debug = false;
+
+    /*
+     * Is the server ready to serve?
+     */
+    volatile boolean serverReady = false;
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doServerSide() throws Exception {
+
+        SSLContext context = generateSSLContext(
+                null, targetCertStr, targetPrivateKey);
+        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+        try (SSLServerSocket sslServerSocket =
+                (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
+
+            serverPort = sslServerSocket.getLocalPort();
+
+            /*
+             * Signal Client, we're ready for his connect.
+             */
+            serverReady = true;
+
+            try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+                sslSocket.setEnabledCipherSuites(
+                        sslSocket.getSupportedCipherSuites());
+                InputStream sslIS = sslSocket.getInputStream();
+                OutputStream sslOS = sslSocket.getOutputStream();
+
+                sslIS.read();
+                sslOS.write('A');
+                sslOS.flush();
+
+                dumpSignatureAlgorithms(sslSocket);
+            }
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        SSLContext context = generateSSLContext(trustedCertStr, null, null);
+        SSLSocketFactory sslsf = context.getSocketFactory();
+
+        try (SSLSocket sslSocket =
+                (SSLSocket)sslsf.createSocket("localhost", serverPort)) {
+
+            // enable TLSv1.2 only
+            sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
+
+            // enable a block cipher
+            sslSocket.setEnabledCipherSuites(new String[] {cipherSuite});
+
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
+
+            sslOS.write('B');
+            sslOS.flush();
+            sslIS.read();
+
+            dumpSignatureAlgorithms(sslSocket);
+        }
+    }
+
+    static void dumpSignatureAlgorithms(SSLSocket sslSocket) throws Exception {
+
+        boolean isClient = sslSocket.getUseClientMode();
+        String mode = "[" + (isClient ? "Client" : "Server") + "]";
+        ExtendedSSLSession session =
+                (ExtendedSSLSession)sslSocket.getSession();
+        String[] signAlgs = session.getLocalSupportedSignatureAlgorithms();
+        System.out.println(
+                mode + " local supported signature algorithms: " +
+                Arrays.asList(signAlgs));
+
+        if (!isClient) {
+            signAlgs = session.getPeerSupportedSignatureAlgorithms();
+            System.out.println(
+                mode + " peer supported signature algorithms: " +
+                Arrays.asList(signAlgs));
+        } else {
+            Certificate[] serverCerts = session.getPeerCertificates();
+
+            // server should always send the authentication cert.
+            String sigAlg = ((X509Certificate)serverCerts[0]).getSigAlgName();
+            System.out.println(
+                mode + " the signature algorithm of server certificate: " +
+                sigAlg);
+            if (sigAlg.contains("SHA1")) {
+                if (disabledAlgorithms.contains("SHA-1")) {
+                    throw new Exception(
+                            "Not the expected server certificate. " +
+                            "SHA-1 should be disabled");
+                }
+            } else if (sigAlg.contains("SHA224")) {
+                if (disabledAlgorithms.contains("SHA-224")) {
+                    throw new Exception(
+                            "Not the expected server certificate. " +
+                            "SHA-224 should be disabled");
+                }
+            } else {    // SHA-256
+                if (disabledAlgorithms.contains("SHA-256")) {
+                    throw new Exception(
+                            "Not the expected server certificate. " +
+                            "SHA-256 should be disabled");
+                }
+            }
+        }
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+    private static String tmAlgorithm;          // trust manager
+    private static String disabledAlgorithms;   // disabled algorithms
+    private static String cipherSuite;          // cipher suite
+
+    private static void parseArguments(String[] args) {
+        tmAlgorithm = args[0];
+        disabledAlgorithms = args[1];
+        cipherSuite = args[2];
+    }
+
+    private static SSLContext generateSSLContext(String trustedCertStr,
+            String[] keyCertStrs, String[] keySpecStrs) throws Exception {
+
+        // generate certificate from cert string
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+        // create a key store
+        KeyStore ks = KeyStore.getInstance("JKS");
+        ks.load(null, null);
+
+        // import the trused cert
+        Certificate trusedCert = null;
+        ByteArrayInputStream is = null;
+        if (trustedCertStr != null) {
+            is = new ByteArrayInputStream(trustedCertStr.getBytes());
+            trusedCert = cf.generateCertificate(is);
+            is.close();
+
+            ks.setCertificateEntry("DSA Signer", trusedCert);
+        }
+
+        if (keyCertStrs != null && keyCertStrs.length != 0) {
+            for (int i = 0; i < keyCertStrs.length; i++) {
+                String keyCertStr = keyCertStrs[i];
+                String keySpecStr = keySpecStrs[i];
+
+                // generate the private key.
+                PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+                                new BASE64Decoder().decodeBuffer(keySpecStr));
+                KeyFactory kf = KeyFactory.getInstance("DSA");
+                DSAPrivateKey priKey =
+                        (DSAPrivateKey)kf.generatePrivate(priKeySpec);
+
+                // generate certificate chain
+                is = new ByteArrayInputStream(keyCertStr.getBytes());
+                Certificate keyCert = cf.generateCertificate(is);
+                is.close();
+
+                Certificate[] chain = null;
+                if (trusedCert != null) {
+                    chain = new Certificate[2];
+                    chain[0] = keyCert;
+                    chain[1] = trusedCert;
+                } else {
+                    chain = new Certificate[1];
+                    chain[0] = keyCert;
+                }
+
+                // import the key entry.
+                ks.setKeyEntry("DSA Entry " + i, priKey, passphrase, chain);
+            }
+        }
+
+        // create SSL context
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
+        tmf.init(ks);
+
+        SSLContext ctx = SSLContext.getInstance("TLS");
+        if (keyCertStrs != null && keyCertStrs.length != 0) {
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
+            kmf.init(ks, passphrase);
+
+            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+            ks = null;
+        } else {
+            ctx.init(null, tmf.getTrustManagers(), null);
+        }
+
+        return ctx;
+    }
+
+
+    // use any free port by default
+    volatile int serverPort = 0;
+
+    volatile Exception serverException = null;
+    volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        /*
+         * debug option
+         */
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        /*
+         * Get the customized arguments.
+         */
+        parseArguments(args);
+
+
+        /*
+         * Ignore testing on Windows if only SHA-224 is available.
+         */
+        if ((Security.getProvider("SunMSCAPI") != null) &&
+                (disabledAlgorithms.contains("SHA-1")) &&
+                (disabledAlgorithms.contains("SHA-256"))) {
+
+            System.out.println(
+                "Windows system does not support SHA-224 algorithms yet. " +
+                "Ignore the testing");
+
+            return;
+        }
+
+        /*
+         * Expose the target algorithms by diabling unexpected algorithms.
+         */
+        Security.setProperty(
+                "jdk.certpath.disabledAlgorithms", disabledAlgorithms);
+
+        /*
+         * Reset the security property to make sure that the algorithms
+         * and keys used in this test are not disabled by default.
+         */
+        Security.setProperty( "jdk.tls.disabledAlgorithms", "");
+
+        /*
+         * Start the tests.
+         */
+        new SignatureAlgorithms();
+    }
+
+    Thread clientThread = null;
+    Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    SignatureAlgorithms() throws Exception {
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            // swallow for now.  Show later
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            serverThread.join();
+        } else {
+            clientThread.join();
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+        String whichRemote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+            whichRemote = "server";
+        } else {
+            remote = clientException;
+            local = serverException;
+            whichRemote = "client";
+        }
+
+        /*
+         * If both failed, return the curthread's exception, but also
+         * print the remote side Exception
+         */
+        if ((local != null) && (remote != null)) {
+            System.out.println(whichRemote + " also threw:");
+            remote.printStackTrace();
+            System.out.println();
+            throw local;
+        }
+
+        if (remote != null) {
+            throw remote;
+        }
+
+        if (local != null) {
+            throw local;
+        }
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died..." + e);
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died..." + e);
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}