changeset 12347:5ce54ea88194 icedtea-3.3.0pre01

Merge jdk8u112-b16
author andrew
date Thu, 12 Jan 2017 06:59:38 +0000
parents fc64fb457172 (current diff) 5dd7e4bae5c2 (diff)
children db24ee48f554
files .hgtags src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java src/macosx/native/sun/awt/AWTView.m src/macosx/native/sun/awt/AWTWindow.h src/macosx/native/sun/awt/AWTWindow.m src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java src/share/classes/com/sun/crypto/provider/CipherCore.java src/share/classes/com/sun/crypto/provider/CipherFeedback.java src/share/classes/com/sun/crypto/provider/CounterMode.java src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java src/share/classes/com/sun/crypto/provider/OutputFeedback.java src/share/classes/com/sun/crypto/provider/PCBC.java src/share/classes/java/lang/invoke/MethodHandles.java src/share/classes/java/security/ProtectionDomain.java src/share/classes/java/security/SecureRandom.java src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java src/share/classes/javax/swing/text/html/parser/Parser.java src/share/classes/sun/security/krb5/Config.java src/share/classes/sun/security/krb5/internal/CredentialsUtil.java src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java src/share/classes/sun/security/ssl/JsseJce.java src/share/classes/sun/security/ssl/SSLContextImpl.java src/share/classes/sun/security/ssl/ServerHandshaker.java src/share/classes/sun/tools/native2ascii/Main.java src/solaris/classes/sun/java2d/xr/XRRenderer.java src/solaris/native/java/net/NetworkInterface.c src/solaris/native/java/net/PlainDatagramSocketImpl.c src/windows/bin/cmdtoargs.c src/windows/native/java/net/Inet4AddressImpl.c src/windows/native/java/net/Inet6AddressImpl.c src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp test/ProblemList.txt test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java test/java/lang/invoke/PermuteArgsTest.java test/sun/security/provider/KeyStore/DKSTest.java
diffstat 247 files changed, 18171 insertions(+), 2064 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Nov 08 05:26:12 2016 +0000
+++ b/.hgtags	Thu Jan 12 06:59:38 2017 +0000
@@ -677,3 +677,19 @@
 b1304d71a2ec04ae6fa0a46120a5beba40a6f5ba jdk8u111-b12
 3f1a07c3a600abdc2eb204f9b67984e6b920846e jdk8u111-b13
 0cc71de3df184547da673a87c307def4c8da54d4 icedtea-3.2.0
+ab26fe28f9ed9c7d0a03ce47d1306427f86f27e9 jdk8u111-b14
+47e20a90bdbb2327289e330606b73a9fe4dc857e jdk8u112-b00
+96393e490afd4acba5b92c5ede68dc9bbb60a38e jdk8u112-b01
+b44d695f738baba091370828b84ae2c4cd715c1b jdk8u112-b02
+1af2eacbc17462f080d70e71c53e073ab0640f32 jdk8u112-b03
+a11ab21bb7991509846e0e45ad3792896c4fe98c jdk8u112-b04
+ecb2bae7905e2fd6f9b837521ee82a2cbb34602c jdk8u112-b06
+c66f5a825a0f0b5fb833bc7f50f327aec43e213b jdk8u112-b07
+89375f5c2c4c2bdc2340d7af1977dc1607908840 jdk8u112-b08
+820ef12b2a56b2a5fe1027a1f77ce81549978534 jdk8u112-b09
+c86d82567b1200bdb2d2a757f676179a637c4244 jdk8u112-b10
+532df0329e8070a75ae229310aa87ae530fa1eee jdk8u112-b11
+2a44e743f1654e39109233322e639bcfeca42e8d jdk8u112-b12
+16c649b70dc3d437ab16ff8125a50125deda2bc9 jdk8u112-b13
+d2d8b67021a0f41e0eabd711bfd87a943dc0a8d5 jdk8u112-b14
+60767ec3909b3d0cb26dd7b3f952c62053719dda jdk8u112-b15
--- a/LICENSE	Tue Nov 08 05:26:12 2016 +0000
+++ b/LICENSE	Thu Jan 12 06:59:38 2017 +0000
@@ -3,7 +3,7 @@
 Version 2, June 1991
 
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 Everyone is permitted to copy and distribute verbatim copies of this license
 document, but changing it is not allowed.
@@ -287,8 +287,8 @@
     more details.
 
     You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc., 59
-    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 Also add information on how to contact you by electronic and paper mail.
 
--- a/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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 sun.lwawt.macosx;
 
+import sun.lwawt.LWWindowPeer;
+
 import java.awt.*;
 import java.beans.*;
 import java.lang.reflect.Field;
@@ -421,6 +423,8 @@
     }
 
     public static AccessibleAction getAccessibleAction(final Accessible a, final Component c) {
+        if (a == null) return null;
+
         return invokeAndWait(new Callable<AccessibleAction>() {
             public AccessibleAction call() throws Exception {
                 final AccessibleContext ac = a.getAccessibleContext();
@@ -667,4 +671,28 @@
             }
         }, c);
     }
+
+    /**
+     * @return AWTView ptr, a peer of the CPlatformView associated with the toplevel container of the Accessible, if any
+     */
+    private static long getAWTView(Accessible a) {
+        Accessible ax = CAccessible.getSwingAccessible(a);
+        if (!(ax instanceof Component)) return 0;
+
+        return invokeAndWait(new Callable<Long>() {
+            public Long call() throws Exception {
+                Component cont = (Component) ax;
+                while (cont != null && !(cont instanceof Window)) {
+                    cont = cont.getParent();
+                }
+                if (cont != null) {
+                    LWWindowPeer peer = (LWWindowPeer) cont.getPeer();
+                    if (peer != null) {
+                        return ((CPlatformWindow) peer.getPlatformWindow()).getContentView().getAWTView();
+                    }
+                }
+                return 0L;
+            }
+        }, (Component)ax);
+    }
 }
--- a/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -264,6 +264,8 @@
                 final double localY = boundsUnion.getY();
 
                 final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
+                if (componentLocation == null) return ret;
+
                 final double screenX = componentLocation.getX() + localX;
                 final double screenY = componentLocation.getY() + localY;
 
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Thu Jan 12 06:59:38 2017 +0000
@@ -34,6 +34,7 @@
 import java.awt.event.InputEvent;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.KeyEvent;
+import java.util.Locale;
 
 /**
  * Translates NSEvents/NPCocoaEvents into AWT events.
@@ -173,6 +174,16 @@
                 }
             }
 
+            // If Pinyin Simplified input method is selected, CAPS_LOCK key is supposed to switch
+            // input to latin letters.
+            // It is necessary to use testCharIgnoringModifiers instead of testChar for event
+            // generation in such case to avoid uppercase letters in text components.
+            LWCToolkit lwcToolkit = (LWCToolkit)Toolkit.getDefaultToolkit();
+            if (lwcToolkit.getLockingKeyState(KeyEvent.VK_CAPS_LOCK) &&
+                    Locale.SIMPLIFIED_CHINESE.equals(lwcToolkit.getDefaultKeyboardLocale())) {
+                testChar = testCharIgnoringModifiers;
+            }
+
             jkeyCode = out[0];
             jkeyLocation = out[1];
             jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(eventType) :
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Thu Jan 12 06:59:38 2017 +0000
@@ -427,9 +427,6 @@
 
     @Override // PlatformWindow
     public void dispose() {
-        if (owner != null) {
-            CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), getNSWindowPtr());
-        }
         contentView.dispose();
         nativeDispose(getNSWindowPtr());
         CPlatformWindow.super.dispose();
@@ -526,25 +523,6 @@
     public void setVisible(boolean visible) {
         final long nsWindowPtr = getNSWindowPtr();
 
-        // Process parent-child relationship when hiding
-        if (!visible) {
-            // Unparent my children
-            for (Window w : target.getOwnedWindows()) {
-                WindowPeer p = (WindowPeer)w.getPeer();
-                if (p instanceof LWWindowPeer) {
-                    CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
-                    if (pw != null && pw.isVisible()) {
-                        CWrapper.NSWindow.removeChildWindow(nsWindowPtr, pw.getNSWindowPtr());
-                    }
-                }
-            }
-
-            // Unparent myself
-            if (owner != null && owner.isVisible()) {
-                CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
-            }
-        }
-
         // Configure stuff
         updateIconImages();
         updateFocusabilityForAutoRequestFocus(false);
@@ -618,19 +596,19 @@
 
         // Manage parent-child relationship when showing
         if (visible) {
-            // Add myself as a child
+            // Order myself above my parent
             if (owner != null && owner.isVisible()) {
-                CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
+                CWrapper.NSWindow.orderWindow(nsWindowPtr, CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
                 applyWindowLevel(target);
             }
 
-            // Add my own children to myself
+            // Order my own children above myself
             for (Window w : target.getOwnedWindows()) {
                 WindowPeer p = (WindowPeer)w.getPeer();
                 if (p instanceof LWWindowPeer) {
                     CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow();
                     if (pw != null && pw.isVisible()) {
-                        CWrapper.NSWindow.addChildWindow(nsWindowPtr, pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove);
+                        CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, nsWindowPtr);
                         pw.applyWindowLevel(w);
                     }
                 }
@@ -1059,8 +1037,8 @@
             // Order the window to front of the stack of child windows
             final long nsWindowSelfPtr = getNSWindowPtr();
             final long nsWindowOwnerPtr = owner.getNSWindowPtr();
-            CWrapper.NSWindow.removeChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr);
-            CWrapper.NSWindow.addChildWindow(nsWindowOwnerPtr, nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove);
+            CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
+            CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
         }
 
         applyWindowLevel(target);
--- a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Thu Jan 12 06:59:38 2017 +0000
@@ -221,15 +221,6 @@
         synchronized (lock) {
             final long nsWindowPtr = getNSWindowPtr();
 
-            // Process parent-child relationship when hiding
-            if (!visible) {
-                // Unparent myself
-                if (owner != null && owner.isVisible()) {
-                    CWrapper.NSWindow.removeChildWindow(
-                            owner.getNSWindowPtr(), nsWindowPtr);
-                }
-            }
-
             // Actually show or hide the window
             if (visible) {
                 CWrapper.NSWindow.orderFront(nsWindowPtr);
@@ -241,10 +232,10 @@
 
             // Manage parent-child relationship when showing
             if (visible) {
-                // Add myself as a child
+                // Order myself above my parent
                 if (owner != null && owner.isVisible()) {
-                    CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(),
-                            nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
+                    CWrapper.NSWindow.orderWindow(nsWindowPtr,
+                            CWrapper.NSWindow.NSWindowAbove, owner.getNSWindowPtr());
 
                     // do not allow security warning to be obscured by other windows
                     applyWindowLevel(ownerWindow);
--- a/src/macosx/native/sun/awt/AWTView.h	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/AWTView.h	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,8 @@
 - (void) deliverJavaMouseEvent: (NSEvent *) event;
 - (jobject) awtComponent:(JNIEnv *)env;
 
++ (AWTView *) awtView:(JNIEnv *)env ofAccessible:(jobject)jaccessible;
+
 // Input method-related events
 - (void)setInputMethod:(jobject)inputMethod;
 - (void)abandonInput;
--- a/src/macosx/native/sun/awt/AWTView.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/AWTView.m	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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 "LWCToolkit.h"
 #import "JavaComponentAccessibility.h"
 #import "JavaTextAccessibility.h"
+#import "JavaAccessibilityUtilities.h"
 #import "GeomUtilities.h"
 #import "OSVersion.h"
 #import "CGLLayer.h"
@@ -132,7 +133,7 @@
     self.cglLayer = nil;
 
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
-    (*env)->DeleteGlobalRef(env, m_cPlatformView);
+    (*env)->DeleteWeakGlobalRef(env, m_cPlatformView);
     m_cPlatformView = NULL;
 
     if (fInputMethodLOCKABLE != NULL)
@@ -402,7 +403,12 @@
 
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
     static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
-    JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
+
+    jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
+    if (!(*env)->IsSameObject(env, jlocal, NULL)) {
+        JNFCallVoidMethod(env, jlocal, jm_deliverMouseEvent, jEvent);
+        (*env)->DeleteLocalRef(env, jlocal);
+    }
 }
 
 - (void) resetTrackingArea {
@@ -463,7 +469,12 @@
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
     static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
                             "deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
-    JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jevent);
+
+    jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
+    if (!(*env)->IsSameObject(env, jlocal, NULL)) {
+        JNFCallVoidMethod(env, jlocal, jm_deliverKeyEvent, jevent);
+        (*env)->DeleteLocalRef(env, jlocal);
+    }
 
     if (characters != NULL) {
         (*env)->DeleteLocalRef(env, characters);
@@ -478,7 +489,12 @@
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
     static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V");
-    JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h);
+
+    jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
+    if (!(*env)->IsSameObject(env, jlocal, NULL)) {
+        JNFCallVoidMethod(env, jlocal, jm_deliverResize, x,y,w,h);
+        (*env)->DeleteLocalRef(env, jlocal);
+    }
 }
 
 
@@ -507,7 +523,12 @@
 */
         static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView");
         static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V");
-        JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent);
+
+        jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
+        if (!(*env)->IsSameObject(env, jlocal, NULL)) {
+            JNFCallVoidMethod(env, jlocal, jm_deliverWindowDidExposeEvent);
+            (*env)->DeleteLocalRef(env, jlocal);
+        }
 /*
         }
 */
@@ -515,8 +536,10 @@
 }
 
 -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint {
-    if ((codePoint >= 0x3000) && (codePoint <= 0x303F)) {
-        // Code point is in 'CJK Symbols and Punctuation' Unicode block.
+    if (((codePoint >= 0x3000) && (codePoint <= 0x303F)) ||
+        ((codePoint >= 0xFF00) && (codePoint <= 0xFFEF))) {
+        // Code point is in 'CJK Symbols and Punctuation' or
+        // 'Halfwidth and Fullwidth Forms' Unicode block.
         return YES;
     }
     return NO;
@@ -535,7 +558,13 @@
         }
         return NULL;
     }
-    jobject peer = JNFGetObjectField(env, m_cPlatformView, jf_Peer);
+
+    jobject peer = NULL;
+    jobject jlocal = (*env)->NewLocalRef(env, m_cPlatformView);
+    if (!(*env)->IsSameObject(env, jlocal, NULL)) {
+        peer = JNFGetObjectField(env, jlocal, jf_Peer);
+        (*env)->DeleteLocalRef(env, jlocal);
+    }
     static JNF_CLASS_CACHE(jc_LWWindowPeer, "sun/lwawt/LWWindowPeer");
     static JNF_MEMBER_CACHE(jf_Target, jc_LWWindowPeer, "target", "Ljava/awt/Component;");
     if (peer == NULL) {
@@ -543,12 +572,27 @@
         JNFDumpJavaStack(env);
         return NULL;
     }
-    return JNFGetObjectField(env, peer, jf_Target);
+    jobject comp = JNFGetObjectField(env, peer, jf_Target);
+    (*env)->DeleteLocalRef(env, peer);
+    return comp;
+}
+
++ (AWTView *) awtView:(JNIEnv*)env ofAccessible:(jobject)jaccessible
+{
+    static JNF_STATIC_MEMBER_CACHE(jm_getAWTView, sjc_CAccessibility, "getAWTView", "(Ljavax/accessibility/Accessible;)J");
+
+    jlong jptr = JNFCallStaticLongMethod(env, jm_getAWTView, jaccessible);
+    if (jptr == 0) return nil;
+
+    return (AWTView *)jlong_to_ptr(jptr);
 }
 
 - (id)getAxData:(JNIEnv*)env
 {
-    return [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:[self awtComponent:env] withIndex:-1 withView:self withJavaRole:nil] autorelease];
+    jobject jcomponent = [self awtComponent:env];
+    id ax = [[[JavaComponentAccessibility alloc] initWithParent:self withEnv:env withAccessible:jcomponent withIndex:-1 withView:self withJavaRole:nil] autorelease];
+    (*env)->DeleteLocalRef(env, jcomponent);
+    return ax;
 }
 
 - (NSArray *)accessibilityAttributeNames
@@ -1291,7 +1335,7 @@
 JNF_COCOA_ENTER(env);
 
     NSRect rect = NSMakeRect(originX, originY, width, height);
-    jobject cPlatformView = (*env)->NewGlobalRef(env, obj);
+    jobject cPlatformView = (*env)->NewWeakGlobalRef(env, obj);
 
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 
--- a/src/macosx/native/sun/awt/AWTWindow.h	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/AWTWindow.h	Thu Jan 12 06:59:38 2017 +0000
@@ -46,6 +46,7 @@
     NSWindow *nsWindow;
     AWTWindow *ownerWindow;
     jint preFullScreenLevel;
+    BOOL isMinimizing;
 }
 
 // An instance of either AWTWindow_Normal or AWTWindow_Panel
@@ -59,6 +60,7 @@
 @property (nonatomic) jint styleBits;
 @property (nonatomic) BOOL isEnabled;
 @property (nonatomic) jint preFullScreenLevel;
+@property (nonatomic) BOOL isMinimizing;
 
 
 - (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
--- a/src/macosx/native/sun/awt/AWTWindow.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/AWTWindow.m	Thu Jan 12 06:59:38 2017 +0000
@@ -184,6 +184,7 @@
 @synthesize isEnabled;
 @synthesize ownerWindow;
 @synthesize preFullScreenLevel;
+@synthesize isMinimizing;
 
 - (void) updateMinMaxSize:(BOOL)resizable {
     if (resizable) {
@@ -308,6 +309,7 @@
     [self.nsWindow release]; // the property retains the object already
 
     self.isEnabled = YES;
+    self.isMinimizing = NO;
     self.javaPlatformWindow = platformWindow;
     self.styleBits = bits;
     self.ownerWindow = owner;
@@ -427,6 +429,68 @@
     [super dealloc];
 }
 
+// Tests wheather the corresponding Java paltform window is visible or not
++ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {
+    BOOL isVisible = NO;
+    
+    if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {
+        AWTWindow *awtWindow = (AWTWindow *)[window delegate];
+        [AWTToolkit eventCountPlusPlus];
+        
+        JNIEnv *env = [ThreadUtilities getJNIEnv];
+        jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];
+        if (platformWindow != NULL) {
+            static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");
+            isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;
+            (*env)->DeleteLocalRef(env, platformWindow);
+            
+        }
+    }
+    return isVisible;
+}
+
+// Orders window's childs based on the current focus state
+- (void) orderChildWindows:(BOOL)focus {
+AWT_ASSERT_APPKIT_THREAD;
+
+    if (self.isMinimizing) {
+        // Do not perform any ordering, if iconify is in progress
+        return;
+    }
+
+    NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
+    NSWindow *window;
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([AWTWindow isJavaPlatformWindowVisible:window]) {
+            AWTWindow *awtWindow = (AWTWindow *)[window delegate];
+            AWTWindow *owner = awtWindow.ownerWindow;
+            if (IS(awtWindow.styleBits, ALWAYS_ON_TOP)) {
+                // Do not order 'always on top' windows
+                continue;
+            }
+            while (awtWindow.ownerWindow != nil) {
+                if (awtWindow.ownerWindow == self) {
+                    if (focus) {
+                        // Move the childWindow to floating level
+                        // so it will appear in front of its
+                        // parent which owns the focus
+                        [window setLevel:NSFloatingWindowLevel];
+                    } else {
+                        // Focus owner has changed, move the childWindow
+                        // back to normal window level
+                        [window setLevel:NSNormalWindowLevel];
+                    }
+                    // The childWindow should be displayed in front of
+                    // its nearest parentWindow
+                    [window orderWindow:NSWindowAbove relativeTo:[owner.nsWindow windowNumber]];
+                    break;
+                }
+                awtWindow = awtWindow.ownerWindow;
+            }
+        }
+    }
+}
+
 // NSWindow overrides
 - (BOOL) canBecomeKeyWindow {
 AWT_ASSERT_APPKIT_THREAD;
@@ -509,6 +573,30 @@
     // window exposing in _setVisible:(BOOL)
 }
 
+// Hides/shows window's childs during iconify/de-iconify operation
+- (void) iconifyChildWindows:(BOOL)iconify {
+AWT_ASSERT_APPKIT_THREAD;
+
+    NSEnumerator *windowEnumerator = [[NSApp windows]objectEnumerator];
+    NSWindow *window;
+    while ((window = [windowEnumerator nextObject]) != nil) {
+        if ([AWTWindow isJavaPlatformWindowVisible:window]) {
+            AWTWindow *awtWindow = (AWTWindow *)[window delegate];
+            while (awtWindow.ownerWindow != nil) {
+                if (awtWindow.ownerWindow == self) {
+                    if (iconify) {
+                        [window orderOut:window];
+                    } else {
+                        [window orderFront:window];
+                    }
+                    break;
+                }
+                awtWindow = awtWindow.ownerWindow;
+            }
+        }
+    }
+}
+
 - (void) _deliverIconify:(BOOL)iconify {
 AWT_ASSERT_APPKIT_THREAD;
 
@@ -522,16 +610,28 @@
     }
 }
 
+- (void)windowWillMiniaturize:(NSNotification *)notification {
+AWT_ASSERT_APPKIT_THREAD;
+
+    self.isMinimizing = YES;
+    // Excplicitly make myself a key window to avoid possible
+    // negative visual effects during iconify operation
+    [self.nsWindow makeKeyAndOrderFront:self.nsWindow];
+    [self iconifyChildWindows:YES];
+}
+
 - (void)windowDidMiniaturize:(NSNotification *)notification {
 AWT_ASSERT_APPKIT_THREAD;
 
     [self _deliverIconify:JNI_TRUE];
+    self.isMinimizing = NO;
 }
 
 - (void)windowDidDeminiaturize:(NSNotification *)notification {
 AWT_ASSERT_APPKIT_THREAD;
 
     [self _deliverIconify:JNI_FALSE];
+    [self iconifyChildWindows:NO];
 }
 
 - (void) _deliverWindowFocusEvent:(BOOL)focused oppositeWindow:(AWTWindow *)opposite {
@@ -577,6 +677,7 @@
     [AWTWindow setLastKeyWindow:nil];
 
     [self _deliverWindowFocusEvent:YES oppositeWindow: opposite];
+    [self orderChildWindows:YES];
 }
 
 - (void) windowDidResignKey: (NSNotification *) notification {
@@ -604,6 +705,7 @@
     }
 
     [self _deliverWindowFocusEvent:NO oppositeWindow: opposite];
+    [self orderChildWindows:NO];
 }
 
 - (void) windowDidBecomeMain: (NSNotification *) notification {
--- a/src/macosx/native/sun/awt/JavaAccessibilityAction.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/JavaAccessibilityAction.m	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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,9 +35,9 @@
 {
     self = [super init];
     if (self) {
-        fAccessibleAction = JNFNewGlobalRef(env, accessibleAction);
+        fAccessibleAction = JNFNewWeakGlobalRef(env, accessibleAction);
         fIndex = index;
-        fComponent = JNFNewGlobalRef(env, component);
+        fComponent = JNFNewWeakGlobalRef(env, component);
     }
     return self;
 }
@@ -46,10 +46,10 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
-    JNFDeleteGlobalRef(env, fAccessibleAction);
+    JNFDeleteWeakGlobalRef(env, fAccessibleAction);
     fAccessibleAction = NULL;
 
-    JNFDeleteGlobalRef(env, fComponent);
+    JNFDeleteWeakGlobalRef(env, fComponent);
     fComponent = NULL;
 
     [super dealloc];
@@ -59,10 +59,10 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
-    JNFDeleteGlobalRef(env, fAccessibleAction);
+    JNFDeleteWeakGlobalRef(env, fAccessibleAction);
     fAccessibleAction = NULL;
 
-    JNFDeleteGlobalRef(env, fComponent);
+    JNFDeleteWeakGlobalRef(env, fComponent);
     fComponent = NULL;
 
     [super finalize];
@@ -75,7 +75,18 @@
 
     JNIEnv* env = [ThreadUtilities getJNIEnv];
 
-    return JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fComponent)); // AWT_THREADING Safe (AWTRunLoopMode)
+    jobject fCompLocal = (*env)->NewLocalRef(env, fComponent);
+    if ((*env)->IsSameObject(env, fCompLocal, NULL)) {
+        return @"unknown";
+    }
+    NSString *str = nil;
+    jobject jstr = JNFCallStaticObjectMethod(env, jm_getAccessibleActionDescription, fAccessibleAction, fIndex, fCompLocal);
+    if (jstr != NULL) {
+        NSString *str = JNFJavaToNSString(env, jstr); // AWT_THREADING Safe (AWTRunLoopMode)
+        (*env)->DeleteLocalRef(env, jstr);
+    }
+    (*env)->DeleteLocalRef(env, fCompLocal);
+    return str == nil ? @"unknown" : str;
 }
 
 - (void)perform
@@ -96,9 +107,9 @@
 {
     self = [super init];
     if (self) {
-        fTabGroup = JNFNewGlobalRef(env, tabGroup);
+        fTabGroup = JNFNewWeakGlobalRef(env, tabGroup);
         fIndex = index;
-        fComponent = JNFNewGlobalRef(env, component);
+        fComponent = JNFNewWeakGlobalRef(env, component);
     }
     return self;
 }
@@ -107,10 +118,10 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
-    JNFDeleteGlobalRef(env, fTabGroup);
+    JNFDeleteWeakGlobalRef(env, fTabGroup);
     fTabGroup = NULL;
 
-    JNFDeleteGlobalRef(env, fComponent);
+    JNFDeleteWeakGlobalRef(env, fComponent);
     fComponent = NULL;
 
     [super dealloc];
@@ -120,10 +131,10 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
-    JNFDeleteGlobalRef(env, fTabGroup);
+    JNFDeleteWeakGlobalRef(env, fTabGroup);
     fTabGroup = NULL;
 
-    JNFDeleteGlobalRef(env, fComponent);
+    JNFDeleteWeakGlobalRef(env, fComponent);
     fComponent = NULL;
 
     [super finalize];
--- a/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -77,7 +77,9 @@
     jobject axRole = JNFCallStaticObjectMethod(env, sjm_getAccessibleRole, axComponent, component); // AWT_THREADING Safe (AWTRunLoopMode)
     if (axRole == NULL) return @"unknown";
 
-    return JNFJavaToNSString(env, axRole);
+    NSString* str = JNFJavaToNSString(env, axRole);
+    (*env)->DeleteLocalRef(env, axRole);
+    return str;
 }
 
 jobject getAxSelection(JNIEnv *env, jobject axContext, jobject component)
@@ -126,21 +128,27 @@
 {
     static JNF_STATIC_MEMBER_CACHE(jm_VERTICAL, sjc_AccessibleState, "VERTICAL", "Ljavax/accessibility/AccessibleState;");
     jobject axVertState = JNFGetStaticObjectField(env, jm_VERTICAL);
-    return containsAxState(env, axContext, axVertState, component);
+    BOOL vertical = containsAxState(env, axContext, axVertState, component);
+    (*env)->DeleteLocalRef(env, axVertState);
+    return vertical;
 }
 
 BOOL isHorizontal(JNIEnv *env, jobject axContext, jobject component)
 {
     static JNF_STATIC_MEMBER_CACHE(jm_HORIZONTAL, sjc_AccessibleState, "HORIZONTAL", "Ljavax/accessibility/AccessibleState;");
     jobject axHorizState = JNFGetStaticObjectField(env, jm_HORIZONTAL);
-    return containsAxState(env, axContext, axHorizState, component);
+    BOOL horizontal = containsAxState(env, axContext, axHorizState, component);
+    (*env)->DeleteLocalRef(env, axHorizState);
+    return horizontal;
 }
 
 BOOL isShowing(JNIEnv *env, jobject axContext, jobject component)
 {
     static JNF_STATIC_MEMBER_CACHE(jm_SHOWING, sjc_AccessibleState, "SHOWING", "Ljavax/accessibility/AccessibleState;");
     jobject axVisibleState = JNFGetStaticObjectField(env, jm_SHOWING);
-    return containsAxState(env, axContext, axVisibleState, component);
+    BOOL showing = containsAxState(env, axContext, axVisibleState, component);
+    (*env)->DeleteLocalRef(env, axVisibleState);
+    return showing;
 }
 
 NSPoint getAxComponentLocationOnScreen(JNIEnv *env, jobject axComponent, jobject component)
--- a/src/macosx/native/sun/awt/JavaComponentAccessibility.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/JavaComponentAccessibility.m	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -75,7 +75,6 @@
 static NSMutableDictionary *sAttributeNamesForRoleCache = nil;
 static NSObject *sAttributeNamesLOCK = nil;
 
-
 @interface TabGroupAccessibility : JavaComponentAccessibility {
     NSInteger _numTabs;
 }
@@ -137,8 +136,11 @@
         fView = [view retain];
         fJavaRole = [javaRole retain];
 
-        fAccessible = JNFNewGlobalRef(env, accessible);
-        fComponent = JNFNewGlobalRef(env, [(AWTView *)fView awtComponent:env]);
+        fAccessible = (*env)->NewWeakGlobalRef(env, accessible);
+        
+        jobject jcomponent = [(AWTView *)fView awtComponent:env];
+        fComponent = (*env)->NewWeakGlobalRef(env, jcomponent);
+        (*env)->DeleteLocalRef(env, jcomponent);
 
         fIndex = index;
 
@@ -166,10 +168,10 @@
 
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
-    JNFDeleteGlobalRef(env, fAccessible);
+    (*env)->DeleteWeakGlobalRef(env, fAccessible);
     fAccessible = NULL;
 
-    JNFDeleteGlobalRef(env, fComponent);
+    (*env)->DeleteWeakGlobalRef(env, fComponent);
     fComponent = NULL;
 
     [fParent release];
@@ -198,10 +200,10 @@
 
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
-    JNFDeleteGlobalRef(env, fAccessible);
+    (*env)->DeleteWeakGlobalRef(env, fAccessible);
     fAccessible = NULL;
 
-    JNFDeleteGlobalRef(env, fComponent);
+    (*env)->DeleteWeakGlobalRef(env, fComponent);
     fComponent = NULL;
 
     [super finalize];
@@ -293,7 +295,7 @@
 
 + (NSArray *)childrenOfParent:(JavaComponentAccessibility *)parent withEnv:(JNIEnv *)env withChildrenCode:(NSInteger)whichChildren allowIgnored:(BOOL)allowIgnored
 {
-    jobjectArray jchildrenAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
+    jobjectArray jchildrenAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, parent->fAccessible, parent->fComponent, whichChildren, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
     if (jchildrenAndRoles == NULL) return nil;
 
     jsize arrayLen = (*env)->GetArrayLength(env, jchildrenAndRoles);
@@ -308,14 +310,21 @@
 
         NSString *childJavaRole = nil;
         if (jchildJavaRole != NULL) {
-            childJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jchildJavaRole, sjf_key));
+            jobject jkey = JNFGetObjectField(env, jchildJavaRole, sjf_key);
+            childJavaRole = JNFJavaToNSString(env, jkey);
+            (*env)->DeleteLocalRef(env, jkey);
         }
 
         JavaComponentAccessibility *child = [self createWithParent:parent accessible:jchild role:childJavaRole index:childIndex withEnv:env withView:parent->fView];
+        
+        (*env)->DeleteLocalRef(env, jchild);
+        (*env)->DeleteLocalRef(env, jchildJavaRole);
+        
         [children addObject:child];
         childIndex++;
     }
-
+    (*env)->DeleteLocalRef(env, jchildrenAndRoles);
+    
     return children;
 }
 
@@ -324,7 +333,7 @@
     jobject jcomponent = [(AWTView *)view awtComponent:env];
     jint index = JNFCallStaticIntMethod(env, sjm_getAccessibleIndexInParent, jaccessible, jcomponent);
     NSString *javaRole = getJavaRole(env, jaccessible, jcomponent);
-
+    (*env)->DeleteLocalRef(env, jcomponent);
     return [self createWithAccessible:jaccessible role:javaRole index:index withEnv:env withView:view];
 }
 
@@ -339,7 +348,10 @@
     jobject jCAX = [JavaComponentAccessibility getCAccessible:jaccessible withEnv:env];
     if (jCAX == NULL) return nil;
     JavaComponentAccessibility *value = (JavaComponentAccessibility *) jlong_to_ptr(JNFGetLongField(env, jCAX, jf_ptr));
-    if (value != nil) return [[value retain] autorelease];
+    if (value != nil) {
+        (*env)->DeleteLocalRef(env, jCAX);
+        return [[value retain] autorelease];
+    }
 
     // otherwise, create a new instance
     JavaComponentAccessibility *newChild = nil;
@@ -362,6 +374,7 @@
     // must hard CFRetain() pointer poked into Java object
     CFRetain(newChild);
     JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild));
+    (*env)->DeleteLocalRef(env, jCAX);
 
     // return autoreleased instance
     return [newChild autorelease];
@@ -394,7 +407,7 @@
 
     // Get all the other accessibility attributes states we need in one swell foop.
     // javaRole isn't pulled in because we need protected access to AccessibleRole.key
-    jbooleanArray attributeStates = JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
+    jbooleanArray attributeStates = (jbooleanArray)JNFCallStaticObjectMethod(env, jm_getInitialAttributeStates, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (attributeStates == NULL) return nil;
     jboolean *attributeStatesArray = (*env)->GetBooleanArrayElements(env, attributeStates, 0);
     if (attributeStatesArray == NULL) {
@@ -489,6 +502,7 @@
         JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent];
         [fActions setObject:action forKey:[self isMenu] ? NSAccessibilityPickAction : NSAccessibilityPressAction];
         [action release];
+        (*env)->DeleteLocalRef(env, axAction);
     }
 }
 
@@ -499,7 +513,9 @@
 
 - (id)parent
 {
+    static JNF_CLASS_CACHE(sjc_Window, "java/awt/Window");
     static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleParent, sjc_CAccessibility, "getAccessibleParent", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/Accessible;");
+    static JNF_STATIC_MEMBER_CACHE(sjm_getSwingAccessible, sjc_CAccessible, "getSwingAccessible", "(Ljavax/accessibility/Accessible;)Ljavax/accessibility/Accessible;");
 
     if(fParent == nil) {
         JNIEnv* env = [ThreadUtilities getJNIEnv];
@@ -509,10 +525,21 @@
         if (jparent == NULL) {
             fParent = fView;
         } else {
-            fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:fView];
+            AWTView *view = fView;
+            jobject jax = JNFCallStaticObjectMethod(env, sjm_getSwingAccessible, fAccessible);
+
+            if (JNFIsInstanceOf(env, jax, &sjc_Window)) {
+                // In this case jparent is an owner toplevel and we should retrieve its own view
+                view = [AWTView awtView:env ofAccessible:jparent];
+            }
+            if (view != nil) {
+                fParent = [JavaComponentAccessibility createWithAccessible:jparent withEnv:env withView:view];
+            }
             if (fParent == nil) {
                 fParent = fView;
             }
+            (*env)->DeleteLocalRef(env, jparent);
+            (*env)->DeleteLocalRef(env, jax );
         }
         [fParent retain];
     }
@@ -560,7 +587,10 @@
         return NO;
     }
 
-    return isShowing(env, [self axContextWithEnv:env], fComponent);
+    jobject axContext = [self axContextWithEnv:env];
+    BOOL showing = isShowing(env, axContext, fComponent);
+    (*env)->DeleteLocalRef(env, axContext);
+    return showing;
 }
 
 // the array of names for each role is cached in the sAttributeNamesForRoleCache
@@ -737,7 +767,12 @@
     JNIEnv* env = [ThreadUtilities getJNIEnv];
 
     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return JNFJavaToNSString(env, val);
+    if (val == NULL) {
+        return @"unknown";
+    }
+    NSString* str = JNFJavaToNSString(env, val);
+    (*env)->DeleteLocalRef(env, val);
+    return str;
 }
 
 - (BOOL)accessibilityIsHelpAttributeSettable
@@ -753,7 +788,12 @@
     JNIEnv* env = [ThreadUtilities getJNIEnv];
 
     jobject axValue = JNFCallStaticObjectMethod(env, jm_getMaximumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return JNFJavaToNSNumber(env, axValue);
+    if (axValue == NULL) {
+        return [NSNumber numberWithInt:0];
+    }
+    NSNumber* num = JNFJavaToNSNumber(env, axValue);
+    (*env)->DeleteLocalRef(env, axValue);
+    return num;
 }
 
 - (BOOL)accessibilityIsMaxValueAttributeSettable
@@ -769,7 +809,12 @@
     JNIEnv* env = [ThreadUtilities getJNIEnv];
 
     jobject axValue = JNFCallStaticObjectMethod(env, jm_getMinimumAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return JNFJavaToNSNumber(env, axValue);
+    if (axValue == NULL) {
+        return [NSNumber numberWithInt:0];
+    }
+    NSNumber* num = JNFJavaToNSNumber(env, axValue);
+    (*env)->DeleteLocalRef(env, axValue);
+    return num;
 }
 
 - (BOOL)accessibilityIsMinValueAttributeSettable
@@ -784,13 +829,16 @@
 
     // cmcnote - should batch these two calls into one that returns an array of two bools, one for vertical and one for horiz
     if (isVertical(env, axContext, fComponent)) {
+        (*env)->DeleteLocalRef(env, axContext);
         return NSAccessibilityVerticalOrientationValue;
     }
 
     if (isHorizontal(env, axContext, fComponent)) {
+        (*env)->DeleteLocalRef(env, axContext);
         return NSAccessibilityHorizontalOrientationValue;
     }
 
+    (*env)->DeleteLocalRef(env, axContext);
     return nil;
 }
 
@@ -822,6 +870,7 @@
     // Get the java screen coords, and make a NSPoint of the bottom left of the AxComponent.
     NSSize size = getAxComponentSize(env, axComponent, fComponent);
     NSPoint point = getAxComponentLocationOnScreen(env, axComponent, fComponent);
+    (*env)->DeleteLocalRef(env, axComponent);
 
     point.y += size.height;
 
@@ -871,8 +920,9 @@
         JNIEnv* env = [ThreadUtilities getJNIEnv];
 
         jobject axRole = JNFCallStaticObjectMethod(env, jm_getAccessibleRoleDisplayString, fAccessible, fComponent);
-        if(axRole != NULL) {
+        if (axRole != NULL) {
             value = JNFJavaToNSString(env, axRole);
+            (*env)->DeleteLocalRef(env, axRole);
         } else {
             value = @"unknown";
         }
@@ -907,7 +957,9 @@
 - (NSValue *)accessibilitySizeAttribute {
     JNIEnv* env = [ThreadUtilities getJNIEnv];
     jobject axComponent = JNFCallStaticObjectMethod(env, sjm_getAccessibleComponent, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)];
+    NSValue* size = [NSValue valueWithSize:getAxComponentSize(env, axComponent, fComponent)];
+    (*env)->DeleteLocalRef(env, axComponent);
+    return size;
 }
 
 - (BOOL)accessibilityIsSizeAttributeSettable
@@ -966,7 +1018,12 @@
     JNIEnv* env = [ThreadUtilities getJNIEnv];
 
     jobject val = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return JNFJavaToNSString(env, val);
+    if (val == NULL) {
+        return @"unknown";
+    }
+    NSString* str = JNFJavaToNSString(env, val);
+    (*env)->DeleteLocalRef(env, val);
+    return str;
 }
 
 - (BOOL)accessibilityIsTitleAttributeSettable
@@ -998,8 +1055,20 @@
     // a text value is taken care of in JavaTextAccessibility
 
     // cmcnote should coalesce these calls into one java call
+    NSNumber *num = nil;
     jobject axValue = JNFCallStaticObjectMethod(env, sjm_getAccessibleValue, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return JNFJavaToNSNumber(env, JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent)); // AWT_THREADING Safe (AWTRunLoop)
+    if (axValue != NULL) {
+        jobject str = JNFCallStaticObjectMethod(env, jm_getCurrentAccessibleValue, axValue, fComponent);
+        if (str != NULL) {
+            num = JNFJavaToNSNumber(env, str); // AWT_THREADING Safe (AWTRunLoop)
+            (*env)->DeleteLocalRef(env, str);
+        }
+        (*env)->DeleteLocalRef(env, axValue);
+    }
+    if (num == nil) {
+        num = [NSNumber numberWithInt:0];
+    }
+    return num;
 }
 
 - (BOOL)accessibilityIsValueAttributeSettable
@@ -1098,7 +1167,10 @@
     id value = nil;
     if (JNFIsInstanceOf(env, jparent, &jc_Container)) {
         jobject jaccessible = JNFCallStaticObjectMethod(env, jm_accessibilityHitTest, jparent, (jfloat)point.x, (jfloat)point.y); // AWT_THREADING Safe (AWTRunLoop)
-        value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
+        if (jaccessible != NULL) {
+            value = [JavaComponentAccessibility createWithAccessible:jaccessible withEnv:env withView:fView];
+            (*env)->DeleteLocalRef(env, jaccessible);
+        }
     }
 
     if (value == nil) {
@@ -1130,6 +1202,7 @@
         if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
             value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
         }
+        (*env)->DeleteLocalRef(env, focused);
     }
 
     if (value == nil) {
@@ -1236,38 +1309,46 @@
     for (i = 0; i < _numTabs; i++) {
         aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i];
         if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
+            (*env)->DeleteLocalRef(env, selAccessible);
             return aTab;
         }
     }
-
+    (*env)->DeleteLocalRef(env, selAccessible);
     return nil;
 }
 
 - (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
 {
-    jobjectArray jtabsAndRoles = JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
+    jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
     if(jtabsAndRoles == NULL) return nil;
 
     jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
-    if (arrayLen == 0) return nil;
-
+    if (arrayLen == 0) {
+        (*env)->DeleteLocalRef(env, jtabsAndRoles);
+        return nil;
+    }
     NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
 
     // all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
     jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
-    if (jtabJavaRole == NULL) return nil;
-
-    NSString *tabJavaRole = JNFJavaToNSString(env, JNFGetObjectField(env, jtabJavaRole, sjf_key));
+    if (jtabJavaRole == NULL) {
+        (*env)->DeleteLocalRef(env, jtabsAndRoles);
+        return nil;
+    }
+    jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
+    NSString *tabJavaRole = JNFJavaToNSString(env, jkey);
+    (*env)->DeleteLocalRef(env, jkey);
 
     NSInteger i;
     NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
     for(i = 0; i < arrayLen; i+=2) {
         jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
         JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
+        (*env)->DeleteLocalRef(env, jtab);
         [tabs addObject:tab];
         tabIndex++;
     }
-
+    (*env)->DeleteLocalRef(env, jtabsAndRoles);
     return tabs;
 }
 
@@ -1286,7 +1367,9 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject axContext = [self axContextWithEnv:env];
-    return [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
+    id tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
+    (*env)->DeleteLocalRef(env, axContext);
+    return tabs;
 }
 
 - (BOOL)accessibilityIsTabsAttributeSettable
@@ -1306,7 +1389,9 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject axContext = [self axContextWithEnv:env];
-    return [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
+    NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
+    (*env)->DeleteLocalRef(env, axContext);
+    return cont;
 }
 
 - (BOOL)accessibilityIsContentsAttributeSettable
@@ -1319,7 +1404,9 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject axContext = [self axContextWithEnv:env];
-    return [self currentTabWithEnv:env withAxContext:axContext];
+    id val = [self currentTabWithEnv:env withAxContext:axContext];
+    (*env)->DeleteLocalRef(env, axContext);
+    return val;
 }
 
 - (BOOL)accessibilityIsValueAttributeSettable
@@ -1336,6 +1423,7 @@
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject axContext = [self axContextWithEnv:env];
     setAxContextSelection(env, axContext, fIndex, fComponent);
+    (*env)->DeleteLocalRef(env, axContext);
 }
 
 - (NSArray *)accessibilityChildrenAttribute
@@ -1371,6 +1459,7 @@
                 result = children;
             }
         }
+        (*env)->DeleteLocalRef(env, axContext);
     } else {
         result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
     }
@@ -1389,7 +1478,7 @@
     self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
     if (self) {
         if (tabGroup != NULL) {
-            fTabGroupAxContext = JNFNewGlobalRef(env, tabGroup);
+            fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup);
         } else {
             fTabGroupAxContext = NULL;
         }
@@ -1402,7 +1491,7 @@
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
     if (fTabGroupAxContext != NULL) {
-        JNFDeleteGlobalRef(env, fTabGroupAxContext);
+        JNFDeleteWeakGlobalRef(env, fTabGroupAxContext);
         fTabGroupAxContext = NULL;
     }
 
@@ -1414,7 +1503,7 @@
     JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
 
     if (fTabGroupAxContext != NULL) {
-        JNFDeleteGlobalRef(env, fTabGroupAxContext);
+        JNFDeleteWeakGlobalRef(env, fTabGroupAxContext);
         fTabGroupAxContext = NULL;
     }
 
@@ -1425,9 +1514,14 @@
 {
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject axContext = [self axContextWithEnv:env];
+    jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
 
     // Returns the current selection of the page tab list
-    return [NSNumber numberWithBool:ObjectEquals(env, axContext, getAxContextSelection(env, [self tabGroup], fIndex, fComponent), fComponent)];
+    id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)];
+
+    (*env)->DeleteLocalRef(env, selAccessible);
+    (*env)->DeleteLocalRef(env, axContext);
+    return val;
 }
 
 - (void)getActionsWithEnv:(JNIEnv *)env
@@ -1442,7 +1536,8 @@
     if (fTabGroupAxContext == NULL) {
         JNIEnv* env = [ThreadUtilities getJNIEnv];
         jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env];
-        fTabGroupAxContext = JNFNewGlobalRef(env, tabGroupAxContext);
+        fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
+        (*env)->DeleteLocalRef(env, tabGroupAxContext);
     }
     return fTabGroupAxContext;
 }
@@ -1477,8 +1572,10 @@
         if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
             jobject elementAxContext = [aElement axContextWithEnv:env];
             if (isHorizontal(env, elementAxContext, fComponent)) {
+                (*env)->DeleteLocalRef(env, elementAxContext);
                 return aElement;
             }
+            (*env)->DeleteLocalRef(env, elementAxContext);
         }
     }
 
@@ -1504,8 +1601,10 @@
         if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
             jobject elementAxContext = [aElement axContextWithEnv:env];
             if (isVertical(env, elementAxContext, fComponent)) {
+                (*env)->DeleteLocalRef(env, elementAxContext);
                 return aElement;
             }
+            (*env)->DeleteLocalRef(env, elementAxContext);
         }
     }
 
--- a/src/macosx/native/sun/awt/JavaTextAccessibility.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/awt/JavaTextAccessibility.m	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -112,7 +112,9 @@
         // if it's static text, the AppKit AXValue is the java accessibleName
         jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
         if (axName != NULL) {
-            return JNFJavaToNSString(env, axName);
+            NSString* str = JNFJavaToNSString(env, axName);
+            (*env)->DeleteLocalRef(env, axName);
+            return str;
         }
         // value is still nil if no accessibleName for static text. Below, try to get the accessibleText.
     }
@@ -120,12 +122,18 @@
     // cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
     jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (axText == NULL) return nil;
-
+    (*env)->DeleteLocalRef(env, axText);
+    
     jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (axEditableText == NULL) return nil;
 
     static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
-    NSString *string = JNFJavaToNSString(env, JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent)); // AWT_THREADING Safe (AWTRunLoop)
+    jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
+    NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
+
+    (*env)->DeleteLocalRef(env, jrange);
+    (*env)->DeleteLocalRef(env, axEditableText);
+    
     if (string == nil) string = @"";
     return string;
 }
@@ -139,6 +147,7 @@
     JNIEnv* env = [ThreadUtilities getJNIEnv];
     jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (axEditableText == NULL) return NO;
+    (*env)->DeleteLocalRef(env, axEditableText);
     return YES;
 }
 
@@ -157,7 +166,9 @@
     static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
     jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
     if (axText == NULL) return @"";
-    return JNFJavaToNSString(env, axText);
+    NSString* str = JNFJavaToNSString(env, axText);
+    (*env)->DeleteLocalRef(env, axText);
+    return str;
 }
 
 - (BOOL)accessibilityIsSelectedTextAttributeSettable
@@ -220,7 +231,9 @@
     // also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
-    return [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
+    NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
+    (*env)->DeleteLocalRef(env, axText);
+    return num;
 }
 
 - (BOOL)accessibilityIsNumberOfCharactersAttributeSettable
@@ -285,7 +298,7 @@
 
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
-    jdoubleArray axBounds = JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
+    jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
     if (axBounds == NULL) return nil;
 
     // We cheat because we know that the array is 4 elements long (x, y, width, height)
@@ -324,7 +337,7 @@
 
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
-    jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
+    jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
     if (axTextRange == NULL) return nil;
 
     return javaIntArrayToNSRangeValue(env,axTextRange);
@@ -350,10 +363,12 @@
 
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
-    jstring jstringForRange = JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
+    jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
 
     if (jstringForRange == NULL) return @"";
-    return JNFJavaToNSString(env, jstringForRange);
+    NSString* str = JNFJavaToNSString(env, jstringForRange);
+    (*env)->DeleteLocalRef(env, jstringForRange);
+    return str;
 }
 
 //
@@ -406,7 +421,7 @@
 
     JNIEnv *env = [ThreadUtilities getJNIEnv];
     static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
-    jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
+    jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
     if (axTextRange == NULL) return nil;
 
     return javaIntArrayToNSRangeValue(env, axTextRange);
--- a/src/macosx/native/sun/java2d/opengl/CGLLayer.h	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/java2d/opengl/CGLLayer.h	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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 @@
 @interface CGLLayer : CAOpenGLLayer
 {
 @private
-    JNFJObjectWrapper *javaLayer;
+    JNFWeakJObjectWrapper *javaLayer;
 
     // intermediate buffer, used the RQ lock to synchronize
     GLuint textureID;
@@ -45,7 +45,7 @@
 #endif /* REMOTELAYER */
 }
 
-@property (nonatomic, retain) JNFJObjectWrapper *javaLayer;
+@property (nonatomic, retain) JNFWeakJObjectWrapper *javaLayer;
 @property (readwrite, assign) GLuint textureID;
 @property (readwrite, assign) GLenum target;
 @property (readwrite, assign) float textureWidth;
@@ -57,7 +57,7 @@
 @property (nonatomic, retain) NSObject<JRSRemoteLayer> *jrsRemoteLayer;
 #endif
 
-- (id) initWithJavaLayer:(JNFJObjectWrapper *)javaLayer;
+- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)javaLayer;
 - (void) blitTexture;
 @end
 
--- a/src/macosx/native/sun/java2d/opengl/CGLLayer.m	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/macosx/native/sun/java2d/opengl/CGLLayer.m	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -46,7 +46,7 @@
 @synthesize jrsRemoteLayer;
 #endif
 
-- (id) initWithJavaLayer:(JNFJObjectWrapper *)layer;
+- (id) initWithJavaLayer:(JNFWeakJObjectWrapper *)layer;
 {
 AWT_ASSERT_APPKIT_THREAD;
     // Initialize ourselves
@@ -133,6 +133,15 @@
 {
     AWT_ASSERT_APPKIT_THREAD;
 
+    JNIEnv *env = [ThreadUtilities getJNIEnv];
+    static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
+    static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
+
+    jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
+    if ((*env)->IsSameObject(env, javaLayerLocalRef, NULL)) {
+        return;
+    }
+
     // Set the current context to the one given to us.
     CGLSetCurrentContext(glContext);
 
@@ -141,12 +150,7 @@
     glClear(GL_COLOR_BUFFER_BIT);
 
     glViewport(0, 0, textureWidth, textureHeight);
-    
-    JNIEnv *env = [ThreadUtilities getJNIEnv];
-    static JNF_CLASS_CACHE(jc_JavaLayer, "sun/java2d/opengl/CGLLayer");
-    static JNF_MEMBER_CACHE(jm_drawInCGLContext, jc_JavaLayer, "drawInCGLContext", "()V");
 
-    jobject javaLayerLocalRef = [self.javaLayer jObjectWithEnv:env];
     JNFCallVoidMethod(env, javaLayerLocalRef, jm_drawInCGLContext);
     (*env)->DeleteLocalRef(env, javaLayerLocalRef);
 
@@ -171,7 +175,7 @@
 
 JNF_COCOA_ENTER(env);
 
-    JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env];
+    JNFWeakJObjectWrapper *javaLayer = [JNFWeakJObjectWrapper wrapperWithJObject:obj withEnv:env];
 
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
             AWT_ASSERT_APPKIT_THREAD;
--- a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,6 +26,8 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.ProviderException;
+
 
 /**
  * This class represents ciphers in cipher block chaining (CBC) mode.
@@ -122,31 +124,31 @@
      *
      * <p>The input plain text <code>plain</code>, starting at
      * <code>plainOffset</code> and ending at
-     * <code>(plainOffset + len - 1)</code>, is encrypted.
+     * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
      * The result is stored in <code>cipher</code>, starting at
      * <code>cipherOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>plainLen</code> is a multiple of the embedded cipher's block size,
-     * as any excess bytes are ignored.
-     *
      * @param plain the buffer with the input data to be encrypted
      * @param plainOffset the offset in <code>plain</code>
      * @param plainLen the length of the input data
      * @param cipher the buffer for the result
      * @param cipherOffset the offset in <code>cipher</code>
+     * @exception ProviderException if <code>len</code> is not
+     * a multiple of the block size
      * @return the length of the encrypted data
      */
     int encrypt(byte[] plain, int plainOffset, int plainLen,
                 byte[] cipher, int cipherOffset)
     {
-        int i;
+        if ((plainLen % blockSize) != 0) {
+            throw new ProviderException("Internal error in input buffering");
+        }
         int endIndex = plainOffset + plainLen;
 
         for (; plainOffset < endIndex;
              plainOffset+=blockSize, cipherOffset += blockSize) {
-            for (i=0; i<blockSize; i++) {
-                k[i] = (byte)(plain[i+plainOffset] ^ r[i]);
+            for (int i = 0; i < blockSize; i++) {
+                k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
             }
             embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
             System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
@@ -159,14 +161,10 @@
      *
      * <p>The input cipher text <code>cipher</code>, starting at
      * <code>cipherOffset</code> and ending at
-     * <code>(cipherOffset + len - 1)</code>, is decrypted.
+     * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
      * The result is stored in <code>plain</code>, starting at
      * <code>plainOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>cipherLen</code> is a multiple of the embedded cipher's block
-     * size, as any excess bytes are ignored.
-     *
      * <p>It is also the application's responsibility to make sure that
      * <code>init</code> has been called before this method is called.
      * (This check is omitted here, to avoid double checking.)
@@ -176,23 +174,23 @@
      * @param cipherLen the length of the input data
      * @param plain the buffer for the result
      * @param plainOffset the offset in <code>plain</code>
+     * @exception ProviderException if <code>len</code> is not
+     * a multiple of the block size
      * @return the length of the decrypted data
-     *
-     * @exception IllegalBlockSizeException if input data whose length does
-     * not correspond to the embedded cipher's block size is passed to the
-     * embedded cipher
      */
     int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
                 byte[] plain, int plainOffset)
     {
-        int i;
+        if ((cipherLen % blockSize) != 0) {
+            throw new ProviderException("Internal error in input buffering");
+        }
         int endIndex = cipherOffset + cipherLen;
 
         for (; cipherOffset < endIndex;
              cipherOffset += blockSize, plainOffset += blockSize) {
             embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0);
-            for (i = 0; i < blockSize; i++) {
-                plain[i+plainOffset] = (byte)(k[i] ^ r[i]);
+            for (int i = 0; i < blockSize; i++) {
+                plain[i + plainOffset] = (byte)(k[i] ^ r[i]);
             }
             System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
         }
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java	Thu Jan 12 06:59:38 2017 +0000
@@ -717,7 +717,7 @@
             len -= blockSize;
         }
         // do not count the trailing bytes which do not make up a unit
-        len = (len > 0 ? (len - (len%unitBytes)) : 0);
+        len = (len > 0 ? (len - (len % unitBytes)) : 0);
 
         // check output buffer capacity
         if ((output == null) ||
@@ -729,6 +729,15 @@
 
         int outLen = 0;
         if (len != 0) { // there is some work to do
+            if ((input == output)
+                 && (outputOffset < (inputOffset + inputLen))
+                 && (inputOffset < (outputOffset + buffer.length))) {
+                // copy 'input' out to avoid its content being
+                // overwritten prematurely.
+                input = Arrays.copyOfRange(input, inputOffset,
+                    inputOffset + inputLen);
+                inputOffset = 0;
+            }
             if (len <= buffered) {
                 // all to-be-processed data are from 'buffer'
                 if (decrypting) {
@@ -741,37 +750,40 @@
                     System.arraycopy(buffer, len, buffer, 0, buffered);
                 }
             } else { // len > buffered
-                if ((input != output) && (buffered == 0)) {
-                    // all to-be-processed data are from 'input'
-                    // however, note that if 'input' and 'output' are the same,
-                    // then they can't be passed directly to the underlying cipher
-                    // engine operations as data may be overwritten before they
-                    // are read.
-                    if (decrypting) {
-                        outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset);
-                    } else {
-                        outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset);
+                int inputConsumed = len - buffered;
+                int temp;
+                if (buffered > 0) {
+                    int bufferCapacity = buffer.length - buffered;
+                    if (bufferCapacity != 0) {
+                        temp = Math.min(bufferCapacity, inputConsumed);
+                        if (unitBytes != blockSize) {
+                            temp -= ((buffered + temp) % unitBytes);
+                        }
+                        System.arraycopy(input, inputOffset, buffer, buffered, temp);
+                        inputOffset += temp;
+                        inputConsumed -= temp;
+                        inputLen -= temp;
+                        buffered += temp;
                     }
-                    inputOffset += len;
-                    inputLen -= len;
-                } else {
-                    // assemble the data using both 'buffer' and 'input'
-                    byte[] in = new byte[len];
-                    int inConsumed = len - buffered;
-                    if (buffered != 0) {
-                        System.arraycopy(buffer, 0, in, 0, buffered);
-                        buffered = 0;
+                    // process 'buffer'
+                    if (decrypting) {
+                         outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset);
+                    } else {
+                         outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
                     }
-                    if (inConsumed != 0) {
-                        System.arraycopy(input, inputOffset, in, len - inConsumed, inConsumed);
-                        inputOffset += inConsumed;
-                        inputLen -= inConsumed;
+                    outputOffset += outLen;
+                    buffered = 0;
+                }
+                if (inputConsumed > 0) { // still has input to process
+                    if (decrypting) {
+                        outLen += cipher.decrypt(input, inputOffset, inputConsumed,
+                            output, outputOffset);
+                    } else {
+                        outLen += cipher.encrypt(input, inputOffset, inputConsumed,
+                            output, outputOffset);
                     }
-                    if (decrypting) {
-                        outLen = cipher.decrypt(in, 0, len, output, outputOffset);
-                    } else {
-                        outLen = cipher.encrypt(in, 0, len, output, outputOffset);
-                    }
+                    inputOffset += inputConsumed;
+                    inputLen -= inputConsumed;
                 }
             }
             // Let's keep track of how many bytes are needed to make
@@ -934,8 +946,10 @@
         byte[] finalBuf = input;
         int finalOffset = inputOffset;
         int finalBufLen = inputLen;
-        if ((input == output) || (buffered != 0) ||
-            (!decrypting && padding != null)) {
+        if ((buffered != 0) || (!decrypting && padding != null) ||
+            ((input == output)
+              && (outputOffset < (inputOffset + inputLen))
+              && (inputOffset < (outputOffset + buffer.length)))) {
             if (decrypting || padding == null) {
                 paddingLen = 0;
             }
--- a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,6 +26,7 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.ProviderException;
 
 /**
  * This class represents ciphers in cipher-feedback (CFB) mode.
@@ -133,66 +134,72 @@
      *
      * <p>The input plain text <code>plain</code>, starting at
      * <code>plainOffset</code> and ending at
-     * <code>(plainOffset + len - 1)</code>, is encrypted.
+     * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
      * The result is stored in <code>cipher</code>, starting at
      * <code>cipherOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>plainLen</code> is a multiple of the stream unit size
-     * <code>numBytes</code>, as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
      * @param plain the buffer with the input data to be encrypted
      * @param plainOffset the offset in <code>plain</code>
      * @param plainLen the length of the input data
      * @param cipher the buffer for the result
      * @param cipherOffset the offset in <code>cipher</code>
+     * @exception ProviderException if <code>plainLen</code> is not
+     * a multiple of the <code>numBytes</code>
      * @return the length of the encrypted data
      */
     int encrypt(byte[] plain, int plainOffset, int plainLen,
-                byte[] cipher, int cipherOffset)
-    {
-        int i, len;
-        len = blockSize - numBytes;
+                byte[] cipher, int cipherOffset) {
+        if ((plainLen % numBytes) != 0) {
+            throw new ProviderException("Internal error in input buffering");
+        }
+
+        int nShift = blockSize - numBytes;
         int loopCount = plainLen / numBytes;
-        int oddBytes = plainLen % numBytes;
 
-        if (len == 0) {
-            for (; loopCount > 0 ;
-                 plainOffset += numBytes, cipherOffset += numBytes,
-                 loopCount--) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i = 0; i < blockSize; i++)
-                    register[i] = cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
+        for (; loopCount > 0 ;
+             plainOffset += numBytes, cipherOffset += numBytes,
+             loopCount--) {
+            embeddedCipher.encryptBlock(register, 0, k, 0);
+            if (nShift != 0) {
+                System.arraycopy(register, numBytes, register, 0, nShift);
+            }
+            for (int i = 0; i < numBytes; i++) {
+                register[nShift + i] = cipher[i + cipherOffset] =
+                        (byte)(k[i] ^ plain[i + plainOffset]);
             }
-            if (oddBytes > 0) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i=0; i<oddBytes; i++)
-                    register[i] = cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
-            }
-        } else {
-            for (; loopCount > 0 ;
-                 plainOffset += numBytes, cipherOffset += numBytes,
-                 loopCount--) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                System.arraycopy(register, numBytes, register, 0, len);
-                for (i=0; i<numBytes; i++)
-                    register[i+len] = cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
+        }
+        return plainLen;
+    }
 
-            }
-            if (oddBytes != 0) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                System.arraycopy(register, numBytes, register, 0, len);
-                for (i=0; i<oddBytes; i++) {
-                    register[i+len] = cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
-                }
+    /**
+     * Performs the last encryption operation.
+     *
+     * <p>The input plain text <code>plain</code>, starting at
+     * <code>plainOffset</code> and ending at
+     * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
+     * The result is stored in <code>cipher</code>, starting at
+     * <code>cipherOffset</code>.
+     *
+     * @param plain the buffer with the input data to be encrypted
+     * @param plainOffset the offset in <code>plain</code>
+     * @param plainLen the length of the input data
+     * @param cipher the buffer for the result
+     * @param cipherOffset the offset in <code>cipher</code>
+     * @return the number of bytes placed into <code>cipher</code>
+     */
+    int encryptFinal(byte[] plain, int plainOffset, int plainLen,
+                     byte[] cipher, int cipherOffset) {
+
+        int oddBytes = plainLen % numBytes;
+        int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
+                          cipher, cipherOffset);
+        plainOffset += len;
+        cipherOffset += len;
+        if (oddBytes != 0) {
+            embeddedCipher.encryptBlock(register, 0, k, 0);
+            for (int i = 0; i < oddBytes; i++) {
+                 cipher[i + cipherOffset] =
+                    (byte)(k[i] ^ plain[i + plainOffset]);
             }
         }
         return plainLen;
@@ -203,17 +210,52 @@
      *
      * <p>The input cipher text <code>cipher</code>, starting at
      * <code>cipherOffset</code> and ending at
-     * <code>(cipherOffset + len - 1)</code>, is decrypted.
+     * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
      * The result is stored in <code>plain</code>, starting at
      * <code>plainOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>cipherLen</code> is a multiple of the stream unit size
-     * <code>numBytes</code>, as any excess bytes are ignored.
+     * @param cipher the buffer with the input data to be decrypted
+     * @param cipherOffset the offset in <code>cipherOffset</code>
+     * @param cipherLen the length of the input data
+     * @param plain the buffer for the result
+     * @param plainOffset the offset in <code>plain</code>
+     * @exception ProviderException if <code>cipherLen</code> is not
+     * a multiple of the <code>numBytes</code>
+     * @return the length of the decrypted data
+     */
+    int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
+                byte[] plain, int plainOffset) {
+        if ((cipherLen % numBytes) != 0) {
+            throw new ProviderException("Internal error in input buffering");
+        }
+
+        int nShift = blockSize - numBytes;
+        int loopCount = cipherLen / numBytes;
+
+        for (; loopCount > 0;
+             plainOffset += numBytes, cipherOffset += numBytes,
+             loopCount--) {
+            embeddedCipher.encryptBlock(register, 0, k, 0);
+            if (nShift != 0) {
+                System.arraycopy(register, numBytes, register, 0, nShift);
+            }
+            for (int i = 0; i < numBytes; i++) {
+                register[i + nShift] = cipher[i + cipherOffset];
+                plain[i + plainOffset]
+                    = (byte)(cipher[i + cipherOffset] ^ k[i]);
+            }
+        }
+        return cipherLen;
+    }
+
+    /**
+     * Performs the last decryption operation.
      *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
+     * <p>The input cipher text <code>cipher</code>, starting at
+     * <code>cipherOffset</code> and ending at
+     * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
+     * The result is stored in <code>plain</code>, starting at
+     * <code>plainOffset</code>.
      *
      * @param cipher the buffer with the input data to be decrypted
      * @param cipherOffset the offset in <code>cipherOffset</code>
@@ -222,53 +264,19 @@
      * @param plainOffset the offset in <code>plain</code>
      * @return the length of the decrypted data
      */
-    int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
-                byte[] plain, int plainOffset)
-    {
-        int i, len;
-        len = blockSize - numBytes;
-        int loopCount = cipherLen / numBytes;
-        int oddBytes = cipherLen % numBytes;
+    int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
+                byte[] plain, int plainOffset) {
 
-        if (len == 0) {
-            for (; loopCount > 0;
-                 plainOffset += numBytes, cipherOffset += numBytes,
-                 loopCount--) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i = 0; i < blockSize; i++) {
-                    register[i] = cipher[i+cipherOffset];
-                    plain[i+plainOffset]
-                        = (byte)(cipher[i+cipherOffset] ^ k[i]);
-                }
-            }
-            if (oddBytes > 0) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i=0; i<oddBytes; i++) {
-                    register[i] = cipher[i+cipherOffset];
-                    plain[i+plainOffset]
-                        = (byte)(cipher[i+cipherOffset] ^ k[i]);
-                }
-            }
-        } else {
-            for (; loopCount > 0;
-                 plainOffset += numBytes, cipherOffset += numBytes,
-                 loopCount--) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                System.arraycopy(register, numBytes, register, 0, len);
-                for (i=0; i<numBytes; i++) {
-                    register[i+len] = cipher[i+cipherOffset];
-                    plain[i+plainOffset]
-                        = (byte)(cipher[i+cipherOffset] ^ k[i]);
-                }
-            }
-            if (oddBytes != 0) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                System.arraycopy(register, numBytes, register, 0, len);
-                for (i=0; i<oddBytes; i++) {
-                    register[i+len] = cipher[i+cipherOffset];
-                    plain[i+plainOffset]
-                        = (byte)(cipher[i+cipherOffset] ^ k[i]);
-                }
+        int oddBytes = cipherLen % numBytes;
+        int len = decrypt(cipher, cipherOffset, (cipherLen - oddBytes),
+                          plain, plainOffset);
+        cipherOffset += len;
+        plainOffset += len;
+        if (oddBytes != 0) {
+            embeddedCipher.encryptBlock(register, 0, k, 0);
+            for (int i = 0; i < oddBytes; i++) {
+                plain[i + plainOffset]
+                    = (byte)(cipher[i + cipherOffset] ^ k[i]);
             }
         }
         return cipherLen;
--- a/src/share/classes/com/sun/crypto/provider/CounterMode.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/CounterMode.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 201313, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 import java.security.InvalidKeyException;
 
+
 /**
  * This class represents ciphers in counter (CTR) mode.
  *
@@ -136,14 +137,6 @@
      * The result is stored in <code>cipher</code>, starting at
      * <code>cipherOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>plainLen</code> is a multiple of the embedded cipher's block size,
-     * as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
      * @param in the buffer with the input data to be encrypted
      * @param inOffset the offset in <code>plain</code>
      * @param len the length of the input data
@@ -155,30 +148,7 @@
         return crypt(in, inOff, len, out, outOff);
     }
 
-    /**
-     * Performs decryption operation.
-     *
-     * <p>The input cipher text <code>cipher</code>, starting at
-     * <code>cipherOffset</code> and ending at
-     * <code>(cipherOffset + len - 1)</code>, is decrypted.
-     * The result is stored in <code>plain</code>, starting at
-     * <code>plainOffset</code>.
-     *
-     * <p>It is the application's responsibility to make sure that
-     * <code>cipherLen</code> is a multiple of the embedded cipher's block
-     * size, as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
-     * @param in the buffer with the input data to be decrypted
-     * @param inOff the offset in <code>cipherOffset</code>
-     * @param len the length of the input data
-     * @param out the buffer for the result
-     * @param outOff the offset in <code>plain</code>
-     * @return the length of the decrypted data
-     */
+    // CTR encrypt and decrypt are identical
     int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
         return crypt(in, inOff, len, out, outOff);
     }
--- a/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Thu Jan 12 06:59:38 2017 +0000
@@ -72,6 +72,17 @@
         initialize(1024, null);
     }
 
+    private static void checkKeySize(int keysize)
+            throws InvalidParameterException {
+
+        if ((keysize < 512) || (keysize > 4096) || ((keysize & 0x3F) != 0)) {
+            throw new InvalidParameterException(
+                    "DH key size must be multiple of 64, and can only range " +
+                    "from 512 to 4096 (inclusive). " +
+                    "The specific key size " + keysize + " is not supported");
+        }
+    }
+
     /**
      * Initializes this key pair generator for a certain keysize and source of
      * randomness.
@@ -81,12 +92,8 @@
      * @param random the source of randomness
      */
     public void initialize(int keysize, SecureRandom random) {
-        if ((keysize < 512) || (keysize > 4096) || (keysize % 64 != 0)) {
-            throw new InvalidParameterException("Keysize must be multiple "
-                                                + "of 64, and can only range "
-                                                + "from 512 to 4096 "
-                                                + "(inclusive)");
-        }
+        checkKeySize(keysize);
+
         this.pSize = keysize;
         this.lSize = 0;
         this.random = random;
@@ -116,11 +123,10 @@
 
         params = (DHParameterSpec)algParams;
         pSize = params.getP().bitLength();
-        if ((pSize < 512) || (pSize > 4096) ||
-            (pSize % 64 != 0)) {
-            throw new InvalidAlgorithmParameterException
-                ("Prime size must be multiple of 64, and can only range "
-                 + "from 512 to 4096 (inclusive)");
+        try {
+            checkKeySize(pSize);
+        } catch (InvalidParameterException ipe) {
+            throw new InvalidAlgorithmParameterException(ipe.getMessage());
         }
 
         // exponent size is optional, could be 0
--- a/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Thu Jan 12 06:59:38 2017 +0000
@@ -60,12 +60,13 @@
     private SecureRandom random = null;
 
     private static void checkKeySize(int keysize)
-        throws InvalidAlgorithmParameterException {
-        if ((keysize != 2048) && (keysize != 4096) &&
+            throws InvalidParameterException {
+            if ((keysize != 2048) && (keysize != 4096) &&
             ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) {
-            throw new InvalidAlgorithmParameterException(
-                "Keysize must be multiple of 64 ranging from "
-                + "512 to 1024 (inclusive), or 2048, or 4096");
+            throw new InvalidParameterException(
+                    "DH key size must be multiple of 64 and range " +
+                    "from 512 to 1024 (inclusive), or 2048, or 4096. " +
+                    "The specific key size " + keysize + " is not supported");
         }
     }
 
@@ -79,11 +80,7 @@
      */
     protected void engineInit(int keysize, SecureRandom random) {
         // Re-uses DSA parameters and thus have the same range
-        try {
-            checkKeySize(keysize);
-        } catch (InvalidAlgorithmParameterException ex) {
-            throw new InvalidParameterException(ex.getMessage());
-        }
+        checkKeySize(keysize);
         this.primeSize = keysize;
         this.random = random;
     }
@@ -112,7 +109,11 @@
         primeSize = dhParamSpec.getPrimeSize();
 
         // Re-uses DSA parameters and thus have the same range
-        checkKeySize(primeSize);
+        try {
+            checkKeySize(primeSize);
+        } catch (InvalidParameterException ipe) {
+            throw new InvalidAlgorithmParameterException(ipe.getMessage());
+        }
 
         exponentSize = dhParamSpec.getExponentSize();
         if (exponentSize <= 0) {
--- a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,6 +26,7 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.ProviderException;
 
 /**
  * This class represents ciphers in electronic codebook (ECB) mode.
@@ -96,28 +97,24 @@
     /**
      * Performs encryption operation.
      *
-     * <p>The input plain text <code>plain</code>, starting at
-     * <code>plainOffset</code> and ending at
-     * <code>(plainOffset + len - 1)</code>, is encrypted.
-     * The result is stored in <code>cipher</code>, starting at
-     * <code>cipherOffset</code>.
-     *
-     * <p>It is the application's responsibility to make sure that
-     * <code>plainLen</code> is a multiple of the embedded cipher's block size,
-     * as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
+     * <p>The input plain text <code>in</code>, starting at
+     * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>,
+     * is encrypted. The result is stored in <code>out</code>, starting at
+     * <code>outOff</code>.
      *
      * @param in the buffer with the input data to be encrypted
-     * @param inOffset the offset in <code>plain</code>
+     * @param inOff the offset in <code>plain</code>
      * @param len the length of the input data
      * @param out the buffer for the result
      * @param outOff the offset in <code>cipher</code>
+     * @exception ProviderException if <code>len</code> is not
+     * a multiple of the block size
      * @return the length of the encrypted data
      */
     int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
+        if ((len % blockSize) != 0) {
+             throw new ProviderException("Internal error in input buffering");
+        }
         for (int i = len; i >= blockSize; i -= blockSize) {
             embeddedCipher.encryptBlock(in, inOff, out, outOff);
             inOff += blockSize;
@@ -129,28 +126,24 @@
     /**
      * Performs decryption operation.
      *
-     * <p>The input cipher text <code>cipher</code>, starting at
-     * <code>cipherOffset</code> and ending at
-     * <code>(cipherOffset + len - 1)</code>, is decrypted.
-     * The result is stored in <code>plain</code>, starting at
-     * <code>plainOffset</code>.
-     *
-     * <p>It is the application's responsibility to make sure that
-     * <code>cipherLen</code> is a multiple of the embedded cipher's block
-     * size, as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
+     * <p>The input cipher text <code>in</code>, starting at
+     * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>,
+     * is decrypted.The result is stored in <code>out</code>, starting at
+     * <code>outOff</code>.
      *
      * @param in the buffer with the input data to be decrypted
      * @param inOff the offset in <code>cipherOffset</code>
      * @param len the length of the input data
      * @param out the buffer for the result
      * @param outOff the offset in <code>plain</code>
+     * @exception ProviderException if <code>len</code> is not
+     * a multiple of the block size
      * @return the length of the decrypted data
      */
     int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
+        if ((len % blockSize) != 0) {
+             throw new ProviderException("Internal error in input buffering");
+        }
         for (int i = len; i >= blockSize; i -= blockSize) {
             embeddedCipher.decryptBlock(in, inOff, out, outOff);
             inOff += blockSize;
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Thu Jan 12 06:59:38 2017 +0000
@@ -403,23 +403,21 @@
      * and ending at <code>(inOff + len - 1)</code>, is encrypted. The result
      * is stored in <code>out</code>, starting at <code>outOfs</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>len</code> is a multiple of the embedded cipher's block size,
-     * otherwise, a ProviderException will be thrown.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
      * @param in the buffer with the input data to be encrypted
      * @param inOfs the offset in <code>in</code>
      * @param len the length of the input data
      * @param out the buffer for the result
      * @param outOfs the offset in <code>out</code>
+     * @exception ProviderException if <code>len</code> is not
+     * a multiple of the block size
+     * @return the number of bytes placed into the <code>out</code> buffer
      */
     int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
         checkDataLength(processed, len);
 
+        if ((len % blockSize) != 0) {
+             throw new ProviderException("Internal error in input buffering");
+        }
         processAAD();
         if (len > 0) {
             gctrPAndC.update(in, inOfs, len, out, outOfs);
@@ -432,9 +430,6 @@
     /**
      * Performs encryption operation for the last time.
      *
-     * <p>NOTE: <code>len</code> may not be multiple of the embedded
-     * cipher's block size for this call.
-     *
      * @param in the input buffer with the data to be encrypted
      * @param inOfs the offset in <code>in</code>
      * @param len the length of the input data
@@ -479,23 +474,21 @@
      * is decrypted. The result is stored in <code>out</code>, starting at
      * <code>outOfs</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>len</code> is a multiple of the embedded cipher's block
-     * size, as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
      * @param in the buffer with the input data to be decrypted
      * @param inOfs the offset in <code>in</code>
      * @param len the length of the input data
      * @param out the buffer for the result
      * @param outOfs the offset in <code>out</code>
+     * @exception ProviderException if <code>len</code> is not
+     * a multiple of the block size
+     * @return the number of bytes placed into the <code>out</code> buffer
      */
     int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
         checkDataLength(ibuffer.size(), len);
 
+        if ((len % blockSize) != 0) {
+             throw new ProviderException("Internal error in input buffering");
+        }
         processAAD();
 
         if (len > 0) {
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -864,7 +864,9 @@
                         if (computed[i] != actual[i]) {
                             throw new IOException(
                                 "Keystore was tampered with, or "
-                                + "password was incorrect");
+                                + "password was incorrect",
+                                    new UnrecoverableKeyException(
+                                            "Password verification failed"));
                         }
                     }
                 }
--- a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,6 +26,7 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.ProviderException;
 
 /**
  * This class represents ciphers in output-feedback (OFB) mode.
@@ -132,17 +133,52 @@
      *
      * <p>The input plain text <code>plain</code>, starting at
      * <code>plainOffset</code> and ending at
-     * <code>(plainOffset + len - 1)</code>, is encrypted.
+     * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
      * The result is stored in <code>cipher</code>, starting at
      * <code>cipherOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>plainLen</code> is a multiple of the stream unit size
-     * <code>numBytes</code>, as any excess bytes are ignored.
+     * @param plain the buffer with the input data to be encrypted
+     * @param plainOffset the offset in <code>plain</code>
+     * @param plainLen the length of the input data
+     * @param cipher the buffer for the result
+     * @param cipherOffset the offset in <code>cipher</code>
+     * @exception ProviderException if <code>plainLen</code> is not
+     * a multiple of the <code>numBytes</code>
+     * @return the length of the encrypted data
+     */
+    int encrypt(byte[] plain, int plainOffset, int plainLen,
+                byte[] cipher, int cipherOffset) {
+
+        if ((plainLen % numBytes) != 0) {
+            throw new ProviderException("Internal error in input buffering");
+        }
+        int nShift = blockSize - numBytes;
+        int loopCount = plainLen / numBytes;
+
+        for (; loopCount > 0;
+             plainOffset += numBytes, cipherOffset += numBytes,
+             loopCount--) {
+            embeddedCipher.encryptBlock(register, 0, k, 0);
+            for (int i = 0; i < numBytes; i++) {
+                cipher[i + cipherOffset] =
+                    (byte)(k[i] ^ plain[i + plainOffset]);
+                if (nShift != 0) {
+                    System.arraycopy(register, numBytes, register, 0, nShift);
+                }
+                System.arraycopy(k, 0, register, nShift, numBytes);
+            }
+        }
+        return plainLen;
+    }
+
+    /**
+     * Performs last encryption operation.
      *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
+     * <p>The input plain text <code>plain</code>, starting at
+     * <code>plainOffset</code> and ending at
+     * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
+     * The result is stored in <code>cipher</code>, starting at
+     * <code>cipherOffset</code>.
      *
      * @param plain the buffer with the input data to be encrypted
      * @param plainOffset the offset in <code>plain</code>
@@ -151,82 +187,34 @@
      * @param cipherOffset the offset in <code>cipher</code>
      * @return the length of the encrypted data
      */
-    int encrypt(byte[] plain, int plainOffset, int plainLen,
-                byte[] cipher, int cipherOffset)
-    {
-        int i;
-        int len = blockSize - numBytes;
-        int loopCount = plainLen / numBytes;
+    int encryptFinal(byte[] plain, int plainOffset, int plainLen,
+                     byte[] cipher, int cipherOffset) {
         int oddBytes = plainLen % numBytes;
+        int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
+                          cipher, cipherOffset);
+        plainOffset += len;
+        cipherOffset += len;
 
-        if (len == 0) {
-            for (; loopCount > 0;
-                 plainOffset += numBytes, cipherOffset += numBytes,
-                 loopCount--) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i=0; i<numBytes; i++)
-                    cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
-                System.arraycopy(k, 0, register, 0, numBytes);
-            }
-            if (oddBytes > 0) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i=0; i<oddBytes; i++)
-                    cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
-                System.arraycopy(k, 0, register, 0, numBytes);
-            }
-        } else {
-            for (; loopCount > 0;
-                 plainOffset += numBytes, cipherOffset += numBytes,
-                 loopCount--) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i=0; i<numBytes; i++)
-                    cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
-                System.arraycopy(register, numBytes, register, 0, len);
-                System.arraycopy(k, 0, register, len, numBytes);
-            }
-            if (oddBytes > 0) {
-                embeddedCipher.encryptBlock(register, 0, k, 0);
-                for (i=0; i<oddBytes; i++)
-                    cipher[i+cipherOffset] =
-                        (byte)(k[i] ^ plain[i+plainOffset]);
-                System.arraycopy(register, numBytes, register, 0, len);
-                System.arraycopy(k, 0, register, len, numBytes);
+        if (oddBytes != 0) {
+            embeddedCipher.encryptBlock(register, 0, k, 0);
+            for (int i = 0; i < oddBytes; i++) {
+                cipher[i + cipherOffset] =
+                    (byte)(k[i] ^ plain[ i + plainOffset]);
             }
         }
         return plainLen;
     }
 
-    /**
-     * Performs decryption operation.
-     *
-     * <p>The input cipher text <code>cipher</code>, starting at
-     * <code>cipherOffset</code> and ending at
-     * <code>(cipherOffset + len - 1)</code>, is decrypted.
-     * The result is stored in <code>plain</code>, starting at
-     * <code>plainOffset</code>.
-     *
-     * <p>It is the application's responsibility to make sure that
-     * <code>cipherLen</code> is a multiple of the stream unit size
-     * <code>numBytes</code>, as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
-     * @param cipher the buffer with the input data to be decrypted
-     * @param cipherOffset the offset in <code>cipherOffset</code>
-     * @param cipherLen the length of the input data
-     * @param plain the buffer for the result
-     * @param plainOffset the offset in <code>plain</code>
-     * @return the length of the decrypted data
-     */
+    // OFB encrypt and decrypt are identical
     int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
-                        byte[] plain, int plainOffset)
-    {
-        // OFB encrypt and decrypt are identical
+                byte[] plain, int plainOffset) {
         return encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
     }
+
+    // OFB encrypt and decrypt are identical
+    int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
+                     byte[] plain, int plainOffset) {
+        // OFB encrypt and decrypt are identical
+        return encryptFinal(cipher, cipherOffset, cipherLen, plain, plainOffset);
+    }
 }
--- a/src/share/classes/com/sun/crypto/provider/PCBC.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/crypto/provider/PCBC.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,6 +26,8 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.ProviderException;
+
 
 /**
  * This class represents ciphers in Plaintext Cipher Block Chaining (PCBC)
@@ -118,38 +120,36 @@
      *
      * <p>The input plain text <code>plain</code>, starting at
      * <code>plainOffset</code> and ending at
-     * <code>(plainOffset + len - 1)</code>, is encrypted.
+     * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
      * The result is stored in <code>cipher</code>, starting at
      * <code>cipherOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>plainLen</code> is a multiple of the embedded cipher's block size,
-     * as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
      * @param plain the buffer with the input data to be encrypted
      * @param plainOffset the offset in <code>plain</code>
      * @param plainLen the length of the input data
      * @param cipher the buffer for the result
      * @param cipherOffset the offset in <code>cipher</code>
+     * @exception ProviderException if <code>plainLen</code> is not
+     * a multiple of the block size
+     * @return the length of the encrypted data
      */
     int encrypt(byte[] plain, int plainOffset, int plainLen,
                 byte[] cipher, int cipherOffset)
     {
+        if ((plainLen % blockSize) != 0) {
+            throw new ProviderException("Internal error in input buffering");
+        }
         int i;
         int endIndex = plainOffset + plainLen;
 
         for (; plainOffset < endIndex;
              plainOffset += blockSize, cipherOffset += blockSize) {
-            for (i=0; i<blockSize; i++) {
-                k[i] ^= plain[i+plainOffset];
+            for (i = 0; i < blockSize; i++) {
+                k[i] ^= plain[i + plainOffset];
             }
             embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
             for (i = 0; i < blockSize; i++) {
-                k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]);
+                k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]);
             }
         }
         return plainLen;
@@ -160,27 +160,25 @@
      *
      * <p>The input cipher text <code>cipher</code>, starting at
      * <code>cipherOffset</code> and ending at
-     * <code>(cipherOffset + len - 1)</code>, is decrypted.
+     * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
      * The result is stored in <code>plain</code>, starting at
      * <code>plainOffset</code>.
      *
-     * <p>It is the application's responsibility to make sure that
-     * <code>cipherLen</code> is a multiple of the embedded cipher's block
-     * size, as any excess bytes are ignored.
-     *
-     * <p>It is also the application's responsibility to make sure that
-     * <code>init</code> has been called before this method is called.
-     * (This check is omitted here, to avoid double checking.)
-     *
      * @param cipher the buffer with the input data to be decrypted
      * @param cipherOffset the offset in <code>cipherOffset</code>
      * @param cipherLen the length of the input data
      * @param plain the buffer for the result
      * @param plainOffset the offset in <code>plain</code>
+     * @exception ProviderException if <code>cipherLen</code> is not
+     * a multiple of the block size
+     * @return the length of the decrypted data
      */
     int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
                 byte[] plain, int plainOffset)
     {
+        if ((cipherLen % blockSize) != 0) {
+             throw new ProviderException("Internal error in input buffering");
+        }
         int i;
         int endIndex = cipherOffset + cipherLen;
 
@@ -189,10 +187,10 @@
             embeddedCipher.decryptBlock(cipher, cipherOffset,
                                    plain, plainOffset);
             for (i = 0; i < blockSize; i++) {
-                plain[i+plainOffset] ^= k[i];
+                plain[i + plainOffset] ^= k[i];
             }
             for (i = 0; i < blockSize; i++) {
-                k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]);
+                k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]);
             }
         }
         return cipherLen;
--- a/src/share/classes/com/sun/java/accessibility/util/package-info.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/java/accessibility/util/package-info.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
--- a/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java	Thu Jan 12 06:59:38 2017 +0000
@@ -300,7 +300,7 @@
         errEx = e;
     }
 
-    protected abstract AbstractLdapNamingEnumeration<T> getReferredResults(
+    protected abstract AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
             LdapReferralContext refCtx) throws NamingException;
 
     /*
@@ -360,7 +360,7 @@
      * Merge the entries and/or referrals from the supplied enumeration
      * with those of the current enumeration.
      */
-    protected void update(AbstractLdapNamingEnumeration<T> ne) {
+    protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
         // Cleanup previous context first
         homeCtx.decEnumCount();
 
--- a/src/share/classes/com/sun/jndi/ldap/DigestClientId.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/DigestClientId.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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,7 +60,6 @@
 
     final private String[] propvals;
     final private int myHash;
-    private int pHash = 0;
 
     DigestClientId(int version, String hostname, int port,
         String protocol, Control[] bindCtls, OutputStream trace,
@@ -78,12 +77,9 @@
             propvals = new String[SASL_PROPS.length];
             for (int i = 0; i < SASL_PROPS.length; i++) {
                 propvals[i] = (String) env.get(SASL_PROPS[i]);
-                if (propvals[i] != null) {
-                    pHash = pHash * 31 + propvals[i].hashCode();
-                }
             }
         }
-        myHash = super.hashCode() + pHash;
+        myHash = super.hashCode() ^ Arrays.hashCode(propvals);
     }
 
     public boolean equals(Object obj) {
@@ -92,7 +88,6 @@
         }
         DigestClientId other = (DigestClientId)obj;
         return myHash == other.myHash
-            && pHash == other.pHash
             && super.equals(obj)
             && Arrays.equals(propvals, other.propvals);
     }
--- a/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java	Thu Jan 12 06:59:38 2017 +0000
@@ -104,9 +104,9 @@
     }
 
     @Override
-    protected LdapBindingEnumeration getReferredResults(
+    protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
             LdapReferralContext refCtx) throws NamingException{
         // repeat the original operation at the new context
-        return (LdapBindingEnumeration)refCtx.listBindings(listArg);
+        return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.listBindings(listArg);
     }
 }
--- a/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java	Thu Jan 12 06:59:38 2017 +0000
@@ -72,9 +72,9 @@
     }
 
     @Override
-    protected LdapNamingEnumeration getReferredResults(
+    protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
             LdapReferralContext refCtx) throws NamingException {
         // repeat the original operation at the new context
-        return (LdapNamingEnumeration)refCtx.list(listArg);
+        return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.list(listArg);
     }
 }
--- a/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java	Thu Jan 12 06:59:38 2017 +0000
@@ -199,15 +199,15 @@
     }
 
     @Override
-    protected LdapSearchEnumeration getReferredResults(
+    protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
             LdapReferralContext refCtx) throws NamingException {
         // repeat the original operation at the new context
-        return (LdapSearchEnumeration)refCtx.search(
+        return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.search(
                 searchArgs.name, searchArgs.filter, searchArgs.cons);
     }
 
     @Override
-    protected void update(AbstractLdapNamingEnumeration<SearchResult> ne) {
+    protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
         super.update(ne);
 
         // Update search-specific variables
--- a/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -49,21 +49,23 @@
                 socketFactory);
 
         this.username = username;
+        int pwdHashCode = 0;
         if (passwd == null) {
             this.passwd = null;
-        } else if (passwd instanceof String) {
-            this.passwd = passwd;
         } else if (passwd instanceof byte[]) {
             this.passwd = ((byte[])passwd).clone();
+            pwdHashCode = Arrays.hashCode((byte[])passwd);
         } else if (passwd instanceof char[]) {
             this.passwd = ((char[])passwd).clone();
+            pwdHashCode = Arrays.hashCode((char[])passwd);
         } else {
             this.passwd = passwd;
+            pwdHashCode = passwd.hashCode();
         }
 
         myHash = super.hashCode()
-            + (username != null ? username.hashCode() : 0)
-            + (passwd != null ? passwd.hashCode() : 0);
+            ^ (username != null ? username.hashCode() : 0)
+            ^ pwdHashCode;
     }
 
     public boolean equals(Object obj) {
--- a/src/share/classes/com/sun/jndi/ldap/pool/Pool.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/pool/Pool.java	Thu Jan 12 06:59:38 2017 +0000
@@ -118,7 +118,11 @@
         PooledConnectionFactory factory) throws NamingException {
 
         d("get(): ", id);
-        d("size: ", map.size());
+        if (debug) {
+            synchronized (map) {
+                d("size: ", map.size());
+            }
+        }
 
         expungeStaleConnections();
 
@@ -141,10 +145,9 @@
                 // Keep the weak reference through the element of a linked list
                 weakRefs.add(weakRef);
             }
+            d("get(): size after: ", map.size());
         }
 
-        d("get(): size after: ", map.size());
-
         return conns.get(timeout, factory); // get one connection from list
     }
 
@@ -209,19 +212,24 @@
         out.println("maximum pool size: " + maxSize);
         out.println("preferred pool size: " + prefSize);
         out.println("initial pool size: " + initSize);
-        out.println("current pool size: " + map.size());
+
+        synchronized (map) {
+            out.println("current pool size: " + map.size());
 
-        for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) {
-            id = entry.getKey();
-            conns = entry.getValue().getConnections();
-            out.println("   " + id + ":" + conns.getStats());
+            for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) {
+                id = entry.getKey();
+                conns = entry.getValue().getConnections();
+                out.println("   " + id + ":" + conns.getStats());
+            }
         }
 
         out.println("====== Pool end =====================");
     }
 
     public String toString() {
-        return super.toString() + " " + map.toString();
+        synchronized (map) {
+            return super.toString() + " " + map.toString();
+        }
     }
 
     private void d(String msg, int i) {
--- a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -133,6 +133,10 @@
             if (!vmDied) {
                 vmDisconnectEvent(event);
             }
+            /*
+             * Inform jdb command line processor that jdb is being shutdown. JDK-8154144.
+             */
+            ((TTY)notifier).setShuttingDown(true);
             Env.shutdown(shutdownMessageKey);
             return false;
         } else {
--- a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -56,6 +56,16 @@
      */
     private static final String progname = "jdb";
 
+    private volatile boolean shuttingDown = false;
+
+    public void setShuttingDown(boolean s) {
+       shuttingDown = s;
+    }
+
+    public boolean isShuttingDown() {
+        return shuttingDown;
+    }
+
     @Override
     public void vmStartEvent(VMStartEvent se)  {
         Thread.yield();  // fetch output
@@ -750,7 +760,13 @@
             while (true) {
                 String ln = in.readLine();
                 if (ln == null) {
-                    MessageOutput.println("Input stream closed.");
+                    /*
+                     *  Jdb is being shutdown because debuggee exited, ignore any 'null'
+                     *  returned by readLine() during shutdown. JDK-8154144.
+                     */
+                    if (!isShuttingDown()) {
+                        MessageOutput.println("Input stream closed.");
+                    }
                     ln = "quit";
                 }
 
--- a/src/share/classes/java/awt/SplashScreen.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/java/awt/SplashScreen.java	Thu Jan 12 06:59:38 2017 +0000
@@ -250,7 +250,7 @@
             assert scale > 0;
             if (scale > 0 && scale != 1) {
                 bounds.setSize((int) (bounds.getWidth() / scale),
-                        (int) (bounds.getWidth() / scale));
+                        (int) (bounds.getHeight() / scale));
             }
             return bounds;
         }
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -915,6 +915,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+            if (refc.isArray()) {
+                throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
+            }
             String name = "<init>";
             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
             return getDirectConstructor(refc, ctor);
--- a/src/share/classes/java/security/ProtectionDomain.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/java/security/ProtectionDomain.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,12 +25,16 @@
 
 package java.security;
 
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
-import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
 import sun.misc.JavaSecurityProtectionDomainAccess;
 import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
 import sun.security.util.Debug;
@@ -456,24 +460,14 @@
     /**
      * Used for storing ProtectionDomains as keys in a Map.
      */
-    final class Key {}
+    static final class Key {}
 
     static {
         SharedSecrets.setJavaSecurityProtectionDomainAccess(
             new JavaSecurityProtectionDomainAccess() {
+                @Override
                 public ProtectionDomainCache getProtectionDomainCache() {
-                    return new ProtectionDomainCache() {
-                        private final Map<Key, PermissionCollection> map =
-                            Collections.synchronizedMap
-                                (new WeakHashMap<Key, PermissionCollection>());
-                        public void put(ProtectionDomain pd,
-                            PermissionCollection pc) {
-                            map.put((pd == null ? null : pd.key), pc);
-                        }
-                        public PermissionCollection get(ProtectionDomain pd) {
-                            return pd == null ? map.get(null) : map.get(pd.key);
-                        }
-                    };
+                    return new PDCache();
                 }
 
                 @Override
@@ -482,4 +476,119 @@
                 }
             });
     }
+
+    /**
+     * A cache of ProtectionDomains and their Permissions.
+     *
+     * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
+     * with additional support for checking and removing weak keys that are no
+     * longer in use. There can be cases where the permission collection may
+     * have a chain of strong references back to the ProtectionDomain, which
+     * ordinarily would prevent the entry from being removed from the map. To
+     * address that, we wrap the permission collection in a SoftReference so
+     * that it can be reclaimed by the garbage collector due to memory demand.
+     */
+    private static class PDCache implements ProtectionDomainCache {
+        private final ConcurrentHashMap<WeakProtectionDomainKey,
+                                        SoftReference<PermissionCollection>>
+                                        pdMap = new ConcurrentHashMap<>();
+        private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
+
+        @Override
+        public void put(ProtectionDomain pd, PermissionCollection pc) {
+            processQueue(queue, pdMap);
+            WeakProtectionDomainKey weakPd =
+                new WeakProtectionDomainKey(pd, queue);
+            pdMap.put(weakPd, new SoftReference<>(pc));
+        }
+
+        @Override
+        public PermissionCollection get(ProtectionDomain pd) {
+            processQueue(queue, pdMap);
+            WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd);
+            SoftReference<PermissionCollection> sr = pdMap.get(weakPd);
+            return (sr == null) ? null : sr.get();
+        }
+
+        /**
+         * Removes weak keys from the map that have been enqueued
+         * on the reference queue and are no longer in use.
+         */
+        private static void processQueue(ReferenceQueue<Key> queue,
+                                         ConcurrentHashMap<? extends
+                                         WeakReference<Key>, ?> pdMap) {
+            Reference<? extends Key> ref;
+            while ((ref = queue.poll()) != null) {
+                pdMap.remove(ref);
+            }
+        }
+    }
+
+    /**
+     * A weak key for a ProtectionDomain.
+     */
+    private static class WeakProtectionDomainKey extends WeakReference<Key> {
+        /**
+         * Saved value of the referent's identity hash code, to maintain
+         * a consistent hash code after the referent has been cleared
+         */
+        private final int hash;
+
+        /**
+         * A key representing a null ProtectionDomain.
+         */
+        private static final Key NULL_KEY = new Key();
+
+        /**
+         * Create a new WeakProtectionDomain with the specified domain and
+         * registered with a queue.
+         */
+        WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) {
+            this((pd == null ? NULL_KEY : pd.key), rq);
+        }
+
+        WeakProtectionDomainKey(ProtectionDomain pd) {
+            this(pd == null ? NULL_KEY : pd.key);
+        }
+
+        private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
+            super(key, rq);
+            hash = key.hashCode();
+        }
+
+        private WeakProtectionDomainKey(Key key) {
+            super(key);
+            hash = key.hashCode();
+        }
+
+        /**
+         * Returns the identity hash code of the original referent.
+         */
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        /**
+         * Returns true if the given object is an identical
+         * WeakProtectionDomainKey instance, or, if this object's referent
+         * has not been cleared and the given object is another
+         * WeakProtectionDomainKey instance with an identical non-null
+         * referent as this one.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+
+            if (obj instanceof WeakProtectionDomainKey) {
+                Object referent = get();
+                return (referent != null) &&
+                       (referent == ((WeakProtectionDomainKey)obj).get());
+            } else {
+                return false;
+            }
+        }
+    }
 }
--- a/src/share/classes/java/security/SecureRandom.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/java/security/SecureRandom.java	Thu Jan 12 06:59:38 2017 +0000
@@ -464,7 +464,7 @@
      * @param bytes the array to be filled in with random bytes.
      */
     @Override
-    synchronized public void nextBytes(byte[] bytes) {
+    public void nextBytes(byte[] bytes) {
         secureRandomSpi.engineNextBytes(bytes);
     }
 
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -125,8 +125,6 @@
     protected MouseMotionListener popupMouseMotionListener;
     protected KeyListener popupKeyListener;
 
-    private MouseWheelListener mouseWheelListener;
-
     // This is used for knowing when to cache the minimum preferred size.
     // If the data in the list changes, the cached value get marked for recalc.
     // Added to the current JComboBox model
@@ -375,10 +373,6 @@
                 comboBox.getModel().addListDataListener( listDataListener );
             }
         }
-
-        if ((mouseWheelListener = createMouseWheelListener()) != null) {
-            comboBox.addMouseWheelListener(mouseWheelListener);
-        }
     }
 
     /**
@@ -425,9 +419,6 @@
                 comboBox.getModel().removeListDataListener( listDataListener );
             }
         }
-        if (mouseWheelListener != null) {
-            comboBox.removeMouseWheelListener(mouseWheelListener);
-        }
     }
 
     /**
@@ -541,10 +532,6 @@
         return handler;
     }
 
-    private MouseWheelListener createMouseWheelListener() {
-        return getHandler();
-    }
-
     //
     // end UI Initialization
     //======================
@@ -1680,8 +1667,7 @@
     //
     private class Handler implements ActionListener, FocusListener,
                                      KeyListener, LayoutManager,
-                                     ListDataListener, PropertyChangeListener,
-                                     MouseWheelListener {
+                                     ListDataListener, PropertyChangeListener {
         //
         // PropertyChangeListener
         //
@@ -1965,10 +1951,6 @@
                 }
             }
         }
-
-        public void mouseWheelMoved(MouseWheelEvent e) {
-            e.consume();
-        }
    }
 
     class DefaultKeySelectionManager implements JComboBox.KeySelectionManager, UIResource {
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -345,17 +345,26 @@
     // PopupMenuListeners.
 
     protected void firePopupMenuWillBecomeVisible() {
+        if (scrollerMouseWheelListener != null) {
+            comboBox.addMouseWheelListener(scrollerMouseWheelListener);
+        }
         super.firePopupMenuWillBecomeVisible();
         // comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method
         // to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible()
     }
 
     protected void firePopupMenuWillBecomeInvisible() {
+        if (scrollerMouseWheelListener != null) {
+            comboBox.removeMouseWheelListener(scrollerMouseWheelListener);
+        }
         super.firePopupMenuWillBecomeInvisible();
         comboBox.firePopupMenuWillBecomeInvisible();
     }
 
     protected void firePopupMenuCanceled() {
+        if (scrollerMouseWheelListener != null) {
+            comboBox.removeMouseWheelListener(scrollerMouseWheelListener);
+        }
         super.firePopupMenuCanceled();
         comboBox.firePopupMenuCanceled();
     }
@@ -997,6 +1006,8 @@
             if (e.getStateChange() == ItemEvent.SELECTED) {
                 JComboBox comboBox = (JComboBox)e.getSource();
                 setListSelection(comboBox.getSelectedIndex());
+            } else {
+                setListSelection(-1);
             }
         }
 
--- a/src/share/classes/javax/swing/plaf/nimbus/skin.laf	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/javax/swing/plaf/nimbus/skin.laf	Thu Jan 12 06:59:38 2017 +0000
@@ -13407,7 +13407,7 @@
             <cacheSettingsInherited>false</cacheSettingsInherited>
             <cacheMode>NO_CACHING</cacheMode>
             <uiproperties>
-               <uiProperty name="rendererUseListColors" type="BOOLEAN" value="true"/>
+               <uiProperty name="rendererUseListColors" type="BOOLEAN" value="false"/>
                <uiProperty name="rendererUseUIBorder" type="BOOLEAN" value="true"/>
                <uiProperty name="cellNoFocusBorder" type="BORDER">
                    <border type="empty" top="2" left="5" bottom="2" right="5"/>
@@ -13513,10 +13513,10 @@
                   <uiproperties/>
                </style>
                <backgroundStates>
-                  <state stateKeys="Disabled">
+                  <state stateKeys="Selected">
                      <style>
                         <textForeground>
-                           <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
+                           <matte red="255" green="255" blue="255" alpha="255" uiDefaultParentName="nimbusLightBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
                         </textForeground>
                         <textBackground/>
                         <background>
@@ -13541,6 +13541,56 @@
                         </layer>
                      </canvas>
                   </state>
+                  <state stateKeys="Disabled+Selected">
+                     <style>
+                        <textForeground/>
+                        <textBackground/>
+                        <background>
+                           <matte red="57" green="105" blue="138" alpha="255" uiDefaultParentName="nimbusSelectionBackground" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
+                        </background>
+                        <inherit-background>false</inherit-background>
+                        <uiproperties/>
+                     </style>
+                     <canvas>
+                        <size width="100" height="30"/>
+                        <nextLayerNameIndex>2</nextLayerNameIndex>
+                        <stretchingInsets top="0" bottom="0" left="0" right="0"/>
+                        <layer name="Layer 1">
+                           <opacity>1.0</opacity>
+                           <fillOpacity>1.0</fillOpacity>
+                           <blendingMode>NORMAL</blendingMode>
+                           <locked>false</locked>
+                           <visible>true</visible>
+                           <shapes/>
+                           <effects/>
+                        </layer>
+                     </canvas>
+                  </state>
+                  <state stateKeys="Disabled">
+                     <style>
+                        <textForeground>
+                           <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/>
+                        </textForeground>
+                        <textBackground/>
+                        <background/>
+                        <inherit-textForeground>false</inherit-textForeground>
+                        <uiproperties/>
+                     </style>
+                     <canvas>
+                        <size width="100" height="30"/>
+                        <nextLayerNameIndex>2</nextLayerNameIndex>
+                        <stretchingInsets top="0" bottom="0" left="0" right="0"/>
+                        <layer name="Layer 1">
+                           <opacity>1.0</opacity>
+                           <fillOpacity>1.0</fillOpacity>
+                           <blendingMode>NORMAL</blendingMode>
+                           <locked>false</locked>
+                           <visible>true</visible>
+                           <shapes/>
+                           <effects/>
+                        </layer>
+                     </canvas>
+                  </state>
                </backgroundStates>
                <foregroundStates/>
                <borderStates/>
--- a/src/share/classes/javax/swing/text/html/parser/Parser.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/javax/swing/text/html/parser/Parser.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1986,57 +1986,69 @@
         while (true) {
             int i = 0;
             while (!insideComment && i < SCRIPT_END_TAG.length
-                       && (SCRIPT_END_TAG[i] == ch
-                           || SCRIPT_END_TAG_UPPER_CASE[i] == ch)) {
+                    && (SCRIPT_END_TAG[i] == ch
+                    || SCRIPT_END_TAG_UPPER_CASE[i] == ch)) {
                 charsToAdd[i] = (char) ch;
                 ch = readCh();
                 i++;
             }
             if (i == SCRIPT_END_TAG.length) {
-
-                /*  '</script>' tag detected */
-                /* Here, ch == the first character after </script> */
                 return;
-            } else {
+            }
 
-                /* To account for extra read()'s that happened */
-                for (int j = 0; j < i; j++) {
-                    addString(charsToAdd[j]);
+            if (!insideComment && i == 1 && charsToAdd[0] == START_COMMENT.charAt(0)) {
+                // it isn't end script tag, but may be it's start comment tag?
+                while (i < START_COMMENT.length()
+                        && START_COMMENT.charAt(i) == ch) {
+                    charsToAdd[i] = (char) ch;
+                    ch = readCh();
+                    i++;
                 }
-
-                switch (ch) {
-                case -1:
-                    error("eof.script");
-                    return;
-                case '\n':
-                    ln++;
+                if (i == START_COMMENT.length()) {
+                    insideComment = true;
+                }
+            }
+            if (insideComment) {
+                while (i < END_COMMENT.length()
+                        && END_COMMENT.charAt(i) == ch) {
+                    charsToAdd[i] = (char) ch;
                     ch = readCh();
-                    lfCount++;
-                    addString('\n');
-                    break;
-                case '\r':
-                    ln++;
-                    if ((ch = readCh()) == '\n') {
-                        ch = readCh();
-                        crlfCount++;
-                    } else {
-                        crCount++;
-                    }
-                    addString('\n');
-                    break;
-                default:
-                    addString(ch);
-                    String str = new String(getChars(0, strpos));
-                    if (!insideComment && str.endsWith(START_COMMENT)) {
-                        insideComment = true;
-                    }
-                    if (insideComment && str.endsWith(END_COMMENT)) {
-                        insideComment = false;
-                    }
+                    i++;
+                }
+                if (i == END_COMMENT.length()) {
+                    insideComment = false;
+                }
+            }
+
+            /* To account for extra read()'s that happened */
+            for (int j = 0; j < i; j++) {
+                addString(charsToAdd[j]);
+            }
+            switch (ch) {
+            case -1:
+                error("eof.script");
+                return;
+            case '\n':
+                ln++;
+                ch = readCh();
+                lfCount++;
+                addString('\n');
+                break;
+            case '\r':
+                ln++;
+                if ((ch = readCh()) == '\n') {
                     ch = readCh();
-                    break;
-                } // switch
-            }
+                    crlfCount++;
+                } else {
+                    crCount++;
+                }
+                addString('\n');
+                break;
+            default:
+                addString(ch);
+                ch = readCh();
+                break;
+            } // switch
         } // while
     }
 
--- a/src/share/classes/sun/font/CompositeFont.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/font/CompositeFont.java	Thu Jan 12 06:59:38 2017 +0000
@@ -270,10 +270,21 @@
                 if (componentNames[slot] == null) {
                     componentNames[slot] = name;
                 } else if (!componentNames[slot].equalsIgnoreCase(name)) {
-                    components[slot] =
-                        (PhysicalFont) fm.findFont2D(componentNames[slot],
-                                                     style,
+                    /* If a component specifies the file with a bad font,
+                     * the corresponding slot will be initialized by
+                     * default physical font. In such case findFont2D may
+                     * return composite font which cannot be casted to
+                     * physical font.
+                     */
+                    try {
+                        components[slot] =
+                            (PhysicalFont) fm.findFont2D(componentNames[slot],
+                                                         style,
                                                 FontManager.PHYSICAL_FALLBACK);
+                    } catch (ClassCastException cce) {
+                        /* Assign default physical font to the slot */
+                        components[slot] = fm.getDefaultPhysicalFont();
+                    }
                 }
             }
             deferredInitialisation[slot] = false;
--- a/src/share/classes/sun/font/FontFamily.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/font/FontFamily.java	Thu Jan 12 06:59:38 2017 +0000
@@ -335,10 +335,10 @@
         case Font.BOLD|Font.ITALIC:
             if (bolditalic != null) {
                 return bolditalic;
+            } else if (bold != null && bold.canDoStyle(style)) {
+                return bold;
             } else if (italic != null && italic.canDoStyle(style)) {
                     return italic;
-            } else if (bold != null && bold.canDoStyle(style)) {
-                    return italic;
             } else if (plain != null && plain.canDoStyle(style)) {
                     return plain;
             } else {
--- a/src/share/classes/sun/font/ScriptRunData.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/font/ScriptRunData.java	Thu Jan 12 06:59:38 2017 +0000
@@ -44,7 +44,7 @@
         if (cp >= data[cache] && cp < data[cache+2]) {
             return data[cache+1];
         }
-        if (cp >= CHAR_START & cp < CHAR_LIMIT) {
+        if ((cp >= CHAR_START) && (cp < CHAR_LIMIT)) {
             int probe = dataPower;
             int index = 0;
 
--- a/src/share/classes/sun/java2d/opengl/OGLMaskFill.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/java2d/opengl/OGLMaskFill.java	Thu Jan 12 06:59:38 2017 +0000
@@ -26,6 +26,7 @@
 package sun.java2d.opengl;
 
 import java.awt.Composite;
+import sun.java2d.InvalidPipeException;
 import sun.java2d.SunGraphics2D;
 import sun.java2d.loops.GraphicsPrimitive;
 import sun.java2d.loops.GraphicsPrimitiveMgr;
@@ -67,7 +68,14 @@
     protected void validateContext(SunGraphics2D sg2d,
                                    Composite comp, int ctxflags)
     {
-        OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
+        OGLSurfaceData dstData;
+        try {
+            dstData = (OGLSurfaceData) sg2d.surfaceData;
+        } catch (ClassCastException e) {
+            throw new InvalidPipeException("wrong surface data type: " +
+                                           sg2d.surfaceData);
+        }
+
         OGLContext.validateContext(dstData, dstData,
                                    sg2d.getCompClip(), comp,
                                    null, sg2d.paint, sg2d, ctxflags);
--- a/src/share/classes/sun/java2d/pipe/BufferedContext.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/java2d/pipe/BufferedContext.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -38,6 +38,8 @@
 import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN;
 
 import java.lang.annotation.Native;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
 
 /**
  * Base context class for managing state in a single-threaded rendering
@@ -87,11 +89,11 @@
      */
     protected static BufferedContext currentContext;
 
-    private AccelSurface    validatedSrcData;
-    private AccelSurface    validatedDstData;
-    private Region          validatedClip;
-    private Composite       validatedComp;
-    private Paint           validatedPaint;
+    private Reference<AccelSurface> validSrcDataRef = new WeakReference<>(null);
+    private Reference<AccelSurface> validDstDataRef = new WeakReference<>(null);
+    private Reference<Region> validClipRef = new WeakReference<>(null);
+    private Reference<Composite> validCompRef = new WeakReference<>(null);
+    private Reference<Paint> validPaintRef = new WeakReference<>(null);
     // renamed from isValidatedPaintAColor as part of a work around for 6764257
     private boolean         isValidatedPaintJustAColor;
     private int             validatedRGB;
@@ -127,9 +129,9 @@
                                        int flags)
     {
         // assert rq.lock.isHeldByCurrentThread();
-        BufferedContext d3dc = dstData.getContext();
-        d3dc.validate(srcData, dstData,
-                      clip, comp, xform, paint, sg2d, flags);
+        BufferedContext context = dstData.getContext();
+        context.validate(srcData, dstData,
+                         clip, comp, xform, paint, sg2d, flags);
     }
 
     /**
@@ -200,13 +202,15 @@
                 updatePaint = true;
                 isValidatedPaintJustAColor = true;
             }
-        } else if (validatedPaint != paint) {
+        } else if (validPaintRef.get() != paint) {
             updatePaint = true;
             // this should be set when we are switching from paint to color
             // in which case this condition will be true
             isValidatedPaintJustAColor = false;
         }
 
+        final AccelSurface validatedSrcData = validSrcDataRef.get();
+        final AccelSurface validatedDstData = validDstDataRef.get();
         if ((currentContext != this) ||
             (srcData != validatedSrcData) ||
             (dstData != validatedDstData))
@@ -228,11 +232,12 @@
             setSurfaces(srcData, dstData);
 
             currentContext = this;
-            validatedSrcData = srcData;
-            validatedDstData = dstData;
+            validSrcDataRef = new WeakReference<>(srcData);
+            validDstDataRef = new WeakReference<>(dstData);
         }
 
         // validate clip
+        final Region validatedClip = validClipRef.get();
         if ((clip != validatedClip) || updateClip) {
             if (clip != null) {
                 if (updateClip ||
@@ -248,13 +253,13 @@
             } else {
                 resetClip();
             }
-            validatedClip = clip;
+            validClipRef = new WeakReference<>(clip);
         }
 
         // validate composite (note that a change in the context flags
         // may require us to update the composite state, even if the
         // composite has not changed)
-        if ((comp != validatedComp) || (flags != validatedFlags)) {
+        if ((comp != validCompRef.get()) || (flags != validatedFlags)) {
             if (comp != null) {
                 setComposite(comp, flags);
             } else {
@@ -263,7 +268,7 @@
             // the paint state is dependent on the composite state, so make
             // sure we update the color below
             updatePaint = true;
-            validatedComp = comp;
+            validCompRef = new WeakReference<>(comp);
             validatedFlags = flags;
         }
 
@@ -297,7 +302,7 @@
             } else {
                 BufferedPaints.resetPaint(rq);
             }
-            validatedPaint = paint;
+            validPaintRef = new WeakReference<>(paint);
         }
 
         // mark dstData dirty
@@ -315,9 +320,9 @@
      * @see RenderQueue#lock
      * @see RenderQueue#unlock
      */
-    public void invalidateSurfaces() {
-        validatedSrcData = null;
-        validatedDstData = null;
+    private void invalidateSurfaces() {
+        validSrcDataRef.clear();
+        validDstDataRef.clear();
     }
 
     private void setSurfaces(AccelSurface srcData,
@@ -434,9 +439,9 @@
         resetClip();
         BufferedPaints.resetPaint(rq);
         invalidateSurfaces();
-        validatedComp = null;
-        validatedClip = null;
-        validatedPaint = null;
+        validCompRef.clear();
+        validClipRef.clear();
+        validPaintRef.clear();
         isValidatedPaintJustAColor = false;
         xformInUse = false;
     }
--- a/src/share/classes/sun/reflect/annotation/AnnotationType.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/reflect/annotation/AnnotationType.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -118,16 +118,22 @@
         members = new HashMap<String, Method>(methods.length+1, 1.0f);
 
         for (Method method :  methods) {
-            if (method.getParameterTypes().length != 0)
-                throw new IllegalArgumentException(method + " has params");
-            String name = method.getName();
-            Class<?> type = method.getReturnType();
-            memberTypes.put(name, invocationHandlerReturnType(type));
-            members.put(name, method);
+            if (Modifier.isPublic(method.getModifiers()) &&
+                Modifier.isAbstract(method.getModifiers()) &&
+                !method.isSynthetic()) {
+                if (method.getParameterTypes().length != 0) {
+                    throw new IllegalArgumentException(method + " has params");
+                }
+                String name = method.getName();
+                Class<?> type = method.getReturnType();
+                memberTypes.put(name, invocationHandlerReturnType(type));
+                members.put(name, method);
 
-            Object defaultValue = method.getDefaultValue();
-            if (defaultValue != null)
-                memberDefaults.put(name, defaultValue);
+                Object defaultValue = method.getDefaultValue();
+                if (defaultValue != null) {
+                    memberDefaults.put(name, defaultValue);
+                }
+            }
         }
 
         // Initialize retention, & inherited fields.  Special treatment
--- a/src/share/classes/sun/security/jca/ProviderConfig.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/jca/ProviderConfig.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -255,6 +255,15 @@
                         disableLoad();
                     }
                     return null;
+                } catch (ExceptionInInitializerError err) {
+                    // unexpected exception thrown from static initialization block in provider
+                    // (ex: insufficient permission to initialize provider class)
+                    if (debug != null) {
+                        debug.println("Error loading provider " + ProviderConfig.this);
+                        err.printStackTrace();
+                    }
+                    disableLoad();
+                    return null;
                 }
             }
         });
--- a/src/share/classes/sun/security/krb5/Config.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/krb5/Config.java	Thu Jan 12 06:59:38 2017 +0000
@@ -525,9 +525,9 @@
                 String previous = null;
                 while ((line = br.readLine()) != null) {
                     line = line.trim();
-                    if (line.startsWith("#") || line.isEmpty()) {
+                    if (line.isEmpty() || line.startsWith("#") || line.startsWith(";")) {
                         // ignore comments and blank line
-                        // Comments start with #.
+                        // Comments start with '#' or ';'
                         continue;
                     }
                     // In practice, a subsection might look like:
--- a/src/share/classes/sun/security/krb5/KrbKdcRep.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/krb5/KrbKdcRep.java	Thu Jan 12 06:59:38 2017 +0000
@@ -62,7 +62,8 @@
             throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
         }
 
-        for (int i = 1; i < 6; i++) {
+        // We allow KDC to return a non-forwardable ticket if request has -f
+        for (int i = 2; i < 6; i++) {
             if (req.reqBody.kdcOptions.get(i) !=
                    rep.encKDCRepPart.flags.get(i)) {
                 if (Krb5.DEBUG) {
--- a/src/share/classes/sun/security/krb5/KrbTgsReq.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java	Thu Jan 12 06:59:38 2017 +0000
@@ -150,19 +150,11 @@
         ctime = KerberosTime.now();
 
         // check if they are valid arguments. The optional fields
-        // should be  consistent with settings in KDCOptions.
-
-        // TODO: Is this necessary? If the TGT is not FORWARDABLE,
-        // you can still request for a FORWARDABLE ticket, just the
-        // KDC will give you a non-FORWARDABLE one. Even if you
-        // cannot use the ticket expected, it still contains info.
-        // This means there will be problem later. We already have
-        // flags check in KrbTgsRep. Of course, sometimes the KDC
-        // will not issue the ticket at all.
+        // should be consistent with settings in KDCOptions.
 
         if (options.get(KDCOptions.FORWARDABLE) &&
                 (!(asCreds.flags.get(Krb5.TKT_OPTS_FORWARDABLE)))) {
-            throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
+            options.set(KDCOptions.FORWARDABLE, false);
         }
         if (options.get(KDCOptions.FORWARDED)) {
             if (!(asCreds.flags.get(KDCOptions.FORWARDABLE)))
--- a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java	Thu Jan 12 06:59:38 2017 +0000
@@ -58,6 +58,9 @@
             // TODO: we do not support kerberos referral now
             throw new KrbException("Cross realm impersonation not supported");
         }
+        if (!ccreds.isForwardable()) {
+            throw new KrbException("S4U2self needs a FORWARDABLE ticket");
+        }
         KrbTgsReq req = new KrbTgsReq(
                 ccreds,
                 ccreds.getClient(),
@@ -68,6 +71,9 @@
         if (!creds.getClient().equals(client)) {
             throw new KrbException("S4U2self request not honored by KDC");
         }
+        if (!creds.isForwardable()) {
+            throw new KrbException("S4U2self ticket must be FORWARDABLE");
+        }
         return creds;
     }
 
--- a/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Thu Jan 12 06:59:38 2017 +0000
@@ -228,29 +228,34 @@
         // check native range first
         if ((minKeySize != -1) && (keySize < minKeySize)) {
             throw new InvalidAlgorithmParameterException(algorithm +
-                " key must be at least " + minKeySize + " bits");
+                " key must be at least " + minKeySize + " bits. " +
+                "The specific key size " + keySize + " is not supported");
         }
         if ((maxKeySize != -1) && (keySize > maxKeySize)) {
             throw new InvalidAlgorithmParameterException(algorithm +
-                " key must be at most " + maxKeySize + " bits");
+                " key must be at most " + maxKeySize + " bits. " +
+                "The specific key size " + keySize + " is not supported");
         }
 
         // check our own algorithm-specific limits also
         if (algorithm.equals("EC")) {
             if (keySize < 112) {
-                throw new InvalidAlgorithmParameterException
-                    ("Key size must be at least 112 bit");
+                    throw new InvalidAlgorithmParameterException(
+                    "EC key size must be at least 112 bit. " +
+                    "The specific key size " + keySize + " is not supported");
             }
             if (keySize > 2048) {
                 // sanity check, nobody really wants keys this large
-                throw new InvalidAlgorithmParameterException
-                    ("Key size must be at most 2048 bit");
+                throw new InvalidAlgorithmParameterException(
+                    "EC key size must be at most 2048 bit. " +
+                    "The specific key size " + keySize + " is not supported");
             }
         } else {
             // RSA, DH, DSA
             if (keySize < 512) {
-                throw new InvalidAlgorithmParameterException
-                    ("Key size must be at least 512 bit");
+                throw new InvalidAlgorithmParameterException(algorithm +
+                    " key size must be at least 512 bit. " +
+                    "The specific key size " + keySize + " is not supported");
             }
             if (algorithm.equals("RSA")) {
                 BigInteger tmpExponent = rsaPublicExponent;
@@ -271,8 +276,10 @@
                 if (algorithm.equals("DH") && (params != null)) {
                     // sanity check, nobody really wants keys this large
                     if (keySize > 64 * 1024) {
-                        throw new InvalidAlgorithmParameterException
-                            ("Key size must be at most 65536 bit");
+                        throw new InvalidAlgorithmParameterException(
+                            "DH key size must be at most 65536 bit. " +
+                            "The specific key size " +
+                            keySize + " is not supported");
                     }
                 } else {
                     // this restriction is in the spec for DSA
@@ -282,7 +289,9 @@
                         ((keySize > 1024) || ((keySize & 0x3f) != 0))) {
                         throw new InvalidAlgorithmParameterException(algorithm +
                             " key must be multiples of 64 if less than 1024 bits" +
-                            ", or 2048 bits, or 4096 bits");
+                            ", or 2048 bits, or 4096 bits. " +
+                            "The specific key size " +
+                            keySize + " is not supported");
                     }
                 }
             }
--- a/src/share/classes/sun/security/pkcs11/P11KeyStore.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/pkcs11/P11KeyStore.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -752,6 +752,21 @@
             } else {
                 login(new PasswordCallbackHandler(password));
             }
+        } catch(LoginException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof PKCS11Exception) {
+                PKCS11Exception pe = (PKCS11Exception) cause;
+                if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
+                    // if password is wrong, the cause of the IOException
+                    // should be an UnrecoverableKeyException
+                    throw new IOException("load failed",
+                            new UnrecoverableKeyException().initCause(e));
+                }
+            }
+            throw new IOException("load failed", e);
+        }
+
+        try {
             if (mapLabels() == true) {
                 // CKA_LABELs are shared by multiple certs
                 writeDisabled = true;
@@ -759,7 +774,7 @@
             if (debug != null) {
                 dumpTokenMap();
             }
-        } catch (LoginException | KeyStoreException | PKCS11Exception e) {
+        } catch (KeyStoreException | PKCS11Exception e) {
             throw new IOException("load failed", e);
         }
     }
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Thu Jan 12 06:59:38 2017 +0000
@@ -2051,7 +2051,7 @@
                 }
 
                 if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
-                   throw new SecurityException("Failed PKCS12" +
+                   throw new UnrecoverableKeyException("Failed PKCS12" +
                                         " integrity checking");
                 }
            } catch (Exception e) {
--- a/src/share/classes/sun/security/ssl/CipherBox.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/CipherBox.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1044,40 +1044,6 @@
         return nonce;
     }
 
-    /*
-     * 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.
      *
--- a/src/share/classes/sun/security/ssl/CipherSuite.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/CipherSuite.java	Thu Jan 12 06:59:38 2017 +0000
@@ -75,12 +75,6 @@
     // minimum priority for default enabled CipherSuites
     final static 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.
-    final static boolean DYNAMIC_AVAILABILITY = true;
-
     private final static boolean ALLOW_ECC = Debug.getBooleanProperty
         ("com.sun.net.ssl.enableECC", true);
 
@@ -186,9 +180,6 @@
      * 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();
@@ -404,10 +395,6 @@
      */
     final static class BulkCipher {
 
-        // Map BulkCipher -> Boolean(available)
-        private final static Map<BulkCipher,Boolean> availableCache =
-                                            new HashMap<>(8);
-
         // descriptive name including key size, e.g. AES/128
         final String description;
 
@@ -451,6 +438,9 @@
         // The secure random used to detect the cipher availability.
         private final static SecureRandom secureRandom;
 
+        // runtime availability
+        private final boolean isAvailable;
+
         static {
             try {
                 secureRandom = JsseJce.getSecureRandom();
@@ -475,6 +465,17 @@
 
             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,
@@ -491,6 +492,17 @@
 
             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;
         }
 
         /**
@@ -508,84 +520,27 @@
 
         /**
          * 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;
-            }
-
-            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();
-            }
+            return this.isAvailable;
         }
 
-        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;
-                    }
-                }
+        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) {
 
-                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,
-                                            key, iv, secureRandom, true);
-                        b = temporary.isAvailable();
-                    } catch (NoSuchAlgorithmException e) {
-                        // not available
-                    } finally {
-                        if (temporary != null) {
-                            temporary.dispose();
-                        }
+                        return false;
                     }
+                } catch (Exception e) {
+                    return false;
                 }
-
-                availableCache.put(cipher, b);
             }
 
-            return b.booleanValue();
+            return true;
         }
 
         @Override
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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 @@
             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 @@
         }
         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();
-        }
-    }
 }
--- a/src/share/classes/sun/security/ssl/JsseJce.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/JsseJce.java	Thu Jan 12 06:59:38 2017 +0000
@@ -55,11 +55,6 @@
 
     private final static 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 final static boolean kerberosAvailable;
@@ -195,24 +190,8 @@
         // no instantiation of this class
     }
 
-    synchronized static 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;
-    }
-
-    synchronized static void clearEcAvailable() {
-        ecAvailable = null;
+    static boolean isEcAvailable() {
+        return EcAvailability.isAvailable;
     }
 
     static boolean isKerberosAvailable() {
@@ -414,4 +393,27 @@
         }
     }
 
+
+    // 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;
+        }
+    }
 }
--- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Thu Jan 12 06:59:38 2017 +0000
@@ -90,6 +90,30 @@
     }
 
     /*
+     * Retrieving the cipher's provider name for the debug purposes
+     * can throw an exception by itself.
+     */
+    private static String safeProviderName(Cipher cipher) {
+        try {
+            return cipher.getProvider().toString();
+        } catch (Exception e) {
+            if (debug != null && Debug.isOn("handshake")) {
+                System.out.println("Retrieving The Cipher provider name" +
+                        " caused exception " + e.getMessage());
+            }
+        }
+        try {
+            return cipher.toString() + " (provider name not available)";
+        } catch (Exception e) {
+            if (debug != null && Debug.isOn("handshake")) {
+                System.out.println("Retrieving The Cipher name" +
+                        " caused exception " + e.getMessage());
+            }
+        }
+        return "(cipher/provider names not available)";
+    }
+
+    /*
      * Server gets the PKCS #1 (block format 02) data, decrypts
      * it with its private key.
      */
@@ -130,15 +154,19 @@
                         cipher.getProvider().getName());
             } catch (InvalidKeyException | UnsupportedOperationException iue) {
                 if (debug != null && Debug.isOn("handshake")) {
-                    System.out.println("The Cipher provider " +
-                        cipher.getProvider().getName() +
-                        " caused exception: " + iue.getMessage());
+                    System.out.println("The Cipher provider "
+                            + safeProviderName(cipher)
+                            + " caused exception: " + iue.getMessage());
                 }
 
                 needFailover = true;
             }
 
             if (needFailover) {
+                // The cipher might be spoiled by unsuccessful call to init(),
+                // so request a fresh instance
+                cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
+
                 // Use DECRYPT_MODE and dispose the previous initialization.
                 cipher.init(Cipher.DECRYPT_MODE, privateKey);
                 boolean failed = false;
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, 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,16 +52,6 @@
     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;
-
     SSLContextImpl() {
         ephemeralKeyManager = new EphemeralKeyManager();
         clientCache = new SSLSessionContextImpl();
@@ -191,6 +181,8 @@
         }
         return new SSLServerSocketFactoryImpl(this);
     }
+    abstract SSLEngine createSSLEngineImpl();
+    abstract SSLEngine createSSLEngineImpl(String host, int port);
 
     @Override
     protected SSLEngine engineCreateSSLEngine() {
@@ -198,7 +190,7 @@
             throw new IllegalStateException(
                 "SSLContextImpl is not initialized");
         }
-        return new SSLEngineImpl(this);
+        return createSSLEngineImpl();
     }
 
     @Override
@@ -207,7 +199,7 @@
             throw new IllegalStateException(
                 "SSLContextImpl is not initialized");
         }
-        return new SSLEngineImpl(this, host, port);
+        return createSSLEngineImpl(host, port);
     }
 
     @Override
@@ -236,78 +228,35 @@
         return ephemeralKeyManager;
     }
 
-    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();
+
+    // Get default ProtocolList for server mode.
+    abstract ProtocolList getServerDefaultProtocolList();
+
+    // Get default ProtocolList for client mode.
+    abstract ProtocolList getClientDefaultProtocolList();
 
-        return supportedProtocolList;
-    }
+    // 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();
     }
 
     /**
@@ -315,16 +264,24 @@
      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
      */
     boolean isDefaultProtocolList(ProtocolList protocols) {
-        return (protocols == defaultServerProtocolList) ||
-               (protocols == defaultClientProtocolList);
+        return (protocols == getServerDefaultProtocolList()) ||
+                (protocols == getClientDefaultProtocolList());
     }
 
+    /**
+     * Return whether a protocol list is the original default enabled
+     * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
+     */
+    boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
+        return (cipherSuites == getServerDefaultCipherSuiteList()) ||
+                (cipherSuites == getClientDefaultCipherSuiteList());
+    }
 
     /*
      * Return the list of all available CipherSuites with a priority of
      * minPriority or above.
      */
-    private CipherSuiteList getApplicableCipherSuiteList(
+    private static CipherSuiteList getApplicableCipherSuiteList(
             ProtocolList protocols, boolean onlyEnabled) {
 
         int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
@@ -370,22 +327,20 @@
         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) {
+
+        List<String> availableProtocols = Collections.<String>emptyList();
+        if (protocolCandidates !=  null && protocolCandidates.length != 0) {
+            availableProtocols = new ArrayList<>(protocolCandidates.length);
+            for (ProtocolVersion p : protocolCandidates) {
+                if (ProtocolVersion.availableProtocols.contains(p)) {
+                    availableProtocols.add(p.name);
+                }
+            }
         }
+
+        return availableProtocols.toArray(new String[0]);
     }
 
     /*
@@ -418,39 +373,37 @@
      */
 
     /*
-     * The base abstract SSLContext implementation.
+     * The base abstract SSLContext implementation for the Transport Layer
+     * Security (TLS) protocols.
      *
      * This abstract class encapsulates supported and the default server
-     * SSL parameters.
+     * SSL/TLS parameters.
      *
      * @see SSLContext
      */
-    private abstract static class AbstractSSLContext extends SSLContextImpl {
-        // parameters
-        private static final SSLParameters defaultServerSSLParams;
-        private static final SSLParameters supportedSSLParams;
+    private abstract static class AbstractTLSContext extends SSLContextImpl {
+        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,
@@ -458,44 +411,50 @@
                     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).toArray(new String[0]));
+            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;
         }
 
-        static List<String> getAvailableProtocols(
-                ProtocolVersion[] protocolCandidates) {
+        @Override
+        CipherSuiteList getServerDefaultCipherSuiteList() {
+            return serverDefaultCipherSuiteList;
+        }
 
-            List<String> availableProtocols = Collections.<String>emptyList();
-            if (protocolCandidates !=  null && protocolCandidates.length != 0) {
-                availableProtocols = new ArrayList<>(protocolCandidates.length);
-                for (ProtocolVersion p : protocolCandidates) {
-                    if (ProtocolVersion.availableProtocols.contains(p)) {
-                        availableProtocols.add(p.name);
-                    }
-                }
-            }
+        @Override
+        SSLEngine createSSLEngineImpl() {
+            return new SSLEngineImpl(this);
+        }
 
-            return availableProtocols;
+        @Override
+        SSLEngine createSSLEngineImpl(String host, int port) {
+            return new SSLEngineImpl(this, host, port);
         }
     }
 
@@ -504,31 +463,36 @@
      *
      * @see SSLContext
      */
-    public static final class TLS10Context extends AbstractSSLContext {
-        private static final SSLParameters defaultClientSSLParams;
+    public static final class TLS10Context extends AbstractTLSContext {
+        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).toArray(new String[0]));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -537,33 +501,38 @@
      *
      * @see SSLContext
      */
-    public static final class TLS11Context extends AbstractSSLContext {
-        private static final SSLParameters defaultClientSSLParams;
+    public static final class TLS11Context extends AbstractTLSContext {
+        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).toArray(new String[0]));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -572,35 +541,101 @@
      *
      * @see SSLContext
      */
-    public static final class TLS12Context extends AbstractSSLContext {
-        private static final SSLParameters defaultClientSSLParams;
+    public static final class TLS12Context extends AbstractTLSContext {
+        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).toArray(new String[0]));
+            clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                    clientDefaultProtocolList, true);       // enabled only
+        }
+
+        @Override
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
+        }
+    }
+
+    /*
+     * The interface for the customized SSL/(D)TLS SSLContext.
+     *
+     * @see SSLContext
+     */
+    private static class CustomizedSSLProtocols {
+        private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
+        static IllegalArgumentException reservedException = null;
+        static ArrayList<ProtocolVersion>
+                customizedProtocols = new ArrayList<>();
+
+        // Don't want a java.lang.LinkageError for illegal system property.
+        //
+        // Please don't throw exception in this static block.  Otherwise,
+        // java.lang.LinkageError may be thrown during the instantiation of
+        // the provider service. Instead, please handle the initialization
+        // exception in the caller's constructor.
+        static {
+            String property = AccessController.doPrivileged(
+                    new GetPropertyAction(PROPERTY_NAME));
+            if (property != null && property.length() != 0) {
+                // remove double quote marks from beginning/end of the property
+                if (property.length() > 1 && property.charAt(0) == '"' &&
+                        property.charAt(property.length() - 1) == '"') {
+                    property = property.substring(1, property.length() - 1);
+                }
+            }
+
+            if (property != null && property.length() != 0) {
+                String[] protocols = property.split(",");
+                for (int i = 0; i < protocols.length; i++) {
+                    protocols[i] = protocols[i].trim();
+                    // Is it a supported protocol name?
+                    try {
+                        ProtocolVersion pro =
+                                ProtocolVersion.valueOf(protocols[i]);
+
+                        if (SunJSSE.isFIPS() &&
+                                ((pro.v == ProtocolVersion.SSL30.v) ||
+                                        (pro.v == ProtocolVersion.SSL20Hello.v))) {
+                            reservedException = new IllegalArgumentException(
+                                    PROPERTY_NAME + ": " + pro +
+                                            " is not FIPS compliant");
+
+                            break;
+                        }
+
+                        // ignore duplicated protocols
+                        if (!customizedProtocols.contains(pro)) {
+                            customizedProtocols.add(pro);
+                        }
+                    } catch (IllegalArgumentException iae) {
+                        reservedException = new IllegalArgumentException(
+                                PROPERTY_NAME + ": " + protocols[i] +
+                                        " is not a standard SSL protocol name", iae);
+                    }
+                }
+            }
         }
     }
 
@@ -609,9 +644,11 @@
      *
      * @see SSLContext
      */
-    private static class CustomizedSSLContext extends AbstractSSLContext {
-        private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
-        private static final SSLParameters defaultClientSSLParams;
+    private static class CustomizedTLSContext extends AbstractTLSContext {
+
+        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.
@@ -621,86 +658,65 @@
         // the provider service. Instead, let's handle the initialization
         // exception in constructor.
         static {
-            // candidates for available protocols
-            ProtocolVersion[] candidates;
-
-            String property = AccessController.doPrivileged(
-                    new GetPropertyAction(PROPERTY_NAME));
-            if (property == null || property.length() == 0) {
-                // the default enabled client TLS protocols
-                if (SunJSSE.isFIPS()) {
-                    candidates = new ProtocolVersion[] {
-                        ProtocolVersion.TLS10,
-                        ProtocolVersion.TLS11,
-                        ProtocolVersion.TLS12
-                    };
-                } else {
-                    candidates = new ProtocolVersion[] {
-                        ProtocolVersion.SSL30,
-                        ProtocolVersion.TLS10,
-                        ProtocolVersion.TLS11,
-                        ProtocolVersion.TLS12
-                    };
-                }
-            } else {
-                // remove double quote marks from beginning/end of the property
-                if (property.length() > 1 && property.charAt(0) == '"' &&
-                        property.charAt(property.length() - 1) == '"') {
-                    property = property.substring(1, property.length() - 1);
+            reservedException = CustomizedSSLProtocols.reservedException;
+            if (reservedException == null) {
+                ArrayList<ProtocolVersion>
+                        customizedTLSProtocols = new ArrayList<>();
+                for (ProtocolVersion protocol :
+                        CustomizedSSLProtocols.customizedProtocols) {
+                        customizedTLSProtocols.add(protocol);
                 }
 
-                String[] protocols = null;
-                if (property != null && property.length() != 0) {
-                    protocols = property.split(",");
+                // candidates for available protocols
+                ProtocolVersion[] candidates;
+                if (customizedTLSProtocols.isEmpty()) {
+                    // Use the default enabled client protocols if no
+                    // customized TLS protocols.
+                    if (SunJSSE.isFIPS()) {
+                        candidates = new ProtocolVersion[] {
+                                ProtocolVersion.TLS10,
+                                ProtocolVersion.TLS11,
+                                ProtocolVersion.TLS12
+                        };
+                    } else {
+                        candidates = new ProtocolVersion[] {
+                                ProtocolVersion.SSL30,
+                                ProtocolVersion.TLS10,
+                                ProtocolVersion.TLS11,
+                                ProtocolVersion.TLS12
+                        };
+                    }
                 } else {
-                    reservedException = new IllegalArgumentException(
-                        "No protocol specified in " +
-                        PROPERTY_NAME + " system property");
-                    protocols = new String[0];
+                    // Use the customized TLS protocols.
+                    candidates =
+                            new ProtocolVersion[customizedTLSProtocols.size()];
+                    candidates = customizedTLSProtocols.toArray(candidates);
                 }
 
-                candidates = new ProtocolVersion[protocols.length];
-                for (int i = 0; i < protocols.length; i++) {
-                    protocols[i] = protocols[i].trim();
-                    // Is it a supported protocol name?
-                    try {
-                        candidates[i] = ProtocolVersion.valueOf(protocols[i]);
-                    } catch (IllegalArgumentException iae) {
-                        reservedException = new IllegalArgumentException(
-                            PROPERTY_NAME + ": " + protocols[i] +
-                            " is not a standard SSL/TLS protocol name", iae);
-                        break;
-                    }
-                }
-
-                if ((reservedException == null) && SunJSSE.isFIPS()) {
-                    for (ProtocolVersion protocolVersion : candidates) {
-                        if (ProtocolVersion.SSL20Hello.v == protocolVersion.v ||
-                                ProtocolVersion.SSL30.v == protocolVersion.v) {
-                            reservedException = new IllegalArgumentException(
-                                    PROPERTY_NAME + ": " + protocolVersion +
-                                    " is not FIPS compliant");
-                        }
-                    }
-                }
-            }
-
-            defaultClientSSLParams = new SSLParameters();
-            if (reservedException == null) {
-                defaultClientSSLParams.setProtocols(
-                    getAvailableProtocols(candidates).toArray(new String[0]));
+                clientDefaultProtocolList = new ProtocolList(
+                        getAvailableProtocols(candidates));
+                clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
+                        clientDefaultProtocolList, true);   // enabled only
+            } else {
+                clientDefaultProtocolList = null;       // unlikely to be used
+                clientDefaultCipherSuiteList = null;    // unlikely to be used
             }
         }
 
-        protected CustomizedSSLContext() {
+        protected CustomizedTLSContext() {
             if (reservedException != null) {
                 throw reservedException;
             }
         }
 
         @Override
-        SSLParameters getDefaultClientSSLParams() {
-            return defaultClientSSLParams;
+        ProtocolList getClientDefaultProtocolList() {
+            return clientDefaultProtocolList;
+        }
+
+        @Override
+        CipherSuiteList getClientDefaultCipherSuiteList() {
+            return clientDefaultCipherSuiteList;
         }
     }
 
@@ -709,75 +725,57 @@
      *
      * @see SSLContext
      */
-    public static final class TLSContext extends CustomizedSSLContext {
+    public static final class TLSContext extends CustomizedTLSContext {
         // use the default constructor and methods
     }
 
-    /*
-     * The SSLContext implementation for default "Default" algorithm
-     *
-     * @see SSLContext
-     */
-    public static final class DefaultSSLContext extends CustomizedSSLContext {
+    // 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(
@@ -874,11 +872,75 @@
                 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;
+        }
+    }
+
+
 }
 
 
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Thu Jan 12 06:59:38 2017 +0000
@@ -137,8 +137,10 @@
                 customizedDHKeySize = Integer.parseUnsignedInt(property);
                 if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) {
                     throw new IllegalArgumentException(
-                        "Customized DH key size should be positive integer " +
-                        "between 1024 and 2048 bits, inclusive");
+                        "Unsupported customized DH key size: " +
+                        customizedDHKeySize + ". " +
+                        "The key size can only range from 1024" +
+                        " to 2048 (inclusive)");
                 }
             } catch (NumberFormatException nfe) {
                 throw new IllegalArgumentException(
--- a/src/share/classes/sun/tools/native2ascii/Main.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/classes/sun/tools/native2ascii/Main.java	Thu Jan 12 06:59:38 2017 +0000
@@ -71,11 +71,8 @@
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
-import java.nio.file.Files;
 import java.io.UnsupportedEncodingException;
 import java.nio.charset.UnsupportedCharsetException;
-import sun.tools.native2ascii.A2NFilter;
-import sun.tools.native2ascii.N2AFilter;
 
 /**
  * Main program of the native2ascii
@@ -94,7 +91,7 @@
     /**
      * Run the converter
      */
-    public synchronized boolean convert(String argv[]){
+    public synchronized boolean convert(String argv[]) {
         List<String> v = new ArrayList<>(2);
         File outputFile = null;
         boolean createOutputFile = false;
@@ -102,14 +99,14 @@
         // Parse arguments
         for (int i = 0; i < argv.length; i++) {
             if (argv[i].equals("-encoding")) {
-                if ((i + 1) < argv.length){
+                if ((i + 1) < argv.length) {
                     encodingString = argv[++i];
                 } else {
                     error(getMsg("err.bad.arg"));
                     usage();
                     return false;
                 }
-            } else if (argv[i].equals("-reverse")){
+            } else if (argv[i].equals("-reverse")) {
                 reverse = true;
             } else {
                 if (v.size() > 1) {
@@ -119,15 +116,18 @@
                 v.add(argv[i]);
             }
         }
-        if (encodingString == null)
-           defaultEncoding = Charset.defaultCharset().name();
 
+        if (encodingString == null) {
+            defaultEncoding = Charset.defaultCharset().name();
+        }
         char[] lineBreak = System.getProperty("line.separator").toCharArray();
+
         try {
             initializeConverter();
 
-            if (v.size() == 1)
+            if (v.size() == 1) {
                 inputFileName = v.get(0);
+            }
 
             if (v.size() == 2) {
                 inputFileName = v.get(0);
@@ -137,40 +137,38 @@
 
             if (createOutputFile) {
                 outputFile = new File(outputFileName);
-                    if (outputFile.exists() && !outputFile.canWrite()) {
-                        throw new Exception(formatMsg("err.cannot.write", outputFileName));
-                    }
+                if (outputFile.exists() && !outputFile.canWrite()) {
+                    throw new Exception(formatMsg("err.cannot.write", outputFileName));
+                }
             }
 
-            if (reverse){
-                BufferedReader reader = getA2NInput(inputFileName);
-                Writer osw = getA2NOutput(outputFileName);
-                String line;
-
-                while ((line = reader.readLine()) != null) {
-                    osw.write(line.toCharArray());
-                    osw.write(lineBreak);
-                    if (outputFileName == null) { // flush stdout
-                        osw.flush();
+            if (reverse) {
+                try (BufferedReader reader = getA2NInput(inputFileName);
+                        Writer osw = getA2NOutput(outputFileName);) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        osw.write(line.toCharArray());
+                        osw.write(lineBreak);
+                        if (outputFileName == null) { // flush stdout
+                            osw.flush();
+                        }
                     }
                 }
-                reader.close();  // Close the stream.
-                osw.close();
             } else {
-             //N2A
-                String inLine;
-                BufferedReader in = getN2AInput(inputFileName);
-                BufferedWriter out = getN2AOutput(outputFileName);
-
-                while ((inLine = in.readLine()) != null) {
-                    out.write(inLine.toCharArray());
-                    out.write(lineBreak);
-                    if (outputFileName == null) { // flush stdout
-                        out.flush();
+                // N2A
+                try (BufferedReader in = getN2AInput(inputFileName);
+                        BufferedWriter out = getN2AOutput(outputFileName);) {
+                    String inLine;
+                    while ((inLine = in.readLine()) != null) {
+                        out.write(inLine.toCharArray());
+                        out.write(lineBreak);
+                        if (outputFileName == null) { // flush stdout
+                            out.flush();
+                        }
                     }
                 }
-                out.close();
             }
+
             // Since we are done rename temporary file to desired output file
             if (createOutputFile) {
                 if (outputFile.exists()) {
@@ -182,8 +180,7 @@
                 }
                 tempFile.renameTo(outputFile);
             }
-
-        } catch(Exception e){
+        } catch (Exception e) {
             error(e.toString());
             return false;
         }
--- a/src/share/lib/security/sunpkcs11-solaris.cfg	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/share/lib/security/sunpkcs11-solaris.cfg	Thu Jan 12 06:59:38 2017 +0000
@@ -18,6 +18,7 @@
 
 disabledMechanisms = {
   CKM_DSA_KEY_PAIR_GEN
+  SecureRandom
 # the following mechanisms are disabled due to performance issues
 # (Solaris bug 6337157)
   CKM_DSA_SHA1
--- a/src/solaris/bin/jexec.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/bin/jexec.c	Thu Jan 12 06:59:38 2017 +0000
@@ -331,6 +331,7 @@
                 off_t end   = start  + xlen;
 
                 if (end <= count) {
+                    end -= 4; // make sure there are 4 bytes to read at start
                     while (start < end) {
                         off_t xhid  = SH(buf, start);
                         off_t xdlen = SH(buf, start + 2);
--- a/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/classes/sun/java2d/xr/XRRenderer.java	Thu Jan 12 06:59:38 2017 +0000
@@ -28,6 +28,7 @@
 import java.awt.*;
 import java.awt.geom.*;
 import sun.awt.SunToolkit;
+import sun.java2d.InvalidPipeException;
 import sun.java2d.SunGraphics2D;
 import sun.java2d.loops.*;
 import sun.java2d.pipe.Region;
@@ -69,7 +70,12 @@
      * destination context.
      */
     private final void validateSurface(SunGraphics2D sg2d) {
-        XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
+        XRSurfaceData xrsd;
+        try {
+            xrsd = (XRSurfaceData) sg2d.surfaceData;
+        } catch (ClassCastException e) {
+            throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
+        }
         xrsd.validateAsDestination(sg2d, sg2d.getCompClip());
         xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform,
                                                sg2d.paint, sg2d);
--- a/src/solaris/classes/sun/security/provider/NativePRNG.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/classes/sun/security/provider/NativePRNG.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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,8 @@
 import java.io.*;
 import java.net.*;
 import java.security.*;
+import java.util.Arrays;
+
 import sun.security.util.Debug;
 
 /**
@@ -334,7 +336,9 @@
         private final static long MAX_BUFFER_TIME = 100;
 
         // size of the "next" buffer
-        private final static int BUFFER_SIZE = 32;
+        private static final int MAX_BUFFER_SIZE = 65536;
+        private static final int MIN_BUFFER_SIZE = 32;
+        private int bufferSize = 256;
 
         // Holder for the seedFile.  Used if we ever add seed material.
         File seedFile;
@@ -351,7 +355,7 @@
         private volatile sun.security.provider.SecureRandom mixRandom;
 
         // buffer for next bits
-        private final byte[] nextBuffer;
+        private byte[] nextBuffer;
 
         // number of bytes left in nextBuffer
         private int buffered;
@@ -359,6 +363,16 @@
         // time we read the data into the nextBuffer
         private long lastRead;
 
+        // Count for the number of buffer size changes requests
+        // Positive value in increase size, negative to lower it.
+        private int change_buffer = 0;
+
+        // Request limit to trigger an increase in nextBuffer size
+        private static final int REQ_LIMIT_INC = 1000;
+
+        // Request limit to trigger a decrease in nextBuffer size
+        private static final int REQ_LIMIT_DEC = -100;
+
         // mutex lock for nextBytes()
         private final Object LOCK_GET_BYTES = new Object();
 
@@ -373,7 +387,7 @@
             this.seedFile = seedFile;
             seedIn = new FileInputStream(seedFile);
             nextIn = new FileInputStream(nextFile);
-            nextBuffer = new byte[BUFFER_SIZE];
+            nextBuffer = new byte[bufferSize];
         }
 
         // get the SHA1PRNG for mixing
@@ -466,9 +480,47 @@
         // if not, read new bytes
         private void ensureBufferValid() throws IOException {
             long time = System.currentTimeMillis();
-            if ((buffered > 0) && (time - lastRead < MAX_BUFFER_TIME)) {
-                return;
+            int new_buffer_size = 0;
+
+            // Check if buffer has bytes available that are not too old
+            if (buffered > 0) {
+                if (time - lastRead < MAX_BUFFER_TIME) {
+                    return;
+                } else {
+                    // byte is old, so subtract from counter to shrink buffer
+                    change_buffer--;
+                }
+            } else {
+                // No bytes available, so add to count to increase buffer
+                change_buffer++;
+            }
+
+            // If counter has it a limit, increase or decrease size
+            if (change_buffer > REQ_LIMIT_INC) {
+                new_buffer_size = nextBuffer.length * 2;
+            } else if (change_buffer < REQ_LIMIT_DEC) {
+                new_buffer_size = nextBuffer.length / 2;
             }
+
+            // If buffer size is to be changed, replace nextBuffer.
+            if (new_buffer_size > 0) {
+                if (new_buffer_size <= MAX_BUFFER_SIZE &&
+                        new_buffer_size >= MIN_BUFFER_SIZE) {
+                    nextBuffer = new byte[new_buffer_size];
+                    if (debug != null) {
+                        debug.println("Buffer size changed to " +
+                                new_buffer_size);
+                    }
+                } else {
+                    if (debug != null) {
+                        debug.println("Buffer reached limit: " +
+                                nextBuffer.length);
+                    }
+                }
+                change_buffer = 0;
+            }
+
+            // Load fresh random bytes into nextBuffer
             lastRead = time;
             readFully(nextIn, nextBuffer);
             buffered = nextBuffer.length;
@@ -478,24 +530,40 @@
         // read from "next" and XOR with bytes generated by the
         // mixing SHA1PRNG
         private void implNextBytes(byte[] data) {
-            synchronized (LOCK_GET_BYTES) {
                 try {
                     getMixRandom().engineNextBytes(data);
-                    int len = data.length;
+                    int data_len = data.length;
                     int ofs = 0;
-                    while (len > 0) {
-                        ensureBufferValid();
-                        int bufferOfs = nextBuffer.length - buffered;
-                        while ((len > 0) && (buffered > 0)) {
-                            data[ofs++] ^= nextBuffer[bufferOfs++];
-                            len--;
-                            buffered--;
+                    int len;
+                    int buf_pos;
+                    int localofs;
+                    byte[] localBuffer;
+
+                    while (data_len > 0) {
+                        synchronized (LOCK_GET_BYTES) {
+                            ensureBufferValid();
+                            buf_pos = nextBuffer.length - buffered;
+                            if (data_len > buffered) {
+                                len = buffered;
+                                buffered = 0;
+                            } else {
+                                len = data_len;
+                                buffered -= len;
+                            }
+                            localBuffer = Arrays.copyOfRange(nextBuffer, buf_pos,
+                                    buf_pos + len);
                         }
+                        localofs = 0;
+                        while (len > localofs) {
+                            data[ofs] ^= localBuffer[localofs];
+                            ofs++;
+                            localofs++;
+                        }
+                    data_len -= len;
                     }
-                } catch (IOException e) {
+                } catch (IOException e){
                     throw new ProviderException("nextBytes() failed", e);
                 }
-            }
+        }
         }
-    }
 }
--- a/src/solaris/native/java/net/NetworkInterface.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/native/java/net/NetworkInterface.c	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -23,7 +23,6 @@
  * questions.
  */
 
-
 #include <errno.h>
 #include <strings.h>
 #if defined(_ALLBSD_SOURCE) && defined(__OpenBSD__)
@@ -38,14 +37,14 @@
 #include <net/if.h>
 #include <net/if_arp.h>
 
-#ifdef __solaris__
+#if defined(__solaris__)
 #include <sys/dlpi.h>
 #include <fcntl.h>
 #include <stropts.h>
 #include <sys/sockio.h>
 #endif
 
-#ifdef __linux__
+#if defined(__linux__)
 #include <sys/ioctl.h>
 #include <bits/ioctls.h>
 #include <sys/utsname.h>
@@ -59,10 +58,6 @@
 #include <sys/kinfo.h>
 #endif
 
-#ifdef __linux__
-#define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
-#endif
-
 #if defined(_ALLBSD_SOURCE)
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -80,6 +75,10 @@
 #include "jni_util.h"
 #include "net_util.h"
 
+#if defined(__linux__)
+#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
+#endif
+
 typedef struct _netaddr  {
     struct sockaddr *addr;
     struct sockaddr *brdcast;
@@ -140,29 +139,32 @@
 static netif  *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
 #endif
 
-static netif  *addif(JNIEnv *env, int sock, const char * if_name, netif *ifs, struct sockaddr* ifr_addrP, int family, short prefix);
+static netif  *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
+                     struct sockaddr *ifr_addrP, int family, short prefix);
 static void    freeif(netif *ifs);
 
 static int     openSocket(JNIEnv *env, int proto);
 static int     openSocketWithFallback(JNIEnv *env, const char *ifname);
 
 
-static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name, struct sockaddr *brdcast_store);
+static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name,
+                                      struct sockaddr *brdcast_store);
 static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
 static int     getIndex(int sock, const char *ifname);
 
 static int     getFlags(int sock, const char *ifname, int *flags);
-static int     getMacAddress(JNIEnv *env, int sock,  const char* ifname, const struct in_addr* addr, unsigned char *buf);
+static int     getMacAddress(JNIEnv *env, int sock,  const char *ifname,
+                             const struct in_addr *addr, unsigned char *buf);
 static int     getMTU(JNIEnv *env, int sock, const char *ifname);
 
 
-
-#ifdef __solaris__
-static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family);
-static int    getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf);
+#if defined(__solaris__)
+static netif  *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family);
+static int     getMacFromDevice(JNIEnv *env, const char *ifname,
+                                unsigned char *retbuf);
 
 #ifndef SIOCGLIFHWADDR
-#define SIOCGLIFHWADDR  _IOWR('i', 192, struct lifreq)
+#define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq)
 #endif
 
 #endif
@@ -174,31 +176,36 @@
  * Method:    init
  * Signature: ()V
  */
-JNIEXPORT void JNICALL
-Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls) {
-    ni_class = (*env)->FindClass(env,"java/net/NetworkInterface");
+JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init
+  (JNIEnv *env, jclass cls)
+{
+    ni_class = (*env)->FindClass(env, "java/net/NetworkInterface");
     CHECK_NULL(ni_class);
     ni_class = (*env)->NewGlobalRef(env, ni_class);
     CHECK_NULL(ni_class);
-    ni_nameID = (*env)->GetFieldID(env, ni_class,"name", "Ljava/lang/String;");
+    ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
     CHECK_NULL(ni_nameID);
     ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
     CHECK_NULL(ni_indexID);
-    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
+    ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs",
+                                    "[Ljava/net/InetAddress;");
     CHECK_NULL(ni_addrsID);
-    ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
+    ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings",
+                                    "[Ljava/net/InterfaceAddress;");
     CHECK_NULL(ni_bindsID);
-    ni_descID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
+    ni_descID = (*env)->GetFieldID(env, ni_class, "displayName",
+                                   "Ljava/lang/String;");
     CHECK_NULL(ni_descID);
     ni_virutalID = (*env)->GetFieldID(env, ni_class, "virtual", "Z");
     CHECK_NULL(ni_virutalID);
-    ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
+    ni_childsID = (*env)->GetFieldID(env, ni_class, "childs",
+                                     "[Ljava/net/NetworkInterface;");
     CHECK_NULL(ni_childsID);
-    ni_parentID = (*env)->GetFieldID(env, ni_class, "parent", "Ljava/net/NetworkInterface;");
+    ni_parentID = (*env)->GetFieldID(env, ni_class, "parent",
+                                     "Ljava/net/NetworkInterface;");
     CHECK_NULL(ni_parentID);
     ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
     CHECK_NULL(ni_ctrID);
-
     ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
     CHECK_NULL(ni_iacls);
     ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
@@ -221,24 +228,26 @@
     CHECK_NULL(ni_ia6ctrID);
     ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
     CHECK_NULL(ni_ibctrID);
-    ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
+    ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address",
+                                        "Ljava/net/InetAddress;");
     CHECK_NULL(ni_ibaddressID);
-    ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
+    ni_ib4broadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast",
+                                           "Ljava/net/Inet4Address;");
     CHECK_NULL(ni_ib4broadcastID);
     ni_ib4maskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
     CHECK_NULL(ni_ib4maskID);
-    ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex", "I");
+    ni_defaultIndexID = (*env)->GetStaticFieldID(env, ni_class, "defaultIndex",
+                                                 "I");
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    getByName0
  * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
-    (JNIEnv *env, jclass cls, jstring name) {
-
+  (JNIEnv *env, jclass cls, jstring name)
+{
     netif *ifs, *curr;
     jboolean isCopy;
     const char* name_utf;
@@ -256,9 +265,8 @@
        freeif(ifs);
        return NULL;
     }
-    /*
-     * Search the list of interface based on name
-     */
+
+    // Search the list of interface based on name
     curr = ifs;
     while (curr != NULL) {
         if (strcmp(name_utf, curr->name) == 0) {
@@ -267,27 +275,26 @@
         curr = curr->next;
     }
 
-    /* if found create a NetworkInterface */
+    // if found create a NetworkInterface
     if (curr != NULL) {;
         obj = createNetworkInterface(env, curr);
     }
 
-    /* release the UTF string and interface list */
+    // release the UTF string and interface list
     (*env)->ReleaseStringUTFChars(env, name, name_utf);
     freeif(ifs);
 
     return obj;
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    getByIndex0
  * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
-    (JNIEnv *env, jclass cls, jint index) {
-
+  (JNIEnv *env, jclass cls, jint index)
+{
     netif *ifs, *curr;
     jobject obj = NULL;
 
@@ -300,9 +307,7 @@
         return NULL;
     }
 
-    /*
-     * Search the list of interface based on index
-     */
+    // Search the list of interface based on index
     curr = ifs;
     while (curr != NULL) {
         if (index == curr->index) {
@@ -311,7 +316,7 @@
         curr = curr->next;
     }
 
-    /* if found create a NetworkInterface */
+    // if found create a NetworkInterface
     if (curr != NULL) {;
         obj = createNetworkInterface(env, curr);
     }
@@ -326,8 +331,8 @@
  * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
-    (JNIEnv *env, jclass cls, jobject iaObj) {
-
+  (JNIEnv *env, jclass cls, jobject iaObj)
+{
     netif *ifs, *curr;
 
 #ifdef AF_INET6
@@ -348,14 +353,13 @@
     while (curr != NULL) {
         netaddr *addrP = curr->addr;
 
-        /*
-         * Iterate through each address on the interface
-         */
+        // Iterate through each address on the interface
         while (addrP != NULL) {
 
             if (family == addrP->family) {
                 if (family == AF_INET) {
-                    int address1 = htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);
+                    int address1 = htonl(
+                        ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr);
                     int address2 = getInetAddress_addr(env, iaObj);
 
                     if (address1 == address2) {
@@ -366,7 +370,8 @@
 
 #ifdef AF_INET6
                 if (family == AF_INET6) {
-                    jbyte *bytes = (jbyte *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr);
+                    jbyte *bytes = (jbyte *)&(
+                        ((struct sockaddr_in6*)addrP->addr)->sin6_addr);
                     jbyte caddr[16];
                     int i;
                     getInet6Address_ipaddress(env, iaObj, (char *)caddr);
@@ -383,7 +388,6 @@
                     }
                 }
 #endif
-
             }
 
             if (match) {
@@ -398,7 +402,7 @@
         curr = curr->next;
     }
 
-    /* if found create a NetworkInterface */
+    // if found create a NetworkInterface
     if (match) {;
         obj = createNetworkInterface(env, curr);
     }
@@ -407,15 +411,14 @@
     return obj;
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    getAll
  * Signature: ()[Ljava/net/NetworkInterface;
  */
 JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
-    (JNIEnv *env, jclass cls) {
-
+  (JNIEnv *env, jclass cls)
+{
     netif *ifs, *curr;
     jobjectArray netIFArr;
     jint arr_index, ifCount;
@@ -425,7 +428,7 @@
         return NULL;
     }
 
-    /* count the interface */
+    // count the interface
     ifCount = 0;
     curr = ifs;
     while (curr != NULL) {
@@ -433,17 +436,15 @@
         curr = curr->next;
     }
 
-    /* allocate a NetworkInterface array */
+    // allocate a NetworkInterface array
     netIFArr = (*env)->NewObjectArray(env, ifCount, cls, NULL);
     if (netIFArr == NULL) {
         freeif(ifs);
         return NULL;
     }
 
-    /*
-     * Iterate through the interfaces, create a NetworkInterface instance
-     * for each array element and populate the object.
-     */
+    // Iterate through the interfaces, create a NetworkInterface instance
+    // for each array element and populate the object.
     curr = ifs;
     arr_index = 0;
     while (curr != NULL) {
@@ -455,7 +456,7 @@
             return NULL;
         }
 
-        /* put the NetworkInterface into the array */
+        // put the NetworkInterface into the array
         (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
 
         curr = curr->next;
@@ -465,13 +466,14 @@
     return netIFArr;
 }
 
-
 /*
  * Class:     java_net_NetworkInterface
  * Method:    isUp0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return ((ret & IFF_UP) && (ret & IFF_RUNNING)) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -481,7 +483,9 @@
  * Method:    isP2P0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return (ret & IFF_POINTOPOINT) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -491,7 +495,9 @@
  * Method:    isLoopback0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return (ret & IFF_LOOPBACK) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -501,7 +507,9 @@
  * Method:    supportsMulticast0
  * Signature: (Ljava/lang/String;I)Z
  */
-JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0(JNIEnv *env, jclass cls, jstring name, jint index) {
+JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     int ret = getFlags0(env, name);
     return (ret & IFF_MULTICAST) ? JNI_TRUE :  JNI_FALSE;
 }
@@ -511,7 +519,9 @@
  * Method:    getMacAddr0
  * Signature: ([bLjava/lang/String;I)[b
  */
-JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
+JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0
+  (JNIEnv *env, jclass cls, jbyteArray addrArray, jstring name, jint index)
+{
     jint addr;
     jbyte caddr[4];
     struct in_addr iaddr;
@@ -533,7 +543,6 @@
        return NULL;
     }
 
-
     if (!IS_NULL(addrArray)) {
        (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
        addr = ((caddr[0]<<24) & 0xff000000);
@@ -543,7 +552,7 @@
        iaddr.s_addr = htonl(addr);
        len = getMacAddress(env, sock, name_utf, &iaddr, mac);
     } else {
-       len = getMacAddress(env, sock, name_utf,NULL, mac);
+       len = getMacAddress(env, sock, name_utf, NULL, mac);
     }
     if (len > 0) {
        ret = (*env)->NewByteArray(env, len);
@@ -551,10 +560,10 @@
           /* we may have memory to free at the end of this */
           goto fexit;
        }
-       (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) (mac));
+       (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *)(mac));
     }
  fexit:
-   /* release the UTF string and interface list */
+   // release the UTF string and interface list
    (*env)->ReleaseStringUTFChars(env, name, name_utf);
 
    close(sock);
@@ -566,8 +575,9 @@
  * Method:      getMTU0
  * Signature:   ([bLjava/lang/String;I)I
  */
-
-JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0(JNIEnv *env, jclass class, jstring name, jint index) {
+JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0
+  (JNIEnv *env, jclass cls, jstring name, jint index)
+{
     jboolean isCopy;
     int ret = -1;
     int sock;
@@ -585,7 +595,7 @@
        return ret;
     }
 
-    if ((sock =openSocketWithFallback(env, name_utf)) < 0) {
+    if ((sock = openSocketWithFallback(env, name_utf)) < 0) {
        (*env)->ReleaseStringUTFChars(env, name, name_utf);
        return JNI_FALSE;
     }
@@ -628,19 +638,17 @@
     (*env)->ReleaseStringUTFChars(env, name, name_utf);
 
     if (ret < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFFLAGS failed");
         return -1;
     }
 
     return flags;
 }
 
-
-
-
 /*
- * Create a NetworkInterface object, populate the name and index, and
- * populate the InetAddress array based on the IP addresses for this
+ * Creates a NetworkInterface object, populates the name, the index, and
+ * populates the InetAddress array based on the IP addresses for this
  * interface.
  */
 jobject createNetworkInterface(JNIEnv *env, netif *ifs) {
@@ -656,9 +664,7 @@
     netif *childP;
     jobject tmp;
 
-    /*
-     * Create a NetworkInterface object and populate it
-     */
+    // Create a NetworkInterface object and populate it
     netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
     CHECK_NULL_RETURN(netifObj, NULL);
     name = (*env)->NewStringUTF(env, ifs->name);
@@ -666,11 +672,10 @@
     (*env)->SetObjectField(env, netifObj, ni_nameID, name);
     (*env)->SetObjectField(env, netifObj, ni_descID, name);
     (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
-    (*env)->SetBooleanField(env, netifObj, ni_virutalID, ifs->virtual ? JNI_TRUE : JNI_FALSE);
+    (*env)->SetBooleanField(env, netifObj, ni_virutalID,
+                            ifs->virtual ? JNI_TRUE : JNI_FALSE);
 
-    /*
-     * Count the number of address on this interface
-     */
+    //Count the number of address on this interface
     addr_count = 0;
     addrP = ifs->addr;
     while (addrP != NULL) {
@@ -678,10 +683,8 @@
         addrP = addrP->next;
     }
 
-    /*
-     * Create the array of InetAddresses
-     */
-    addrArr = (*env)->NewObjectArray(env, addr_count,  ni_iacls, NULL);
+    // Create the array of InetAddresses
+    addrArr = (*env)->NewObjectArray(env, addr_count, ni_iacls, NULL);
     if (addrArr == NULL) {
         return NULL;
     }
@@ -700,7 +703,8 @@
         if (addrP->family == AF_INET) {
             iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
             if (iaObj) {
-                 setInetAddress_addr(env, iaObj, htonl(((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
+                 setInetAddress_addr(env, iaObj, htonl(
+                     ((struct sockaddr_in*)addrP->addr)->sin_addr.s_addr));
             } else {
                 return NULL;
             }
@@ -711,7 +715,8 @@
                     jobject ia2Obj = NULL;
                     ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
                     if (ia2Obj) {
-                       setInetAddress_addr(env, ia2Obj, htonl(((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
+                       setInetAddress_addr(env, ia2Obj, htonl(
+                           ((struct sockaddr_in*)addrP->brdcast)->sin_addr.s_addr));
                        (*env)->SetObjectField(env, ibObj, ni_ib4broadcastID, ia2Obj);
                     } else {
                         return NULL;
@@ -729,7 +734,8 @@
             int scope=0;
             iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
             if (iaObj) {
-                int ret = setInet6Address_ipaddress(env, iaObj, (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr));
+                jboolean ret = setInet6Address_ipaddress(env, iaObj,
+                    (char *)&(((struct sockaddr_in6*)addrP->addr)->sin6_addr));
                 if (ret == JNI_FALSE) {
                     return NULL;
                 }
@@ -758,9 +764,7 @@
         addrP = addrP->next;
     }
 
-    /*
-     * See if there is any virtual interface attached to this one.
-     */
+    // See if there is any virtual interface attached to this one.
     child_count = 0;
     childP = ifs->childs;
     while (childP) {
@@ -773,10 +777,7 @@
         return NULL;
     }
 
-    /*
-     * Create the NetworkInterface instances for the sub-interfaces as
-     * well.
-     */
+    // Create the NetworkInterface instances for the sub-interfaces as well.
     child_index = 0;
     childP = ifs->childs;
     while(childP) {
@@ -792,7 +793,7 @@
     (*env)->SetObjectField(env, netifObj, ni_bindsID, bindArr);
     (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
 
-    /* return the NetworkInterface */
+    // return the NetworkInterface
     return netifObj;
 }
 
@@ -803,10 +804,7 @@
     netif *ifs;
     int sock;
 
-    /*
-     * Enumerate IPv4 addresses
-     */
-
+    // Enumerate IPv4 addresses
     sock = openSocket(env, AF_INET);
     if (sock < 0 && (*env)->ExceptionOccurred(env)) {
         return NULL;
@@ -819,19 +817,16 @@
         return NULL;
     }
 
-    /* return partial list if an exception occurs in the middle of process ???*/
+    // return partial list if an exception occurs in the middle of process ???
 
-    /*
-     * If IPv6 is available then enumerate IPv6 addresses.
-     */
+    // If IPv6 is available then enumerate IPv6 addresses.
 #ifdef AF_INET6
 
-        /* User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
-         * so we have to call ipv6_available()
-         */
+        // User can disable ipv6 explicitly by -Djava.net.preferIPv4Stack=true,
+        // so we have to call ipv6_available()
         if (ipv6_available()) {
 
-           sock =  openSocket(env, AF_INET6);
+           sock = openSocket(env, AF_INET6);
            if (sock < 0 && (*env)->ExceptionOccurred(env)) {
                freeif(ifs);
                return NULL;
@@ -851,18 +846,18 @@
     return ifs;
 }
 
-#define CHECKED_MALLOC3(_pointer,_type,_size) \
-       do{ \
-        _pointer = (_type)malloc( _size ); \
+#define CHECKED_MALLOC3(_pointer, _type, _size) \
+    do { \
+        _pointer = (_type)malloc(_size); \
         if (_pointer == NULL) { \
             JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
             return ifs; /* return untouched list */ \
         } \
-       } while(0)
+    } while(0)
 
 
 /*
- * Free an interface list (including any attached addresses)
+ * Frees an interface list (including any attached addresses)
  */
 void freeif(netif *ifs) {
     netif *currif = ifs;
@@ -874,24 +869,21 @@
             netaddr *next = addrP->next;
             free(addrP);
             addrP = next;
-         }
+        }
 
-            /*
-            * Don't forget to free the sub-interfaces.
-            */
-          if (currif->childs != NULL) {
-                freeif(currif->childs);
-          }
+        // Don't forget to free the sub-interfaces.
+        if (currif->childs != NULL) {
+            freeif(currif->childs);
+        }
 
-          ifs = currif->next;
-          free(currif);
-          currif = ifs;
+        ifs = currif->next;
+        free(currif);
+        currif = ifs;
     }
 }
 
-netif *addif(JNIEnv *env, int sock, const char * if_name,
-             netif *ifs, struct sockaddr* ifr_addrP, int family,
-             short prefix)
+netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
+             struct sockaddr *ifr_addrP, int family, short prefix)
 {
     netif *currif = ifs, *parent;
     netaddr *addrP;
@@ -904,37 +896,34 @@
     char name[IFNAMSIZ], vname[IFNAMSIZ];
 #endif
 
-    char  *name_colonP;
+    char *name_colonP;
     int mask;
     int isVirtual = 0;
     int addr_size;
     int flags = 0;
 
-    /*
-     * If the interface name is a logical interface then we
-     * remove the unit number so that we have the physical
-     * interface (eg: hme0:1 -> hme0). NetworkInterface
-     * currently doesn't have any concept of physical vs.
-     * logical interfaces.
-     */
+    // If the interface name is a logical interface then we remove the unit
+    // number so that we have the physical interface (eg: hme0:1 -> hme0).
+    // NetworkInterface currently doesn't have any concept of physical vs.
+    // logical interfaces.
     strncpy(name, if_name, ifnam_size);
     name[ifnam_size - 1] = '\0';
     *vname = 0;
 
-    /*
-     * Create and populate the netaddr node. If allocation fails
-     * return an un-updated list.
-     */
-    /*Allocate for addr and brdcast at once*/
+     // Create and populate the netaddr node. If allocation fails
+     // return an un-updated list.
+
+     // Allocate for addr and brdcast at once
 
 #ifdef AF_INET6
-    addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
+    addr_size = (family == AF_INET) ? sizeof(struct sockaddr_in)
+                                    : sizeof(struct sockaddr_in6);
 #else
     addr_size = sizeof(struct sockaddr_in);
 #endif
 
-    CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr)+2*addr_size);
-    addrP->addr = (struct sockaddr *)( (char *) addrP+sizeof(netaddr) );
+    CHECKED_MALLOC3(addrP, netaddr *, sizeof(netaddr) + 2 * addr_size);
+    addrP->addr = (struct sockaddr *)((char *)addrP + sizeof(netaddr));
     memcpy(addrP->addr, ifr_addrP, addr_size);
 
     addrP->family = family;
@@ -943,8 +932,9 @@
     addrP->next = 0;
     if (family == AF_INET) {
        // Deal with broadcast addr & subnet mask
-       struct sockaddr * brdcast_to = (struct sockaddr *) ((char *) addrP + sizeof(netaddr) + addr_size);
-       addrP->brdcast = getBroadcast(env, sock, name,  brdcast_to );
+       struct sockaddr *brdcast_to =
+              (struct sockaddr *) ((char *)addrP + sizeof(netaddr) + addr_size);
+       addrP->brdcast = getBroadcast(env, sock, name, brdcast_to);
        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
            return ifs;
        }
@@ -955,36 +945,28 @@
        }
      }
 
-    /**
-     * Deal with virtual interface with colon notation e.g. eth0:1
-     */
+    // Deal with virtual interface with colon notation e.g. eth0:1
     name_colonP = strchr(name, ':');
     if (name_colonP != NULL) {
-      /**
-       * This is a virtual interface. If we are able to access the parent
-       * we need to create a new entry if it doesn't exist yet *and* update
-       * the 'parent' interface with the new records.
-       */
+        // This is a virtual interface. If we are able to access the parent
+        // we need to create a new entry if it doesn't exist yet *and* update
+        // the 'parent' interface with the new records.
         *name_colonP = 0;
         if (getFlags(sock, name, &flags) < 0 || flags < 0) {
-            // failed to access parent interface do not create parent.
-            // We are a virtual interface with no parent.
-            isVirtual = 1;
-            *name_colonP = ':';
-        }
-        else{
-           // Got access to parent, so create it if necessary.
-           // Save original name to vname and truncate name by ':'
-            memcpy(vname, name, sizeof(vname) );
-            vname[name_colonP - name] = ':';
+             // failed to access parent interface do not create parent.
+             // We are a virtual interface with no parent.
+             isVirtual = 1;
+             *name_colonP = ':';
+        } else {
+             // Got access to parent, so create it if necessary.
+             // Save original name to vname and truncate name by ':'
+             memcpy(vname, name, sizeof(vname) );
+             vname[name_colonP - name] = ':';
         }
     }
 
-    /*
-     * Check if this is a "new" interface. Use the interface
-     * name for matching because index isn't supported on
-     * Solaris 2.6 & 7.
-     */
+    // Check if this is a "new" interface. Use the interface name for
+    // matching because index isn't supported on Solaris 2.6 & 7.
     while (currif != NULL) {
         if (strcmp(name, currif->name) == 0) {
             break;
@@ -992,13 +974,10 @@
         currif = currif->next;
     }
 
-    /*
-     * If "new" then create an netif structure and
-     * insert it onto the list.
-     */
+    // If "new" then create an netif structure and insert it into the list.
     if (currif == NULL) {
          CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
-         currif->name = (char *) currif+sizeof(netif);
+         currif->name = (char *)currif + sizeof(netif);
          strncpy(currif->name, name, ifnam_size);
          currif->name[ifnam_size - 1] = '\0';
          currif->index = getIndex(sock, name);
@@ -1009,17 +988,13 @@
          ifs = currif;
     }
 
-    /*
-     * Finally insert the address on the interface
-     */
+    // Finally insert the address on the interface
     addrP->next = currif->addr;
     currif->addr = addrP;
 
     parent = currif;
 
-    /**
-     * Let's deal with the virtual interface now.
-     */
+    // Deal with the virtual interface now.
     if (vname[0]) {
         netaddr *tmpaddr;
 
@@ -1034,27 +1009,29 @@
 
         if (currif == NULL) {
             CHECKED_MALLOC3(currif, netif *, sizeof(netif) + ifnam_size);
-            currif->name = (char *) currif + sizeof(netif);
+            currif->name = (char *)currif + sizeof(netif);
             strncpy(currif->name, vname, ifnam_size);
             currif->name[ifnam_size - 1] = '\0';
             currif->index = getIndex(sock, vname);
             currif->addr = NULL;
-           /* Need to duplicate the addr entry? */
+            // Need to duplicate the addr entry?
             currif->virtual = 1;
             currif->childs = NULL;
             currif->next = parent->childs;
             parent->childs = currif;
         }
 
-        CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr)+2*addr_size);
+        CHECKED_MALLOC3(tmpaddr, netaddr *, sizeof(netaddr) + 2 * addr_size);
         memcpy(tmpaddr, addrP, sizeof(netaddr));
         if (addrP->addr != NULL) {
-            tmpaddr->addr = (struct sockaddr *) ( (char*)tmpaddr + sizeof(netaddr) ) ;
+            tmpaddr->addr = (struct sockaddr *)
+                ((char*)tmpaddr + sizeof(netaddr));
             memcpy(tmpaddr->addr, addrP->addr, addr_size);
         }
 
         if (addrP->brdcast != NULL) {
-            tmpaddr->brdcast = (struct sockaddr *) ((char *) tmpaddr + sizeof(netaddr)+addr_size);
+            tmpaddr->brdcast = (struct sockaddr *)
+                ((char *)tmpaddr + sizeof(netaddr) + addr_size);
             memcpy(tmpaddr->brdcast, addrP->brdcast, addr_size);
         }
 
@@ -1065,19 +1042,18 @@
     return ifs;
 }
 
-/* Open socket for further ioct calls
- * proto is AF_INET/AF_INET6
+/*
+ * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6.
  */
-static int  openSocket(JNIEnv *env, int proto){
+static int openSocket(JNIEnv *env, int proto) {
     int sock;
 
     if ((sock = JVM_Socket(proto, SOCK_DGRAM, 0)) < 0) {
-        /*
-         * If EPROTONOSUPPORT is returned it means we don't have
-         * support  for this proto so don't throw an exception.
-         */
+        // If EPROTONOSUPPORT is returned it means we don't have
+        // support for this proto so don't throw an exception.
         if (errno != EPROTONOSUPPORT) {
-            NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "Socket creation failed");
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "Socket creation failed");
         }
         return -1;
     }
@@ -1088,36 +1064,38 @@
 
 /** Linux, AIX **/
 #if defined(__linux__) || defined(_AIX)
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
- */
 
 #ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+/*
+ * Opens a socket for further ioct calls. Tries AF_INET socket first and
+ * if it falls return AF_INET6 socket.
+ */
+// unused arg ifname and struct if2
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     int sock;
     struct ifreq if2;
 
-     if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-         if (errno == EPROTONOSUPPORT){
-              if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                 return -1;
-              }
-         }
-         else{ // errno is not NOSUPPORT
-             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-             return -1;
-         }
-   }
+    if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        if (errno == EPROTONOSUPPORT) {
+            if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                             "IPV6 Socket creation failed");
+                return -1;
+            }
+        } else { // errno is not NOSUPPORT
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "IPV4 Socket creation failed");
+            return -1;
+        }
+    }
 
-     /* Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or IPv6 socket regardless of type
-        of address of an interface */
-
-       return sock;
+    // Linux starting from 2.6.? kernel allows ioctl call with either IPv4 or
+    // IPv6 socket regardless of type of address of an interface.
+    return sock;
 }
 
 #else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     return openSocket(env,AF_INET);
 }
 #endif
@@ -1130,52 +1108,48 @@
     unsigned i;
     int siocgifconfRequest = SIOCGIFCONF;
 
-
 #if defined(__linux__)
-    /* need to do a dummy SIOCGIFCONF to determine the buffer size.
-     * SIOCGIFCOUNT doesn't work
-     */
+    // need to do a dummy SIOCGIFCONF to determine the buffer size.
+    // SIOCGIFCOUNT doesn't work
     ifc.ifc_buf = NULL;
     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFCONF failed");
         return ifs;
     }
 #elif defined(_AIX)
     ifc.ifc_buf = NULL;
     if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGSIZIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGSIZIFCONF failed");
         return ifs;
     }
 #endif /* __linux__ */
 
-    CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
+    CHECKED_MALLOC3(buf, char *, ifc.ifc_len);
 
     ifc.ifc_buf = buf;
 #if defined(_AIX)
     siocgifconfRequest = CSIOCGIFCONF;
 #endif
     if (ioctl(sock, siocgifconfRequest, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
-        (void) free(buf);
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFCONF failed");
+        free(buf);
         return ifs;
     }
 
-    /*
-     * Iterate through each interface
-     */
+    // Iterate through each interface
     ifreqP = ifc.ifc_req;
-    for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
+    for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) {
 #if defined(_AIX)
         if (ifreqP->ifr_addr.sa_family != AF_INET) continue;
 #endif
-        /*
-         * Add to the list
-         */
-        ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
+        // Add to the list
+        ifs = addif(env, sock, ifreqP->ifr_name, ifs,
+                    (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET, 0);
 
-        /*
-         * If an exception occurred then free the list
-         */
+        // If an exception occurred then free the list
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
             freeif(ifs);
@@ -1183,37 +1157,37 @@
         }
     }
 
-    /*
-     * Free socket and buffer
-     */
+    // Free socket and buffer
     free(buf);
     return ifs;
 }
 
 
+#if defined(AF_INET6) && defined(__linux__)
+
 /*
- * Enumerates and returns all IPv6 interfaces on Linux
+ * Enumerates and returns all IPv6 interfaces on Linux.
  */
-
-#if defined(AF_INET6) && defined(__linux__)
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     FILE *f;
     char addr6[40], devname[21];
     char addr6p[8][5];
-    int plen, scope, dad_status, if_idx;
+    int prefix, scope, dad_status, if_idx;
     uint8_t ipv6addr[16];
 
     if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
         while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
-                         addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7],
-                         &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
+                      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+                      addr6p[4], addr6p[5], addr6p[6], addr6p[7],
+                      &if_idx, &prefix, &scope, &dad_status, devname) != EOF) {
 
             struct netif *ifs_ptr = NULL;
             struct netif *last_ptr = NULL;
             struct sockaddr_in6 addr;
 
             sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
-                           addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
+                    addr6p[0], addr6p[1], addr6p[2], addr6p[3],
+                    addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
             inet_pton(AF_INET6, addr6, ipv6addr);
 
             memset(&addr, 0, sizeof(struct sockaddr_in6));
@@ -1221,12 +1195,10 @@
 
             addr.sin6_scope_id = if_idx;
 
-            ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr, AF_INET6, plen);
-
+            ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr,
+                        AF_INET6, (short)prefix);
 
-            /*
-             * If an exception occurred then return the list as is.
-             */
+            // If an exception occurred then return the list as is.
             if ((*env)->ExceptionOccurred(env)) {
                 fclose(f);
                 return ifs;
@@ -1239,11 +1211,11 @@
 #endif
 
 
+#if defined(AF_INET6) && defined(_AIX)
+
 /*
- * Enumerates and returns all IPv6 interfaces on AIX
+ * Enumerates and returns all IPv6 interfaces on AIX.
  */
-
-#if defined(AF_INET6) && defined(_AIX)
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     struct ifconf ifc;
     struct ifreq *ifreqP;
@@ -1253,12 +1225,12 @@
     unsigned bufsize;
     char *cp, *cplimit;
 
-    /* use SIOCGSIZIFCONF to get size for  SIOCGIFCONF */
+    // use SIOCGSIZIFCONF to get size for  SIOCGIFCONF
 
     ifc.ifc_buf = NULL;
     if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                        "ioctl SIOCGSIZIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                    "ioctl SIOCGSIZIFCONF failed");
         return ifs;
     }
     bufsize = ifc.ifc_len;
@@ -1271,29 +1243,27 @@
     ifc.ifc_len = bufsize;
     ifc.ifc_buf = buf;
     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                       "ioctl CSIOCGIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl CSIOCGIFCONF failed");
         free(buf);
         return ifs;
     }
 
-    /*
-     * Iterate through each interface
-     */
+    // Iterate through each interface
     ifreqP = ifc.ifc_req;
     cp = (char *)ifc.ifc_req;
     cplimit = cp + ifc.ifc_len;
 
-    for ( ; cp < cplimit; cp += (sizeof(ifreqP->ifr_name) + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) {
+    for (; cp < cplimit;
+        cp += (sizeof(ifreqP->ifr_name) +
+               MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr))))
+    {
         ifreqP = (struct ifreq *)cp;
         struct ifreq if2;
-
         memset((char *)&if2, 0, sizeof(if2));
-        strcpy(if2.ifr_name, ifreqP->ifr_name);
+        strncpy(if2.ifr_name, ifreqP->ifr_name, sizeof(if2.ifr_name) - 1);
 
-        /*
-         * Skip interface that aren't UP
-         */
+        // Skip interface that aren't UP
         if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) {
             if (!(if2.ifr_flags & IFF_UP)) {
                 continue;
@@ -1308,16 +1278,11 @@
             s6->sin6_scope_id = if2.ifr_site6;
         }
 
-        /*
-         * Add to the list
-         */
+        // Add to the list
         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
-                    (struct sockaddr *)&(ifreqP->ifr_addr),
-                    AF_INET6, 0);
+                    (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET6, 0);
 
-        /*
-         * If an exception occurred then free the list
-         */
+        // If an exception occurred then free the list
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
             freeif(ifs);
@@ -1325,24 +1290,21 @@
         }
     }
 
-    /*
-     * Free socket and buffer
-     */
+    // Free socket and buffer
     free(buf);
     return ifs;
 }
 #endif
 
 
-static int getIndex(int sock, const char *name){
-     /*
-      * Try to get the interface index
-      */
+static int getIndex(int sock, const char *name) {
+     // Try to get the interface index
 #if defined(_AIX)
     return if_nametoindex(name);
 #else
     struct ifreq if2;
-    strcpy(if2.ifr_name, name);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
         return -1;
@@ -1352,38 +1314,41 @@
 #endif
 }
 
-/**
+/*
  * Returns the IPv4 broadcast address of a named interface, if it exists.
  * Returns 0 if it doesn't have one.
  */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2)  < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGIFFLAGS failed");
-      return ret;
-  }
+static struct sockaddr *getBroadcast
+  (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store)
+{
+    struct sockaddr *ret = NULL;
+    struct ifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  if (if2.ifr_flags & IFF_BROADCAST) {
-      /* It does, let's retrieve it*/
-      if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
-          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
-          return ret;
-      }
+    // Let's make sure the interface does have a broadcast address.
+    if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2)  < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFFLAGS failed");
+        return ret;
+    }
 
-      ret = brdcast_store;
-      memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
-  }
+    if (if2.ifr_flags & IFF_BROADCAST) {
+        // It does, let's retrieve it
+        if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGIFBRDADDR failed");
+            return ret;
+        }
 
-  return ret;
+        ret = brdcast_store;
+        memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+    }
+
+    return ret;
 }
 
-/**
+/*
  * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
  * interface, if it has one, otherwise return -1.
  */
@@ -1391,12 +1356,12 @@
     unsigned int mask;
     short ret;
     struct ifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.ifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFNETMASK failed");
         return -1;
     }
 
@@ -1410,12 +1375,15 @@
     return ret;
 }
 
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
+/*
+ * Gets the Hardware address (usually MAC address) for the named interface.
+ * On return puts the data in buf, and returns the length, in byte, of the
  * MAC address. Returns -1 if there is no hardware address on that interface.
  */
-static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
+static int getMacAddress
+  (JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr,
+   unsigned char *buf)
+{
 #if defined (_AIX)
     int size;
     struct kinfo_ndd *nddp;
@@ -1434,7 +1402,8 @@
     nddp = (struct kinfo_ndd *)malloc(size);
 
     if (!nddp) {
-        JNU_ThrowOutOfMemoryError(env, "Network interface getMacAddress native buffer allocation failed");
+        JNU_ThrowOutOfMemoryError(env,
+            "Network interface getMacAddress native buffer allocation failed");
         return -1;
     }
 
@@ -1455,22 +1424,20 @@
     }
 
     return -1;
-
 #elif defined(__linux__)
     static struct ifreq ifr;
     int i;
-
-    strcpy(ifr.ifr_name, ifname);
+    memset((char *)&ifr, 0, sizeof(ifr));
+    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
     if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFHWADDR failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFHWADDR failed");
         return -1;
     }
 
     memcpy(buf, &ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
 
-   /*
-    * All bytes to 0 means no hardware address.
-    */
+    // All bytes to 0 means no hardware address.
 
     for (i = 0; i < IFHWADDRLEN; i++) {
         if (buf[i] != 0)
@@ -1483,17 +1450,18 @@
 
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
     struct ifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
 
-    memset((char *) &if2, 0, sizeof(if2));
     if (ifname != NULL) {
-        strcpy(if2.ifr_name, ifname);
+        strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
     } else {
         JNU_ThrowNullPointerException(env, "network interface name is NULL");
         return -1;
     }
 
     if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "IOCTL SIOCGIFMTU failed");
         return -1;
     }
 
@@ -1502,11 +1470,10 @@
 
 static int getFlags(int sock, const char *ifname, int *flags) {
   struct ifreq if2;
+  memset((char *)&if2, 0, sizeof(if2));
+  strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
+  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
       return -1;
   }
 
@@ -1518,53 +1485,54 @@
   return 0;
 }
 
-#endif
+#endif  /* defined(__linux__) || defined(_AIX) */
 
 /** Solaris **/
-#ifdef __solaris__
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
+#if defined(__solaris__)
+
+/*
+ * Opens a socket for further ioct calls. Tries AF_INET socket first and
+ * if it falls return AF_INET6 socket.
  */
-
 #ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     int sock, alreadyV6 = 0;
     struct lifreq if2;
 
-     if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-         if (errno == EPROTONOSUPPORT){
-              if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                 return -1;
-              }
+    if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        if (errno == EPROTONOSUPPORT) {
+            if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                             "IPV6 Socket creation failed");
+                return -1;
+            }
 
-              alreadyV6=1;
-         }
-         else{ // errno is not NOSUPPORT
-             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
-             return -1;
-         }
-   }
+            alreadyV6=1;
+        } else { // errno is not NOSUPPORT
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "IPV4 Socket creation failed");
+            return -1;
+        }
+    }
+
 
-     /**
-      * Solaris requires that we have an IPv6 socket to query an
-      * interface without an IPv4 address - check it here.
-      * POSIX 1 require the kernel to return ENOTTY if the call is
-      * inappropriate for a device e.g. the NETMASK for a device having IPv6
-      * only address but not all devices follow the standard so
-      * fall back on any error. It's not an ecologically friendly gesture
-      * but more reliable.
-      */
+    // Solaris requires that we have an IPv6 socket to query an  interface
+    // without an IPv4 address - check it here. POSIX 1 require the kernel to
+    // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK
+    // for a device having IPv6 only address but not all devices follow the
+    // standard so fall back on any error. It's not an ecologically friendly
+    // gesture but more reliable.
 
-    if (! alreadyV6 ){
-        memset((char *) &if2, 0, sizeof(if2));
-        strcpy(if2.lifr_name, ifname);
+    if (!alreadyV6) {
+        memset((char *)&if2, 0, sizeof(if2));
+        strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
         if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-                close(sock);
-                if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                      NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
-                      return -1;
-                }
+            close(sock);
+            if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                             "IPV6 Socket creation failed");
+                return -1;
+            }
         }
     }
 
@@ -1572,18 +1540,16 @@
 }
 
 #else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     return openSocket(env,AF_INET);
 }
 #endif
 
 /*
- * Enumerates and returns all IPv4 interfaces
- * (linux verision)
+ * Enumerates and returns all IPv4 interfaces.
  */
-
 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
-     return enumIPvXInterfaces(env,sock, ifs, AF_INET);
+    return enumIPvXInterfaces(env,sock, ifs, AF_INET);
 }
 
 #ifdef AF_INET6
@@ -1593,8 +1559,8 @@
 #endif
 
 /*
-   Enumerates and returns all interfaces on Solaris
-   use the same code for IPv4 and IPv6
+ * Enumerates and returns all interfaces on Solaris.
+ * Uses the same code for IPv4 and IPv6.
  */
 static netif *enumIPvXInterfaces(JNIEnv *env, int sock, netif *ifs, int family) {
     struct lifconf ifc;
@@ -1604,19 +1570,16 @@
     struct lifnum numifs;
     unsigned bufsize;
 
-    /*
-     * Get the interface count
-     */
+    // Get the interface count
     numifs.lifn_family = family;
     numifs.lifn_flags = 0;
     if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFNUM failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFNUM failed");
         return ifs;
     }
 
-    /*
-     *  Enumerate the interface configurations
-     */
+    //  Enumerate the interface configurations
     bufsize = numifs.lifn_count * sizeof (struct lifreq);
     CHECKED_MALLOC3(buf, char *, bufsize);
 
@@ -1625,22 +1588,19 @@
     ifc.lifc_len = bufsize;
     ifc.lifc_buf = buf;
     if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGLIFCONF failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFCONF failed");
         free(buf);
         return ifs;
     }
 
-    /*
-     * Iterate through each interface
-     */
+    // Iterate through each interface
     ifr = ifc.lifc_req;
     for (n=0; n<numifs.lifn_count; n++, ifr++) {
         int index = -1;
         struct lifreq if2;
 
-        /*
-        * Ignore either IPv4 or IPv6 addresses
-        */
+        // Ignore either IPv4 or IPv6 addresses
         if (ifr->lifr_addr.ss_family != family) {
             continue;
         }
@@ -1652,12 +1612,12 @@
         }
 #endif
 
-        /* add to the list */
-        ifs = addif(env, sock,ifr->lifr_name, ifs, (struct sockaddr *)&(ifr->lifr_addr),family, (short) ifr->lifr_addrlen);
+        // add to the list
+        ifs = addif(env, sock,ifr->lifr_name, ifs,
+                    (struct sockaddr *)&(ifr->lifr_addr), family,
+                    (short)ifr->lifr_addrlen);
 
-        /*
-        * If an exception occurred we return immediately
-        */
+        // If an exception occurred we return immediately
         if ((*env)->ExceptionOccurred(env)) {
             free(buf);
             return ifs;
@@ -1669,13 +1629,11 @@
     return ifs;
 }
 
-static int getIndex(int sock, const char *name){
-   /*
-    * Try to get the interface index
-    * (Not supported on Solaris 2.6 or 7)
-    */
+static int getIndex(int sock, const char *name) {
+    // Try to get the interface index.  (Not supported on Solaris 2.6 or 7)
     struct lifreq if2;
-    strcpy(if2.lifr_name, name);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, name, sizeof(if2.lifr_name) - 1);
 
     if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) {
         return -1;
@@ -1684,27 +1642,30 @@
     return if2.lifr_index;
 }
 
-/**
+/*
  * Returns the IPv4 broadcast address of a named interface, if it exists.
  * Returns 0 if it doesn't have one.
  */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
+static struct sockaddr *getBroadcast
+  (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store)
+{
     struct sockaddr *ret = NULL;
     struct lifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
 
-    /* Let's make sure the interface does have a broadcast address */
+    // Let's make sure the interface does have a broadcast address
     if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2)  < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL  SIOCGLIFFLAGS failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFFLAGS failed");
         return ret;
     }
 
     if (if2.lifr_flags & IFF_BROADCAST) {
-        /* It does, let's retrieve it*/
+        // It does, let's retrieve it
         if (ioctl(sock, SIOCGLIFBRDADDR, (char *)&if2) < 0) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFBRDADDR failed");
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGLIFBRDADDR failed");
             return ret;
         }
 
@@ -1715,7 +1676,7 @@
     return ret;
 }
 
-/**
+/*
  * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
  * interface, if it has one, otherwise return -1.
  */
@@ -1723,12 +1684,12 @@
     unsigned int mask;
     short ret;
     struct lifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
 
     if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFNETMASK failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGLIFNETMASK failed");
         return -1;
     }
 
@@ -1744,15 +1705,16 @@
 }
 
 
-
 #define DEV_PREFIX  "/dev/"
 
-/**
+/*
  * Solaris specific DLPI code to get hardware address from a device.
  * Unfortunately, at least up to Solaris X, you have to have special
  * privileges (i.e. be root).
  */
-static int getMacFromDevice(JNIEnv *env, const char* ifname, unsigned char* retbuf) {
+static int getMacFromDevice
+  (JNIEnv *env, const char* ifname, unsigned char* retbuf)
+{
     char style1dev[MAXPATHLEN];
     int fd;
     dl_phys_addr_req_t dlpareq;
@@ -1761,17 +1723,12 @@
     char buf[128];
     int flags = 0;
 
-   /**
-    * Device is in /dev
-    * e.g.: /dev/bge0
-    */
+    // Device is in /dev.  e.g.: /dev/bge0
     strcpy(style1dev, DEV_PREFIX);
     strcat(style1dev, ifname);
     if ((fd = open(style1dev, O_RDWR)) < 0) {
-        /*
-         * Can't open it. We probably are missing the privilege.
-         * We'll have to try something else
-         */
+         // Can't open it. We probably are missing the privilege.
+         // We'll have to try something else
          return 0;
     }
 
@@ -1782,7 +1739,8 @@
     msg.len = DL_PHYS_ADDR_REQ_SIZE;
 
     if (putmsg(fd, &msg, NULL, 0) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "putmsg failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "putmsg failed");
         return -1;
     }
 
@@ -1792,12 +1750,14 @@
     msg.len = 0;
     msg.maxlen = sizeof (buf);
     if (getmsg(fd, &msg, NULL, &flags) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "getmsg failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "getmsg failed");
         return -1;
     }
 
     if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Couldn't obtain phys addr\n");
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Couldn't obtain phys addr\n");
         return -1;
     }
 
@@ -1805,21 +1765,23 @@
     return dlpaack->dl_addr_length;
 }
 
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
- * return puts the data in buf, and returns the length, in byte, of the
+/*
+ * Gets the Hardware address (usually MAC address) for the named interface.
+ * On return puts the data in buf, and returns the length, in byte, of the
  * MAC address. Returns -1 if there is no hardware address on that interface.
  */
-static int getMacAddress(JNIEnv *env, int sock, const char *ifname,  const struct in_addr* addr, unsigned char *buf) {
+static int getMacAddress
+  (JNIEnv *env, int sock, const char *ifname, const struct in_addr* addr,
+   unsigned char *buf)
+{
     struct arpreq arpreq;
     struct sockaddr_in* sin;
     struct sockaddr_in ipAddr;
     int len, i;
     struct lifreq lif;
 
-    /* First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
-     * try the old way.
-     */
+    // First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails
+    // try the old way.
     memset(&lif, 0, sizeof(lif));
     strlcpy(lif.lifr_name, ifname, sizeof(lif.lifr_name));
 
@@ -1830,18 +1792,14 @@
         return sp->sdl_alen;
     }
 
-   /**
-    * On Solaris we have to use DLPI, but it will only work if we have
-    * privileged access (i.e. root). If that fails, we try a lookup
-    * in the ARP table, which requires an IPv4 address.
-    */
+    // On Solaris we have to use DLPI, but it will only work if we have
+    // privileged access (i.e. root). If that fails, we try a lookup
+    // in the ARP table, which requires an IPv4 address.
     if ((len = getMacFromDevice(env, ifname, buf))  == 0) {
-        /*DLPI failed - trying to do arp lookup*/
+        // DLPI failed - trying to do arp lookup
 
         if (addr == NULL) {
-            /**
-             * No IPv4 address for that interface, so can't do an ARP lookup.
-             */
+             // No IPv4 address for that interface, so can't do an ARP lookup.
              return -1;
          }
 
@@ -1862,10 +1820,7 @@
          memcpy(buf, &arpreq.arp_ha.sa_data[0], len );
     }
 
-    /*
-     * All bytes to 0 means no hardware address.
-     */
-
+    // All bytes to 0 means no hardware address.
     for (i = 0; i < len; i++) {
       if (buf[i] != 0)
          return len;
@@ -1876,56 +1831,57 @@
 
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
     struct lifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.lifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
 
     if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGLIFMTU failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                    "ioctl SIOCGLIFMTU failed");
         return -1;
     }
 
-    return  if2.lifr_mtu;
+    return if2.lifr_mtu;
+}
+
+static int getFlags(int sock, const char *ifname, int *flags) {
+    struct lifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
+
+    if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) {
+        return -1;
+    }
+
+    *flags = if2.lifr_flags;
+    return 0;
 }
 
 
-static int getFlags(int sock, const char *ifname, int *flags) {
-     struct   lifreq lifr;
-     memset((caddr_t)&lifr, 0, sizeof(lifr));
-     strcpy((caddr_t)&(lifr.lifr_name), ifname);
-
-     if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
-         return -1;
-     }
-
-     *flags = lifr.lifr_flags;
-     return 0;
-}
-
-
-#endif
+#endif  /* __solaris__ */
 
 
 /** BSD **/
 #ifdef _ALLBSD_SOURCE
-/* Open socket for further ioct calls, try v4 socket first and
- * if it falls return v6 socket
+
+/*
+ * Opens a socket for further ioct calls. Tries AF_INET socket first and
+ * if it falls return AF_INET6 socket.
  */
-
 #ifdef AF_INET6
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     int sock;
     struct ifreq if2;
 
      if ((sock = JVM_Socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-         if (errno == EPROTONOSUPPORT){
-              if ( (sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ){
-                 NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed");
+         if (errno == EPROTONOSUPPORT) {
+              if ((sock = JVM_Socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                              "IPV6 Socket creation failed");
                  return -1;
               }
-         }
-         else{ // errno is not NOSUPPORT
-             NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed");
+         } else { // errno is not NOSUPPORT
+             NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                          "IPV4 Socket creation failed");
              return -1;
          }
    }
@@ -1934,39 +1890,33 @@
 }
 
 #else
-static int openSocketWithFallback(JNIEnv *env, const char *ifname){
+static int openSocketWithFallback(JNIEnv *env, const char *ifname) {
     return openSocket(env,AF_INET);
 }
 #endif
 
 /*
- * Enumerates and returns all IPv4 interfaces
+ * Enumerates and returns all IPv4 interfaces.
  */
 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
     struct ifaddrs *ifa, *origifa;
 
     if (getifaddrs(&origifa) != 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                         "getifaddrs() function failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "getifaddrs() function failed");
         return ifs;
     }
 
     for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
 
-        /*
-         * Skip non-AF_INET entries.
-         */
+        // Skip non-AF_INET entries.
         if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
             continue;
 
-        /*
-         * Add to the list.
-         */
+        // Add to the list.
         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0);
 
-        /*
-         * If an exception occurred then free the list.
-         */
+        // If an exception occurred then free the list.
         if ((*env)->ExceptionOccurred(env)) {
             freeifaddrs(origifa);
             freeif(ifs);
@@ -1974,33 +1924,25 @@
         }
     }
 
-    /*
-     * Free socket and buffer
-     */
+    // Free socket and buffer
     freeifaddrs(origifa);
     return ifs;
 }
 
-
-/*
- * Enumerates and returns all IPv6 interfaces on Linux
- */
-
 #ifdef AF_INET6
 /*
  * Determines the prefix on BSD for IPv6 interfaces.
  */
-static
-int prefix(void *val, int size) {
+static int prefix(void *val, int size) {
     u_char *name = (u_char *)val;
-    int byte, bit, plen = 0;
+    int byte, bit, prefix = 0;
 
-    for (byte = 0; byte < size; byte++, plen += 8)
+    for (byte = 0; byte < size; byte++, prefix += 8)
         if (name[byte] != 0xff)
             break;
     if (byte == size)
-        return (plen);
-    for (bit = 7; bit != 0; bit--, plen++)
+        return prefix;
+    for (bit = 7; bit != 0; bit--, prefix++)
         if (!(name[byte] & (1 << bit)))
             break;
     for (; bit != 0; bit--)
@@ -2010,11 +1952,11 @@
     for (; byte < size; byte++)
         if (name[byte])
             return (0);
-    return (plen);
+    return prefix;
 }
 
 /*
- * Enumerates and returns all IPv6 interfaces on BSD
+ * Enumerates and returns all IPv6 interfaces on BSD.
  */
 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
     struct ifaddrs *ifa, *origifa;
@@ -2022,37 +1964,36 @@
     struct in6_ifreq ifr6;
 
     if (getifaddrs(&origifa) != 0) {
-        NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                         "getifaddrs() function failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "getifaddrs() function failed");
         return ifs;
     }
 
     for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
 
-        /*
-         * Skip non-AF_INET6 entries.
-         */
+        // Skip non-AF_INET6 entries.
         if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET6)
             continue;
 
         memset(&ifr6, 0, sizeof(ifr6));
         strlcpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
-        memcpy(&ifr6.ifr_addr, ifa->ifa_addr, MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len));
+        memcpy(&ifr6.ifr_addr, ifa->ifa_addr,
+               MIN(sizeof(ifr6.ifr_addr), ifa->ifa_addr->sa_len));
 
         if (ioctl(sock, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) < 0) {
-            NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
-                             "ioctl SIOCGIFNETMASK_IN6 failed");
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGIFNETMASK_IN6 failed");
             freeifaddrs(origifa);
             freeif(ifs);
             return NULL;
         }
 
-        /* Add to the list.  */
+        // Add to the list.
         sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6,
-                    prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
+            (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
 
-        /* If an exception occurred then free the list.  */
+        // If an exception occurred then free the list.
         if ((*env)->ExceptionOccurred(env)) {
             freeifaddrs(origifa);
             freeif(ifs);
@@ -2060,22 +2001,19 @@
         }
     }
 
-    /*
-     * Free socket and ifaddrs buffer
-     */
+    // Free socket and ifaddrs buffer
     freeifaddrs(origifa);
     return ifs;
 }
 #endif
 
-static int getIndex(int sock, const char *name){
+static int getIndex(int sock, const char *name) {
 #ifdef __FreeBSD__
-     /*
-      * Try to get the interface index
-      * (Not supported on Solaris 2.6 or 7)
-      */
+    // Try to get the interface index
+    // (Not supported on Solaris 2.6 or 7)
     struct ifreq if2;
-    strcpy(if2.ifr_name, name);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, name, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
         return -1;
@@ -2083,46 +2021,47 @@
 
     return if2.ifr_index;
 #else
-    /*
-     * Try to get the interface index using BSD specific if_nametoindex
-     */
+    // Try to get the interface index using BSD specific if_nametoindex
     int index = if_nametoindex(name);
     return (index == 0) ? -1 : index;
 #endif
 }
 
-/**
+/*
  * Returns the IPv4 broadcast address of a named interface, if it exists.
  * Returns 0 if it doesn't have one.
  */
-static struct sockaddr *getBroadcast(JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store) {
-  struct sockaddr *ret = NULL;
-  struct ifreq if2;
-
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  /* Let's make sure the interface does have a broadcast address */
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
-      NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFFLAGS failed");
-      return ret;
-  }
+static struct sockaddr *getBroadcast
+  (JNIEnv *env, int sock, const char *ifname, struct sockaddr *brdcast_store)
+{
+    struct sockaddr *ret = NULL;
+    struct ifreq if2;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  if (if2.ifr_flags & IFF_BROADCAST) {
-      /* It does, let's retrieve it*/
-      if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
-          NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFBRDADDR failed");
-          return ret;
-      }
+    // Make sure the interface does have a broadcast address
+    if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFFLAGS failed");
+        return ret;
+    }
 
-      ret = brdcast_store;
-      memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
-  }
+    if (if2.ifr_flags & IFF_BROADCAST) {
+        // It does, let's retrieve it
+        if (ioctl(sock, SIOCGIFBRDADDR, (char *)&if2) < 0) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                         "ioctl SIOCGIFBRDADDR failed");
+            return ret;
+        }
 
-  return ret;
+        ret = brdcast_store;
+        memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+    }
+
+    return ret;
 }
 
-/**
+/*
  * Returns the IPv4 subnet prefix length (aka subnet mask) for the named
  * interface, if it has one, otherwise return -1.
  */
@@ -2130,12 +2069,12 @@
     unsigned int mask;
     short ret;
     struct ifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.ifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFNETMASK, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFNETMASK failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFNETMASK failed");
         return -1;
     }
 
@@ -2149,25 +2088,28 @@
     return ret;
 }
 
-/**
- * Get the Hardware address (usually MAC address) for the named interface.
+/*
+ * Gets the Hardware address (usually MAC address) for the named interface.
  * return puts the data in buf, and returns the length, in byte, of the
  * MAC address. Returns -1 if there is no hardware address on that interface.
  */
-static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
+static int getMacAddress
+  (JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr,
+   unsigned char *buf)
+{
     struct ifaddrs *ifa0, *ifa;
     struct sockaddr *saddr;
     int i;
 
-    /* Grab the interface list */
+    // Grab the interface list
     if (!getifaddrs(&ifa0)) {
-        /* Cycle through the interfaces */
+        // Cycle through the interfaces
         for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) {
             saddr = ifa->ifa_addr;
-            /* Link layer contains the MAC address */
+            // Link layer contains the MAC address
             if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) {
                 struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr;
-                /* Check the address is the correct length */
+                // Check the address is the correct length
                 if (sadl->sdl_alen == ETHER_ADDR_LEN) {
                     memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN);
                     freeifaddrs(ifa0);
@@ -2183,12 +2125,12 @@
 
 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
     struct ifreq if2;
-
-    memset((char *) &if2, 0, sizeof(if2));
-    strcpy(if2.ifr_name, ifname);
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
     if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
+        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
+                                     "ioctl SIOCGIFMTU failed");
         return -1;
     }
 
@@ -2196,22 +2138,20 @@
 }
 
 static int getFlags(int sock, const char *ifname, int *flags) {
-  struct ifreq if2;
-  int ret = -1;
+    struct ifreq if2;
+    int ret = -1;
+    memset((char *)&if2, 0, sizeof(if2));
+    strncpy(if2.ifr_name, ifname, sizeof(if2.ifr_name) - 1);
 
-  memset((char *) &if2, 0, sizeof(if2));
-  strcpy(if2.ifr_name, ifname);
-
-  if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0){
-      return -1;
-  }
+    if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) < 0) {
+        return -1;
+    }
 
-  if (sizeof(if2.ifr_flags) == sizeof(short)) {
-    *flags = (if2.ifr_flags & 0xffff);
-  } else {
-    *flags = if2.ifr_flags;
-  }
-  return 0;
+    if (sizeof(if2.ifr_flags) == sizeof(short)) {
+        *flags = (if2.ifr_flags & 0xffff);
+    } else {
+        *flags = if2.ifr_flags;
+    }
+    return 0;
 }
-
-#endif
+#endif /* __ALLBSD_SOURCE__ */
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c	Thu Jan 12 06:59:38 2017 +0000
@@ -992,17 +992,24 @@
                        (char *)&arg, sizeof(arg)) < 0) {
         getErrorString(errno, tmpbuf, sizeof(tmpbuf));
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
+        close(fd);
         return;
     }
     if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF,
                        (char *)&arg, sizeof(arg)) < 0) {
         getErrorString(errno, tmpbuf, sizeof(tmpbuf));
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
+        close(fd);
         return;
     }
 #endif /* __APPLE__ */
 
-     setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
+    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof (int)) < 0) {
+        getErrorString(errno, tmpbuf, sizeof(tmpbuf));
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
+        close(fd);
+        return;
+    }
 
 #if defined(__linux__)
     arg = 0;
@@ -1024,8 +1031,13 @@
      */
     if (domain == AF_INET6) {
         int ttl = 1;
-        setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
-                   sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl,
+                sizeof (ttl)) < 0) {
+            getErrorString(errno, tmpbuf, sizeof(tmpbuf));
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", tmpbuf);
+            close(fd);
+            return;
+        }
     }
 #endif /* __linux__ */
 
@@ -2182,7 +2194,7 @@
             caddr[14] = ((address >> 8) & 0xff);
             caddr[15] = (address & 0xff);
         } else {
-            getInet6Address_ipaddress(env, iaObj, caddr);
+            getInet6Address_ipaddress(env, iaObj, (char *) caddr);
         }
 
         memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr));
--- a/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -94,6 +94,7 @@
                     return 0;
                 }
                 start = now;
+                a.dp_timeout = remaining;
             }
         } else {
             return res;
--- a/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -53,7 +53,7 @@
     start = t.tv_sec * 1000 + t.tv_usec / 1000;
 
     for (;;) {
-        int res = epoll_wait(epfd, events, numfds, timeout);
+        int res = epoll_wait(epfd, events, numfds, remaining);
         if (res < 0 && errno == EINTR) {
             if (remaining >= 0) {
                 gettimeofday(&t, NULL);
--- a/src/windows/bin/cmdtoargs.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/bin/cmdtoargs.c	Thu Jan 12 06:59:38 2017 +0000
@@ -155,6 +155,7 @@
                 }
             }
             dest += copyCh(ch, dest);
+            slashes = 0;
             break;
 
         default:
--- a/src/windows/classes/sun/awt/windows/fontconfig.properties	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/classes/sun/awt/windows/fontconfig.properties	Thu Jan 12 06:59:38 2017 +0000
@@ -40,6 +40,7 @@
 allfonts.dingbats=Wingdings
 allfonts.lucida=Lucida Sans Regular
 allfonts.symbol=Symbol
+allfonts.symbols=Segoe UI Symbol
 allfonts.thai=Lucida Sans Regular
 allfonts.georgian=Sylfaen
 
@@ -236,7 +237,7 @@
 
 sequence.allfonts.x-windows-874=alphabetic,thai,dingbats,symbol
 
-sequence.fallback=lucida,\
+sequence.fallback=lucida,symbols,\
                   chinese-ms950,chinese-hkscs,chinese-ms936,chinese-gb18030,\
                   japanese,korean,chinese-ms950-extb,chinese-ms936-extb,georgian
 
@@ -298,3 +299,4 @@
 filename.Wingdings=WINGDING.TTF
 
 filename.Sylfaen=sylfaen.ttf
+filename.Segoe_UI_Symbol=SEGUISYM.TTF
--- a/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java	Thu Jan 12 06:59:38 2017 +0000
@@ -26,6 +26,7 @@
 package sun.java2d.d3d;
 
 import java.awt.Composite;
+import sun.java2d.InvalidPipeException;
 import sun.java2d.SunGraphics2D;
 import sun.java2d.loops.GraphicsPrimitive;
 import sun.java2d.loops.GraphicsPrimitiveMgr;
@@ -67,7 +68,13 @@
     protected void validateContext(SunGraphics2D sg2d,
                                    Composite comp, int ctxflags)
     {
-        D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
+        D3DSurfaceData dstData;
+        try {
+            dstData = (D3DSurfaceData) sg2d.surfaceData;
+        } catch (ClassCastException e) {
+            throw new InvalidPipeException("wrong surface data type: " +
+                                           sg2d.surfaceData);
+        }
         D3DContext.validateContext(dstData, dstData,
                                    sg2d.getCompClip(), comp,
                                    null, sg2d.paint, sg2d, ctxflags);
--- a/src/windows/native/java/lang/ProcessEnvironment_md.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/native/java/lang/ProcessEnvironment_md.c	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
--- a/src/windows/native/java/net/Inet4AddressImpl.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/native/java/net/Inet4AddressImpl.c	Thu Jan 12 06:59:38 2017 +0000
@@ -292,7 +292,6 @@
 }
 
 
-
 static BOOL
 WindowsVersionCheck(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) {
     OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
@@ -316,7 +315,7 @@
 }
 
 static jboolean
-wxp_ping4(JNIEnv *env,
+tcp_ping4(JNIEnv *env,
           jbyteArray addrArray,
           jint timeout,
           jbyteArray ifArray,
@@ -471,23 +470,17 @@
 ping4(JNIEnv *env,
       unsigned long src_addr,
       unsigned long dest_addr,
-      jint timeout)
+      jint timeout,
+      HANDLE hIcmpFile)
 {
     // See https://msdn.microsoft.com/en-us/library/aa366050%28VS.85%29.aspx
 
-    HANDLE hIcmpFile;
     DWORD dwRetVal = 0;
     char SendData[32] = {0};
     LPVOID ReplyBuffer = NULL;
     DWORD ReplySize = 0;
     jboolean ret = JNI_FALSE;
 
-    hIcmpFile = IcmpCreateFile();
-    if (hIcmpFile == INVALID_HANDLE_VALUE) {
-        NET_ThrowNew(env, WSAGetLastError(), "Unable to open handle");
-        return JNI_FALSE;
-    }
-
     ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
     ReplyBuffer = (VOID*) malloc(ReplySize);
     if (ReplyBuffer == NULL) {
@@ -553,6 +546,7 @@
         jint dest_addr = 0;
         jbyte caddr[4];
         int sz;
+        HANDLE hIcmpFile;
 
         /**
          * Convert IP address from byte array to integer
@@ -583,8 +577,20 @@
             src_addr = htonl(src_addr);
         }
 
-        return ping4(env, src_addr, dest_addr, timeout);
+        hIcmpFile = IcmpCreateFile();
+        if (hIcmpFile == INVALID_HANDLE_VALUE) {
+            int err = WSAGetLastError();
+            if (err == ERROR_ACCESS_DENIED) {
+                // fall back to TCP echo if access is denied to ICMP
+                return tcp_ping4(env, addrArray, timeout, ifArray, ttl);
+            } else {
+                NET_ThrowNew(env, err, "Unable to create ICMP file handle");
+                return JNI_FALSE;
+            }
+        } else {
+            return ping4(env, src_addr, dest_addr, timeout, hIcmpFile);
+        }
     } else {
-        wxp_ping4(env, addrArray, timeout, ifArray, ttl);
+        tcp_ping4(env, addrArray, timeout, ifArray, ttl);
     }
 }
--- a/src/windows/native/java/net/Inet6AddressImpl.c	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/native/java/net/Inet6AddressImpl.c	Thu Jan 12 06:59:38 2017 +0000
@@ -360,6 +360,109 @@
 
 #ifdef AF_INET6
 
+/**
+ * ping implementation using tcp port 7 (echo)
+ */
+static jboolean
+tcp_ping6(JNIEnv *env,
+          jint timeout,
+          jint ttl,
+          struct sockaddr_in6 him6,
+          struct sockaddr_in6* netif,
+          int len)
+{
+    jint fd;
+    WSAEVENT hEvent;
+    int connect_rv = -1;
+
+    fd = NET_Socket(AF_INET6, SOCK_STREAM, 0);
+    if (fd == SOCKET_ERROR) {
+        /* note: if you run out of fds, you may not be able to load
+         * the exception class, and get a NoClassDefFoundError
+         * instead.
+         */
+        NET_ThrowNew(env, errno, "Can't create socket");
+        return JNI_FALSE;
+    }
+
+    /**
+     * A TTL was specified, let's set the socket option.
+     */
+    if (ttl > 0) {
+      setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const char *)&ttl, sizeof(ttl));
+    }
+
+    /**
+     * A network interface was specified, let's bind to it.
+     */
+    if (netif != NULL) {
+      if (NET_Bind(fd, (struct sockaddr*)netif, sizeof(struct sockaddr_in6)) < 0) {
+        NET_ThrowNew(env, WSAGetLastError(), "Can't bind socket to interface");
+        closesocket(fd);
+        return JNI_FALSE;
+      }
+    }
+
+    /**
+     * Make the socket non blocking.
+     */
+    hEvent = WSACreateEvent();
+    WSAEventSelect(fd, hEvent, FD_READ|FD_CONNECT|FD_CLOSE);
+
+    /* no need to use NET_Connect as non-blocking */
+    him6.sin6_port = htons((short) 7); /* Echo port */
+    connect_rv = connect(fd, (struct sockaddr *)&him6, len);
+
+    /**
+     * connection established or refused immediately, either way it means
+     * we were able to reach the host!
+     */
+    if (connect_rv == 0 || WSAGetLastError() == WSAECONNREFUSED) {
+        WSACloseEvent(hEvent);
+        closesocket(fd);
+        return JNI_TRUE;
+    } else {
+        int optlen;
+
+        switch (WSAGetLastError()) {
+        case WSAEHOSTUNREACH:   /* Host Unreachable */
+        case WSAENETUNREACH:    /* Network Unreachable */
+        case WSAENETDOWN:       /* Network is down */
+        case WSAEPFNOSUPPORT:   /* Protocol Family unsupported */
+          WSACloseEvent(hEvent);
+          closesocket(fd);
+          return JNI_FALSE;
+        }
+
+        if (WSAGetLastError() != WSAEWOULDBLOCK) {
+            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
+                                         "connect failed");
+            WSACloseEvent(hEvent);
+            closesocket(fd);
+            return JNI_FALSE;
+        }
+
+        timeout = NET_Wait(env, fd, NET_WAIT_CONNECT, timeout);
+
+        if (timeout >= 0) {
+          /* has connection been established? */
+          optlen = sizeof(connect_rv);
+          if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
+                         &optlen) <0) {
+            connect_rv = WSAGetLastError();
+          }
+
+          if (connect_rv == 0 || connect_rv == WSAECONNREFUSED) {
+            WSACloseEvent(hEvent);
+            closesocket(fd);
+            return JNI_TRUE;
+          }
+        }
+    }
+    WSACloseEvent(hEvent);
+    closesocket(fd);
+    return JNI_FALSE;
+}
 
 /**
  * ping implementation.
@@ -371,9 +474,9 @@
 ping6(JNIEnv *env,
       struct sockaddr_in6* src,
       struct sockaddr_in6* dest,
-      jint timeout)
+      jint timeout,
+      HANDLE hIcmpFile)
 {
-    HANDLE hIcmpFile;
     DWORD dwRetVal = 0;
     char SendData[32] = {0};
     LPVOID ReplyBuffer = NULL;
@@ -381,12 +484,6 @@
     IP_OPTION_INFORMATION ipInfo = {255, 0, 0, 0, NULL};
     struct sockaddr_in6 sa6Source;
 
-    hIcmpFile = Icmp6CreateFile();
-    if (hIcmpFile == INVALID_HANDLE_VALUE) {
-        NET_ThrowNew(env, WSAGetLastError(), "Unable to open handle");
-        return JNI_FALSE;
-    }
-
     ReplySize = sizeof(ICMPV6_ECHO_REPLY) + sizeof(SendData);
     ReplyBuffer = (VOID*) malloc(ReplySize);
     if (ReplyBuffer == NULL) {
@@ -445,7 +542,7 @@
     struct sockaddr_in6* netif = NULL;
     struct sockaddr_in6 inf6;
     int len = 0;
-    int connect_rv = -1;
+    HANDLE hIcmpFile;
 
     /*
      * If IPv6 is not enable, then we can't reach an IPv6 address, can we?
@@ -489,7 +586,21 @@
       inf6.sin6_scope_id = if_scope;
       netif = &inf6;
     }
-    return ping6(env, netif, &him6, timeout);
+
+    hIcmpFile = Icmp6CreateFile();
+    if (hIcmpFile == INVALID_HANDLE_VALUE) {
+        int err = WSAGetLastError();
+        if (err == ERROR_ACCESS_DENIED) {
+            // fall back to TCP echo if access is denied to ICMP
+            return tcp_ping6(env, timeout, ttl, him6, netif, len);
+        } else {
+            NET_ThrowNew(env, err, "Unable to create ICMP file handle");
+            return JNI_FALSE;
+        }
+    } else {
+        return ping6(env, netif, &him6, timeout, hIcmpFile);
+    }
+
 #endif /* AF_INET6 */
     return JNI_FALSE;
 }
--- a/src/windows/native/sun/bridge/WinAccessBridge.cpp	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/native/sun/bridge/WinAccessBridge.cpp	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -1125,7 +1125,7 @@
 
     PrintDebugString("WinAccessBridge::getAccessibleContextWithFocus(%p, %X, )", window, vmID);
     // find vmID, etc. from HWND; ask that VM for the AC w/Focus
-        HWND pkgVMID = (HWND)ABLongToHandle( pkg->rVMID ) ;
+    HWND pkgVMID;
     if (getAccessibleContextFromHWND(window, (long *)&(pkgVMID), &(pkg->rAccessibleContext)) == TRUE) {
         HWND destABWindow = javaVMs->findAccessBridgeWindow((long)pkgVMID);     // ineffecient [[[FIXME]]]
         if (sendMemoryPackage(buffer, sizeof(buffer), destABWindow) == TRUE) {
--- a/src/windows/native/sun/windows/awt_TrayIcon.cpp	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/native/sun/windows/awt_TrayIcon.cpp	Thu Jan 12 06:59:38 2017 +0000
@@ -93,6 +93,12 @@
 
 void AwtTrayIcon::Dispose() {
     SendTrayMessage(NIM_DELETE);
+
+    // Destroy the icon to avoid leak of GDI objects
+    if (m_nid.hIcon != NULL) {
+        ::DestroyIcon(m_nid.hIcon);
+    }
+
     UnlinkObjects();
 
     if (--sm_instCount == 0) {
--- a/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp	Tue Nov 08 05:26:12 2016 +0000
+++ b/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp	Thu Jan 12 06:59:38 2017 +0000
@@ -981,6 +981,9 @@
     // Only want to call this once per session
     make_uns_ordered_dither_array(img_oda_alpha, 256);
 
+    // workaround JDK-6477756, ignore return value to keep dll in memory
+    JDK_LoadSystemLibrary("opengl32.dll");
+
     CATCH_BAD_ALLOC;
 }
 
--- a/test/ProblemList.txt	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/ProblemList.txt	Thu Jan 12 06:59:38 2017 +0000
@@ -237,6 +237,9 @@
 # 8026393
 sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java      generic-all
 
+# 8158827
+sun/security/krb5/auto/tools/KinitConfPlusProps.java                       windows-all
+
 ############################################################################
 
 # jdk_sound
--- a/test/com/sun/corba/cachedSocket/7056731.sh	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/com/sun/corba/cachedSocket/7056731.sh	Thu Jan 12 06:59:38 2017 +0000
@@ -102,7 +102,7 @@
 sleep 5 # give time for Client to throw exception
 
 # JVM_PROC should have exited but just in case, include it.
-kill -9 $ORB_PROC $JVM_PROC
+kill -9 $ORB_PROC $JVM_PROC $SERVER_PROC
 
 grep "ORBUtilSystemException.writeErrorSend" client.$$
 result=$?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,186 @@
+/*
+ * 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
+ * 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.PrintStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+public class Dynamic {
+
+    static final String ALGORITHM = "AES";
+    static final String[] MODE = {
+        "ECb", "CbC", "CTR", "PCBC", "OFB", "OFB150", "cFB", "CFB7",
+        "cFB8", "cFB16", "cFB24", "cFB32", "Cfb40", "cfB48", "cfB56",
+        "cfB64", "cfB72", "cfB80", "cfB88", "cfB96", "cfb104", "cfB112",
+        "cfB120", "cfB128", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40",
+        "OFB48", "OFB56", "OFB64", "OFB72", "OFB80", "OFB88", "OFB96",
+        "OFB104", "OFB112", "OFB120", "OFB128", "GCM"
+    };
+    static final String[] PADDING = {
+        "NoPadding", "PKCS5Padding", "ISO10126Padding"
+    };
+    static final String SUNJCE = "SunJCE";
+
+    Cipher ci = null;
+    byte[] iv = null;
+    AlgorithmParameterSpec aps = null;
+    SecretKey key = null;
+    int keyStrength;
+    static int DefaultSize = 128;
+
+    public void run(String[] argv) throws Exception {
+        if (!runAllTest(argv, System.out)) {
+            throw new Exception("Test Failed");
+        }
+    }
+
+    protected boolean runAllTest(String argv[], PrintStream out) {
+        boolean result = true;
+        StringBuilder failedList = new StringBuilder();
+        int failedCnt = 0;
+        int testCount = 0;
+        int padKinds; // how many kinds of padding mode such as PKCS5padding and
+        // NoPadding.
+
+        try {
+            for (int i = 0; i < 3; i++) {
+                keyStrength = DefaultSize + i * 64; // obtain the key size 128,
+                // 192, 256
+
+                for (int j = 0; j < MODE.length; j++) {
+                    if (MODE[j].equalsIgnoreCase("ECB")
+                            || MODE[j].equalsIgnoreCase("PCBC")
+                            || MODE[j].equalsIgnoreCase("CBC")) {
+                        padKinds = PADDING.length;
+                    } else {
+                        padKinds = 1;
+                    }
+
+                    for (int k = 0; k < padKinds; k++) {
+                        testCount++;
+                        try {
+                            if (!runTest(ALGORITHM, MODE[j], PADDING[k])) {
+                                result = false;
+                                failedCnt++;
+                                failedList.append(ALGORITHM + "/" + MODE[j]
+                                        + "/" + PADDING[k] + " ");
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            result = false;
+                            failedCnt++;
+                            failedList.append(ALGORITHM + "/" + MODE[j] + "/"
+                                    + PADDING[k] + " ");
+                        }
+
+                    }
+                }
+            }
+
+            if (result) {
+                out.println("STATUS:Passed. Test " + testCount
+                        + " cases, All Passed");
+                return true;
+            }
+            out.println("STATUS:Failed. " + failedCnt + " Failed: "
+                    + failedList);
+            return false;
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            out.println("STATUS:Failed. Unexpected Exception: " + ex);
+            return false;
+        }
+    }
+
+    protected boolean runTest(String algo, String mo, String pad)
+            throws Exception {
+        boolean result = true;
+        try {
+            byte[] plainText = new byte[160000];
+            new Random().nextBytes(plainText);
+
+            String transformation = algo + "/" + mo + "/" + pad;
+            ci = Cipher.getInstance(transformation, SUNJCE);
+            KeyGenerator kg = KeyGenerator.getInstance(algo, SUNJCE);
+            if (keyStrength > Cipher.getMaxAllowedKeyLength(transformation)) {
+                // skip if this key length is larger than what's
+                // configured in the jce jurisdiction policy files
+                System.out.println(keyStrength
+                        + " is larger than what's configured "
+                        + "in the jce jurisdiction policy files");
+                return result;
+            }
+            kg.init(keyStrength);
+            key = kg.generateKey();
+
+            if (!mo.equalsIgnoreCase("GCM")) {
+                ci.init(Cipher.ENCRYPT_MODE, key, aps);
+            } else {
+                ci.init(Cipher.ENCRYPT_MODE, key);
+            }
+            byte[] cipherText = new byte[ci.getOutputSize(plainText.length)];
+            int offset = ci.update(plainText, 0, plainText.length, cipherText,
+                    0);
+            ci.doFinal(cipherText, offset);
+
+            if (!mo.equalsIgnoreCase("ECB")) {
+                iv = ci.getIV();
+                aps = new IvParameterSpec(iv);
+            } else {
+                aps = null;
+            }
+
+            if (!mo.equalsIgnoreCase("GCM")) {
+                ci.init(Cipher.DECRYPT_MODE, key, aps);
+            } else {
+                ci.init(Cipher.DECRYPT_MODE, key, ci.getParameters());
+            }
+            byte[] recoveredText = new byte[ci.getOutputSize(cipherText.length)];
+            int len = ci.doFinal(cipherText, 0, cipherText.length,
+                    recoveredText);
+
+            byte[] tmp = new byte[len];
+            for (int i = 0; i < len; i++) {
+                tmp[i] = recoveredText[i];
+            }
+
+            result = Arrays.equals(plainText, tmp);
+        } catch (NoSuchAlgorithmException nsaEx) {
+            nsaEx.printStackTrace();
+            // CFB7 and OFB150 are negative test,SunJCE not support this
+            // algorithm
+            result = mo.equalsIgnoreCase("CFB7")
+                    || mo.equalsIgnoreCase("OFB150");
+
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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
+ * 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 8044193
+ * @summary Test AES ciphers with different modes and padding schemes with
+ *  default provider
+ */
+
+public class TestAESWithDefaultProvider extends Dynamic {
+    public static void main(String argv[]) throws Exception {
+        new TestAESWithDefaultProvider().run(argv);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,39 @@
+/* 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
+ * 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.Security;
+
+/*
+ * @test
+ * @bug 8044193
+ * @summary Test AES ciphers with different modes and padding schemes after
+ *  remove then add provider.
+ * @run main/othervm/policy=testAES.policy TestAESWithProviderChange
+ */
+
+public class TestAESWithProviderChange extends Dynamic {
+    public static void main(String argv[]) throws Exception {
+        Security.removeProvider(SUNJCE);
+        Security.addProvider(new com.sun.crypto.provider.SunJCE());
+        new TestAESWithProviderChange().run(argv);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * 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.*;
+import java.security.Provider;
+
+/*
+ * @test
+ * @bug 8044193
+ * @summary Test AES ciphers with different modes and padding schemes after
+ *  remove default provider then add it back.
+ * @run main/othervm/policy=testAES.policy TestAESWithRemoveAddProvider
+ */
+
+public class TestAESWithRemoveAddProvider extends Dynamic {
+    public static void main(String argv[]) throws Exception {
+        Provider pJCE = Security.getProvider(SUNJCE);
+        Security.removeProvider(SUNJCE);
+        Security.addProvider(pJCE);
+        new TestAESWithRemoveAddProvider().run(argv);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,6 @@
+grant 
+{
+    permission java.security.SecurityPermission "removeProvider.SunJCE";
+    permission java.security.SecurityPermission "insertProvider.SunJCE";
+    permission java.security.SecurityPermission "putProviderProperty.SunJCE";
+};
--- a/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8026943
+ * @bug 8026943 8027575
  * @summary Verify that same buffer can be used as input and output when
  * using Cipher objects.
  * @author Valerie Peng
@@ -44,7 +44,7 @@
     private static SecretKey KEY = new SecretKeySpec(new byte[16], "AES");
     private static byte[] IV = new byte[16];
 
-    private static int[] OFFSETS = { 1, 8, 17 };
+    private static int[] OFFSETS = { 1, 8, 9, 16, 17, 32, 33 };
 
     private static final String[] MODES = {
         "ECB", "CBC", "PCBC", "CTR", "CTS",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,51 @@
+/*
+ * 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.security.NoSuchAlgorithmException;
+
+/*
+ * @test
+ * @bug 8048601
+ * @library ../
+ * @summary Test Blowfish cipher with different MODES and padding
+ */
+
+public class TestCipherBlowfish extends TestCipher {
+
+    TestCipherBlowfish() throws NoSuchAlgorithmException {
+        super("Blowfish",
+                new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC",
+                    //CFBx
+                    "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56",
+                    "CFB64",
+                    //OFBx
+                    "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56",
+                    "OFB64"},
+                new String[]{"NoPaDDing", "PKCS5Padding"},
+                true);
+    }
+
+    public static void main(String[] args) throws Exception {
+        new TestCipherBlowfish().runAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,48 @@
+/*
+ * 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 8048601
+ * @library ../
+ * @summary Test DES/DESede cipher with different MODES and padding
+ */
+
+public class TestCipherDES extends TestCipher {
+
+    TestCipherDES() {
+        super("DES",
+                new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC",
+                    //CFBx
+                    "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56",
+                    "CFB64",
+                    //OFBx
+                    "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56",
+                    "OFB64"},
+                new String[]{"NoPaDDing", "PKCS5Padding"});
+    }
+
+    public static void main(String[] args) throws Exception {
+        new TestCipherDES().runAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,48 @@
+/*
+ * 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 8048601
+ * @library ../
+ * @summary Test DES/DESede cipher with different MODES and padding
+ */
+
+public class TestCipherDESede extends TestCipher {
+
+    TestCipherDESede() {
+        super("DESede",
+                new String[]{"CBC", "CTR", "CTS", "ECB", "PCBC",
+                    //CFBx
+                    "CFB", "CFB8", "CFB16", "CFB24", "CFB32", "CFB40", "CFB48", "CFB56",
+                    "CFB64",
+                    //OFBx
+                    "OFB", "OFB8", "OFB16", "OFB24", "OFB32", "OFB40", "OFB48", "OFB56",
+                    "OFB64"},
+                new String[]{"NoPaDDing", "PKCS5Padding"});
+    }
+
+    public static void main(String[] args) throws Exception {
+        new TestCipherDESede().runAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,128 @@
+/*
+ * 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 static java.lang.System.out;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+/*
+ * @test
+ * @bug 8048601
+ * @summary Tests for PBE ciphers
+ */
+public class TestCipherPBE {
+
+    private static final String[] ALGORITHMS = {"PBEWithMD5AndDES",
+        "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndTripleDES",
+        "PBEWithMD5AndTripleDES/CBC/PKCS5Padding"};
+
+    private static final String KEY_ALGO = "pbeWithMD5ANDdes";
+    private final byte[] SALT;
+    private final byte[] PLAIN_TEXT;
+
+    public TestCipherPBE() {
+        SALT = generateBytes(8);
+        PLAIN_TEXT = generateBytes(200);
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        new TestCipherPBE().runAll();
+    }
+
+    private void runAll() throws Exception {
+        for (String algorithm : ALGORITHMS) {
+            runTest(algorithm);
+        }
+    }
+
+    private void runTest(String algorithm)
+            throws InvalidKeySpecException, NoSuchAlgorithmException,
+            InvalidAlgorithmParameterException, ShortBufferException,
+            NoSuchPaddingException, IllegalBlockSizeException,
+            BadPaddingException, InvalidKeyException {
+
+        out.println("=> Testing: " + algorithm);
+
+        try {
+            // Initialization
+            AlgorithmParameterSpec algoParamSpec
+                    = new PBEParameterSpec(SALT, 6);
+
+            SecretKey secretKey
+                    = SecretKeyFactory.getInstance(KEY_ALGO).generateSecret(
+                    new PBEKeySpec(("Secret Key Value").toCharArray()));
+
+            Cipher ci = Cipher.getInstance(algorithm);
+            ci.init(Cipher.ENCRYPT_MODE, secretKey, algoParamSpec);
+
+            // Encryption
+            byte[] cipherText = ci.doFinal(PLAIN_TEXT);
+
+            // Decryption
+            ci.init(Cipher.DECRYPT_MODE, secretKey, algoParamSpec);
+            byte[] recoveredText = ci.doFinal(cipherText);
+
+            if (algorithm.contains("TripleDES")) {
+                throw new RuntimeException(
+                        "Expected InvalidKeyException exception uncaugh");
+            }
+
+            // Comparison
+            if (!Arrays.equals(PLAIN_TEXT, recoveredText)) {
+                throw new RuntimeException(
+                        "Test failed: plainText is not equal to recoveredText");
+            }
+            out.println("Test Passed.");
+        } catch (InvalidKeyException ex) {
+            if (algorithm.contains("TripleDES")) {
+                out.println("Expected InvalidKeyException raised");
+            } else {
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+
+    public static byte[] generateBytes(int length) {
+        byte[] bytes = new byte[length];
+        for (int i = 0; i < length; i++) {
+            bytes[i] = (byte) (i & 0xff);
+        }
+        return bytes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/TestCipher.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2015, 2016, 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 static java.lang.System.out;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * This is a abstract class used to test various ciphers
+ */
+public abstract class TestCipher {
+
+    private final String SUNJCE = "SunJCE";
+    private final String ALGORITHM;
+    private final String[] MODES;
+    private final String[] PADDINGS;
+
+    /* Used to test cipher with different key strengths
+       Key size tested is increment of KEYCUTTER from MINIMUM_KEY_SIZE to
+       maximum allowed keysize.
+       DES/DESede/Blowfish work with currently selected key sizes.
+    */
+    private final int variousKeySize;
+    private final int KEYCUTTER = 8;
+    private final int MINIMUM_KEY_SIZE = 32;
+
+    // Used to assert that Encryption/Decryption works with same buffer
+    // TEXT_LEN is multiple of blocks in order to work against ciphers w/ NoPadding
+    private final int TEXT_LEN = 800;
+    private final int ENC_OFFSET = 6;
+    private final int STORAGE_OFFSET = 3;
+    private final int PAD_BYTES = 16;
+
+    private final byte[] IV;
+    private final byte[] INPUT_TEXT;
+
+    TestCipher(String algo, String[] modes, String[] paddings,
+            boolean keyStrength) throws NoSuchAlgorithmException {
+        ALGORITHM = algo;
+        MODES = modes;
+        PADDINGS = paddings;
+        this.variousKeySize
+                = keyStrength ? Cipher.getMaxAllowedKeyLength(ALGORITHM) : 0;
+
+        IV = generateBytes(8);
+        INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET);
+    }
+
+    TestCipher(String algo, String[] modes, String[] paddings) {
+        ALGORITHM = algo;
+        MODES = modes;
+        PADDINGS = paddings;
+        variousKeySize = 0;
+
+        IV = generateBytes(8);
+        INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET);
+    }
+
+    private static byte[] generateBytes(int length) {
+        byte[] bytes = new byte[length];
+        for (int i = 0; i < length; i++) {
+            bytes[i] = (byte) (i & 0xff);
+        }
+        return bytes;
+    }
+
+    private boolean isKeyStrenthSupported() {
+        return (variousKeySize != 0);
+    }
+
+    public void runAll() throws InvalidKeyException,
+            NoSuchPaddingException, InvalidAlgorithmParameterException,
+            ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException, NoSuchAlgorithmException,
+            NoSuchProviderException {
+
+        for (String mode : MODES) {
+            for (String padding : PADDINGS) {
+                if (!isKeyStrenthSupported()) {
+                    runTest(mode, padding, 0);
+                } else {
+                    int keySize = variousKeySize;
+                    while (keySize >= MINIMUM_KEY_SIZE) {
+                        out.println("With Key Strength: " + keySize);
+                        runTest(mode, padding, keySize);
+                        keySize -= KEYCUTTER;
+                    }
+                }
+            }
+        }
+    }
+
+    private void runTest(String mo, String pad, int keySize)
+            throws NoSuchPaddingException, BadPaddingException,
+            ShortBufferException, IllegalBlockSizeException,
+            InvalidAlgorithmParameterException, InvalidKeyException,
+            NoSuchAlgorithmException, NoSuchProviderException {
+
+        String TRANSFORMATION = ALGORITHM + "/" + mo + "/" + pad;
+        out.println("Testing: " + TRANSFORMATION);
+
+        // Initialization
+        Cipher ci = Cipher.getInstance(TRANSFORMATION, SUNJCE);
+        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM, SUNJCE);
+        if (keySize != 0) {
+            kg.init(keySize);
+        }
+        SecretKey key = kg.generateKey();
+        SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM);
+
+        AlgorithmParameterSpec aps = new IvParameterSpec(IV);
+        if (mo.equalsIgnoreCase("ECB")) {
+            ci.init(Cipher.ENCRYPT_MODE, key);
+        } else {
+            ci.init(Cipher.ENCRYPT_MODE, key, aps);
+        }
+
+        // Encryption
+
+        byte[] plainText = INPUT_TEXT.clone();
+
+        // Generate cipher and save to separate buffer
+        byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN);
+
+        // Generate cipher and save to same buffer
+        int enc_bytes = ci.update(
+                INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET);
+        enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET);
+
+        if (!equalsBlock(
+                INPUT_TEXT, STORAGE_OFFSET, enc_bytes,
+                cipherText, 0, cipherText.length)) {
+            throw new RuntimeException(
+                    "Different ciphers generated with same buffer");
+        }
+
+        // Decryption
+        if (mo.equalsIgnoreCase("ECB")) {
+            ci.init(Cipher.DECRYPT_MODE, skeySpec);
+        } else {
+            ci.init(Cipher.DECRYPT_MODE, skeySpec, aps);
+        }
+
+        // Recover text from cipher and save to separate buffer
+        byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length);
+
+        if (!equalsBlock(
+                plainText, ENC_OFFSET, TEXT_LEN,
+                recoveredText, 0, recoveredText.length)) {
+            throw new RuntimeException(
+                    "Recovered text not same as plain text");
+        } else {
+            out.println("Recovered and plain text are same");
+        }
+
+        // Recover text from cipher and save to same buffer
+        int dec_bytes = ci.update(
+                INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET);
+        dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET);
+
+        if (!equalsBlock(
+                plainText, ENC_OFFSET, TEXT_LEN,
+                INPUT_TEXT, ENC_OFFSET, dec_bytes)) {
+            throw new RuntimeException(
+                    "Recovered text not same as plain text with same buffer");
+        } else {
+            out.println("Recovered and plain text are same with same buffer");
+        }
+
+        out.println("Test Passed.");
+    }
+
+    private static boolean equalsBlock(byte[] b1, int off1, int len1,
+            byte[] b2, int off2, int len2) {
+        if (len1 != len2) {
+            return false;
+        }
+        for (int i = off1, j = off2, k = 0; k < len1; i++, j++, k++) {
+            if (b1[i] != b2[j]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/TextLength/DESCipherWrapper.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,172 @@
+/*
+ * 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 static java.lang.System.out;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * Wrapper class to test a given DES algorithm.
+ */
+public class DESCipherWrapper {
+
+    private final Cipher ci;
+    private final byte[] iv;
+    private final SecretKey key;
+    private final String algo;
+    private final String mode;
+    private final String pad;
+    private final int keyStrength;
+    private byte[] resultText = null;
+
+    public DESCipherWrapper(String algo, String mode, String pad)
+            throws NoSuchAlgorithmException, NoSuchPaddingException {
+        ci = Cipher.getInstance(algo + "/" + mode + "/" + pad);
+
+        iv = new byte[8];
+        for (int i = 0; i < 8; i++) {
+            iv[i] = (byte) (i & 0xff);
+        }
+
+        KeyGenerator kg = KeyGenerator.getInstance(algo);
+        key = kg.generateKey();
+        keyStrength = algo.equalsIgnoreCase("DESede") ? 112
+                : key.getEncoded().length * 8;
+
+        this.algo = algo;
+        this.mode = mode;
+        this.pad = pad;
+    }
+
+    public byte[] getResult() {
+        return resultText.clone();
+    }
+
+    public void execute(int edMode, byte[] inputText)
+            throws InvalidKeyException, InvalidAlgorithmParameterException,
+            IllegalBlockSizeException, BadPaddingException,
+            ShortBufferException, NoSuchAlgorithmException {
+        AlgorithmParameterSpec aps = null;
+
+        try {
+            if (!mode.equalsIgnoreCase("ECB")) {
+                aps = new IvParameterSpec(iv);
+            }
+            ci.init(edMode, key, aps);
+
+            // Generate a resultText using a single-part enc/dec
+            resultText = ci.doFinal(inputText);
+
+            // Generate outputText for each multi-part en/de-cryption
+            /* Combination #1:
+            update(byte[], int, int)
+            doFinal(byte[], int, int)
+             */
+            byte[] part11 = ci.update(inputText, 0, inputText.length);
+            byte[] part12 = ci.doFinal();
+            byte[] outputText1 = new byte[part11.length + part12.length];
+            System.arraycopy(part11, 0, outputText1, 0, part11.length);
+            System.arraycopy(part12, 0, outputText1, part11.length,
+                    part12.length);
+
+            List<byte[]> outputTexts = new ArrayList<>(4);
+            outputTexts.add(outputText1);
+
+            /* Combination #2:
+            update(byte[], int, int)
+            doFinal(byte[], int, int, byte[], int)
+             */
+            byte[] part21 = ci.update(inputText, 0, inputText.length - 5);
+            byte[] part22 = new byte[ci.getOutputSize(inputText.length)];
+            int len2 = ci
+                    .doFinal(inputText, inputText.length - 5, 5, part22, 0);
+            byte[] outputText2 = new byte[part21.length + len2];
+            System.arraycopy(part21, 0, outputText2, 0, part21.length);
+            System.arraycopy(part22, 0, outputText2, part21.length, len2);
+
+            outputTexts.add(outputText2);
+
+            /* Combination #3:
+            update(byte[], int, int, byte[], int)
+            doFinal(byte[], int, int)
+             */
+            byte[] part31 = new byte[ci.getOutputSize(inputText.length)];
+            int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0);
+            byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8);
+            byte[] outputText3 = new byte[len3 + part32.length];
+            System.arraycopy(part31, 0, outputText3, 0, len3);
+            System.arraycopy(part32, 0, outputText3, len3, part32.length);
+
+            outputTexts.add(outputText3);
+
+            /* Combination #4:
+            update(byte[], int, int, byte[], int)
+            doFinal(byte[], int, int, byte[], int)
+             */
+            byte[] part41 = new byte[ci.getOutputSize(inputText.length)];
+            int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0);
+            int rest4 = ci.doFinal(inputText, inputText.length - 8, 8, part41,
+                    len4);
+            byte[] outputText4 = new byte[len4 + rest4];
+            System.arraycopy(part41, 0, outputText4, 0, outputText4.length);
+
+            outputTexts.add(outputText4);
+
+            // Compare results
+            for (int k = 0; k < outputTexts.size(); k++) {
+                if (!Arrays.equals(resultText, outputTexts.get(k))) {
+                    out.println(" Testing: " + algo + "/" + mode + "/" + pad);
+                    throw new RuntimeException(
+                            "Compare value of resultText and combination " + k
+                            + " are not same. Test failed.");
+                }
+            }
+            if (keyStrength > Cipher.getMaxAllowedKeyLength(algo)) {
+                throw new RuntimeException(
+                        "Expected exception uncaught, keyStrength "
+                        + keyStrength);
+            }
+        } catch (InvalidKeyException ex) {
+            if (keyStrength <= Cipher.getMaxAllowedKeyLength(algo)) {
+                out.println("Unexpected exception in " + algo + "/" + mode
+                        + "/" + pad + " ,  KeySize " + keyStrength);
+                throw ex;
+            }
+            out.println("Caught InvalidKeyException as expected");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,258 @@
+/*
+ * 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.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * PBECipherWrapper is the abstract class for all concrete PBE Cipher wrappers.
+ */
+public abstract class PBECipherWrapper {
+
+    public static final int ITERATION_COUNT = 1000;
+    private final String algorithm;
+    private final byte[] salt;
+    protected SecretKey key;
+    protected Cipher ci;
+    protected String baseAlgo;
+    protected byte[] resultText = null;
+    protected AlgorithmParameterSpec aps = null;
+
+    public PBECipherWrapper(String algorithm, int saltSize) {
+        this.algorithm = algorithm;
+        baseAlgo = algorithm.split("/")[0].toUpperCase();
+        salt = generateSalt(saltSize);
+    }
+
+    protected abstract void initCipher(int mode) throws InvalidKeyException,
+            InvalidAlgorithmParameterException, InvalidParameterSpecException;
+
+    public void execute(int edMode, byte[] inputText)
+            throws InvalidAlgorithmParameterException,
+            InvalidParameterSpecException, IllegalBlockSizeException,
+            BadPaddingException, ShortBufferException, InvalidKeyException {
+        // Initialize
+        initCipher(edMode);
+
+        // Generate a resultText using a single-part enc/dec
+        resultText = ci.doFinal(inputText);
+
+        // Generate outputText for each multi-part en/de-cryption
+        /* Combination #1:
+        update(byte[], int, int)
+        doFinal(byte[], int, int)
+         */
+        byte[] part11 = ci.update(inputText, 0, inputText.length);
+        byte[] part12 = ci.doFinal();
+        byte[] outputText1 = new byte[part11.length + part12.length];
+        System.arraycopy(part11, 0, outputText1, 0, part11.length);
+        System.arraycopy(part12, 0, outputText1, part11.length, part12.length);
+
+        List<byte[]> outputTexts = new ArrayList<>(4);
+        outputTexts.add(outputText1);
+
+        /* Combination #2:
+        update(byte[], int, int)
+        doFinal(byte[], int, int, byte[], int)
+         */
+        byte[] part21 = ci.update(inputText, 0, inputText.length - 5);
+        byte[] part22 = new byte[ci.getOutputSize(inputText.length)];
+        int len2 = ci.doFinal(inputText, inputText.length - 5, 5, part22, 0);
+        byte[] outputText2 = new byte[part21.length + len2];
+        System.arraycopy(part21, 0, outputText2, 0, part21.length);
+        System.arraycopy(part22, 0, outputText2, part21.length, len2);
+
+        outputTexts.add(outputText2);
+
+        /* Combination #3:
+        update(byte[], int, int, byte[], int)
+        doFinal(byte[], int, int)
+         */
+        byte[] part31 = new byte[ci.getOutputSize(inputText.length)];
+        int len3 = ci.update(inputText, 0, inputText.length - 8, part31, 0);
+        byte[] part32 = ci.doFinal(inputText, inputText.length - 8, 8);
+        byte[] outputText3 = new byte[len3 + part32.length];
+        System.arraycopy(part31, 0, outputText3, 0, len3);
+        System.arraycopy(part32, 0, outputText3, len3, part32.length);
+
+        outputTexts.add(outputText3);
+
+        /* Combination #4:
+        update(byte[], int, int, byte[], int)
+        doFinal(byte[], int, int, byte[], int)
+         */
+        byte[] part41 = new byte[ci.getOutputSize(inputText.length)];
+        int len4 = ci.update(inputText, 0, inputText.length - 8, part41, 0);
+        int rest4 = ci
+                .doFinal(inputText, inputText.length - 8, 8, part41, len4);
+        byte[] outputText4 = new byte[len4 + rest4];
+        System.arraycopy(part41, 0, outputText4, 0, outputText4.length);
+
+        outputTexts.add(outputText4);
+
+        // Compare results
+        for (int k = 0; k < outputTexts.size(); k++) {
+            if (!Arrays.equals(resultText, outputTexts.get(k))) {
+                throw new RuntimeException(
+                        "Compare value of resultText and combination " + k
+                        + " are not same. Test failed.");
+            }
+        }
+
+    }
+
+    public final byte[] generateSalt(int numberOfBytes) {
+        byte[] aSalt = new byte[numberOfBytes];
+        for (int i = 0; i < numberOfBytes; i++) {
+            aSalt[i] = (byte) (i & 0xff);
+        }
+        return aSalt;
+    }
+
+    public byte[] getResult() {
+        return resultText;
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public byte[] getSalt() {
+        return salt;
+    }
+
+    /**
+     * Wrapper class to test a given SecretKeyFactory.PBKDF2 algorithm.
+     */
+    public static class PBKDF2 extends PBECipherWrapper {
+
+        private static final int PBKDF2_SALT_SIZE = 64;
+        private static final int CIPHER_KEY_SIZE = 128;
+        private static final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
+        private static final String KEY_ALGORITHM = "AES";
+        private byte[] iv = null;
+
+        public PBKDF2(String algo, String passwd)
+                throws InvalidKeySpecException, NoSuchAlgorithmException,
+                NoSuchPaddingException {
+            super(algo, PBKDF2_SALT_SIZE);
+
+            ci = Cipher.getInstance(CIPHER_TRANSFORMATION);
+
+            PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray(), getSalt(),
+                    ITERATION_COUNT, CIPHER_KEY_SIZE);
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algo);
+            key = keyFactory.generateSecret(pbeKeySpec);
+        }
+
+        @Override
+        protected void initCipher(int mode) throws InvalidKeyException,
+                InvalidAlgorithmParameterException, InvalidParameterSpecException {
+            if (Cipher.ENCRYPT_MODE == mode) {
+                ci.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getEncoded(),
+                        KEY_ALGORITHM));
+                iv = ci.getParameters().getParameterSpec(IvParameterSpec.class)
+                        .getIV();
+            } else {
+                ci.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getEncoded(),
+                        KEY_ALGORITHM), new IvParameterSpec(iv));
+            }
+        }
+    }
+
+    /**
+     * Wrapper class to test a given AES-based PBE algorithm.
+     */
+    public static class AES extends PBECipherWrapper {
+
+        private AlgorithmParameters pbeParams;
+
+        public AES(String algo, String passwd)
+                throws NoSuchAlgorithmException, NoSuchPaddingException,
+                InvalidKeySpecException {
+            super(algo, 0);
+
+            ci = Cipher.getInstance(algo);
+
+            SecretKeyFactory skf = SecretKeyFactory.getInstance(algo);
+            key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));
+        }
+
+        @Override
+        protected void initCipher(int mode) throws InvalidKeyException,
+                InvalidAlgorithmParameterException, InvalidParameterSpecException {
+            if (Cipher.ENCRYPT_MODE == mode) {
+                ci.init(Cipher.ENCRYPT_MODE, key);
+                pbeParams = ci.getParameters();
+            } else {
+                ci.init(Cipher.DECRYPT_MODE, key, pbeParams);
+            }
+        }
+    }
+
+    /**
+     * Wrapper class to test a given PBE algorithm.
+     */
+    public static class Legacy extends PBECipherWrapper {
+
+        private static final int PBE_SALT_SIZE = 8;
+
+        public Legacy(String algo, String passwd)
+                throws NoSuchAlgorithmException, NoSuchPaddingException,
+                InvalidKeySpecException {
+            super(algo, PBE_SALT_SIZE);
+
+            SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);
+            key = skf.generateSecret(new PBEKeySpec(passwd.toCharArray()));
+
+            aps = new PBEParameterSpec(getSalt(), ITERATION_COUNT);
+
+            ci = Cipher.getInstance(algo);
+        }
+
+        @Override
+        protected void initCipher(int mode) throws InvalidKeyException,
+                InvalidAlgorithmParameterException, InvalidParameterSpecException {
+            ci.init(mode, key, aps);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,136 @@
+/*
+ * 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 static java.lang.System.out;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+/*
+ * @test
+ * @bug 8048601
+ * @summary Performs multiple-part encryption/decryption depending on the
+ *  specified encryption mode and check if the results obtained by
+ *  different ways are the same.
+ */
+public class TestCipherTextLength {
+
+    /* Algorithms tested by DESCipherWrapper */
+    private static final String[] DES_ALGORITHMS = {"DES", "DESede",
+        "Blowfish"};
+    private static final String[] DES_MODES = {"ECB", "CBC", "PCBC"};
+    private static final String[] DES_PADDING = {"PKCS5Padding"};
+
+    /* Algorithms tested by PBECipherWrapper */
+    private static final String[] PBE_ALGORITHMS = {"PBEWithMD5AndDES",
+        "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5ANDTripleDES",
+        "PBEWithMD5AndTripleDES/CBC/PKCS5Padding", "PBEwithSHA1AndDESede",
+        "PBEwithSHA1AndDESede/CBC/PKCS5Padding", "PBEwithSHA1AndRC2_40",
+        "PBEwithSHA1Andrc2_40/CBC/PKCS5Padding", "PBEWithSHA1AndRC2_128",
+        "PBEWithSHA1andRC2_128/CBC/PKCS5Padding", "PBEWithSHA1AndRC4_40",
+        "PBEWithsha1AndRC4_40/ECB/NoPadding", "PBEWithSHA1AndRC4_128",
+        "PBEWithSHA1AndRC4_128/ECB/NoPadding", "PBEWithHmacSHA1AndAES_128",
+        "PBEWithHmacSHA224AndAES_128", "PBEWithHmacSHA256AndAES_128",
+        "PBEWithHmacSHA384AndAES_128", "PBEWithHmacSHA512AndAES_128",
+        "PBEWithHmacSHA1AndAES_256", "PBEWithHmacSHA224AndAES_256",
+        "PBEWithHmacSHA256AndAES_256", "PBEWithHmacSHA384AndAES_256",
+        "PBEWithHmacSHA512AndAES_256", "PBKDF2WithHmacSHA1",
+        "PBKDF2WithHmacSHA224", "PBKDF2WithHmacSHA256",
+        "PBKDF2WithHmacSHA384", "PBKDF2WithHmacSHA512"};
+    private static final String PBE_PASSWORD = "Hush, it's a secret!!";
+
+    // Algorithm tested by PBKDF2Wrappter
+    private static final String PBKDF2 = "PBKDF2";
+
+    // Algorithm tested by AESPBEWrapper
+    private static final String AES = "AES";
+
+    public static void main(String[] args) throws Exception {
+        byte[] plainText = new byte[64];
+        for (int i = 0; i < 64; i++) {
+            plainText[i] = (byte) (i & 0xff);
+        }
+
+        new TestCipherTextLength().runAll(plainText);
+    }
+
+    public void runAll(byte[] plainText) throws Exception {
+
+        // Testing DES/Blowfish Cipher
+        for (String algorithm : DES_ALGORITHMS) {
+            for (String desMode : DES_MODES) {
+                for (String padding : DES_PADDING) {
+                    out.println("=>Testing: " + algorithm + "/" + desMode
+                            + "/" + padding);
+                    DESCipherWrapper desCi = new DESCipherWrapper(algorithm,
+                            desMode, padding);
+                    desCi.execute(Cipher.ENCRYPT_MODE, plainText);
+                    desCi.execute(Cipher.DECRYPT_MODE, desCi.getResult());
+                    if (!Arrays.equals(plainText, desCi.getResult())) {
+                        throw new RuntimeException(
+                                "Plain and recovered texts are not same for:"
+                                + algorithm + "/" + desMode + "/"
+                                + padding);
+                    }
+                }
+            }
+        }
+
+        // Testing PBE Cipher
+        for (String algorithm : PBE_ALGORITHMS) {
+            int maxKeyLen = Cipher.getMaxAllowedKeyLength(algorithm);
+            boolean isUnlimited = maxKeyLen == Integer.MAX_VALUE;
+            if (!isUnlimited
+                    && (algorithm.contains("TripleDES") || algorithm
+                    .contains("AES_256"))) {
+                out.println("Test " + algorithm + " will be ignored");
+                continue;
+            }
+
+            out.println("=>Testing: " + algorithm);
+            PBECipherWrapper pbeCi = createWrapper(algorithm, PBE_PASSWORD);
+            pbeCi.execute(Cipher.ENCRYPT_MODE, plainText);
+            pbeCi.execute(Cipher.DECRYPT_MODE, pbeCi.getResult());
+            if (!Arrays.equals(plainText, pbeCi.getResult())) {
+                throw new RuntimeException(
+                        "Plain and recovered texts are not same for:"
+                        + algorithm);
+            }
+        }
+    }
+
+    private PBECipherWrapper createWrapper(String algo, String passwd)
+            throws InvalidKeySpecException, NoSuchAlgorithmException,
+            NoSuchPaddingException {
+        if (algo.contains(PBKDF2)) {
+            return new PBECipherWrapper.PBKDF2(algo, passwd);
+        } else if (algo.contains(AES)) {
+            return new PBECipherWrapper.AES(algo, passwd);
+        } else {
+            return new PBECipherWrapper.Legacy(algo, passwd);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jndi/ldap/SimpleClientIdHashCode.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, 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 8158802
+ * @summary com.sun.jndi.ldap.SimpleClientId produces wrong hash code
+ * @modules java.naming/com.sun.jndi.ldap
+ */
+
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import javax.naming.ldap.Control;
+
+
+public class SimpleClientIdHashCode {
+    public static void main(String[] args) throws Throwable {
+        Class<?> simpleClientIdClass
+                = Class.forName("com.sun.jndi.ldap.SimpleClientId");
+        Constructor<?> init = simpleClientIdClass.getDeclaredConstructor(
+                int.class, String.class, int.class, String.class,
+                Control[].class, OutputStream.class, String.class,
+                String.class, Object.class);
+        init.setAccessible(true);
+
+        Object p1 = new byte[]{66,77};
+        Object p2 = new char[]{'w','d'};
+        Object p3 = "word";
+
+        test(init, new byte[]{65}, new byte[]{65});
+        test(init, new char[]{'p'}, new char[]{'p'});
+        test(init, "pass", "pass");
+        test(init, p1, p1);
+        test(init, p2, p2);
+        test(init, p3, p3);
+        test(init, null, null);
+    }
+
+    private static void test(Constructor<?> init, Object pass1, Object pass2)
+            throws Throwable {
+
+        Object o1 = init.newInstance(1, "host", 3, "", null, System.out,
+                null, null, pass1);
+        Object o2 = init.newInstance(1, "host", 3, "", null, System.out,
+                null, null, pass2);
+
+        if (!o1.equals(o2))
+            throw new RuntimeException("Objects not equal");
+
+        if (o1.hashCode() != o2.hashCode())
+            throw new RuntimeException("Inconsistent hash codes");
+    }
+}
--- a/test/demo/jvmti/hprof/CpuOldTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/CpuOldTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with cpu=old */
-        hprof = new DemoRun("hprof", "cpu=old");
+        hprof = new DemoRun("hprof", "cpu=old,file=cpuold.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/CpuSamplesTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/CpuSamplesTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with cpu=samples */
-        hprof = new DemoRun("hprof", "cpu=samples");
+        hprof = new DemoRun("hprof", "cpu=samples,file=cpusamples.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with cpu=times */
-        hprof = new DemoRun("hprof", "cpu=times");
+        hprof = new DemoRun("hprof", "cpu=times,file=cputimedefineclass.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/CpuTimesTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/CpuTimesTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with cpu=times */
-        hprof = new DemoRun("hprof", "cpu=times");
+        hprof = new DemoRun("hprof", "cpu=times,file=cputimes.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapAllTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/HeapAllTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with heap=all */
-        hprof = new DemoRun("hprof", "heap=all");
+        hprof = new DemoRun("hprof", "heap=all,file=heapall.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapBinaryFormatTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/HeapBinaryFormatTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent to get binary format dump */
-        hprof = new DemoRun("hprof", "heap=dump,format=b,logflags=4");
+        hprof = new DemoRun("hprof", "heap=dump,format=b,logflags=4,file=heapbinaryformat.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapDumpTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/HeapDumpTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with heap=dump */
-        hprof = new DemoRun("hprof", "heap=dump");
+        hprof = new DemoRun("hprof", "heap=dump,file=heapdump.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/HeapSitesTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/HeapSitesTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with heap=sites */
-        hprof = new DemoRun("hprof", "heap=sites");
+        hprof = new DemoRun("hprof", "heap=sites,file=heapsites.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/MonitorTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/MonitorTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
         DemoRun hprof;
 
         /* Run JVMTI hprof agent with monitor=y */
-        hprof = new DemoRun("hprof", "monitor=y");
+        hprof = new DemoRun("hprof", "monitor=y,file=monitor.txt");
         hprof.runit(args[0]);
 
         /* Make sure patterns in output look ok */
--- a/test/demo/jvmti/hprof/OptionsTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/OptionsTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,10 +39,10 @@
         DemoRun hprof;
         List<String> options = new LinkedList<String>();
 
-        options.add("cpu=samples,depth=0");
-        options.add("cpu=times,depth=0");
-        options.add("cpu=old,depth=0");
-        options.add("depth=0");
+        options.add("cpu=samples,depth=0,file=options0.txt");
+        options.add("cpu=times,depth=0,file=options1.txt");
+        options.add("cpu=old,depth=0,file=options2.txt");
+        options.add("depth=0,file=options3.txt");
 
         for(String option: options) {
             /* Run JVMTI hprof agent with various options */
--- a/test/demo/jvmti/hprof/StackMapTableTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/demo/jvmti/hprof/StackMapTableTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -40,10 +40,10 @@
         DemoRun hprof;
         List<String> options = new LinkedList<String>();
 
-        options.add("cpu=samples");
-        options.add("cpu=times");
-        options.add("heap=sites");
-        options.add("");
+        options.add("cpu=samples,file=stackmaptable0.txt");
+        options.add("cpu=times,file=stackmaptable1.txt");
+        options.add("heap=sites,file=stackmaptable2.txt");
+        options.add("file=stackmaptable3.txt");
 
         for(String option: options) {
             /* Run JVMTI hprof agent with various options */
--- a/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -94,6 +94,15 @@
         int screenX = (int) splashBounds.getCenterX();
         int screenY = (int) splashBounds.getCenterY();
 
+        if(splashBounds.width != IMAGE_WIDTH){
+            throw new RuntimeException(
+                    "SplashScreen#getBounds has wrong width");
+        }
+        if(splashBounds.height != IMAGE_HEIGHT){
+            throw new RuntimeException(
+                    "SplashScreen#getBounds has wrong height");
+        }
+
         Robot robot = new Robot();
         Color splashScreenColor = robot.getPixelColor(screenX, screenY);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Window/WindowJumpingTest/WindowJumpingTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, 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 8080729
+ * @summary Dialogs on multiscreen jump to parent frame on focus gain
+ * @author Dmitry Markov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main WindowJumpingTest
+ */
+import java.awt.*;
+
+import test.java.awt.regtesthelpers.Util;
+
+public class WindowJumpingTest {
+    public static void main(String[] args) throws AWTException {
+        Robot r = Util.createRobot();
+
+        GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        GraphicsDevice[] graphicsDevices = graphicsEnvironment.getScreenDevices();
+        if (graphicsDevices.length < 2) {
+            System.out.println("This is multi-screen test... Skipping!");
+            return;
+        }
+
+        Frame frame = new Frame("Frame", graphicsDevices[0].getDefaultConfiguration());
+        frame.setSize(400, 300);
+        frame.setVisible(true);
+        Util.waitForIdle(r);
+
+        Dialog dialog = new Dialog(frame, "Dialog", false, graphicsDevices[1].getDefaultConfiguration());
+        dialog.setSize(400, 300);
+        dialog.setVisible(true);
+        Util.waitForIdle(r);
+
+        checkGraphicsDevice(frame, graphicsDevices[0]);
+        checkGraphicsDevice(dialog, graphicsDevices[1]);
+
+        Util.clickOnComp(frame, r);
+        Util.waitForIdle(r);
+
+        checkGraphicsDevice(frame, graphicsDevices[0]);
+        checkGraphicsDevice(dialog, graphicsDevices[1]);
+
+        Util.clickOnComp(dialog, r);
+        Util.waitForIdle(r);
+
+        checkGraphicsDevice(frame, graphicsDevices[0]);
+        checkGraphicsDevice(dialog, graphicsDevices[1]);
+
+        dialog.dispose();
+        frame.dispose();
+    }
+
+    private static void checkGraphicsDevice(Window window, GraphicsDevice graphicsDevice) {
+        GraphicsDevice actualGraphicsDevice = window.getGraphicsConfiguration().getDevice();
+
+        if (!actualGraphicsDevice.equals(graphicsDevice)) {
+            System.err.println("Expected screen: " + graphicsDevice);
+            System.err.println("Actual screen: "+ actualGraphicsDevice);
+            throw new RuntimeException("Test FAILED: " + window + " is displayed on wrong screen");
+        }
+    }
+}
+
--- a/test/java/awt/Window/WindowsLeak/WindowsLeak.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/awt/Window/WindowsLeak/WindowsLeak.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -23,41 +23,40 @@
 
 /*
  * @test
- * @bug 8013563
+ * @bug 8013563 8028486
  * @summary Tests that windows are removed from windows list
+ * @library /javax/swing/regtesthelpers
+ * @build Util
  * @run main/othervm -Xms32M -Xmx32M WindowsLeak
 */
 
-import java.awt.*;
-import sun.awt.AppContext;
+import java.awt.Frame;
+import java.awt.Robot;
+import java.awt.Window;
+import java.lang.ref.WeakReference;
+import java.util.Vector;
 
-import java.lang.ref.WeakReference;
-
-import java.util.Vector;
+import sun.awt.AppContext;
+import sun.java2d.Disposer;
 
 public class WindowsLeak {
 
-    public static void main(String[] args) {
-        for (int i = 0; i < 100; i++)
-        {
+    private static volatile boolean disposerPhantomComplete;
+
+    public static void main(String[] args) throws Exception {
+        Robot r = new Robot();
+        for (int i = 0; i < 100; i++) {
             Frame f = new Frame();
             f.pack();
             f.dispose();
         }
+        r.waitForIdle();
 
-        Vector garbage = new Vector();
-        while (true)
-        {
-            try
-            {
-                garbage.add(new byte[1000]);
-            }
-            catch (OutOfMemoryError e)
-            {
-                break;
-            }
+        Disposer.addRecord(new Object(), () -> disposerPhantomComplete = true);
+
+        while (!disposerPhantomComplete) {
+            Util.generateOOME();
         }
-        garbage = null;
 
         Vector<WeakReference<Window>> windowList =
                         (Vector<WeakReference<Window>>) AppContext.getAppContext().get(Window.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/im/8148984/bug8148984.html	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,38 @@
+<!--
+ Copyright (c) 2016, 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.
+-->
+
+<html>
+<body>
+Verify that Chinese comma can be entered in JTextField with Pinyin input method (IM).
+
+This test is for OS X only. For other platforms please simply press "Pass".
+
+1. Go to "System Preferences -> Keyboard -> Input Sources" and add "Pinyin – Traditional" or "Pinyin – Simplified" IM from Chinese language group.
+2. Set current IM to "Pinyin".
+3. Set focus to the text field of the test and press "comma" character on the keyboard.
+4. Set current IM to the IM used before "Pinyin" was set.
+5. If "," character is displayed in the text area, press "Pass", if "," character is displayed, press "Fail".
+
+<applet  code="bug8148984.class" width=400 height=400></applet>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/im/8148984/bug8148984.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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 8148984
+ * @summary Chinese Comma cannot be entered using Pinyin Input Method on OS X
+ * @author Dmitry Markov
+ * @run applet/manual=yesno bug8148984.html
+ */
+
+import javax.swing.*;
+
+public class bug8148984 extends JApplet {
+    @Override
+    public void init() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                JPanel panel = new JPanel();
+                panel.add(new JLabel("Text field:"));
+                panel.add(new JTextField(20));
+                add(panel);
+            }
+        });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/im/8154816/bug8154816.html	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,39 @@
+<!--
+ Copyright (c) 2016, 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.
+-->
+
+<html>
+<body>
+Verify that Caps Lock key works properly with Pinyin input method, (i.e. if 
+Caps Lock is pressed, input should be swithced to lowercase latin letters).
+
+This test is for OS X only. For other platforms please simply press "Pass".
+
+1. Go to "System Preferences -> Keyboard -> Input Sources" and add "Pinyin – Traditional" or "Pinyin – Simplified" IM from Chinese language group.
+2. Set current IM to "Pinyin".
+3. Set focus to the text field of the test and press Caps Lock key on the keyboard.
+4. Press "a" character on the keyboard
+5. If "a" character is displayed in the text field, press "Pass", if "A" character is displayed, press "Fail".
+
+<applet  code="bug8154816.class" width=400 height=400></applet>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/im/8154816/bug8154816.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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 8154816
+ * @summary Caps Lock doesn't work as expected when using Pinyin Simplified input method
+ * @author Dmitry Markov
+ * @run applet/manual=yesno bug8154816.html
+ */
+
+import javax.swing.*;
+
+public class bug8154816 extends JApplet {
+    @Override
+    public void init() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                JPanel panel = new JPanel();
+                panel.add(new JLabel("Text field:"));
+                panel.add(new JTextField(20));
+                add(panel);
+            }
+        });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/annotation/AnnotationWithLambda.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/*
+ * @test
+ * @bug 8147585
+ * @summary Check Annotation with Lambda, with or without parameter
+ * @run testng AnnotationWithLambda
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.function.Consumer;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+public class AnnotationWithLambda {
+
+    @Test
+    void testAnnotationWithLambda() {
+        Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods();
+        for (Method method : methods) {
+            assertTrue((method.isAnnotationPresent(LambdaWithParameter.class)) &&
+                       (method.isAnnotationPresent(LambdaWithoutParameter.class)));
+
+        }
+    }
+
+    static class MethodsWithAnnotations {
+
+        @LambdaWithParameter
+        @LambdaWithoutParameter
+        public void testAnnotationLambda() {
+        }
+    }
+}
+
+@Target(value = ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface LambdaWithParameter {
+    Consumer<Integer> f1 = a -> {
+        System.out.println("lambda has parameter");
+    };
+}
+
+@Target(value = ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface LambdaWithoutParameter {
+    Runnable r = () -> System.out.println("lambda without parameter");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/ArrayConstructorTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/* @test
+ * @bug 8155106
+ * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayConstructorTest
+ */
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import static java.lang.invoke.MethodType.methodType;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.*;
+
+
+public class ArrayConstructorTest {
+
+    static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+    @Test
+    public static void testFindConstructorArray() {
+        boolean caught = false;
+        try {
+            MethodHandle h = LOOKUP.findConstructor(Object[].class, methodType(void.class));
+        } catch (NoSuchMethodException nsme) {
+            assertEquals("no constructor for array class: [Ljava.lang.Object;", nsme.getMessage());
+            caught = true;
+        } catch (Exception e) {
+            throw new AssertionError("unexpected exception: " + e);
+        }
+        assertTrue(caught);
+    }
+
+}
+
--- a/test/java/lang/invoke/CustomizedLambdaFormTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/lang/invoke/CustomizedLambdaFormTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -26,7 +26,7 @@
 /* @test
  * @summary Assertion in LambdaFormEditor.bindArgumentType is too strong
  *
- * @run main/bootclasspath -esa java.lang.invoke.CustomizedLambdaFormTest
+ * @run main/othervm/bootclasspath -esa java.lang.invoke.CustomizedLambdaFormTest
  */
 public class CustomizedLambdaFormTest {
 
--- a/test/java/lang/invoke/PermuteArgsTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/lang/invoke/PermuteArgsTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -23,6 +23,7 @@
 
 /* @test
  * @summary unit tests for method handles which permute their arguments
+ * @library /lib/testlibrary/jsr292 /lib/testlibrary
  * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
  */
 /* Examples of manual runs:
@@ -36,6 +37,8 @@
 import org.testng.*;
 import org.testng.annotations.*;
 
+import com.oracle.testlibrary.jsr292.CodeCacheOverflowProcessor;
+
 import java.util.*;
 import java.lang.reflect.*;
 
@@ -122,9 +125,15 @@
         }
         new PermuteArgsTest().test();
     }
+
     static int testCases;
+
     @Test
     public void test() throws Throwable {
+        CodeCacheOverflowProcessor.runMHTest(this::test0);
+    }
+
+    public void test0() throws Throwable {
         testCases = 0;
         Lookup lookup = lookup();
         for (Method m : lookup.lookupClass().getDeclaredMethods()) {
--- a/test/java/lang/invoke/VarargsArrayTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/lang/invoke/VarargsArrayTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -32,13 +32,12 @@
  * @summary unit tests for varargs array methods: MethodHandleInfo.varargsArray(int),
  *          MethodHandleInfo.varargsArray(Class,int) & MethodHandleInfo.varargsList(int)
  * @library /lib/testlibrary /lib/testlibrary/jsr292
- * @run main/bootclasspath java.lang.invoke.VarargsArrayTest
- * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250
- *                         java.lang.invoke.VarargsArrayTest
+ * @run main/othervm/bootclasspath java.lang.invoke.VarargsArrayTest
+ * @run main/othervm/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.START_ARITY=250 java.lang.invoke.VarargsArrayTest
  */
 
 /* This might take a while and burn lots of metadata:
- * @run main/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.EXHAUSTIVE=true java.lang.invoke.VarargsArrayTest
+ * @run main/othervm/bootclasspath -DVarargsArrayTest.MAX_ARITY=255 -DVarargsArrayTest.EXHAUSTIVE=true java.lang.invoke.VarargsArrayTest
  */
 public class VarargsArrayTest {
     private static final Class<?> CLASS = VarargsArrayTest.class;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/KeyStore/TestKeyStoreBasic.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2001, 2016, 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.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Base64;
+
+/*
+ * @test
+ * @bug 8048621 8133090
+ * @summary Test basic operations with keystores (jks, jceks, pkcs12)
+ * @author Yu-Ching Valerie PENG
+ */
+public class TestKeyStoreBasic {
+
+    private static final String PRIVATE_KEY_PKCS8_BASE64 = ""
+        + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCpyz97liuWPDYcLH9TX8BiT78o"
+        + "lCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgKmLhuczF3M9VIcWr+"
+        + "JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz7leikne7KmclHvTfvFd0WDI7Gb9v"
+        + "o4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXRv5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfF"
+        + "e1DDsMg/KpKGiILYZ+g2qtVMZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e"
+        + "+sO6H24w2F19AgMBAAECggEBAId/12187dO6wUPCjumuJA1QrrBnbKdKONyai36uoc1Od4s5QFj7"
+        + "+hEIeS7rbGNYQuBvnkgusAbzkW0FIpxpHce3EJez/emux6pEOKoP77BwMt9gy+txyu0+BHi91FQg"
+        + "AGvrnQDO5EYVY4Cz/WjOsJzKu8zVLg+DS0Toa2qRFwmUe9mVAXPNOCZ3Oae/Q6tCDsaINNw0fmjj"
+        + "jn6uohPbS+n6xENG3FkQXB36getXy310xTGED2J27cmAQH6gLR6Kl2iROzNPbbpBqbuemI9kbcld"
+        + "EwBS1jRfZWeaPstYA1niVrE9UgUBzemnoh4TDkG076sYthHMr5QFGjPswnwtJ4ECgYEA0sURQ5+v"
+        + "baH4tdaemI3qpnknXTlzSpuZZmAoyvY0Id0mlduwKwmZ3Y5989wHfnnhFfyNO4IkTKjI2Wp97qP5"
+        + "4eqUNpA7FtNU7KUzMcFDTtwtNZuRYMrKlqo2lLbA+gVrAYpYZFL4b7tcwtX4DnYorDsmude6W8sG"
+        + "4Mx2VdFJC9UCgYEAzjsdXCYH5doWUHb0dvn9ID7IikffEMRM720MRjrnnnVbpzx6ACntkPDNZg7p"
+        + "TRE/mx7iBz81ZaUWE+V0wd0JvCHEdpAz3mksyvDFhU4Bgs6xzf2pSul5muhsx3hHcvvPezz5Bnxs"
+        + "faJlzkxfwotyGmvWN15GA/pyfsZjsbbTpwkCgYAO6NnbysQCIV8SnegCKqfatt9N/O5m7LLhRxQb"
+        + "p2bwrlA4cZ34rWkw/w9x3LK7A6wkfgUPnJkswxPSLXJTG05l6M4rPfCwIKr1Qopojp9QSMr569NQ"
+        + "4YeLOOc7heIIzbFQHpU6I5Rncv2Q2sn9W+ZsqJKIuvX34FjQNiZ406EzMQKBgHSxOGS61D84DuZK"
+        + "2Ps1awhC3kB4eHzJRms3vflDPWoJJ+pSKwpKrzUTPHXiPBqyhtYkPGszVeiE6CAr9sv3YZnFVaBs"
+        + "6hyQUJsob+uE/w/gGvXe8VsFDx0bJOodYfhrCbTHBHWqE81nBcocpxayxsayfAzqWB3KKd0YLrMR"
+        + "K2PZAoGAcZa8915R2m0KZ6HVJUt/JDR85jCbN71kcVDFY2XSFkOJvOdFoHNfRckfLzjq9Y2MSSTV"
+        + "+QDWbDo2doUQCejJUTaN8nP79tfyir24X5uVPvQaeVoGTKYb+LfUqK0F60lStmjuddIGSZH55y3v"
+        + "+9XjmxbVERtd1lqgQg3VlmKlEXY=";
+
+    /*
+     * Certificate:
+     * Data:
+     *     Version: 3 (0x2)
+     *     Serial Number: 7 (0x7)
+     * Signature Algorithm: sha512WithRSAEncryption
+     *     Issuer: CN=Root
+     *     Validity
+     *         Not Before: Sep  1 18:03:59 2015 GMT
+     *         Not After : Jan 17 18:03:59 2043 GMT
+     *     Subject: CN=EE
+     */
+    private static final String CERTIFICATE = ""
+        + "-----BEGIN CERTIFICATE-----\n"
+        + "MIIDHTCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQ0FADAPMQ0wCwYDVQQDDARSb290\n"
+        + "MB4XDTE1MDkwMTE4MDM1OVoXDTQzMDExNzE4MDM1OVowDTELMAkGA1UEAwwCRUUw\n"
+        + "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpyz97liuWPDYcLH9TX8Bi\n"
+        + "T78olCmAfmevvch6ncXUVuCzbdaKuKXwn4EVbDszsVJLoK5zdtP+X3iDhutj+IgK\n"
+        + "mLhuczF3M9VIcWr+JJUyTH4+3h/RT8cjCDZOmk9iXkb5ifruVsLqzb9g+Vp140Oz\n"
+        + "7leikne7KmclHvTfvFd0WDI7Gb9vo4f5rT717BXJ/n+M6pNk8DLpLiEu6eziYvXR\n"
+        + "v5x+t5Go3x0eCXdaxEQUf2j876Wfr2qHRJK7lDfFe1DDsMg/KpKGiILYZ+g2qtVM\n"
+        + "ZSxtp5BZEtfB5qV/IE5kWO+mCIAGpXSZIdbERR6pZUq8GLEe1T9e+sO6H24w2F19\n"
+        + "AgMBAAGjgYUwgYIwNAYDVR0fBC0wKzApoCegJYYjbGRhcDovL2xkYXAuaG9zdC5m\n"
+        + "b3IuY3JsZHAvbWFpbi5jcmwwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzAChi5s\n"
+        + "ZGFwOi8vbGRhcC5ob3N0LmZvci5haWEvZGM9Um9vdD9jQUNlcnRpZmljYXRlMA0G\n"
+        + "CSqGSIb3DQEBDQUAA4IBAQBWDfZHpuUx0yn5d3+BuztFqoks1MkGdk+USlH0TB1/\n"
+        + "gWWBd+4S4PCKlpSur0gj2rMW4fP5HQfNlHci8JV8/bG4KuKRAXW56dg1818Hl3pc\n"
+        + "iIrUSRn8uUjH3p9qb+Rb/u3mmVQRyJjN2t/zceNsO8/+Dd808OB9aEwGs8lMT0nn\n"
+        + "ZYaaAqYz1GIY/Ecyx1vfEZEQ1ljo6i/r70C3igbypBUShxSiGsleiVTLOGNA+MN1\n"
+        + "/a/Qh0bkaQyTGqK3bwvzzMeQVqWu2EWTBD/PmND5ExkpRICdv8LBVXfLnpoBr4lL\n"
+        + "hnxn9+e0Ah+t8dS5EKfn44w5bI5PCu2bqxs6RCTxNjcY\n"
+        + "-----END CERTIFICATE-----\n";
+
+    private static final char[] PASSWD2 = new char[] {
+            'b', 'o', 'r', 'e', 'd'
+    };
+    private static final char[] PASSWDK = "cannot be null"
+            .toCharArray();
+    private static final String[] KS_Type = {
+            "jks", "jceks", "pkcs12", "PKCS11KeyStore"
+    };
+    private static final String[] PROVIDERS = {
+            "SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris"
+    };
+    private static final String ALIAS_HEAD = "test";
+
+    public static void main(String args[]) throws Exception {
+        TestKeyStoreBasic jstest = new TestKeyStoreBasic();
+        jstest.run();
+    }
+
+    public void run() throws Exception {
+        for (String provider : PROVIDERS) {
+            try {
+                runTest(provider);
+                System.out.println("Test with provider " + provider + "passed");
+            } catch (java.security.KeyStoreException e) {
+                if (provider.equals("SunPKCS11-Solaris")) {
+                    System.out.println("KeyStoreException is expected: "
+                            + "PKCS11KeyStore is invalid keystore type: " + e);
+                } else {
+                    throw e;
+                }
+            } catch (NoSuchProviderException e) {
+                String osName = System.getProperty("os.name");
+                if (provider.equals("SunPKCS11-Solaris")
+                        && !osName.equals("SunOS")) {
+                    System.out.println("Skip SunPKCS11-Solaris provider on "
+                            + osName);
+                } else {
+                    throw e;
+                }
+            }
+        }
+    }
+
+    public void runTest(String provider) throws Exception {
+
+        // load private key
+        // all keystore types should support private keys
+        KeySpec spec = new PKCS8EncodedKeySpec(
+                Base64.getMimeDecoder().decode(PRIVATE_KEY_PKCS8_BASE64));
+        PrivateKey privateKey = KeyFactory.getInstance("RSA")
+                .generatePrivate(spec);
+
+        // load x509 certificate
+        Certificate cert;
+        try (InputStream is = new BufferedInputStream(
+                new ByteArrayInputStream(CERTIFICATE.getBytes()))) {
+            cert = CertificateFactory.getInstance("X.509")
+                    .generateCertificate(is);
+        }
+
+        int numEntries = 5;
+        String type = null;
+        for (int i = 0; i < PROVIDERS.length; i++) {
+            if (provider.compareTo(PROVIDERS[i]) == 0) {
+                type = KS_Type[i];
+                break;
+            }
+        }
+
+        System.out.printf("Test %s provider and %s keystore%n", provider, type);
+        KeyStore ks = KeyStore.getInstance(type, provider);
+        KeyStore ks2 = KeyStore.getInstance(type, ks.getProvider().getName());
+
+        // create an empty key store
+        ks.load(null, null);
+
+        // store the secret keys
+        for (int j = 0; j < numEntries; j++) {
+            ks.setKeyEntry(ALIAS_HEAD + j, privateKey, PASSWDK,
+                    new Certificate[] { cert });
+        }
+
+        // initialize the 2nd key store object with the 1st one
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ks.store(baos, PASSWDK);
+        byte[] bArr = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bArr);
+        ks2.load(bais, null);
+
+        // check 2nd key store type
+        checkType(ks2, type);
+        // check the existing aliases for the 2nd key store
+        checkAlias(ks2, numEntries);
+
+        // compare the creation date of the 2 key stores for all aliases
+        compareCreationDate(ks, ks2, numEntries);
+        // remove the last entry from the 2nd key store
+        numEntries--;
+        ks2.deleteEntry(ALIAS_HEAD + numEntries);
+
+        // re-initialize the 1st key store with the 2nd key store
+        baos.reset();
+        ks2.store(baos, PASSWD2);
+        bais = new ByteArrayInputStream(baos.toByteArray());
+        try {
+            // expect an exception since the password is incorrect
+            ks.load(bais, PASSWDK);
+            throw new RuntimeException(
+                    "ERROR: passed the loading with incorrect password");
+        } catch (IOException ex) {
+            System.out.println("Expected exception: " + ex);
+            if (!causedBy(ex, UnrecoverableKeyException.class)) {
+                ex.printStackTrace(System.out);
+                throw new RuntimeException("Unexpected cause");
+            }
+            System.out.println("Expected cause: "
+                    + UnrecoverableKeyException.class.getName());
+
+            bais.reset();
+            ks.load(bais, PASSWD2);
+            bais.reset();
+            ks.load(bais, null);
+        }
+
+        // check key store type
+        checkType(ks, type);
+
+        // check the existing aliases
+        checkAlias(ks, numEntries);
+
+        // compare the creation date of the 2 key stores for all aliases
+        compareCreationDate(ks, ks2, numEntries);
+
+    }
+
+    // check key store type
+    private void checkType(KeyStore obj, String type) {
+        if (!obj.getType().equals(type)) {
+            throw new RuntimeException("ERROR: wrong key store type");
+        }
+    }
+
+    // check the existing aliases
+    private void checkAlias(KeyStore obj, int range) throws KeyStoreException {
+        for (int k = 0; k < range; k++) {
+            if (!obj.containsAlias(ALIAS_HEAD + k)) {
+                throw new RuntimeException("ERROR: alias (" + k
+                        + ") should exist");
+            }
+        }
+    }
+
+    // compare the creation dates - true if all the same
+    private void compareCreationDate(KeyStore o1, KeyStore o2, int range)
+            throws KeyStoreException {
+        String alias;
+        for (int k = 0; k < range; k++) {
+            alias = ALIAS_HEAD + k;
+            if (!o1.getCreationDate(alias).equals(o2.getCreationDate(alias))) {
+                throw new RuntimeException("ERROR: entry creation time (" + k
+                        + ") differs");
+            }
+        }
+    }
+
+    // checks if an exception was caused by specified exception class
+    private static boolean causedBy(Exception e, Class klass) {
+        Throwable cause = e;
+        while ((cause = cause.getCause()) != null) {
+            if (cause.getClass().equals(klass)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/KeyStore/TestKeyStoreEntry.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001, 2016, 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 static java.lang.System.out;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+/*
+ * @test
+ * @bug 8048621
+ * @summary Test the basic operations of KeyStore entry, provided by SunJCE
+ *  (jceks), and SunPKCS11-Solaris(PKCS11KeyStore)
+ * @author Yu-Ching Valerie PENG
+ */
+
+public class TestKeyStoreEntry {
+    private static final char[] PASSWDK = new char[] {
+            't', 'e', 'r', 'c', 'e', 's'
+    };
+    private static final char[] PASSWDF = new String("guardian Angel")
+            .toCharArray();
+    private static final String[] KS_ALGOS = {
+            "DES", "DESede", "Blowfish"
+    };
+    private static final int NUM_ALGOS = KS_ALGOS.length;
+
+    private static final String[] KS_TYPE = {
+            "jks", "jceks", "pkcs12", "PKCS11KeyStore"
+    };
+    private static final String[] PRO_TYPE = {
+            "SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris"
+    };
+
+    private final SecretKey[] sks = new SecretKey[NUM_ALGOS];
+
+    TestKeyStoreEntry() throws Exception {
+        // generate secret keys which are to be stored in the jce
+        // key store object
+        KeyGenerator[] kgs = new KeyGenerator[NUM_ALGOS];
+        for (int i = 0; i < NUM_ALGOS; i++) {
+            kgs[i] = KeyGenerator.getInstance(KS_ALGOS[i], "SunJCE");
+            sks[i] = kgs[i].generateKey();
+        }
+
+    }
+
+    public static void main(String args[]) throws Exception {
+        TestKeyStoreEntry jstest = new TestKeyStoreEntry();
+        jstest.run();
+    }
+
+    public void run() throws Exception {
+
+        Provider[] providers = Security.getProviders();
+        for (Provider p: providers) {
+            String prvName = p.getName();
+            if (prvName.startsWith("SunJCE")
+                    || prvName.startsWith("SunPKCS11-Solaris")) {
+                try {
+                    runTest(p);
+                    out.println("Test with provider " + p.getName() + ""
+                            + " passed");
+
+                } catch (java.security.KeyStoreException e) {
+                    if (prvName.startsWith("SunPKCS11-Solaris")) {
+                        out.println("KeyStoreException is expected because "
+                                + "PKCS11KeyStore is invalid keystore type.");
+                        e.printStackTrace();
+                    } else {
+                        throw e;
+                    }
+                }
+            }
+        }
+    }
+
+    public void runTest(Provider p) throws Exception {
+        try (FileOutputStream fos = new FileOutputStream("jceks");
+                FileInputStream fis = new FileInputStream("jceks");) {
+
+            KeyStore ks = KeyStore.getInstance("jceks", p);
+            // create an empty key store
+            ks.load(null, null);
+
+            // store the secret keys
+            String aliasHead = new String("secretKey");
+            for (int j = 0; j < NUM_ALGOS; j++) {
+                ks.setKeyEntry(aliasHead + j, sks[j], PASSWDK, null);
+            }
+
+            // write the key store out to a file
+            ks.store(fos, PASSWDF);
+            // wipe clean the existing key store
+            for (int k = 0; k < NUM_ALGOS; k++) {
+                ks.deleteEntry(aliasHead + k);
+            }
+            if (ks.size() != 0) {
+                throw new RuntimeException("ERROR: re-initialization failed");
+            }
+
+            // reload the key store with the file
+            ks.load(fis, PASSWDF);
+
+            // check the integrity/validaty of the key store
+            Key temp = null;
+            String alias = null;
+            if (ks.size() != NUM_ALGOS) {
+                throw new RuntimeException("ERROR: wrong number of key"
+                        + " entries");
+            }
+
+            for (int m = 0; m < ks.size(); m++) {
+                alias = aliasHead + m;
+                temp = ks.getKey(alias, PASSWDK);
+                // compare the keys
+                if (!temp.equals(sks[m])) {
+                    throw new RuntimeException("ERROR: key comparison (" + m
+                            + ") failed");
+                }
+                // check the type of key
+                if (ks.isCertificateEntry(alias) || !ks.isKeyEntry(alias)) {
+                    throw new RuntimeException("ERROR: type identification ("
+                            + m + ") failed");
+                }
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,65 @@
+/*
+ * 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 TVJar.TVPermission;
+import java.security.AccessController;
+
+/**
+ * @test @bug 8050402
+ * @summary Check policy is extensible with user defined permissions
+ * @run main/othervm/policy=ExtensiblePolicyTest1.policy
+ *      ExtensiblePolicyTest false
+ * @run main/othervm/policy=ExtensiblePolicyTest2.policy
+ *      ExtensiblePolicyTest true
+ * @run main/othervm/policy=ExtensiblePolicyTest3.policy
+ *      ExtensiblePolicyTest true
+ */
+public class ExtensiblePolicyTest {
+
+    public static void main(String args[]) throws Throwable {
+        // ExtensiblePolicyTest1.policy: policy file grants permission to
+        // watch TVChannel 3-6
+        // ExtensiblePolicyTest2.policy: policy file grants permission to
+        // watch TVChanel 4
+        // ExtensiblePolicyTest3.policy: policy file grants permission signed
+        // by duke2 to watch TVChanel 5
+
+        TVPermission perm = new TVPermission("channel:5", "watch");
+        boolean getException = false;
+        String exceptionMessage = null;
+        boolean expectException = Boolean.parseBoolean(args[0]);
+        try {
+            AccessController.checkPermission(perm);
+        } catch (SecurityException se) {
+            getException = true;
+            exceptionMessage = se.getMessage();
+        }
+
+        if (expectException ^ getException) {
+            throw new RuntimeException("Test Failed: expectException = "
+                    + expectException + " getException = " + getException
+                    + "\n" + exceptionMessage);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,4 @@
+grant {
+	permission TVJar.TVPermission "channel:3-6", "watch";
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,3 @@
+grant {
+	permission TVJar.TVPermission "channel:4", "watch";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,5 @@
+keystore "file:${user.dir}/epkeystore";
+
+grant {
+	permission TVJar.TVPermission "channel:5", "watch", SignedBy "duke2";
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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.
+ */
+
+import TVJar.TVPermission;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8050402
+ * @summary Check policy is extensible with user defined permissions
+ * @library /lib/testlibrary
+ * @compile TVJar/TVPermission.java
+ * @run main ExtensiblePolicyWithJarTest
+ */
+public class ExtensiblePolicyWithJarTest {
+
+    public static void main(String args[]) throws Throwable {
+        final String FS = File.separator;
+        final String PS = File.pathSeparator;
+        final String POL = "ExtensiblePolicyTest3.policy";
+        final String JAVA_HOME = System.getProperty("test.jdk");
+        final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
+        final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
+        final String KEYSTORE = "epkeystore";
+        final String PASSWORD = "password";
+        final String ALIAS = "duke2";
+        final String CLASSPATH = System.getProperty("test.class.path", "");
+        final String TESTCLASSES = System.getProperty("test.classes", "");
+        final String TVPERMJAR = "tvPerm.jar";
+        final String PATHTOJAR = System.getProperty("user.dir", "")
+                                + FS + TVPERMJAR;
+
+        // create jar file for TVpermission
+        new File("TVJar").mkdir();
+        Files.copy(Paths.get(TESTCLASSES + FS + "TVJar", "TVPermission.class"),
+                Paths.get("TVJar", "TVPermission.class"));
+        Files.copy(Paths.get(TESTCLASSES + FS + "TVJar",
+                "TVPermissionCollection.class"),
+                Paths.get("TVJar", "TVPermissionCollection.class"));
+        JarUtils.createJar(TVPERMJAR, "TVJar/TVPermission.class",
+                "TVJar/TVPermissionCollection.class");
+
+        // create key pair for jar signing
+        ProcessTools.executeCommand(KEYTOOL,
+                "-genkey",
+                "-alias", ALIAS,
+                "-keystore", KEYSTORE,
+                "-storetype", "JKS",
+                "-keypass", PASSWORD,
+                "-dname", "cn=Blah",
+                "-storepass", PASSWORD
+        ).shouldHaveExitValue(0);
+        // sign jar
+        ProcessTools.executeCommand(JARSIGNER,
+                "-keystore", KEYSTORE,
+                "-storepass", PASSWORD,
+                "-keypass", PASSWORD,
+                TVPERMJAR,
+                ALIAS).shouldHaveExitValue(0);
+        // add jar file to classpath
+        String cp = PATHTOJAR + PS + CLASSPATH;
+
+        // policy file grants permission signed by duke2 to watch TVChanel 5
+        try {
+            String[] cmd = {
+            "-classpath", cp,
+            "-Djava.security.manager",
+            "-Djava.security.policy=" + POL,
+            "ExtensiblePolicyTest_orig$TestMain"};
+            ProcessTools.executeTestJvm(cmd).shouldHaveExitValue(0);
+        } catch (Exception ex) {
+            System.out.println("ExtensiblePolicyWithJarTest Failed");
+        }
+
+    }
+
+    public static class TestMain {
+        public static void main(String args[]) {
+            TVPermission perm = new TVPermission("channel:5", "watch");
+            try {
+                AccessController.checkPermission(perm);
+            } catch (SecurityException se) {
+                throw new RuntimeException(se);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,358 @@
+/*
+ * 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
+ * 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.
+ */
+package TVJar;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.StringJoiner;
+import java.util.StringTokenizer;
+
+public class TVPermission extends Permission {
+
+    /**
+     * Watch
+     */
+    private final static int WATCH = 0x1;
+
+    /**
+     * Preview
+     */
+    private final static int PREVIEW = 0x2;
+
+    /**
+     * No actions
+     */
+    private final static int NONE = 0x0;
+
+    /**
+     * All actions
+     */
+    private final static int ALL = WATCH | PREVIEW;
+
+    // the actions mask
+    private int mask;
+
+    // the actions string
+    private String actions;
+
+    // the canonical name of the channel
+    private String cname;
+
+    // true if the channelname is a wildcard
+    private boolean wildcard;
+
+    // num range on channel
+    private int[] numrange;
+
+    // various num constants
+    private final static int NUM_MIN = 1;
+    private final static int NUM_MAX = 128;
+
+    public TVPermission(String channel, String action) {
+        this(channel, getMask(action));
+    }
+
+    TVPermission(String channel, int mask) {
+        super(channel);
+        init(channel, mask);
+    }
+
+    private synchronized int[] parseNum(String num)
+            throws Exception {
+
+        if (num == null || num.equals("") || num.equals("*")) {
+            wildcard = true;
+            return new int[]{NUM_MIN, NUM_MAX};
+        }
+
+        int dash = num.indexOf('-');
+
+        if (dash == -1) {
+            int p = 0;
+            try {
+                p = Integer.parseInt(num);
+            } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid input" + num);
+            }
+            return new int[]{p, p};
+        } else {
+            String low = num.substring(0, dash);
+            String high = num.substring(dash + 1);
+            int l, h;
+
+            if (low.equals("")) {
+                l = NUM_MIN;
+            } else {
+                try {
+                    l = Integer.parseInt(low);
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("invalid input" + num);
+                }
+            }
+
+            if (high.equals("")) {
+                h = NUM_MAX;
+            } else {
+                try {
+                    h = Integer.parseInt(high);
+                } catch (NumberFormatException nfe) {
+                    throw new IllegalArgumentException("invalid input" + num);
+                }
+            }
+            if (h < l || l < NUM_MIN || h > NUM_MAX) {
+                throw new IllegalArgumentException("invalid num range");
+            }
+
+            return new int[]{l, h};
+        }
+    }
+
+    /**
+     * Initialize the TVPermission object.
+     */
+    private synchronized void init(String channel, int mask) {
+
+        // Parse the channel name.
+        int sep = channel.indexOf(':');
+
+        if (sep != -1) {
+            String num = channel.substring(sep + 1);
+            cname = channel.substring(0, sep);
+            try {
+                numrange = parseNum(num);
+            } catch (Exception e) {
+                throw new IllegalArgumentException("invalid num range: " + num);
+            }
+        } else {
+            numrange = new int[]{NUM_MIN, NUM_MAX};
+        }
+    }
+
+    /**
+     * Convert an action string to an integer actions mask.
+     *
+     * @param action the action string
+     * @return the action mask
+     */
+    private synchronized static int getMask(String action) {
+        int mask = NONE;
+
+        if (action == null) {
+            return mask;
+        }
+
+        StringTokenizer st = new StringTokenizer(action.toLowerCase(), ",");
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if (token.equals("watch")) {
+                mask |= WATCH;
+            } else if (token.equals("preview")) {
+                mask |= PREVIEW;
+            } else {
+                throw new IllegalArgumentException("invalid TV permission: " + token);
+            }
+        }
+        return mask;
+    }
+
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TVPermission)) {
+            return false;
+        }
+
+        if (this.wildcard) {
+            return true;
+        }
+
+        TVPermission that = (TVPermission) p;
+
+        if ((this.mask & that.mask) != that.mask) {
+            System.out.println("Masks are not ok this = "
+                    + this.mask + "THat = " + that.mask);
+            return false;
+        }
+
+        if ((this.numrange[0] > that.numrange[0])
+                || (this.numrange[1] < that.numrange[1])) {
+
+            System.out.println("This 0= " + this.numrange[0]
+                    + " 1 = " + this.numrange[1]);
+            System.out.println("That 0= " + that.numrange[0]
+                    + " 1 = " + that.numrange[1]);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Checks two TVPermission objects for equality.
+     * <p>
+     * @param obj the object we are testing for equality.
+     * @return true if obj is a TVPermission, and has the same channelname and
+     * action mask as this TVPermission object.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+
+        if (!(obj instanceof TVPermission)) {
+            return false;
+        }
+
+        TVPermission that = (TVPermission) obj;
+
+        // check the mask first
+        if (this.mask != that.mask) {
+            return false;
+        }
+
+        // now check the num range...
+        if ((this.numrange[0] != that.numrange[0])
+                || (this.numrange[1] != that.numrange[1])) {
+            return false;
+        }
+
+        return this.getName().equals(that.getName());
+    }
+
+    /**
+     * Returns the hash code value for this object.
+     *
+     * @return a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return this.getName().hashCode();
+    }
+
+    /**
+     * Return the canonical string representation of the actions. Always returns
+     * actions in the following order: watch,preview.
+     *
+     * @param mask a specific integer action mask to translate into a string
+     * @return the canonical string representation of the actions
+     */
+    private synchronized static String getActions(int mask) {
+        StringJoiner sj = new StringJoiner(",");
+        if ((mask & WATCH) == WATCH) {
+            sj.add("watch");
+        }
+        if ((mask & PREVIEW) == PREVIEW) {
+            sj.add("preview");
+        }
+        return sj.toString();
+    }
+
+    /**
+     * Return the canonical string representation of the actions. Always returns
+     * actions in the following order: watch,preview.
+     *
+     * @return the canonical string representation of the actions.
+     */
+    @Override
+    public String getActions() {
+        if (actions == null) {
+            actions = getActions(this.mask);
+        }
+
+        return actions;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "\n"
+                + "cname = " + cname + "\n"
+                + "wildcard = " + wildcard + "\n"
+                + "numrange = " + numrange[0] + "," + numrange[1] + "\n";
+
+    }
+
+    @Override
+    public PermissionCollection newPermissionCollection() {
+        return new TVPermissionCollection();
+    }
+}
+
+final class TVPermissionCollection extends PermissionCollection {
+
+    /**
+     * The TVPermissions for this set.
+     */
+    private final ArrayList<TVPermission> permissions = new ArrayList<>();
+
+    /**
+     * Adds a permission to the TVPermissions. The key for the hash is the name
+     * in the case of wildcards, or all the IP addresses.
+     *
+     * @param permission the Permission object to add.
+     */
+    @Override
+    public void add(Permission permission) {
+        if (!(permission instanceof TVPermission)) {
+            throw new IllegalArgumentException("invalid permission: " + permission);
+        }
+        permissions.add((TVPermission) permission);
+    }
+
+    /**
+     * Check and see if this collection of permissions implies the permissions
+     * expressed in "permission".
+     *
+     * @param p the Permission object to compare
+     *
+     * @return true if "permission" is a proper subset of a permission in the
+     * collection, false if not.
+     */
+    @Override
+    public boolean implies(Permission p) {
+        if (!(p instanceof TVPermission)) {
+            return false;
+        }
+
+        Iterator<TVPermission> i = permissions.iterator();
+        while (i.hasNext()) {
+            if (((TVPermission) i.next()).implies(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns an enumeration of all the TVPermission objects in the container.
+     *
+     * @return an enumeration of all the TVPermission objects.
+     */
+    @Override
+    public Enumeration elements() {
+        return Collections.enumeration(permissions);
+    }
+
+}
--- a/test/java/security/SecureRandom/DefaultProvider.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/SecureRandom/DefaultProvider.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
@@ -43,12 +43,7 @@
         out.println("TEST: Default provider with constructor");
         SecureRandom secureRandom = new SecureRandom();
         String provider = secureRandom.getProvider().getName();
-        if (OS_NAME.startsWith(SUNOS)) {
-            if (!provider.startsWith("SunPKCS11-")) {
-                throw new RuntimeException("Unexpected provider name: "
-                        + provider);
-            }
-        } else if (!provider.equals("SUN")) {
+        if (!provider.equals("SUN")) {
             throw new RuntimeException("Unexpected provider name: "
                     + provider);
         }
@@ -77,16 +72,6 @@
         instance = SecureRandom.getInstance(algorithm);
         assertInstance(instance, algorithm, provider);
         out.println("Passed.");
-
-        if (OS_NAME.startsWith(SUNOS)) {
-            out.println(
-                    "TEST: PKCS11 is supported on Solaris by SunPKCS11 provider");
-            algorithm = "PKCS11";
-            provider = "SunPKCS11-Solaris";
-            instance = SecureRandom.getInstance(algorithm);
-            assertInstance(instance, algorithm, provider);
-            out.println("Passed.");
-        }
     }
 
     private static void assertInstance(SecureRandom instance,
--- a/test/java/security/Security/AddProvider.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/Security/AddProvider.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8001319
+ * @bug 8001319 8154009
  * @summary check that SecurityPermission insertProvider permission is enforced
  *          correctly
  * @run main/othervm/policy=AddProvider.policy.1 AddProvider 1
--- a/test/java/security/Security/AddProvider.policy.1	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/Security/AddProvider.policy.1	Thu Jan 12 06:59:38 2017 +0000
@@ -1,7 +1,3 @@
-grant codeBase "file:${{java.ext.dirs}}/*" {
-	permission java.security.AllPermission;
-};
-
 grant {
     permission java.security.SecurityPermission "insertProvider";
 };
--- a/test/java/security/Security/AddProvider.policy.2	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/Security/AddProvider.policy.2	Thu Jan 12 06:59:38 2017 +0000
@@ -1,7 +1,3 @@
-grant codeBase "file:${{java.ext.dirs}}/*" {
-	permission java.security.AllPermission;
-};
-
 grant {
     permission java.security.SecurityPermission "insertProvider.Test1";
     permission java.security.SecurityPermission "insertProvider.Test2";
--- a/test/java/security/Security/AddProvider.policy.3	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/Security/AddProvider.policy.3	Thu Jan 12 06:59:38 2017 +0000
@@ -1,7 +1,3 @@
-grant codeBase "file:${{java.ext.dirs}}/*" {
-	permission java.security.AllPermission;
-};
-
 grant {
     permission java.security.SecurityPermission "insertProvider.*";
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Security/EmptyPolicy.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,2 @@
+// empty policy file for testing
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Security/GetProviders.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, 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 8154009
+ * @summary make sure getProviders() doesn't require additional permissions
+ * @run main/othervm/policy=EmptyPolicy.policy GetProviders
+ */
+
+import java.security.Provider;
+import java.security.Security;
+import java.util.HashMap;
+import java.util.Map;
+
+public class GetProviders {
+
+    private static final String serviceAlgFilter = "Signature.SHA1withRSA";
+    private static final String emptyServAlgFilter = "wrongSig.wrongAlg";
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Provider[] providers1 = Security.getProviders();
+            System.out.println("Amount of providers1: " + providers1.length);
+
+            Provider[] providers2 = Security.getProviders(serviceAlgFilter);
+            System.out.println("Amount of providers2: " + providers2.length);
+
+            Map<String, String> filter = new HashMap<String, String>();
+            filter.put(serviceAlgFilter, "");
+            Provider[] providers3 = Security.getProviders(filter);
+            System.out.println("Amount of providers3: " + providers3.length);
+
+            Provider[] emptyProv1 = Security.getProviders(emptyServAlgFilter);
+            if (emptyProv1 != null) {
+                throw new RuntimeException("Empty Filter returned: " +
+                    emptyProv1.length + " providers");
+            }
+            System.out.println("emptyProv1 is empty as expected");
+
+            Map<String, String> emptyFilter = new HashMap<String, String>();
+            emptyFilter.put(emptyServAlgFilter, "");
+            Provider[] emptyProv2 = Security.getProviders(emptyFilter);
+            if (emptyProv2 != null) {
+                throw new RuntimeException("Empty Filter returned: " +
+                    emptyProv2.length + " providers");
+            }
+            System.out.println("emptyProv2 is empty as expected");
+
+        } catch(ExceptionInInitializerError e) {
+            e.printStackTrace(System.out);
+            throw new RuntimeException("Provider initialization error due to "
+                    + e.getCause());
+        }
+        System.out.println("Test passed");
+    }
+
+}
--- a/test/java/security/Security/removing/RemoveStaticProvider.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/Security/removing/RemoveStaticProvider.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 4420687
+ * @bug 4420687 8154009
  * @summary Make sure that a removed provider won't be acceessable.
  * @run main/othervm/policy=RemoveStaticProvider.policy RemoveStaticProvider
  */
--- a/test/java/security/Security/removing/RemoveStaticProvider.policy	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/java/security/Security/removing/RemoveStaticProvider.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -3,8 +3,3 @@
     permission java.security.SecurityPermission "insertProvider.SunJCE";
 };
 
-// Standard extensions get all permissions
-grant codeBase "file:${java.home}/lib/ext/*" {
-        permission java.security.AllPermission;
-};
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/MBeanServer/ExceptionFactory.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/MBeanServer/ExceptionTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+            }
+        }
+    }
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/MBeanServer/ExceptionThrower.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/MBeanServer/ExceptionThrowerMBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+}
Binary file test/javax/management/keystoreAgent has changed
Binary file test/javax/management/keystoreClient has changed
--- a/test/javax/management/monitor/GaugeMonitorDeadlockTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/javax/management/monitor/GaugeMonitorDeadlockTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -27,6 +27,7 @@
  * @summary Test that no locks are held when a monitor attribute is sampled
  * or notif delivered.
  * @author Eamonn McManus
+ * @library /lib/testlibrary
  * @run clean GaugeMonitorDeadlockTest
  * @run build GaugeMonitorDeadlockTest
  * @run main GaugeMonitorDeadlockTest 1
@@ -47,6 +48,8 @@
 import javax.management.monitor.GaugeMonitor;
 import javax.management.monitor.GaugeMonitorMBean;
 
+import jdk.testlibrary.Utils;
+
 public class GaugeMonitorDeadlockTest {
     private static enum When {IN_GET_ATTRIBUTE, IN_NOTIFY};
     private static long checkingTime;
@@ -54,8 +57,7 @@
     public static void main(String[] args) throws Exception {
         if (args.length != 1)
             throw new Exception("Arg should be test number");
-        double factor = Double.parseDouble(System.getProperty("test.timeout.factor", "1.0"));
-        checkingTime = (long)factor*1000;
+        checkingTime = Utils.adjustTimeout(1000); // default 1s timeout
         System.out.println("=== checkingTime = " + checkingTime + "ms");
 
         int testNo = Integer.parseInt(args[0]) - 1;
@@ -101,11 +103,12 @@
             monitorProxy.setGranularityPeriod(10L); // 10 ms
             monitorProxy.setNotifyHigh(true);
             monitorProxy.setNotifyLow(true);
-            monitorProxy.start();
 
             System.out.println("=== Waiting observedProxy.getGetCount() to be "
                     + "changed, presumable deadlock if timeout?");
             final int initGetCount = observedProxy.getGetCount();
+            monitorProxy.start();
+
             long checkedTime = System.currentTimeMillis();
             long nowTime;
             ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
--- a/test/javax/management/monitor/StringMonitorDeadlockTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/javax/management/monitor/StringMonitorDeadlockTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -37,7 +37,6 @@
 
 import java.lang.management.ManagementFactory;
 import java.util.concurrent.atomic.AtomicInteger;
-import javax.management.Attribute;
 import javax.management.JMX;
 import javax.management.MBeanServer;
 import javax.management.Notification;
@@ -95,9 +94,10 @@
             monitorProxy.setStringToCompare("old");
             monitorProxy.setGranularityPeriod(10L); // 10 ms
             monitorProxy.setNotifyDiffer(true);
+
+            final int initGetCount = observedProxy.getGetCount();
             monitorProxy.start();
 
-            final int initGetCount = observedProxy.getGetCount();
             int getCount = initGetCount;
             for (int i = 0; i < 500; i++) { // 500 * 10 = 5 seconds
                 getCount = observedProxy.getGetCount();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/Basic.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/BasicMXBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/MXBeanInteropTest1.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/MXBeanInteropTest2.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/MXBeanLoadingTest1.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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() {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/MXBeanNotifTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/MXBeanWeirdParamTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/SqeDescriptorKey.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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 {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/SqeNotification.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/SqeParameter.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/mxbean/Utils.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/QueryData.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/QueryFactory.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/ServerDelegate.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/ServerDelegateMBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/SqeDescriptorKey.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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 {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/SupportedQueryTypesTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/TestQuery.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/query/TestQueryMBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/AuthorizationTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/MBS_Light.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/MBS_LightMBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/RjmxMBeanParameter.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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 ;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/SecurityTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/ServerDelegate.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/ServerDelegateMBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/Simple.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * 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;
+
+/**
+ * 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")
+    @ConstructorProperties({"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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/SimpleListener.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/SimpleMBean.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/SqeDescriptorKey.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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 {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/TestJMXAuthenticator.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/TestSampleLoginModule.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/Utils.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/access.properties	Thu Jan 12 06:59:38 2017 +0000
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/java.policy.authorization	Thu Jan 12 06:59:38 2017 +0000
@@ -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.
+    //
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/login.config	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,8 @@
+PasswordFileAuthentication {
+    com.sun.jmx.remote.security.FileLoginModule required
+	passwordFile="${password.file}";
+};
+
+SampleLoginModule {
+    TestSampleLoginModule required;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/security/password.properties	Thu Jan 12 06:59:38 2017 +0000
@@ -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
Binary file test/javax/management/truststoreAgent has changed
Binary file test/javax/management/truststoreClient has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloClient.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016, 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.naming.InitialContext;
+import javax.naming.Context;
+import javax.naming.NameNotFoundException;
+
+import javax.rmi.PortableRemoteObject;
+
+
+
+public class HelloClient implements Runnable {
+    static final int MAX_RETRY = 10;
+    static final int ONE_SECOND = 1000;
+    private static boolean responseReceived;
+
+    public static void main(String args[]) throws Exception {
+        executeRmiClientCall();
+    }
+
+    @Override
+    public void run() {
+        try {
+            executeRmiClientCall();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    public static boolean isResponseReceived () {
+        return responseReceived;
+    }
+
+    public static void executeRmiClientCall() throws Exception {
+        Context ic;
+        Object objref;
+        HelloInterface helloSvc;
+        String response;
+        Object testResponse;
+        int retryCount = 0;
+
+        ArrayList<Test> listParam = new ArrayList<Test>();
+        listParam.add(null);
+        System.out.println("HelloClient.main: enter ...");
+        while (retryCount < MAX_RETRY) {
+            try {
+                ic = new InitialContext();
+                System.out.println("HelloClient.main: HelloService lookup ...");
+                // STEP 1: Get the Object reference from the Name Service
+                // using JNDI call.
+                objref = ic.lookup("HelloService");
+                System.out.println("HelloClient: Obtained a ref. to Hello server.");
+
+                // STEP 2: Narrow the object reference to the concrete type and
+                // invoke the method.
+                helloSvc = (HelloInterface) PortableRemoteObject.narrow(objref,
+                    HelloInterface.class);
+
+                Test3 test3 = new Test3(listParam);
+                Test3 test3Response = helloSvc.sayHelloWithTest3(test3);
+                System.out.println("Server says: Test3 response  ==  " + test3Response);
+
+                Test3 test3WithNullList = new Test3(null);
+                test3Response = helloSvc.sayHelloWithTest3(test3WithNullList);
+                System.out.println("Server says: Test3 response  ==  "
+                        + test3Response);
+
+                Test4 test4 = new Test4(listParam);
+                Test3 test4Response = helloSvc.sayHelloWithTest3(test4);
+                System.out.println("Server says: Test3 response  ==  " + test4Response);
+
+                responseReceived = true;
+                break;
+            } catch (NameNotFoundException nnfEx) {
+                System.err.println("NameNotFoundException Caught  .... try again");
+                retryCount++;
+                try {
+                    Thread.sleep(ONE_SECOND);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                continue;
+            } catch (Exception e) {
+                System.err.println("Exception " + e + "Caught");
+                e.printStackTrace();
+                throw new RuntimeException(e);
+            }
+        }
+        System.err.println("HelloClient terminating ");
+        try {
+            Thread.sleep(ONE_SECOND);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloImpl.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, 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.rmi.RemoteException;
+import javax.rmi.PortableRemoteObject;
+
+public class HelloImpl extends PortableRemoteObject implements HelloInterface {
+
+    public HelloImpl() throws java.rmi.RemoteException {
+        super(); // invoke rmi linking and remote object initialization
+    }
+
+    @Override
+    public Test3 sayHelloWithTest3(Test3 test) throws RemoteException {
+        System.out.println("sayHelloToTest3: ENTER " );
+
+        return test;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloInterface.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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.rmi.Remote;
+
+public interface HelloInterface extends Remote {
+    public Test3 sayHelloWithTest3( Test3 test ) throws java.rmi.RemoteException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloServer.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, 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.naming.InitialContext;
+import javax.naming.Context;
+
+public class HelloServer {
+
+    static final int MAX_RETRY = 10;
+    static final int ONE_SECOND = 1000;
+
+    public static void main(String[] args) {
+        int retryCount = 0;
+        while (retryCount < MAX_RETRY) {
+            try {
+                //HelloServer.set("SETTING TEST ITL");
+                // Step 1: Instantiate the Hello servant
+                HelloImpl helloRef = new HelloImpl();
+
+                // Step 2: Publish the reference in the Naming Service
+                // using JNDI API
+                Context initialNamingContext = new InitialContext();
+                initialNamingContext.rebind("HelloService", helloRef);
+
+                System.out.println("Hello Server: Ready...");
+                break;
+            } catch (Exception e) {
+                System.out.println("Server initialization problem: " + e);
+                e.printStackTrace();
+                retryCount++;
+                try {
+                    Thread.sleep(ONE_SECOND);
+                } catch (InterruptedException e1) {
+                    e1.printStackTrace();
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016, 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 8146975
+ * @summary test RMI-IIOP with value object return
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @compile Test.java Test2.java Test3.java Test4.java
+ * HelloInterface.java HelloServer.java HelloClient.java
+ * HelloImpl.java _HelloImpl_Tie.java _HelloInterface_Stub.java
+ * RmiIiopReturnValueTest.java
+ * @run main/othervm -Djava.naming.provider.url=iiop://localhost:5050
+ *     -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ *     RmiIiopReturnValueTest -port 5049
+ * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy
+ *     -Djava.naming.provider.url=iiop://localhost:5050
+ *     -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ *     RmiIiopReturnValueTest -port 5049
+ */
+
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.CountDownLatch;
+import jdk.testlibrary.JDKToolFinder;
+import jdk.testlibrary.JDKToolLauncher;
+
+public class RmiIiopReturnValueTest {
+
+    static final String ORBD = JDKToolFinder.getTestJDKTool("orbd");
+    static final String JAVA = JDKToolFinder.getTestJDKTool("java");
+    static final JDKToolLauncher orbdLauncher = JDKToolLauncher.createUsingTestJDK("orbd");
+    static final String CLASSPATH = System.getProperty("java.class.path");
+    static final int FIVE_SECONDS = 5000;
+
+    private static Throwable clientException;
+    private static boolean exceptionInClient;
+    private static Process orbdProcess;
+    private static Process rmiServerProcess;
+
+    public static void main(String[] args) throws Exception {
+        startTestComponents();
+        stopTestComponents();
+        System.err.println("Test completed OK ");
+    }
+
+    static void startTestComponents () throws Exception {
+        startOrbd();
+        Thread.sleep(FIVE_SECONDS);
+        startRmiIiopServer();
+        Thread.sleep(FIVE_SECONDS);
+        executeRmiIiopClient();
+    }
+
+    private static void stopTestComponents() throws Exception {
+        stopRmiIiopServer();
+        stopOrbd();
+        if (exceptionInClient) {
+            throw new RuntimeException(clientException);
+        } else if (!isResponseReceived()) {
+            throw new RuntimeException("Expected Response not received");
+        }
+    }
+
+    static void startOrbd() throws Exception {
+        System.out.println("\nStarting orbd with NS port 5050 and activation port 5049 ");
+
+        //orbd -ORBInitialHost localhost -ORBInitialPort 5050 -port 5049
+        orbdLauncher.addToolArg("-ORBInitialHost").addToolArg("localhost")
+            .addToolArg("-ORBInitialPort").addToolArg("5050")
+            .addToolArg("-port").addToolArg("5049");
+
+        System.out.println("RmiIiopReturnValueTest: Executing: " + Arrays.asList(orbdLauncher.getCommand()));
+        ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand());
+        pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+        orbdProcess = pb.start();
+    }
+
+
+    static void startRmiIiopServer() throws Exception {
+        System.out.println("\nStarting RmiIiopServer");
+        // java -cp .
+        // -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+        // -Djava.naming.provider.url=iiop://localhost:5050 HelloServer -port 5049
+        List<String> commands = new ArrayList<>();
+        commands.add(RmiIiopReturnValueTest.JAVA);
+        commands.add("-Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory");
+        commands.add("-Djava.naming.provider.url=iiop://localhost:5050");
+        commands.add("-cp");
+        commands.add(RmiIiopReturnValueTest.CLASSPATH);
+        commands.add("HelloServer");
+        commands.add("-port");
+        commands.add("5049");
+
+        System.out.println("RmiIiopReturnValueTest: Executing: " + commands);
+        ProcessBuilder pb = new ProcessBuilder(commands);
+        pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+        rmiServerProcess = pb.start();
+    }
+
+    static boolean isResponseReceived() {
+        return HelloClient.isResponseReceived();
+    }
+
+    static void stopRmiIiopServer() throws Exception {
+        if (rmiServerProcess != null) {
+            System.out.println("RmiIiopReturnValueTest.stopRmiIiopServer: destroy rmiServerProcess");
+            rmiServerProcess.destroyForcibly();
+            rmiServerProcess.waitFor();
+            System.out.println("serverProcess exitCode:"
+                + rmiServerProcess.exitValue());
+        }
+    }
+
+    static void stopOrbd() throws Exception {
+        System.out.println("RmiIiopReturnValueTest.stopOrbd: destroy orbdProcess ");
+        orbdProcess.destroyForcibly();
+        orbdProcess.waitFor();
+        System.out.println("orbd exitCode:"
+            + orbdProcess.exitValue());
+    }
+
+    static void executeRmiIiopClient() throws Exception {
+        System.out.println("RmiIiopReturnValueTest.executeRmiIiopClient: HelloClient.executeRmiClientCall");
+        try {
+            HelloClient.executeRmiClientCall();
+        } catch (Throwable t) {
+            clientException = t;
+            exceptionInClient = true;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016, 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;
+
+
+public class Test implements Serializable {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test2.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016, 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;
+
+
+public class Test2 implements Serializable {
+
+    private int testValue;
+    private String name;
+    private Test aTest;
+
+    public Test2 (String name, int value, Test test) {
+        this.name = name;
+        this.aTest = test;
+        this.testValue = value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test3.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, 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;
+import java.util.List;
+
+
+public class Test3 implements Serializable {
+
+    private List<Test> list;
+
+    public Test3(List<Test> list) {
+        this.list = list;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test4.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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.List;
+
+
+public class Test4 extends Test3 {
+
+    private int aNumber = 1;
+
+    public Test4(List<Test> list) {
+        super(list);
+    }
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloImpl_Tie.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+// Tie class generated by rmic, do not edit.
+// Contents subject to change without notice.
+
+import java.io.Serializable;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.CORBA_2_3.portable.ObjectImpl;
+
+
+public class _HelloImpl_Tie extends ObjectImpl implements Tie {
+
+    volatile private HelloImpl target = null;
+
+    private static final String[] _type_ids = {
+        "RMI:HelloInterface:0000000000000000"
+    };
+
+    public void setTarget(Remote target) {
+        this.target = (HelloImpl) target;
+    }
+
+    public Remote getTarget() {
+        return target;
+    }
+
+    public org.omg.CORBA.Object thisObject() {
+        return this;
+    }
+
+    public void deactivate() {
+        _orb().disconnect(this);
+        _set_delegate(null);
+        target = null;
+    }
+
+    public ORB orb() {
+        return _orb();
+    }
+
+    public void orb(ORB orb) {
+        orb.connect(this);
+    }
+
+    public String[] _ids() {
+        return (String[]) _type_ids.clone();
+    }
+
+    public OutputStream  _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
+        try {
+            HelloImpl target = this.target;
+            if (target == null) {
+                throw new java.io.IOException();
+            }
+            org.omg.CORBA_2_3.portable.InputStream in =
+                (org.omg.CORBA_2_3.portable.InputStream) _in;
+            if (method.equals("sayHelloWithTest3")) {
+                Test3 arg0 = (Test3) in.read_value(Test3.class);
+                Test3 result = target.sayHelloWithTest3(arg0);
+                org.omg.CORBA_2_3.portable.OutputStream out =
+                    (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
+                out.write_value(result,Test3.class);
+                return out;
+            }
+            throw new BAD_OPERATION();
+        } catch (SystemException ex) {
+            throw ex;
+        } catch (Throwable ex) {
+            throw new UnknownException(ex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloInterface_Stub.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+// Stub class generated by rmic, do not edit.
+// Contents subject to change without notice.
+
+import java.io.Serializable;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Util;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.RemarshalException;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.ServantObject;
+
+
+public class _HelloInterface_Stub extends Stub implements HelloInterface {
+
+    private static final String[] _type_ids = {
+        "RMI:HelloInterface:0000000000000000"
+    };
+
+        public String[] _ids() {
+            return (String[]) _type_ids.clone();
+        }
+
+        public Test3 sayHelloWithTest3(Test3 arg0) throws java.rmi.RemoteException {
+            if (!Util.isLocal(this)) {
+                try {
+                    org.omg.CORBA_2_3.portable.InputStream in = null;
+                    try {
+                        org.omg.CORBA_2_3.portable.OutputStream out =
+                            (org.omg.CORBA_2_3.portable.OutputStream)
+                            _request("sayHelloWithTest3", true);
+                        out.write_value(arg0,Test3.class);
+                        in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
+                        return (Test3) in.read_value(Test3.class);
+                    } catch (ApplicationException ex) {
+                        in = (org.omg.CORBA_2_3.portable.InputStream) ex.getInputStream();
+                        String $_id = in.read_string();
+                        throw new UnexpectedException($_id);
+                    } catch (RemarshalException ex) {
+                        return sayHelloWithTest3(arg0);
+                    } finally {
+                        _releaseReply(in);
+                    }
+                } catch (SystemException ex) {
+                    throw Util.mapSystemException(ex);
+                }
+            } else {
+                ServantObject so = _servant_preinvoke("sayHelloWithTest3",HelloInterface.class);
+                if (so == null) {
+                    return sayHelloWithTest3(arg0);
+                }
+                try {
+                    Test3 arg0Copy = (Test3) Util.copyObject(arg0,_orb());
+                    Test3 result = ((HelloInterface)so.servant).sayHelloWithTest3(arg0Copy);
+                    return (Test3)Util.copyObject(result,_orb());
+                } catch (Throwable ex) {
+                    Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
+                    throw Util.wrapException(exCopy);
+                } finally {
+                    _servant_postinvoke(so);
+                }
+            }
+        }
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/8146975/jtreg.test.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+
+grant {
+  permission java.io.FilePermission "*", "read";
+  permission java.io.FilePermission "./-", "read,write,execute";
+  permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve";
+  permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.*";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.security.util";
+  permission java.io.SerializablePermission "enableSubclassImplementation";
+  permission java.util.PropertyPermission "*", "read, write";
+  permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute";
+};
--- a/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -28,7 +28,11 @@
  * @library /lib/testlibrary
  * @build jdk.testlibrary.*
  * @build Test HelloInterface HelloServer HelloClient HelloImpl _HelloImpl_Tie _HelloInterface_Stub ConcurrentHashMapTest
- * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050 -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory  ConcurrentHashMapTest
+ * @run main/othervm -Djava.naming.provider.url=iiop://localhost:1050
+ *    -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory  ConcurrentHashMapTest
+ * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy
+ *    -Djava.naming.provider.url=iiop://localhost:1050
+ *    -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory ConcurrentHashMapTest
  */
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/rmi/PortableRemoteObject/jtreg.test.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+
+grant {
+  permission java.io.FilePermission "*", "read";
+  permission java.io.FilePermission "./-", "read,write,execute";
+  permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve";
+  permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.*";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.security.util";
+  permission java.io.SerializablePermission "enableSubclassImplementation";
+  permission java.util.PropertyPermission "*", "read, write";
+  permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,98 @@
+/*
+ * 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 com.sun.security.auth.NTUserPrincipal;
+import com.sun.security.auth.UnixPrincipal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import javax.security.auth.Subject;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @bug 8050409
+ * @summary Tests with Subject.getPrivateCredentials to check permission checks with one or more principals.
+ * @run testng/othervm/policy=MoreThenOnePrincipals.policy MoreThenOnePrincipals
+ */
+public class MoreThenOnePrincipals {
+    private static final String[] CRED_VALUES =
+            new String[]{"testPrivateCredential-1", "testPrivateCredentials-2"};
+    private static final HashSet CREDS = new HashSet<>(Arrays.asList(CRED_VALUES));
+
+    /**
+     * Policy file grants access to the private Credential,belonging to a
+     * Subject with at least two associated Principals:"com.sun.security.auth
+     * .NTUserPrincipal", with the name,"NTUserPrincipal-1", and
+     * "com.sun.security.auth.UnixPrincipal", with the name, "UnixPrincipals-1".
+     *
+     * For test1 and test2, subjects are associated with none or only one of
+     * principals mentioned above, SecurityException is expected.
+     * For test 3 and test 4, subjects are associated with two or more
+     * Principals (above principals are included), no exception is expected.
+     *
+     */
+
+    @Test(dataProvider = "Provider1", expectedExceptions = SecurityException.class)
+    public void test1(Subject s) {
+        s.getPrivateCredentials(String.class);
+    }
+
+    @Test(dataProvider = "Provider1", expectedExceptions = SecurityException.class)
+    public void test2(Subject s) {
+        s.getPrivateCredentials().iterator().next();
+    }
+
+    @Test(dataProvider = "Provider2")
+    public void test3(Subject s) {
+        s.getPrivateCredentials(String.class);
+    }
+
+    @Test(dataProvider = "Provider2")
+    public void test4(Subject s) {
+        s.getPrivateCredentials().iterator().next();
+    }
+
+    @DataProvider
+    public Object[][] Provider1() {
+        Subject s1 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS);
+        s1.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-2"));
+        Subject s2 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS);
+        s2.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-1"));
+        return new Object[][]{{s1}, {s2}};
+    }
+
+    @DataProvider
+    public Object[][] Provider2() {
+        Subject s3 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS);
+        s3.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-1"));
+        s3.getPrincipals().add(new UnixPrincipal("UnixPrincipals-1"));
+        Subject s4 = new Subject(false, Collections.EMPTY_SET, Collections.EMPTY_SET, CREDS);
+        s4.getPrincipals().add(new NTUserPrincipal("NTUserPrincipal-1"));
+        s4.getPrincipals().add(new UnixPrincipal("UnixPrincipals-1"));
+        s4.getPrincipals().add(new UnixPrincipal("UnixPrincipals-2"));
+        return new Object[][]{{s3}, {s4}};
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,10 @@
+grant{
+// permissions for TestNG execution
+permission java.io.FilePermission "*","read,write";
+permission java.lang.RuntimePermission "accessDeclaredMembers";
+permission java.util.PropertyPermission "*","read";
+permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+// permissions for test itself
+permission javax.security.auth.AuthPermission "modifyPrincipals";
+permission javax.security.auth.PrivateCredentialPermission "* com.sun.security.auth.NTUserPrincipal \"NTUserPrincipal-1\" com.sun.security.auth.UnixPrincipal \"UnixPrincipals-1\"", "read";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/smartcardio/CommandAPDUTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2007, 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
+ * @bug 8049021
+ * @summary Test different constructors for CommandAPDU and check CLA,INS,NC,NE,
+ * P1,and P2
+ * @run testng CommandAPDUTest
+ */
+import java.nio.ByteBuffer;
+import javax.smartcardio.CommandAPDU;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class CommandAPDUTest {
+
+    static final byte[] C1 = {(byte) 0x00, (byte) 0xA4, (byte) 0x04,
+        (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x62, (byte) 0x81, (byte) 0x01, (byte) 0x00};
+    static int cla, ins, nc, ne, p1, p2;
+    static byte[] apdu, data;
+    static CommandAPDU cm1, cm2, cm3, cm4, cm5, cm6, cm7, cm8, cm9;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        //expected values of apdu, data, headers, nc, ne
+        CommandAPDU capdu = new CommandAPDU(C1);
+        apdu = capdu.getBytes();
+        data = capdu.getData();
+
+        cla = capdu.getCLA();
+        if (cla != (C1[0] & 0xff)) {
+            throw new RuntimeException("Failure: cla is not right");
+        }
+
+        ins = capdu.getINS();
+        if (ins != (C1[1] & 0xff)) {
+            throw new RuntimeException("Failure: ins is not right");
+        }
+
+        p1 = capdu.getP1();
+        if (p1 != (C1[2] & 0xff)) {
+            throw new RuntimeException("Failure: p1 is not right");
+        }
+
+        p2 = capdu.getP2();
+        if (p2 != (C1[3] & 0xff)) {
+            throw new RuntimeException("Failure: p2 is not right");
+        }
+
+        nc = capdu.getNc();
+        ne = capdu.getNe();
+
+        //Test on following constructors
+        cm1 = new CommandAPDU(apdu);
+        cm2 = new CommandAPDU(cla, ins, p1, p2);
+        cm3 = new CommandAPDU(cla, ins, p1, p2, data);
+        cm4 = new CommandAPDU(cla, ins, p1, p2, data, ne);
+        cm5 = new CommandAPDU(cla, ins, p1, p2, ne);
+        cm6 = new CommandAPDU(ByteBuffer.wrap(apdu));
+        cm7 = new CommandAPDU(apdu, 0, apdu.length);
+        cm8 = new CommandAPDU(cla, ins, p1, p2, data, 0, nc);
+        cm9 = new CommandAPDU(cla, ins, p1, p2, data, 0, nc, ne);
+    }
+
+    @Test(dataProvider = "provider1")
+    public static void testHeaders(CommandAPDU cm) {
+        assertEquals(cla, cm.getCLA());
+        assertEquals(ins, cm.getINS());
+        assertEquals(p1, cm.getP1());
+        assertEquals(p2, cm.getP2());
+    }
+
+    @Test(dataProvider = "provider2")
+    public static void testAPDU(CommandAPDU cm) {
+        assertEquals(apdu, cm.getBytes());
+    }
+
+    @Test(dataProvider = "provider3")
+    public static void testData(CommandAPDU cm) {
+        assertEquals(data, cm.getData());
+    }
+
+    @Test(dataProvider = "provider3")
+    public static void testNC(CommandAPDU cm) {
+        assertEquals(nc, cm.getNc());
+    }
+
+    @Test(dataProvider = "provider4")
+    public static void testNE(CommandAPDU cm) {
+        assertEquals(ne, cm.getNe());
+    }
+
+    @DataProvider
+    public Object[][] provider1() {
+        return new Object[][]{{cm1}, {cm2}, {cm3}, {cm4}, {cm5}, {cm6}, {cm7},
+        {cm8}, {cm9}};
+    }
+
+    @DataProvider
+    public Object[][] provider2() {
+        return new Object[][]{{cm1}, {cm6}, {cm7}};
+    }
+
+    @DataProvider
+    public Object[][] provider3() {
+        return new Object[][]{{cm1}, {cm3}, {cm4}, {cm6}, {cm7}, {cm8}, {cm9}};
+    }
+
+    @DataProvider
+    public Object[][] provider4() {
+        return new Object[][]{{cm1}, {cm4}, {cm5}, {cm6}, {cm7}, {cm9}};
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/smartcardio/ResponseAPDUTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2007, 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
+ * @bug 8049021
+ * @summary Construct ResponseAPDU from byte array and check NR< SW, SW1 and SW2
+ * @run testng ResponseAPDUTest
+ */
+import javax.smartcardio.ResponseAPDU;
+import static org.testng.Assert.*;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ResponseAPDUTest {
+
+    static final byte[] R1 = {(byte) 0x07, (byte) 0xA0, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x81, (byte) 0x01,
+        (byte) 0x04, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x24,
+        (byte) 0x05, (byte) 0x00, (byte) 0x0B, (byte) 0x04, (byte) 0xB0,
+        (byte) 0x25, (byte) 0x90, (byte) 0x00};
+    static final ResponseAPDU RAPDU = new ResponseAPDU(R1);
+    static byte[] expectedData;
+    static int expectedNr, expectedSw1, expectedSw2, expectedSw;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        //expected values for data,nr,sw1,sw2 and sw
+
+        int apduLen = R1.length;
+        expectedData = new byte[apduLen - 2];
+        for (int i = 0; i < (apduLen - 2); i++) {
+            expectedData[i] = R1[i];
+        }
+
+        expectedNr = expectedData.length;
+        expectedSw1 = R1[apduLen - 2] & 0xff;
+        expectedSw2 = R1[apduLen - 1] & 0xff;
+        expectedSw = (expectedSw1 << 8) | expectedSw2;
+    }
+
+    @Test
+    public static void test() {
+        assertEquals(RAPDU.getBytes(), R1);
+        assertEquals(RAPDU.getData(), expectedData);
+        assertEquals(RAPDU.getNr(), expectedNr);
+        assertEquals(RAPDU.getSW(), expectedSw);
+        assertEquals(RAPDU.getSW1(), expectedSw1);
+        assertEquals(RAPDU.getSW2(), expectedSw2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/smartcardio/TerminalFactorySpiTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007, 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
+ * @bug 8049021
+ * @summary Test if we can write new provider for smart card
+ * @run main/othervm/policy=policy TerminalFactorySpiTest
+ */
+import java.security.Provider;
+import java.security.Security;
+import java.util.Arrays;
+import javax.smartcardio.CardTerminals;
+import javax.smartcardio.TerminalFactory;
+import javax.smartcardio.TerminalFactorySpi;
+
+public class TerminalFactorySpiTest {
+
+    static boolean callMethod = false;
+
+    public static void main(String[] args) throws Exception {
+        Provider myProvider = new MyProvider();
+        Security.addProvider(myProvider);
+        System.out.println(Arrays.asList(Security.getProviders()));
+
+        TerminalFactory.getInstance("MyType", new Object()).terminals();
+        if (!callMethod) {
+            throw new RuntimeException("Expected engineTerminals() not called");
+        }
+    }
+
+    public static class MyProvider extends Provider {
+
+        MyProvider() {
+            super("MyProvider", 1.0d, "smart Card Example");
+            put("TerminalFactory.MyType", "TerminalFactorySpiTest$MyTerminalFactorySpi");
+        }
+    }
+
+    public static class MyTerminalFactorySpi extends TerminalFactorySpi {
+
+        public MyTerminalFactorySpi(Object ob) {
+        }
+
+        protected CardTerminals engineTerminals() {
+            System.out.println("MyTerminalFactory.engineTerminals()");
+            callMethod = true;
+            return null;
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/smartcardio/policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,4 @@
+grant {
+        permission java.security.SecurityPermission "insertProvider.MyProvider";
+        permission java.security.SecurityPermission "putProviderProperty.MyProvider";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/JComboBox/8136998/bug8136998.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016, 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.AWTException;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.WindowConstants;
+
+/* @test
+ * @bug 8136998
+ * @summary Checks that JComboBox does not prevent mouse-wheel scrolling JScrollPane.
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main bug8136998
+ * @author Alexey Ivanov
+ */
+public class bug8136998 {
+
+    private static final String[] ITEMS = new String[] {
+        "A", "B", "C", "D", "E", "F"
+    };
+
+    private final Robot robot;
+
+    private JFrame frame;
+    private JComboBox comboBox;
+    private JScrollPane scrollPane;
+
+    public static void main(String[] args) throws Exception {
+        iterateLookAndFeels(new bug8136998());
+    }
+
+    protected static void iterateLookAndFeels(final bug8136998 test) throws Exception {
+        LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels();
+        for (LookAndFeelInfo info : lafInfo) {
+            try {
+                UIManager.setLookAndFeel(info.getClassName());
+                System.out.println("Look and Feel: " + info.getClassName());
+                test.runTest();
+            } catch (UnsupportedLookAndFeelException e) {
+                System.out.println("Skipping unsupported LaF: " + info);
+            }
+        }
+    }
+
+    public bug8136998() throws AWTException {
+        robot = new Robot();
+        robot.setAutoDelay(200);
+    }
+
+    private void setupUI() {
+        frame = new JFrame();
+        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+
+        comboBox = new JComboBox<>(ITEMS);
+
+        JPanel scrollable = new JPanel();
+        scrollable.setLayout(new BoxLayout(scrollable, BoxLayout.Y_AXIS));
+
+        scrollable.add(Box.createVerticalStrut(200));
+        scrollable.add(comboBox);
+        scrollable.add(Box.createVerticalStrut(200));
+
+        scrollPane = new JScrollPane(scrollable);
+
+        frame.add(scrollPane);
+
+        frame.setSize(100, 200);
+        frame.setVisible(true);
+    }
+
+    public void runTest() throws Exception {
+        try {
+            SwingUtilities.invokeAndWait(this::setupUI);
+
+            robot.waitForIdle();
+
+            SwingUtilities.invokeAndWait(() ->
+                scrollPane.getViewport().scrollRectToVisible(comboBox.getBounds())
+            );
+            robot.waitForIdle();
+
+            // Move mouse pointer to the center of the combo box
+            Point p = comboBox.getLocationOnScreen();
+            Dimension d = comboBox.getSize();
+            robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
+
+            // The currently visible rectangle in scrollPane
+            Rectangle viewRect0 = Util.invokeOnEDT(scrollPane.getViewport()::getViewRect);
+
+            // Scroll the scrollPane with mouse wheel
+            robot.mouseWheel(1);
+            robot.waitForIdle();
+
+            // The updated rectangle
+            Rectangle viewRect1 = Util.invokeOnEDT(scrollPane.getViewport()::getViewRect);
+
+            if (viewRect0.y == viewRect1.y) {
+                throw new RuntimeException("Mouse wheel should have scrolled the JScrollPane");
+            }
+        } finally {
+            if (frame != null) {
+                frame.dispose();
+            }
+        }
+
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/plaf/basic/BasicComboPopup/8154069/Bug8154069.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016, 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 8154069
+ * @summary Jaws reads wrong values from comboboxes when no element is selected
+ * @run main Bug8154069
+ */
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleSelection;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+public class Bug8154069 {
+
+    private static JFrame frame;
+    private static volatile Exception exception = null;
+
+    public static void main(String args[]) throws Exception {
+        try {
+            try {
+                UIManager.setLookAndFeel(new NimbusLookAndFeel());
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            SwingUtilities.invokeAndWait(() -> {
+                frame = new JFrame();
+                String[] petStrings = { "Bird", "Cat" };
+                JComboBox<String> cb = new JComboBox<>(petStrings);
+                cb.setSelectedIndex(1);  // select Cat
+                frame.add(cb);
+                frame.pack();
+                try {
+                    cb.setSelectedIndex(-1);
+                    int i = cb.getSelectedIndex();
+                    if (i != -1) {
+                        throw new RuntimeException("getSelectedIndex is not -1");
+                    }
+                    Object o = cb.getSelectedItem();
+                    if (o != null) {
+                        throw new RuntimeException("getSelectedItem is not null");
+                    }
+                    AccessibleContext ac = cb.getAccessibleContext();
+                    AccessibleSelection as = ac.getAccessibleSelection();
+                    int count = as.getAccessibleSelectionCount();
+                    if (count != 0) {
+                        throw new RuntimeException("getAccessibleSelection count is not 0");
+                    }
+                    Accessible a = as.getAccessibleSelection(0);
+                    if (a != null) {
+                        throw new RuntimeException("getAccessibleSelection(0) is not null");
+                    }
+                } catch (Exception e) {
+                    exception = e;
+                }
+            });
+            if (exception != null) {
+                System.out.println("Test failed: " + exception.getMessage());
+                throw exception;
+            } else {
+                System.out.println("Test passed.");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                frame.dispose();
+            });
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/swing/plaf/nimbus/8057791/bug8057791.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, 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 8057791
+   @summary Selection in JList is drawn with wrong colors in Nimbus L&F
+   @author Anton Litvinov
+   @run main bug8057791
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashSet;
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+public class bug8057791 {
+    public static void main(String[] args) {
+        try {
+            UIManager.setLookAndFeel(new NimbusLookAndFeel());
+
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    final int listWidth = 50;
+                    final int listHeight = 50;
+                    final int selCellIndex = 0;
+
+                    JList<String> list = new JList<String>();
+                    list.setSize(listWidth, listHeight);
+                    DefaultListModel<String> listModel = new DefaultListModel<String>();
+                    listModel.add(selCellIndex, "E");
+                    list.setModel(listModel);
+                    list.setSelectedIndex(selCellIndex);
+
+                    BufferedImage img = new BufferedImage(listWidth, listHeight,
+                        BufferedImage.TYPE_INT_ARGB);
+                    Graphics g = img.getGraphics();
+                    list.paint(g);
+                    g.dispose();
+
+                    Rectangle cellRect = list.getCellBounds(selCellIndex, selCellIndex);
+                    HashSet<Color> cellColors = new HashSet<Color>();
+                    int uniqueColorIndex = 0;
+                    for (int x = cellRect.x; x < (cellRect.x + cellRect.width); x++) {
+                        for (int y = cellRect.y; y < (cellRect.y + cellRect.height); y++) {
+                            Color cellColor = new Color(img.getRGB(x, y), true);
+                            if (cellColors.add(cellColor)) {
+                                System.err.println(String.format("Cell color #%d: %s",
+                                    uniqueColorIndex++, cellColor));
+                            }
+                        }
+                    }
+
+                    Color selForegroundColor = list.getSelectionForeground();
+                    Color selBackgroundColor = list.getSelectionBackground();
+                    if (!cellColors.contains(new Color(selForegroundColor.getRGB(), true))) {
+                        throw new RuntimeException(String.format(
+                            "Selected cell is drawn without selection foreground color '%s'.",
+                            selForegroundColor));
+                    }
+                    if (!cellColors.contains(new Color(selBackgroundColor.getRGB(), true))) {
+                        throw new RuntimeException(String.format(
+                            "Selected cell is drawn without selection background color '%s'.",
+                            selBackgroundColor));
+                    }
+                }
+            });
+        } catch (UnsupportedLookAndFeelException | InterruptedException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- a/test/javax/xml/crypto/dsig/GenerationTests.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/javax/xml/crypto/dsig/GenerationTests.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349
+ * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8074784
  * @summary Basic unit tests for generating XML Signatures with JSR 105
  * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
  *     X509KeySelector.java GenerationTests.java
@@ -31,16 +31,23 @@
  * @author Sean Mullan
  */
 
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
 import java.io.*;
 import java.math.BigInteger;
+import java.net.InetSocketAddress;
 import java.security.Key;
 import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
 import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
+import java.security.SecureRandom;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
 import java.security.cert.X509CRL;
 import java.security.spec.KeySpec;
 import java.security.spec.DSAPrivateKeySpec;
@@ -48,10 +55,10 @@
 import java.security.spec.RSAPrivateKeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.util.*;
+import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.xml.XMLConstants;
 import javax.xml.parsers.*;
-import org.w3c.dom.*;
 import javax.xml.crypto.Data;
 import javax.xml.crypto.KeySelector;
 import javax.xml.crypto.OctetStreamData;
@@ -69,6 +76,7 @@
 import javax.xml.transform.*;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
+import org.w3c.dom.*;
 
 /**
  * Test that recreates merlin-xmldsig-twenty-three test vectors but with
@@ -110,6 +118,73 @@
     private final static String DSA_SHA256 =
         "http://www.w3.org/2009/xmldsig11#dsa-sha256";
 
+    private static final String BOGUS = "bogus";
+
+    private static final  String xslt = ""
+          + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n"
+          + "            xmlns='http://www.w3.org/TR/xhtml1/strict' \n"
+          + "            exclude-result-prefixes='foo' \n"
+          + "            version='1.0'>\n"
+          + "  <xsl:output encoding='UTF-8' \n"
+          + "           indent='no' \n"
+          + "           method='xml' />\n"
+          + "  <xsl:template match='/'>\n"
+          + "    <html>\n"
+          + "   <head>\n"
+          + "    <title>Notaries</title>\n"
+          + "   </head>\n"
+          + "   <body>\n"
+          + "    <table>\n"
+          + "      <xsl:for-each select='Notaries/Notary'>\n"
+          + "           <tr>\n"
+          + "           <th>\n"
+          + "            <xsl:value-of select='@name' />\n"
+          + "           </th>\n"
+          + "           </tr>\n"
+          + "      </xsl:for-each>\n"
+          + "    </table>\n"
+          + "   </body>\n"
+          + "    </html>\n"
+          + "  </xsl:template>\n"
+          + "</xsl:stylesheet>\n";
+
+    private static final String[] canonicalizationMethods = new String[] {
+        CanonicalizationMethod.EXCLUSIVE,
+        CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
+        CanonicalizationMethod.INCLUSIVE,
+        CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS
+    };
+
+    private static final String[] xml_transforms = new String[] {
+        Transform.XSLT,
+        Transform.XPATH,
+        Transform.XPATH2,
+        CanonicalizationMethod.EXCLUSIVE,
+        CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
+        CanonicalizationMethod.INCLUSIVE,
+        CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
+    };
+
+    private static final String[] non_xml_transforms = new String[] {
+        null, Transform.BASE64
+    };
+
+    private static final String[] signatureMethods = new String[] {
+        SignatureMethod.DSA_SHA1,
+        SignatureMethod.RSA_SHA1,
+        SignatureMethod.HMAC_SHA1
+    };
+
+    private static enum Content {
+        Xml, Text, Base64, NotExisitng
+    }
+
+    private static enum KeyInfoType {
+        KeyValue, x509data, KeyName
+    }
+
+    private static boolean result = true;
+
     public static void main(String args[]) throws Exception {
         setup();
         test_create_signature_enveloped_dsa(1024);
@@ -140,6 +215,97 @@
         test_create_signature_reference_dependency();
         test_create_signature_with_attr_in_no_namespace();
         test_create_signature_with_empty_id();
+
+        // run tests for detached signatures with local http server
+        try (Http server = Http.startServer()) {
+            server.start();
+
+            // tests for XML documents
+            Arrays.stream(canonicalizationMethods).forEach(c ->
+                Arrays.stream(signatureMethods).forEach(s ->
+                    Arrays.stream(xml_transforms).forEach(t ->
+                        Arrays.stream(KeyInfoType.values()).forEach(k -> {
+                            test_create_detached_signature(c, s, t, k,
+                                    Content.Xml, server.getPort(), false, null);
+                        }))));
+
+            // tests for text data with no transform
+            Arrays.stream(canonicalizationMethods).forEach(c ->
+                Arrays.stream(signatureMethods).forEach(s ->
+                    Arrays.stream(KeyInfoType.values()).forEach(k -> {
+                        test_create_detached_signature(c, s, null, k,
+                                Content.Text, server.getPort(), false, null);
+                    })));
+
+            // tests for base64 data
+            Arrays.stream(canonicalizationMethods).forEach(c ->
+                Arrays.stream(signatureMethods).forEach(s ->
+                    Arrays.stream(non_xml_transforms).forEach(t ->
+                        Arrays.stream(KeyInfoType.values()).forEach(k -> {
+                            test_create_detached_signature(c, s, t, k,
+                                    Content.Base64, server.getPort(),
+                                    false, null);
+                        }))));
+
+            // negative tests
+
+            // unknown CanonicalizationMethod
+            test_create_detached_signature(
+                    CanonicalizationMethod.EXCLUSIVE + BOGUS,
+                    SignatureMethod.DSA_SHA1,
+                    CanonicalizationMethod.INCLUSIVE,
+                    KeyInfoType.KeyName,
+                    Content.Xml,
+                    server.getPort(),
+                    true,
+                    NoSuchAlgorithmException.class);
+
+            // unknown SignatureMethod
+            test_create_detached_signature(
+                    CanonicalizationMethod.EXCLUSIVE,
+                    SignatureMethod.DSA_SHA1 + BOGUS,
+                    CanonicalizationMethod.INCLUSIVE,
+                    KeyInfoType.KeyName, Content.Xml,
+                    server.getPort(),
+                    true,
+                    NoSuchAlgorithmException.class);
+
+            // unknown Transform
+            test_create_detached_signature(
+                    CanonicalizationMethod.EXCLUSIVE,
+                    SignatureMethod.DSA_SHA1,
+                    CanonicalizationMethod.INCLUSIVE + BOGUS,
+                    KeyInfoType.KeyName, Content.Xml,
+                    server.getPort(),
+                    true,
+                    NoSuchAlgorithmException.class);
+
+            // no source document
+            test_create_detached_signature(
+                    CanonicalizationMethod.EXCLUSIVE,
+                    SignatureMethod.DSA_SHA1,
+                    CanonicalizationMethod.INCLUSIVE,
+                    KeyInfoType.KeyName,
+                    Content.NotExisitng,
+                    server.getPort(),
+                    true,
+                    XMLSignatureException.class);
+
+            // wrong transform for text data
+            test_create_detached_signature(
+                    CanonicalizationMethod.EXCLUSIVE,
+                    SignatureMethod.DSA_SHA1,
+                    CanonicalizationMethod.INCLUSIVE,
+                    KeyInfoType.KeyName,
+                    Content.Text,
+                    server.getPort(),
+                    true,
+                    XMLSignatureException.class);
+        }
+
+        if (!result) {
+            throw new RuntimeException("At least one test case failed");
+        }
     }
 
     private static void setup() throws Exception {
@@ -716,33 +882,6 @@
 
         // Manifest Reference 3
         List<Transform> manTrans = new ArrayList<Transform>();
-        String xslt = ""
-          + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n"
-          + "            xmlns='http://www.w3.org/TR/xhtml1/strict' \n"
-          + "            exclude-result-prefixes='foo' \n"
-          + "            version='1.0'>\n"
-          + "  <xsl:output encoding='UTF-8' \n"
-          + "           indent='no' \n"
-          + "           method='xml' />\n"
-          + "  <xsl:template match='/'>\n"
-          + "    <html>\n"
-          + "   <head>\n"
-          + "    <title>Notaries</title>\n"
-          + "   </head>\n"
-          + "   <body>\n"
-          + "    <table>\n"
-          + "      <xsl:for-each select='Notaries/Notary'>\n"
-          + "           <tr>\n"
-          + "           <th>\n"
-          + "            <xsl:value-of select='@name' />\n"
-          + "           </th>\n"
-          + "           </tr>\n"
-          + "      </xsl:for-each>\n"
-          + "    </table>\n"
-          + "   </body>\n"
-          + "    </html>\n"
-          + "  </xsl:template>\n"
-          + "</xsl:stylesheet>\n";
         Document docxslt = db.parse(new ByteArrayInputStream(xslt.getBytes()));
         Node xslElem = docxslt.getDocumentElement();
 
@@ -1121,6 +1260,200 @@
         System.out.println();
     }
 
+    static void test_create_detached_signature(String canonicalizationMethod,
+            String signatureMethod, String transform, KeyInfoType keyInfo,
+            Content contentType, int port, boolean expectedFailure,
+            Class expectedException) {
+
+        final String digestMethod = DigestMethod.SHA1;
+        System.out.println("Test detached signature:");
+        System.out.println("    Canonicalization method: "
+                + canonicalizationMethod);
+        System.out.println("    Signature method: " + signatureMethod);
+        System.out.println("    Transform: " + transform);
+        System.out.println("    Digest method: " + digestMethod);
+        System.out.println("    KeyInfoType: " + keyInfo);
+        System.out.println("    Content type: " + contentType);
+        System.out.println("    Expected failure: "
+                + (expectedFailure ? "yes" : "no"));
+        System.out.println("    Expected exception: "
+                + (expectedException == null ?
+                        "no" : expectedException.getName()));
+
+        try {
+            boolean success = test_create_detached_signature(
+                    canonicalizationMethod,
+                    signatureMethod,
+                    digestMethod,
+                    transform,
+                    keyInfo,
+                    contentType,
+                    port);
+
+            if (success && expectedFailure) {
+                System.out.println("Signature validation unexpectedly passed");
+                result = false;
+            } else if (!success && !expectedFailure) {
+                System.out.println("Signature validation unexpectedly failed");
+                result = false;
+            } else if (expectedException != null) {
+                System.out.println("Expected " + expectedException
+                        + " not thrown");
+                result = false;
+            }
+        } catch (Exception e) {
+            if (expectedException == null
+                    || !e.getClass().isAssignableFrom(expectedException)) {
+                System.out.println("Unexpected exception: " + e);
+                e.printStackTrace(System.out);
+                result = false;
+            } else {
+                System.out.println("Expected exception: " + e);
+            }
+        }
+
+        System.out.println("Test case passed");
+    }
+
+    static boolean test_create_detached_signature(String canonicalizationMethod,
+            String signatureMethod, String digestMethod, String transform,
+            KeyInfoType keyInfo, Content contentType, int port)
+            throws Exception {
+
+        System.out.print("Sign ...");
+
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+        dbf.setValidating(false);
+
+        // Create SignedInfo
+        DigestMethod dm = fac.newDigestMethod(digestMethod, null);
+
+        List transformList = null;
+        if (transform != null) {
+            TransformParameterSpec params = null;
+            switch (transform) {
+                case Transform.XPATH:
+                    params = new XPathFilterParameterSpec("//.");
+                    break;
+                case Transform.XPATH2:
+                    params = new XPathFilter2ParameterSpec(
+                            Collections.singletonList(new XPathType("//.",
+                                    XPathType.Filter.INTERSECT)));
+                    break;
+                case Transform.XSLT:
+                    Element element = dbf.newDocumentBuilder()
+                            .parse(new ByteArrayInputStream(xslt.getBytes()))
+                            .getDocumentElement();
+                    DOMStructure stylesheet = new DOMStructure(element);
+                    params = new XSLTTransformParameterSpec(stylesheet);
+                    break;
+            }
+            transformList = Collections.singletonList(fac.newTransform(
+                    transform, params));
+        }
+
+        String url = String.format("http://localhost:%d/%s", port, contentType);
+        List refs = Collections.singletonList(fac.newReference(url, dm,
+                transformList, null, null));
+
+        CanonicalizationMethod cm = fac.newCanonicalizationMethod(
+                canonicalizationMethod, (C14NMethodParameterSpec) null);
+
+        SignatureMethod sm = fac.newSignatureMethod(signatureMethod, null);
+
+        Key signingKey;
+        Key validationKey;
+        switch (signatureMethod) {
+            case SignatureMethod.DSA_SHA1:
+            case SignatureMethod.RSA_SHA1:
+                KeyPair kp = generateKeyPair(sm);
+                validationKey = kp.getPublic();
+                signingKey = kp.getPrivate();
+                break;
+            case SignatureMethod.HMAC_SHA1:
+                KeyGenerator kg = KeyGenerator.getInstance("HmacSHA1");
+                signingKey = kg.generateKey();
+                validationKey = signingKey;
+                break;
+            default:
+                throw new RuntimeException("Unsupported signature algorithm");
+        }
+
+        SignedInfo si = fac.newSignedInfo(cm, sm, refs, null);
+
+        // Create KeyInfo
+        KeyInfoFactory kif = fac.getKeyInfoFactory();
+        List list = null;
+        if (keyInfo == KeyInfoType.KeyValue) {
+            if (validationKey instanceof PublicKey) {
+                KeyValue kv = kif.newKeyValue((PublicKey) validationKey);
+                list = Collections.singletonList(kv);
+            }
+        } else if (keyInfo == KeyInfoType.x509data) {
+            list = Collections.singletonList(
+                    kif.newX509Data(Collections.singletonList("cn=Test")));
+        } else if (keyInfo == KeyInfoType.KeyName) {
+            list = Collections.singletonList(kif.newKeyName("Test"));
+        } else {
+            throw new RuntimeException("Unexpected KeyInfo: " + keyInfo);
+        }
+        KeyInfo ki = list != null ? kif.newKeyInfo(list) : null;
+
+        // Create an empty doc for detached signature
+        Document doc = dbf.newDocumentBuilder().newDocument();
+        DOMSignContext xsc = new DOMSignContext(signingKey, doc);
+
+        // Generate signature
+        XMLSignature signature = fac.newXMLSignature(si, ki);
+        signature.sign(xsc);
+
+        // Save signature
+        String signatureString;
+        try (StringWriter writer = new StringWriter()) {
+            TransformerFactory tf = TransformerFactory.newInstance();
+            Transformer trans = tf.newTransformer();
+            Node parent = xsc.getParent();
+            trans.transform(new DOMSource(parent), new StreamResult(writer));
+            signatureString = writer.toString();
+        }
+
+        System.out.print("Validate ... ");
+        try (ByteArrayInputStream bis = new ByteArrayInputStream(
+                signatureString.getBytes())) {
+            doc = dbf.newDocumentBuilder().parse(bis);
+        }
+
+        NodeList nodeLst = doc.getElementsByTagName("Signature");
+        Node node = nodeLst.item(0);
+        if (node == null) {
+            throw new RuntimeException("Couldn't find Signature element");
+        }
+        if (!(node instanceof Element)) {
+            throw new RuntimeException("Unexpected node type");
+        }
+        Element sig = (Element) node;
+
+        // Validate signature
+        DOMValidateContext vc = new DOMValidateContext(validationKey, sig);
+        vc.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.FALSE);
+        signature = fac.unmarshalXMLSignature(vc);
+
+        boolean success = signature.validate(vc);
+        if (!success) {
+            System.out.println("Core signature validation failed");
+            return false;
+        }
+
+        success = signature.getSignatureValue().validate(vc);
+        if (!success) {
+            System.out.println("Cryptographic validation of signature failed");
+            return false;
+        }
+
+        return true;
+    }
+
     private static final String DSA_Y =
         "070662842167565771936588335128634396171789331656318483584455493822" +
         "400811200853331373030669235424928346190274044631949560438023934623" +
@@ -1231,6 +1564,25 @@
         };
     }
 
+    static KeyPair generateKeyPair(SignatureMethod sm)
+            throws NoSuchAlgorithmException {
+        KeyPairGenerator keygen;
+        switch (sm.getAlgorithm()) {
+            case SignatureMethod.DSA_SHA1:
+                keygen = KeyPairGenerator.getInstance("DSA");
+                break;
+            case SignatureMethod.RSA_SHA1:
+                keygen = KeyPairGenerator.getInstance("RSA");
+                break;
+            default:
+                throw new RuntimeException("Unsupported signature algorithm");
+        }
+
+        SecureRandom random = new SecureRandom();
+        keygen.initialize(1024, random);
+        return keygen.generateKeyPair();
+    }
+
     /**
      * This URIDereferencer returns locally cached copies of http content to
      * avoid test failures due to network glitches, etc.
@@ -1257,4 +1609,82 @@
             return defaultUd.dereference(ref, ctx);
         }
     }
+
+    // local http server
+    static class Http implements HttpHandler, AutoCloseable {
+
+        private final HttpServer server;
+
+        private Http(HttpServer server) {
+            this.server = server;
+        }
+
+        static Http startServer() throws IOException {
+            HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+            return new Http(server);
+        }
+
+        void start() {
+            server.createContext("/", this);
+            server.start();
+        }
+
+        void stop() {
+            server.stop(0);
+        }
+
+        int getPort() {
+            return server.getAddress().getPort();
+        }
+
+        @Override
+        public void handle(HttpExchange t) throws IOException {
+            try {
+                String type;
+                String path = t.getRequestURI().getPath();
+                if (path.startsWith("/")) {
+                    type = path.substring(1);
+                } else {
+                    type = path;
+                }
+
+                String contentTypeHeader = "";
+                byte[] output = new byte[] {};
+                int code = 200;
+                Content testContentType = Content.valueOf(type);
+                switch (testContentType) {
+                    case Base64:
+                        contentTypeHeader = "application/octet-stream";
+                        output = "VGVzdA==".getBytes();
+                        break;
+                    case Text:
+                        contentTypeHeader = "text/plain";
+                        output = "Text".getBytes();
+                        break;
+                    case Xml:
+                        contentTypeHeader = "application/xml";
+                        output = "<tag>test</tag>".getBytes();
+                        break;
+                    case NotExisitng:
+                        code = 404;
+                        break;
+                    default:
+                        throw new IOException("Unknown test content type");
+                }
+
+                t.getResponseHeaders().set("Content-Type", contentTypeHeader);
+                t.sendResponseHeaders(code, output.length);
+                t.getResponseBody().write(output);
+            } catch (IOException e) {
+                System.out.println("Exception: " + e);
+                t.sendResponseHeaders(500, 0);
+            }
+            t.close();
+        }
+
+        @Override
+        public void close() {
+            stop();
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/stream/8153781/SkipDTDTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016, 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 com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
+import java.io.StringReader;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @bug 8153781
+ * @run testng/othervm SkipDTDTest
+ * @summary Test if method skipDTD of class XMLDTDScannerImpl will correctly skip the DTD section,
+ *          even if a call to XMLEntityScanner.scanData for skipping to the closing ']' returns true.
+ */
+public class SkipDTDTest {
+    public static int DOCTYPE_SECTION_LENGTH = XMLEntityManager.DEFAULT_BUFFER_SIZE * 2;
+    public static int DOCUMENT_LENGTH = DOCTYPE_SECTION_LENGTH + 4096;
+
+    public String createXMLDocument(int doctypeoffset) {
+        StringBuilder xmlcontentbuilder = new StringBuilder(DOCUMENT_LENGTH);
+        xmlcontentbuilder.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n");
+        xmlcontentbuilder.append("<!DOCTYPE dummy [\r\n");
+        xmlcontentbuilder.append("  <!ELEMENT dummy EMPTY>\r\n");
+        xmlcontentbuilder.append("  <!--\r\n");
+        int doctypelines = DOCTYPE_SECTION_LENGTH / 3;
+        for (int i = 0; i < doctypeoffset; i++)
+            xmlcontentbuilder.append('a');
+        for (int i = 0; i < doctypelines; i++)
+            xmlcontentbuilder.append("a\r\n");
+        xmlcontentbuilder.append("  -->\r\n");
+        xmlcontentbuilder.append("  ]\r\n");
+        xmlcontentbuilder.append(">\r\n");
+        xmlcontentbuilder.append("<dummy>\r\n");
+        xmlcontentbuilder.append("</dummy>\r\n");
+        System.out.println("Document length:" + xmlcontentbuilder.length());
+        return xmlcontentbuilder.toString();
+    }
+
+    public void runReader(XMLInputFactory factory, int offset) throws XMLStreamException {
+        StringReader stringReader = new StringReader(createXMLDocument(offset));
+        XMLEventReader reader = factory.createXMLEventReader(stringReader);
+
+        while (reader.hasNext()) {
+            XMLEvent event = reader.nextEvent();
+            System.out.println("Event Type: " + event.getEventType());
+        }
+    }
+
+    @Test
+    public void test() {
+        try {
+            XMLInputFactory factory = XMLInputFactory.newInstance();
+            factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+            for (int i = 0; i < 3; i++) {
+                runReader(factory, i);
+            }
+        } catch (XMLStreamException xe) {
+            xe.printStackTrace();
+            Assert.fail(xe.getMessage());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/java2d/ClassCastExceptionForInvalidSurface.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016, 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.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.image.BufferedImage;
+import java.awt.image.VolatileImage;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+
+/**
+ * @test
+ * @bug 8158072 7172749
+ */
+public final class ClassCastExceptionForInvalidSurface {
+
+    static GraphicsEnvironment ge
+            = GraphicsEnvironment.getLocalGraphicsEnvironment();
+
+    static GraphicsConfiguration gc
+            = ge.getDefaultScreenDevice().getDefaultConfiguration();
+
+    static volatile VolatileImage vi = gc.createCompatibleVolatileImage(10, 10);
+
+    static volatile Throwable failed;
+
+    static BlockingQueue<VolatileImage> list = new ArrayBlockingQueue<>(50);
+
+    // Will run the test no more than 15 seconds
+    static long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(15);
+
+    public static void main(final String[] args) throws InterruptedException {
+
+        // Catch all uncaught exceptions and treat them as test failure
+        Thread.setDefaultUncaughtExceptionHandler((t, e) -> failed = e);
+
+        // Data for rendering
+        BufferedImage bi = new BufferedImage(10, 10, TYPE_INT_ARGB);
+        FontRenderContext frc = new FontRenderContext(null, false, false);
+        Font font = new Font("Serif", Font.PLAIN, 12);
+        GlyphVector gv = font.createGlyphVector(frc, new char[]{'a', '1'});
+
+        Thread t1 = new Thread(() -> {
+            while (!isComplete()) {
+                vi = gc.createCompatibleVolatileImage(10, 10);
+                if (!list.offer(vi)) {
+                    vi.flush();
+                }
+            }
+            list.forEach(Image::flush);
+        });
+        Thread t2 = new Thread(() -> {
+            while (!isComplete()) {
+                VolatileImage vi = list.poll();
+                if (vi != null) {
+                    vi.flush();
+                }
+            }
+        });
+
+        Thread t3 = new Thread(() -> {
+            while (!isComplete()) {
+                vi.createGraphics().drawImage(bi, 1, 1, null);
+            }
+        });
+        Thread t4 = new Thread(() -> {
+            while (!isComplete()) {
+                vi.createGraphics().drawGlyphVector(gv, 0, 0);
+                vi.createGraphics().drawOval(0, 0, 10, 10);
+                vi.createGraphics().drawLine(0, 0, 10, 10);
+                vi.createGraphics().drawString("123", 1, 1);
+                vi.createGraphics().draw(new Rectangle(0, 0, 10, 10));
+                vi.createGraphics().fillOval(0, 0, 10, 10);
+                final Graphics2D graphics = vi.createGraphics();
+                graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                          RenderingHints.VALUE_ANTIALIAS_ON);
+                graphics.fillPolygon(new int[] {0, 10, 10, 0},
+                                     new int [] {0, 0, 10, 10}, 4);
+            }
+        });
+        t1.start();
+        t2.start();
+        t3.start();
+        t4.start();
+        t1.join();
+        t2.join();
+        t3.join();
+        t4.join();
+
+        if (failed != null) {
+            System.err.println("Test failed");
+            failed.printStackTrace();
+        }
+    }
+
+    private static boolean isComplete() {
+        return endtime - System.nanoTime() < 0 || failed != null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/BogusKDC.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,118 @@
+/*
+ * 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.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 4515853 8075297
+ * @summary Checks that Kerberos client tries slave KDC
+ *          if master KDC is not responding
+ * @run main/othervm BogusKDC
+ */
+public class BogusKDC {
+
+    static final String TEST_SRC = System.getProperty("test.src", ".");
+    static final String HOST = "localhost";
+    static final String NOT_EXISTING_HOST = "not.existing.host";
+    static final String REALM = "TEST.REALM";
+    static final String USER = "USER";
+    static final String USER_PRINCIPAL = USER + "@" + REALM;
+    static final String USER_PASSWORD = "password";
+    static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    static final String KRB5_CONF = "krb5.conf";
+    static final int WRONG_KDC_PORT = 21;
+
+    static final String KRB5_CONF_TEMPLATE = ""
+            + "[libdefaults]\n"
+            + "default_realm = TEST.REALM\n"
+            + "max_retries = 1\n"
+            + "\n"
+            + "[realms]\n"
+            + "TEST.REALM = {\n"
+            + "    kdc = %s\n"
+            + "    kdc = localhost:%d\n"
+            + "}";
+
+    public static void main(String[] args) throws LoginException, IOException {
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, USER_PASSWORD);
+        principals.put(KRBTGT_PRINCIPAL, null);
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF);
+
+        // start a local KDC
+        KDC kdc = KDC.startKDC(HOST, KRB5_CONF, REALM, principals, null, null);
+
+        System.setProperty("java.security.auth.login.config",
+                TEST_SRC + File.separator + "refreshKrb5Config.jaas");
+
+        CallbackHandler handler = new Helper.UserPasswordHandler(
+                USER, USER_PASSWORD);
+
+        // create a krb5 config with non-existing host for master KDC,
+        // and wrong port for slave KDC
+        try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) {
+            w.write(String.format(KRB5_CONF_TEMPLATE,
+                    KDC.KDCNameService.NOT_EXISTING_HOST, WRONG_KDC_PORT));
+            w.flush();
+        }
+
+        // login with not-refreshable config
+        try {
+            new LoginContext("NotRefreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // create a krb5 config with non-existing host for master KDC,
+        // but correct port for slave KDC
+        try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) {
+            w.write(String.format(KRB5_CONF_TEMPLATE,
+                    KDC.KDCNameService.NOT_EXISTING_HOST, kdc.getPort()));
+            w.flush();
+        }
+
+        // login with not-refreshable config
+        try {
+            new LoginContext("NotRefreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // login with refreshable config
+        new LoginContext("Refreshable", handler).login();
+
+        System.out.println("Test passed");
+    }
+}
--- a/test/sun/security/krb5/auto/Context.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/krb5/auto/Context.java	Thu Jan 12 06:59:38 2017 +0000
@@ -23,6 +23,7 @@
 
 import com.sun.security.auth.module.Krb5LoginModule;
 import java.security.Key;
+import java.lang.reflect.InvocationTargetException;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.util.Arrays;
@@ -581,7 +582,12 @@
             out.name = name + " as " + out.cred.getName().toString();
             return out;
         } catch (PrivilegedActionException pae) {
-            throw pae.getException();
+            Exception e = pae.getException();
+            if (e instanceof InvocationTargetException) {
+                throw (Exception)((InvocationTargetException) e).getTargetException();
+            } else {
+                throw e;
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/ForwardableCheck.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8022582
+ * @summary Relax response flags checking in sun.security.krb5.KrbKdcRep.check.
+ * @compile -XDignore.symbol.file ForwardableCheck.java
+ * @run main/othervm ForwardableCheck
+ */
+
+import org.ietf.jgss.GSSException;
+import sun.security.jgss.GSSUtil;
+
+import java.util.Arrays;
+
+public class ForwardableCheck {
+
+    public static void main(String[] args) throws Exception {
+        OneKDC kdc = new OneKDC(null);
+        kdc.writeJAASConf();
+
+        // USER can impersonate someone else
+        kdc.setOption(KDC.Option.ALLOW_S4U2SELF,
+                Arrays.asList(OneKDC.USER + "@" + OneKDC.REALM));
+        // USER2 is sensitive
+        kdc.setOption(KDC.Option.SENSITIVE_ACCOUNTS,
+                Arrays.asList(OneKDC.USER2 + "@" + OneKDC.REALM));
+
+        Context c;
+
+        // USER2 is sensitive but it's still able to get a normal ticket
+        c = Context.fromUserPass(OneKDC.USER2, OneKDC.PASS2, false);
+
+        // ... and connect to another account
+        c.startAsClient(OneKDC.USER, GSSUtil.GSS_KRB5_MECH_OID);
+        c.x().requestCredDeleg(true);
+        c.x().requestMutualAuth(false);
+
+        c.take(new byte[0]);
+
+        if (!c.x().isEstablished()) {
+            throw new Exception("Context should have been established");
+        }
+
+        // ... but will not be able to delegate itself
+        if (c.x().getCredDelegState()) {
+            throw new Exception("Impossible");
+        }
+
+        // Although USER is allowed to impersonate other people,
+        // it cannot impersonate USER2 coz it's sensitive.
+        c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+        try {
+            c.impersonate(OneKDC.USER2);
+            throw new Exception("Should fail");
+        } catch (GSSException e) {
+            e.printStackTrace();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/Helper.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,57 @@
+/*
+ * 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.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.callback.UnsupportedCallbackException;
+
+public class Helper {
+
+    static class UserPasswordHandler implements CallbackHandler {
+
+        private final String name;
+        private final String password;
+
+        UserPasswordHandler(String name, String password) {
+            this.name = name;
+            this.password = password;
+        }
+
+        @Override
+        public void handle(Callback[] callbacks)
+                throws UnsupportedCallbackException {
+            for (Callback callback : callbacks) {
+                if (callback instanceof PasswordCallback) {
+                    ((PasswordCallback) callback).setPassword(
+                            password.toCharArray());
+                } else if (callback instanceof NameCallback) {
+                    ((NameCallback)callback).setName(name);
+                } else {
+                    throw new UnsupportedCallbackException(callback);
+                }
+            }
+        }
+    }
+}
--- a/test/sun/security/krb5/auto/KDC.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/krb5/auto/KDC.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, 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
@@ -30,6 +30,7 @@
 import java.security.SecureRandom;
 import java.util.*;
 import java.util.concurrent.*;
+
 import sun.net.spi.nameservice.NameService;
 import sun.net.spi.nameservice.NameServiceDescriptor;
 import sun.security.krb5.*;
@@ -145,9 +146,14 @@
     private List<String> conf = new ArrayList<>();
 
     private Thread thread1, thread2, thread3;
+    private volatile boolean udpConsumerReady = false;
+    private volatile boolean tcpConsumerReady = false;
+    private volatile boolean dispatcherReady = false;
     DatagramSocket u1 = null;
     ServerSocket t1 = null;
 
+    public static enum KtabMode { APPEND, EXISTING };
+
     /**
      * Option names, to be expanded forever.
      */
@@ -194,6 +200,10 @@
          * Krb5.KDC_ERR_POLICY will be send for S4U2proxy request.
          */
         ALLOW_S4U2PROXY,
+        /**
+         * Sensitive accounts can never be delegated.
+         */
+        SENSITIVE_ACCOUNTS,
     };
 
     static {
@@ -638,7 +648,7 @@
         try {
             System.out.println(realm + "> " + tgsReq.reqBody.cname +
                     " sends TGS-REQ for " +
-                    service);
+                    service + ", " + tgsReq.reqBody.kdcOptions);
             KDCReqBody body = tgsReq.reqBody;
             int[] eTypes = KDCReqBodyDotEType(body);
             int e2 = eTypes[0];     // etype for outgoing session key
@@ -714,7 +724,13 @@
             boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
             if (body.kdcOptions.get(KDCOptions.FORWARDABLE)
                     && allowForwardable) {
-                bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
+                List<String> sensitives = (List<String>)
+                        options.get(Option.SENSITIVE_ACCOUNTS);
+                if (sensitives != null && sensitives.contains(cname.toString())) {
+                    // Cannot make FORWARDABLE
+                } else {
+                    bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
+                }
             }
             if (body.kdcOptions.get(KDCOptions.FORWARDED) ||
                     etp.flags.get(Krb5.TKT_OPTS_FORWARDED)) {
@@ -819,7 +835,8 @@
                     t,
                     edata);
             System.out.println("     Return " + tgsRep.cname
-                    + " ticket for " + tgsRep.ticket.sname);
+                    + " ticket for " + tgsRep.ticket.sname + ", flags "
+                    + tFlags);
 
             DerOutputStream out = new DerOutputStream();
             out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
@@ -865,7 +882,7 @@
         try {
             System.out.println(realm + "> " + asReq.reqBody.cname +
                     " sends AS-REQ for " +
-                    service);
+                    service + ", " + asReq.reqBody.kdcOptions);
 
             KDCReqBody body = asReq.reqBody;
 
@@ -908,7 +925,13 @@
             //body.from
             boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
             if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) {
-                bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
+                List<String> sensitives = (List<String>)
+                        options.get(Option.SENSITIVE_ACCOUNTS);
+                if (sensitives != null && sensitives.contains(body.cname.toString())) {
+                    // Cannot make FORWARDABLE
+                } else {
+                    bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
+                }
             }
             if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
                 bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
@@ -1084,7 +1107,8 @@
                     edata);
 
             System.out.println("     Return " + asRep.cname
-                    + " ticket for " + asRep.ticket.sname);
+                    + " ticket for " + asRep.ticket.sname + ", flags "
+                    + tFlags);
 
             DerOutputStream out = new DerOutputStream();
             out.write(DerValue.createTag(DerValue.TAG_APPLICATION,
@@ -1192,6 +1216,7 @@
         // The UDP consumer
         thread1 = new Thread() {
             public void run() {
+                udpConsumerReady = true;
                 while (true) {
                     try {
                         byte[] inbuf = new byte[8192];
@@ -1212,6 +1237,7 @@
         // The TCP consumer
         thread2 = new Thread() {
             public void run() {
+                tcpConsumerReady = true;
                 while (true) {
                     try {
                         Socket socket = tcp.accept();
@@ -1234,6 +1260,7 @@
         // The dispatcher
         thread3 = new Thread() {
             public void run() {
+                dispatcherReady = true;
                 while (true) {
                     try {
                         q.take().send();
@@ -1244,6 +1271,19 @@
         };
         thread3.setDaemon(true);
         thread3.start();
+
+        // wait for the KDC is ready
+        try {
+            while (!isReady()) {
+                Thread.sleep(100);
+            }
+        } catch(InterruptedException e) {
+            throw new IOException(e);
+        }
+    }
+
+    boolean isReady() {
+        return udpConsumerReady && tcpConsumerReady && dispatcherReady;
     }
 
     public void terminate() {
@@ -1257,6 +1297,72 @@
             // OK
         }
     }
+
+    public static KDC startKDC(final String host, final String krbConfFileName,
+            final String realm, final Map<String, String> principals,
+            final String ktab, final KtabMode mode) {
+
+        KDC kdc;
+        try {
+            kdc = KDC.create(realm, host, 0, true);
+            kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE);
+            if (krbConfFileName != null) {
+                KDC.saveConfig(krbConfFileName, kdc);
+            }
+
+            // Add principals
+            if (principals != null) {
+                principals.forEach((name, password) -> {
+                    if (password == null || password.isEmpty()) {
+                        System.out.println(String.format(
+                                "KDC:add a principal '%s' with a random " +
+                                        "password", name));
+                        kdc.addPrincipalRandKey(name);
+                    } else {
+                        System.out.println(String.format(
+                                "KDC:add a principal '%s' with '%s' password",
+                                name, password));
+                        kdc.addPrincipal(name, password.toCharArray());
+                    }
+                });
+            }
+
+            // Create or append keys to existing keytab file
+            if (ktab != null) {
+                File ktabFile = new File(ktab);
+                switch(mode) {
+                    case APPEND:
+                        if (ktabFile.exists()) {
+                            System.out.println(String.format(
+                                    "KDC:append keys to an exising keytab "
+                                    + "file %s", ktab));
+                            kdc.appendKtab(ktab);
+                        } else {
+                            System.out.println(String.format(
+                                    "KDC:create a new keytab file %s", ktab));
+                            kdc.writeKtab(ktab);
+                        }
+                        break;
+                    case EXISTING:
+                        System.out.println(String.format(
+                                "KDC:use an existing keytab file %s", ktab));
+                        break;
+                    default:
+                        throw new RuntimeException(String.format(
+                                "KDC:unsupported keytab mode: %s", mode));
+                }
+            }
+
+            System.out.println(String.format(
+                    "KDC: started on %s:%s with '%s' realm",
+                    host, kdc.getPort(), realm));
+        } catch (Exception e) {
+            throw new RuntimeException("KDC: unexpected exception", e);
+        }
+
+        return kdc;
+    }
+
     /**
      * Helper class to encapsulate a job in a KDC.
      */
@@ -1304,13 +1410,20 @@
     }
 
     public static class KDCNameService implements NameServiceDescriptor {
+
+        public static String NOT_EXISTING_HOST = "not.existing.host";
+
         @Override
         public NameService createNameService() throws Exception {
             NameService ns = new NameService() {
                 @Override
                 public InetAddress[] lookupAllHostAddr(String host)
                         throws UnknownHostException {
-                    // Everything is localhost
+                    // Everything is localhost except NOT_EXISTING_HOST
+                    if (NOT_EXISTING_HOST.equals(host)) {
+                        throw new UnknownHostException("Unknown host name: "
+                                + NOT_EXISTING_HOST);
+                    }
                     return new InetAddress[]{
                         InetAddress.getByAddress(host, new byte[]{127,0,0,1})
                     };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/KrbTicket.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,146 @@
+/*
+ * 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.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.security.auth.RefreshFailedException;
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.login.LoginContext;
+
+/*
+ * @test
+ * @bug 6857795 8075299
+ * @summary Checks Kerberos ticket properties
+ * @run main/othervm KrbTicket
+ */
+public class KrbTicket {
+
+    private static final String REALM = "TEST.REALM";
+    private static final String HOST = "localhost";
+    private static final String USER = "TESTER";
+    private static final String USER_PRINCIPAL = USER + "@" + REALM;
+    private static final String PASSWORD = "password";
+    private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    private static final String KRB5_CONF_FILENAME = "krb5.conf";
+    private static final String JAAS_CONF = "jaas.conf";
+    private static final long TICKET_LIFTETIME = 5 * 60 * 1000; // 5 mins
+
+    public static void main(String[] args) throws Exception {
+        // define principals
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, PASSWORD);
+        principals.put(KRBTGT_PRINCIPAL, null);
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME);
+
+        // start a local KDC instance
+        KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null);
+        KDC.saveConfig(KRB5_CONF_FILENAME, kdc,
+                "forwardable = true", "proxiable = true");
+
+        // create JAAS config
+        Files.write(Paths.get(JAAS_CONF), Arrays.asList(
+                "Client {",
+                "    com.sun.security.auth.module.Krb5LoginModule required;",
+                "};"
+        ));
+        System.setProperty("java.security.auth.login.config", JAAS_CONF);
+        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+
+        long startTime = Instant.now().getEpochSecond() * 1000;
+
+        LoginContext lc = new LoginContext("Client",
+                new Helper.UserPasswordHandler(USER, PASSWORD));
+        lc.login();
+
+        Subject subject = lc.getSubject();
+        System.out.println("subject: " + subject);
+
+        Set creds = subject.getPrivateCredentials(
+                KerberosTicket.class);
+
+        if (creds.size() > 1) {
+            throw new RuntimeException("Multiple credintials found");
+        }
+
+        Object o = creds.iterator().next();
+        if (!(o instanceof KerberosTicket)) {
+            throw new RuntimeException("Instance of KerberosTicket expected");
+        }
+        KerberosTicket krbTkt = (KerberosTicket) o;
+
+        System.out.println("forwardable = " + krbTkt.isForwardable());
+        System.out.println("proxiable   = " + krbTkt.isProxiable());
+        System.out.println("renewable   = " + krbTkt.isRenewable());
+        System.out.println("current     = " + krbTkt.isCurrent());
+
+        if (!krbTkt.isForwardable()) {
+            throw new RuntimeException("Forwardable ticket expected");
+        }
+
+        if (!krbTkt.isProxiable()) {
+            throw new RuntimeException("Proxiable ticket expected");
+        }
+
+        if (!krbTkt.isCurrent()) {
+            throw new RuntimeException("Ticket is not current");
+        }
+
+        if (krbTkt.isRenewable()) {
+            throw new RuntimeException("Not renewable ticket expected");
+        }
+        try {
+            krbTkt.refresh();
+            throw new RuntimeException(
+                    "Expected RefreshFailedException not thrown");
+        } catch(RefreshFailedException e) {
+            System.out.println("Expected exception: " + e);
+        }
+
+        if (!checkTime(krbTkt, startTime)) {
+            throw new RuntimeException("Wrong ticket life time");
+        }
+
+        krbTkt.destroy();
+        if (!krbTkt.isDestroyed()) {
+            throw new RuntimeException("Ticket not destroyed");
+        }
+
+        System.out.println("Test passed");
+    }
+
+    private static boolean checkTime(KerberosTicket krbTkt, long startTime) {
+        long ticketEndTime = krbTkt.getEndTime().getTime();
+        long roughLifeTime = ticketEndTime - startTime;
+        System.out.println("start time            = " + startTime);
+        System.out.println("end time              = " + ticketEndTime);
+        System.out.println("rough life time       = " + roughLifeTime);
+        return roughLifeTime >= TICKET_LIFTETIME;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/RefreshKrb5Config.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,100 @@
+/*
+ * 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.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 4745056 8075297
+ * @summary Checks if refreshKrb5Config is set to true for Krb5LoginModule,
+ *          then configuration will be refreshed before login() method is called
+ * @run main/othervm RefreshKrb5Config
+ */
+public class RefreshKrb5Config {
+
+    static final String TEST_SRC = System.getProperty("test.src", ".");
+    static final String HOST = "localhost";
+    static final String NOT_EXISTING_HOST = "not.existing.host";
+    static final String REALM = "TEST.REALM";
+    static final String USER = "USER";
+    static final String USER_PRINCIPAL = USER + "@" + REALM;
+    static final String USER_PASSWORD = "password";
+    static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    static final String KRB5_CONF_FILENAME = "krb5.conf";
+
+    public static void main(String[] args) throws LoginException, IOException {
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, USER_PASSWORD);
+        principals.put(KRBTGT_PRINCIPAL, null);
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME);
+
+        // start a local KDC, and save krb5 config
+        KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null);
+        KDC.saveConfig(KRB5_CONF_FILENAME, kdc, "max_retries = 1");
+
+        System.setProperty("java.security.auth.login.config",
+                TEST_SRC + File.separator + "refreshKrb5Config.jaas");
+
+        CallbackHandler handler = new Helper.UserPasswordHandler(
+                USER, USER_PASSWORD);
+
+        // set incorrect KDC
+        System.out.println("java.security.krb5.kdc = " + NOT_EXISTING_HOST);
+        System.setProperty("java.security.krb5.kdc", NOT_EXISTING_HOST);
+        System.out.println("java.security.krb5.realm = " + REALM);
+        System.setProperty("java.security.krb5.realm", REALM);
+        try {
+            new LoginContext("Refreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // reset properties
+        System.out.println("Reset java.security.krb5.kdc");
+        System.clearProperty("java.security.krb5.kdc");
+        System.out.println("Reset java.security.krb5.realm");
+        System.clearProperty("java.security.krb5.realm");
+
+        // login with not-refreshable config
+        try {
+            new LoginContext("NotRefreshable", handler).login();
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (LoginException le) {
+            System.out.println("Expected login failure: " + le);
+        }
+
+        // login with refreshable config
+        new LoginContext("Refreshable", handler).login();
+
+        System.out.println("Test passed");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/UnboundSSL.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,136 @@
+/*
+ * 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.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedActionException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 8025123
+ * @summary Checks if an unbound server can handle connections
+ *          only for allowed service principals
+ * @run main/othervm/policy=unbound.ssl.policy UnboundSSL
+ *                              unbound.ssl.jaas.conf server_star
+ * @run main/othervm/policy=unbound.ssl.policy UnboundSSL
+ *                              unbound.ssl.jaas.conf server_multiple_principals
+ */
+public class UnboundSSL {
+
+    public static void main(String[] args) throws IOException,
+            NoSuchAlgorithmException,LoginException, PrivilegedActionException,
+            InterruptedException {
+        UnboundSSL test = new UnboundSSL();
+        test.start(args[0], args[1]);
+    }
+
+    private void start(String jaacConfigFile, String serverJaasConfig)
+            throws IOException, NoSuchAlgorithmException,LoginException,
+            PrivilegedActionException, InterruptedException {
+
+        // define principals
+        String service1host = "service1." + UnboundSSLUtils.HOST;
+        String service2host = "service2." + UnboundSSLUtils.HOST;
+        String service3host = "service3." + UnboundSSLUtils.HOST;
+        String service1Principal = "host/" + service1host + "@"
+                + UnboundSSLUtils.REALM;
+        String service2Principal = "host/" + service2host + "@"
+                + UnboundSSLUtils.REALM;
+        String service3Principal = "host/" + service3host + "@"
+                + UnboundSSLUtils.REALM;
+
+        Map<String, String> principals = new HashMap<>();
+        principals.put(UnboundSSLUtils.USER_PRINCIPAL,
+                UnboundSSLUtils.USER_PASSWORD);
+        principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, null);
+        principals.put(service1Principal, null);
+        principals.put(service2Principal, null);
+        principals.put(service3Principal, null);
+
+        System.setProperty("java.security.krb5.conf",
+               UnboundSSLUtils.KRB5_CONF_FILENAME);
+
+        // start a local KDC instance
+        KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME,
+                UnboundSSLUtils.REALM, principals,
+                UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND);
+
+        System.setProperty("java.security.auth.login.config",
+                UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile);
+        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+
+        try (final SSLEchoServer server = SSLEchoServer.init(
+                UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) {
+
+            // start a server instance
+            UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig);
+
+            // wait for the server is ready
+            while (!server.isReady()) {
+                Thread.sleep(UnboundSSLUtils.DELAY);
+            }
+
+            int port = server.getPort();
+
+            // run clients
+
+            // the server should have a permission to handle a request
+            // with this service principal (there should be an appropriate
+            // javax.security.auth.kerberos.ServicePermission in policy file)
+            System.out.println("Connect: SNI hostname = " + service1host
+                    + ", successful connection is expected");
+            SSLClient.init(UnboundSSLUtils.HOST, port,
+                    UnboundSSLUtils.TLS_KRB5_FILTER, service1host).connect();
+
+            // the server should NOT have a permission to handle a request
+            // with this service principal (there should be an appropriate
+            // javax.security.auth.kerberos.ServicePermission in policy file)
+            // handshake failures is expected
+            System.out.println("Connect: SNI hostname = " + service2host
+                    + ", connection failure is expected");
+            try {
+                SSLClient.init(UnboundSSLUtils.HOST, port,
+                        UnboundSSLUtils.TLS_KRB5_FILTER, service2host)
+                            .connect();
+                throw new RuntimeException("Test failed: "
+                        + "expected IOException not thrown");
+            } catch (IOException e) {
+                System.out.println("Expected exception: " + e);
+            }
+
+            // the server should have a permission to handle a request
+            // with this service principal (there should be an appropriate
+            // javax.security.auth.kerberos.ServicePermission in policy file)
+            System.out.println("Connect: SNI hostname = " + service3host
+                    + ", successful connection is expected");
+            SSLClient.init(UnboundSSLUtils.HOST, port,
+                    UnboundSSLUtils.TLS_KRB5_FILTER, service3host).connect();
+        }
+
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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.
+ */
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedActionException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 8025123
+ * @summary Checks if an unbound server pick up a correct key from keytab
+ * @run main/othervm UnboundSSLMultipleKeys
+ *                              unbound.ssl.jaas.conf server_star
+ * @run main/othervm UnboundSSLMultipleKeys
+ *                              unbound.ssl.jaas.conf server_multiple_principals
+ */
+public class UnboundSSLMultipleKeys {
+
+    public static void main(String[] args)
+            throws IOException, NoSuchAlgorithmException, LoginException,
+            PrivilegedActionException, InterruptedException {
+        UnboundSSLMultipleKeys test = new UnboundSSLMultipleKeys();
+        test.start(args[0], args[1]);
+    }
+
+    private void start(String jaacConfigFile, String serverJaasConfig)
+            throws IOException, NoSuchAlgorithmException, LoginException,
+            PrivilegedActionException, InterruptedException {
+
+        // define service principals
+        String service1host = "service1." + UnboundSSLUtils.HOST;
+        String service2host = "service2." + UnboundSSLUtils.HOST;
+        String service3host = "service3." + UnboundSSLUtils.HOST;
+        String service1Principal = "host/" + service1host + "@"
+                + UnboundSSLUtils.REALM;
+        String service2Principal = "host/" + service2host + "@"
+                + UnboundSSLUtils.REALM;
+        String service3Principal = "host/" + service3host + "@"
+                + UnboundSSLUtils.REALM;
+
+        Map<String, String> principals = new HashMap<>();
+        principals.put(UnboundSSLUtils.USER_PRINCIPAL,
+                UnboundSSLUtils.USER_PASSWORD);
+        principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, "pass");
+        principals.put(service1Principal, "pass0");
+        principals.put(service1Principal, "pass1");
+        principals.put(service1Principal, "pass2");
+        principals.put(service2Principal, "pass");
+        principals.put(service3Principal, "pass");
+
+        System.setProperty("java.security.krb5.conf",
+                UnboundSSLUtils.KRB5_CONF_FILENAME);
+
+        /*
+         * Start a local KDC instance
+         *
+         * Keytab file contains 3 keys (with different KVNO) for service1
+         * principal, but password for only one key is the same with the record
+         * for service1 principal in KDC.
+         */
+        KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME,
+                UnboundSSLUtils.REALM, principals,
+                UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND);
+
+        System.setProperty("java.security.auth.login.config",
+                UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile);
+        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+
+        // start an SSL server instance
+        try (SSLEchoServer server = SSLEchoServer.init(
+                UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) {
+
+            UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig);
+
+            //  wait for the server is ready
+            while (!server.isReady()) {
+                Thread.sleep(UnboundSSLUtils.DELAY);
+            }
+
+            // run a client
+            System.out.println("Successful connection is expected");
+            SSLClient.init(UnboundSSLUtils.HOST, server.getPort(),
+                    UnboundSSLUtils.TLS_KRB5_FILTER, service1host).connect();
+        }
+
+        System.out.println("Test passed");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,120 @@
+/*
+ * 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.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedActionException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.security.auth.login.LoginException;
+
+/*
+ * @test
+ * @bug 8025123
+ * @summary Checks if an unbound server uses a service principal
+ *          from sun.security.krb5.principal system property if specified
+ * @run main/othervm UnboundSSLPrincipalProperty
+ *                              unbound.ssl.jaas.conf server_star
+ * @run main/othervm UnboundSSLPrincipalProperty
+ *                              unbound.ssl.jaas.conf server_multiple_principals
+ */
+public class UnboundSSLPrincipalProperty {
+
+    public static void main(String[] args) throws IOException,
+            NoSuchAlgorithmException,LoginException, PrivilegedActionException,
+            InterruptedException {
+        UnboundSSLPrincipalProperty test = new UnboundSSLPrincipalProperty();
+        test.start(args[0], args[1]);
+    }
+
+    public void start(String jaacConfigFile, String serverJaasConfig)
+            throws IOException, NoSuchAlgorithmException,LoginException,
+            PrivilegedActionException, InterruptedException {
+
+        // define principals
+        String service1host = "service1." + UnboundSSLUtils.HOST;
+        String service3host = "service3." + UnboundSSLUtils.HOST;
+        String service1Principal = "host/" + service1host + "@"
+                + UnboundSSLUtils.REALM;
+        String service3Principal = "host/" + service3host
+                + "@" + UnboundSSLUtils.REALM;
+
+        Map<String, String> principals = new HashMap<>();
+        principals.put(UnboundSSLUtils.USER_PRINCIPAL,
+                UnboundSSLUtils.USER_PASSWORD);
+        principals.put(UnboundSSLUtils.KRBTGT_PRINCIPAL, null);
+        principals.put(service1Principal, null);
+        principals.put(service3Principal, null);
+
+        System.setProperty("java.security.krb5.conf",
+                UnboundSSLUtils.KRB5_CONF_FILENAME);
+
+        // start a local KDC instance
+        KDC.startKDC(UnboundSSLUtils.HOST, UnboundSSLUtils.KRB5_CONF_FILENAME,
+                UnboundSSLUtils.REALM, principals,
+                UnboundSSLUtils.KTAB_FILENAME, KDC.KtabMode.APPEND);
+
+        System.setProperty("java.security.auth.login.config",
+                UnboundSSLUtils.TEST_SRC + UnboundSSLUtils.FS + jaacConfigFile);
+        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
+
+        // start an SSL server instance
+        try (final SSLEchoServer server = SSLEchoServer.init(
+                UnboundSSLUtils.TLS_KRB5_FILTER, UnboundSSLUtils.SNI_PATTERN)) {
+
+            // specify a service principal for the server
+            System.setProperty("sun.security.krb5.principal",
+                    service3Principal);
+
+            UnboundSSLUtils.startServerWithJaas(server, serverJaasConfig);
+
+            // wait for the server is ready
+            while (!server.isReady()) {
+                Thread.sleep(UnboundSSLUtils.DELAY);
+            }
+
+            int port = server.getPort();
+
+            // connetion failure is expected
+            // since service3 principal was specified to use by the server
+            System.out.println("Connect: SNI hostname = " + service1host
+                    + ", connection failure is expected");
+            try {
+                SSLClient.init(UnboundSSLUtils.HOST, port,
+                        UnboundSSLUtils.TLS_KRB5_FILTER, service1host)
+                            .connect();
+                throw new RuntimeException("Test failed: "
+                        + "expected IOException not thrown");
+            } catch (IOException e) {
+                System.out.println("Expected exception: " + e);
+            }
+
+            System.out.println("Connect: SNI hostname = " + service3host
+                    + ", successful connection is expected");
+            SSLClient.init(UnboundSSLUtils.HOST, port,
+                    UnboundSSLUtils.TLS_KRB5_FILTER, service3host).connect();
+        }
+
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/UnboundSSLUtils.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,292 @@
+/*
+ * 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.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIMatcher;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+/*
+ * Helper class for unbound krb5 tests.
+ */
+class UnboundSSLUtils {
+
+    static final String KTAB_FILENAME = "krb5.keytab.data";
+    static final String HOST = "localhost";
+    static final String REALM = "TEST.REALM";
+    static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    static final String TEST_SRC = System.getProperty("test.src", ".");
+    static final String TLS_KRB5_FILTER = "TLS_KRB5";
+    static final String USER = "USER";
+    static final String USER_PASSWORD = "password";
+    static final String FS = System.getProperty("file.separator");
+    static final String SNI_PATTERN = ".*";
+    static final String USER_PRINCIPAL = USER + "@" + REALM;
+    static final String KRB5_CONF_FILENAME = "krb5.conf";
+    static final int DELAY = 1000;
+
+   static String[] filterStringArray(String[] src, String filter) {
+        return Arrays.stream(src).filter((item) -> item.startsWith(filter))
+                .toArray(size -> new String[size]);
+    }
+
+    /*
+     * The method does JAAS login,
+     * and runs an SSL server in the JAAS context.
+     */
+    static void startServerWithJaas(final SSLEchoServer server,
+            String config) throws LoginException, PrivilegedActionException {
+        LoginContext context = new LoginContext(config);
+        context.login();
+        System.out.println("Server: successful authentication");
+        Subject.doAs(context.getSubject(),
+                (PrivilegedExceptionAction<Object>) () -> {
+            SSLEchoServer.startServer(server);
+            return null;
+        });
+    }
+
+}
+
+class SSLClient {
+
+    private final static byte[][] arrays = {
+        new byte[] {-1, 0, 2},
+        new byte[] {}
+    };
+
+    private final SSLSocket socket;
+
+    private SSLClient(SSLSocket socket) {
+        this.socket = socket;
+    }
+
+    void connect() throws IOException {
+        System.out.println("Client: connect to server");
+        try (BufferedInputStream bis = new BufferedInputStream(
+                        socket.getInputStream());
+                BufferedOutputStream bos = new BufferedOutputStream(
+                        socket.getOutputStream())) {
+
+            for (byte[] bytes : arrays) {
+                System.out.println("Client: send byte array: "
+                        + Arrays.toString(bytes));
+
+                bos.write(bytes);
+                bos.flush();
+
+                byte[] recieved = new byte[bytes.length];
+                int read = bis.read(recieved, 0, bytes.length);
+                if (read < 0) {
+                    throw new IOException("Client: couldn't read a response");
+                }
+
+                System.out.println("Client: recieved byte array: "
+                        + Arrays.toString(recieved));
+
+                if (!Arrays.equals(bytes, recieved)) {
+                    throw new IOException("Client: sent byte array "
+                                + "is not equal with recieved byte array");
+                }
+            }
+            socket.getSession().invalidate();
+        } finally {
+            if (!socket.isClosed()) {
+                socket.close();
+            }
+        }
+    }
+
+    static SSLClient init(String host, int port, String cipherSuiteFilter,
+            String sniHostName) throws NoSuchAlgorithmException, IOException {
+        SSLContext sslContext = SSLContext.getDefault();
+        SSLSocketFactory ssf = (SSLSocketFactory) sslContext.getSocketFactory();
+        SSLSocket socket = (SSLSocket) ssf.createSocket(host, port);
+        SSLParameters params = new SSLParameters();
+
+        if (cipherSuiteFilter != null) {
+            String[] cipherSuites = UnboundSSLUtils.filterStringArray(
+                    ssf.getSupportedCipherSuites(), cipherSuiteFilter);
+            System.out.println("Client: enabled cipher suites: "
+                    + Arrays.toString(cipherSuites));
+            params.setCipherSuites(cipherSuites);
+        }
+
+        if (sniHostName != null) {
+            System.out.println("Client: set SNI hostname: " + sniHostName);
+            SNIHostName serverName = new SNIHostName(sniHostName);
+            List<SNIServerName> serverNames = new ArrayList<>();
+            serverNames.add(serverName);
+            params.setServerNames(serverNames);
+        }
+
+        socket.setSSLParameters(params);
+
+        return new SSLClient(socket);
+    }
+
+}
+
+class SSLEchoServer implements Runnable, AutoCloseable {
+
+    private final SSLServerSocket ssocket;
+    private volatile boolean stopped = false;
+    private volatile boolean ready = false;
+
+    /*
+     * Starts the server in a separate thread.
+     */
+    static void startServer(SSLEchoServer server) {
+        Thread serverThread = new Thread(server, "SSL echo server thread");
+        serverThread.setDaemon(true);
+        serverThread.start();
+    }
+
+    private SSLEchoServer(SSLServerSocket ssocket) {
+        this.ssocket = ssocket;
+    }
+
+    /*
+     * Main server loop.
+     */
+    @Override
+    public void run() {
+        System.out.println("Server: started");
+        while (!stopped) {
+            ready = true;
+            try (SSLSocket socket = (SSLSocket) ssocket.accept()) {
+                System.out.println("Server: client connection accepted");
+                try (
+                    BufferedInputStream bis = new BufferedInputStream(
+                            socket.getInputStream());
+                    BufferedOutputStream bos = new BufferedOutputStream(
+                            socket.getOutputStream())
+                ) {
+                    byte[] buffer = new byte[1024];
+                    int read;
+                    while ((read = bis.read(buffer)) > 0) {
+                        bos.write(buffer, 0, read);
+                        System.out.println("Server: recieved " + read
+                                + " bytes: "
+                                + Arrays.toString(Arrays.copyOf(buffer, read)));
+                        bos.flush();
+                    }
+                }
+            } catch (IOException e) {
+                if (stopped) {
+                    // stopped == true means that stop() method was called,
+                    // so just ignore the exception, and finish the loop
+                    break;
+                }
+                System.out.println("Server: couldn't accept client connection: "
+                        + e);
+            }
+        }
+        System.out.println("Server: finished");
+    }
+
+    boolean isReady() {
+        return ready;
+    }
+
+    void stop() {
+        stopped = true;
+        ready = false;
+
+        // close the server socket to interupt accept() method
+        try {
+            if (!ssocket.isClosed()) {
+                ssocket.close();
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("Unexpected exception: " + e);
+        }
+    }
+
+    @Override
+    public void close() {
+        stop();
+    }
+
+    int getPort() {
+        return ssocket.getLocalPort();
+    }
+
+    /*
+     * Creates server instance.
+     *
+     * @param cipherSuiteFilter Filter for enabled cipher suites
+     * @param sniMatcherPattern Pattern for SNI server hame
+     */
+    static SSLEchoServer init(String cipherSuiteFilter,
+            String sniPattern) throws NoSuchAlgorithmException, IOException {
+        SSLContext context = SSLContext.getDefault();
+        SSLServerSocketFactory ssf =
+                (SSLServerSocketFactory) context.getServerSocketFactory();
+        SSLServerSocket ssocket =
+                (SSLServerSocket) ssf.createServerSocket(0);
+
+        // specify enabled cipher suites
+        if (cipherSuiteFilter != null) {
+            String[] ciphersuites = UnboundSSLUtils.filterStringArray(
+                    ssf.getSupportedCipherSuites(), cipherSuiteFilter);
+            System.out.println("Server: enabled cipher suites: "
+                    + Arrays.toString(ciphersuites));
+            ssocket.setEnabledCipherSuites(ciphersuites);
+        }
+
+        // specify SNI matcher pattern
+        if (sniPattern != null) {
+            System.out.println("Server: set SNI matcher: " + sniPattern);
+            SNIMatcher matcher = SNIHostName.createSNIMatcher(sniPattern);
+            List<SNIMatcher> matchers = new ArrayList<>();
+            matchers.add(matcher);
+            SSLParameters params = ssocket.getSSLParameters();
+            params.setSNIMatchers(matchers);
+            ssocket.setSSLParameters(params);
+        }
+
+        return new SSLEchoServer(ssocket);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,155 @@
+/*
+ * 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 8075301
+ * @library /sun/security/krb5/auto
+ * @summary New test for sun.security.krb5.principal system property.
+ * The principal can set using the system property sun.security.krb5.principal.
+ * This property is checked during login. If this property is not set,
+ * then the principal name from the configuration is used.
+ * @run main/othervm/java.security.policy=principalSystemPropTest.policy
+ * PrincipalSystemPropTest
+ */
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.login.LoginContext;
+import com.sun.security.auth.callback.TextCallbackHandler;
+
+public class PrincipalSystemPropTest {
+
+    private static final boolean PASS = Boolean.TRUE;
+    private static final boolean FAIL = Boolean.FALSE;
+    private static final String VALID_PRINCIPAL_JAAS_ENTRY =
+            "ValidPrincipalSystemPropTest";
+    private static final String INVALID_PRINCIPAL_JAAS_ENTRY =
+            "InvalidPrincipalSystemPropTest";
+    private static final String NO_PRINCIPAL_JAAS_ENTRY =
+            "NoPrincipalSystemPropTest";
+    private static final String SAME_PRINCIPAL_JAAS_ENTRY =
+            "SelfPrincipalSystemPropTest";
+    private static final String HOST = "localhost";
+    private static final String KTAB_FILENAME = "krb5.keytab.data";
+    private static final String REALM = "TEST.REALM";
+    private static final String TEST_SRC = System.getProperty("test.src", ".");
+    private static final String USER = "USER";
+    private static final String AVAILABLE_USER = "AVAILABLE";
+    private static final String USER_PASSWORD = "password";
+    private static final String FS = System.getProperty("file.separator");
+    private static final String KRB5_CONF_FILENAME = "krb5.conf";
+    private static final String JAAS_CONF_FILENAME = "jaas.conf";
+    private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    private static final String USER_PRINCIPAL = USER + "@" + REALM;
+    private static final String AVAILABLE_USER_PRINCIPAL =
+            AVAILABLE_USER + "@" + REALM;
+
+    public static void main(String[] args) throws Exception {
+
+        setupTest();
+
+        // Expected result, Jaas Config Entry, Login Principal Expected,
+        // Principal passed through System property
+        runTest(PASS, VALID_PRINCIPAL_JAAS_ENTRY,
+                USER_PRINCIPAL, "USER@TEST.REALM");
+        runTest(PASS, VALID_PRINCIPAL_JAAS_ENTRY,
+                AVAILABLE_USER_PRINCIPAL,  null);
+        runTest(PASS, INVALID_PRINCIPAL_JAAS_ENTRY,
+                USER_PRINCIPAL, "USER@TEST.REALM");
+        runTest(FAIL, INVALID_PRINCIPAL_JAAS_ENTRY, null,  null);
+        runTest(PASS, NO_PRINCIPAL_JAAS_ENTRY,
+                USER_PRINCIPAL, "USER@TEST.REALM");
+        runTest(FAIL, NO_PRINCIPAL_JAAS_ENTRY, null, null);
+        runTest(PASS, SAME_PRINCIPAL_JAAS_ENTRY,
+                USER_PRINCIPAL, "USER@TEST.REALM");
+
+    }
+
+    private static void setupTest() {
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME);
+        System.setProperty("java.security.auth.login.config",
+                TEST_SRC + FS + JAAS_CONF_FILENAME);
+
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, USER_PASSWORD);
+        principals.put(AVAILABLE_USER_PRINCIPAL, USER_PASSWORD);
+        principals.put(KRBTGT_PRINCIPAL, null);
+        KDC.startKDC(HOST, KRB5_CONF_FILENAME, REALM, principals,
+                KTAB_FILENAME, KDC.KtabMode.APPEND);
+
+    }
+
+    private static void runTest(boolean expected, String jaasConfigEntry,
+            String expectedLoginUser, String loginUserBySysProp) {
+
+        if(loginUserBySysProp != null) {
+            System.setProperty("sun.security.krb5.principal",
+                    loginUserBySysProp);
+        } else {
+            System.clearProperty("sun.security.krb5.principal");
+        }
+
+        try {
+            LoginContext lc = new LoginContext(jaasConfigEntry,
+                    new TextCallbackHandler());
+            lc.login();
+            System.out.println(String.format(
+                    "Authentication completed with Subject '%s' ",
+                    lc.getSubject()));
+
+            if (!expected) {
+                throw new RuntimeException(
+                        "TEST FAILED - JAAS login success isn't expected");
+            }
+            if(expectedLoginUser != null && !lc.getSubject().getPrincipals()
+                    .stream().map(p -> p.getName()).filter(
+                            expectedLoginUser :: equals).findFirst()
+                            .isPresent()) {
+                throw new RuntimeException(String.format(
+                        "TEST FAILED - Login principal is not matched "
+                        + "to expected principal '%s'.", expectedLoginUser));
+            }
+            System.out.println(
+                    "TEST PASSED - JAAS login success is expected.");
+        } catch (LoginException ie) {
+            System.out.println(String.format(
+                    "Authentication failed with exception: %s",
+                    ie.getMessage()));
+            if (expected) {
+                System.out.println(
+                        "TEST FAILED - JAAS login failure isn't expected");
+                throw new RuntimeException(ie);
+            }
+            System.out.println(
+                    "TEST PASSED - JAAS login failure is expected.");
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/principalProperty/jaas.conf	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,34 @@
+NoPrincipalSystemPropTest {
+	com.sun.security.auth.module.Krb5LoginModule required 
+	useKeyTab = true
+  	keyTab = krb5.keytab.data
+  	doNotPrompt =true
+  	debug=true;
+};
+
+InvalidPrincipalSystemPropTest {
+  	com.sun.security.auth.module.Krb5LoginModule required 
+  	principal="UNAVAILABLE@TEST.REALM"
+  	useKeyTab = true
+  	keyTab = krb5.keytab.data
+  	doNotPrompt =true
+  	debug=true;
+};
+
+ValidPrincipalSystemPropTest {
+  	com.sun.security.auth.module.Krb5LoginModule required 
+  	principal="AVAILABLE@TEST.REALM"
+  	useKeyTab = true
+  	keyTab = krb5.keytab.data
+  	doNotPrompt =true
+  	debug=true;
+};
+
+SelfPrincipalSystemPropTest {
+  	com.sun.security.auth.module.Krb5LoginModule required 
+  	principal="USER@TEST.REALM"
+  	useKeyTab = true
+  	keyTab = krb5.keytab.data
+  	doNotPrompt =true
+  	debug=true;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,21 @@
+grant {
+  	permission javax.security.auth.AuthPermission
+    	"createLoginContext.ValidPrincipalSystemPropTest";
+    	permission javax.security.auth.AuthPermission
+    	"createLoginContext.InvalidPrincipalSystemPropTest";
+    	permission javax.security.auth.AuthPermission
+    	"createLoginContext.NoPrincipalSystemPropTest";
+    	permission javax.security.auth.AuthPermission
+    	"createLoginContext.SelfPrincipalSystemPropTest";
+  	permission javax.security.auth.AuthPermission "doAs";
+  	permission javax.security.auth.AuthPermission "modifyPrincipals";
+  	permission javax.security.auth.AuthPermission "getSubject";
+  	permission java.util.PropertyPermission "*", "read,write";
+  	permission java.io.FilePermission "*", "read,write,delete";
+  	permission java.lang.RuntimePermission "accessDeclaredMembers";
+  	permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+  	permission java.lang.RuntimePermission "accessClassInPackage.*";
+  	permission java.net.SocketPermission "*:*", 
+  		"listen,resolve,accept,connect";
+}; 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/refreshKrb5Config.jaas	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,11 @@
+Refreshable {
+    com.sun.security.auth.module.Krb5LoginModule required
+        useTicketCache=false
+        refreshKrb5Config=true;
+};
+
+NotRefreshable {
+    com.sun.security.auth.module.Krb5LoginModule required
+        useTicketCache=false
+        refreshKrb5Config=false;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,188 @@
+/*
+ * 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.net.PortUnreachableException;
+import java.util.HashMap;
+import java.util.Map;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.OutputAnalyzer;
+
+/*
+ * @test
+ * @bug 6857795 8075299
+ * @summary Checks if kinit uses both krb5 conf file and system properties
+ * @requires os.family == "windows"
+ * @library /lib/testlibrary
+ * @library /sun/security/krb5/auto
+ * @run main/othervm KinitConfPlusProps
+ */
+public class KinitConfPlusProps {
+
+    private static final String KINIT = System.getProperty("java.home")
+            + File.separator + "bin" + File.separator + "kinit";
+    private static final String KLIST = System.getProperty("java.home")
+            + File.separator + "bin" + File.separator + "klist";
+    private static final String REALM = "REALM";
+    private static final String ANOTHER_REALM = "ANOTHER.REALM";
+    private static final String HOST = "localhost";
+    private static final String CC_FILENAME = "krb5cc_test";
+    private static final String USER = "TESTER";
+    private static final String USER_PRINCIPAL = USER + "@" + REALM;
+    private static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM;
+    private static final String KEYTAB_FILE = "test.keytab";
+    private static final String KRB5_CONF_FILENAME = "krb5.conf";
+
+    public static void main(String[] args) throws Exception {
+        // define principals
+        Map<String, String> principals = new HashMap<>();
+        principals.put(USER_PRINCIPAL, null);
+        principals.put(KRBTGT_PRINCIPAL, null);
+
+        System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME);
+
+        // start a local KDC instance
+        KDC kdc = KDC.startKDC(HOST, null, REALM, principals, KEYTAB_FILE,
+                KDC.KtabMode.APPEND);
+        KDC.saveConfig(KRB5_CONF_FILENAME, kdc,
+                "forwardable = true", "proxiable = true");
+
+        boolean success = true;
+
+        /*
+         * kinit should fail since java.security.krb5.kdc
+         * and java.security.krb5.realm properties override correct values
+         * in krb5 conf file
+         */
+        String[] command = {KINIT, "-k",
+            "-J-Djava.security.krb5.realm=" + REALM,
+            "-J-Djava.security.krb5.kdc=" + HOST,   // without port
+            "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME,
+            "-t", KEYTAB_FILE,
+            "-c", CC_FILENAME,
+            USER
+        };
+
+        try {
+            OutputAnalyzer out = ProcessTools.executeCommand(command);
+            out.shouldHaveExitValue(-1);
+            out.shouldContain(PortUnreachableException.class.getName());
+        } catch(Throwable e) {
+            System.out.println("Unexpected exception: " + e);
+            e.printStackTrace(System.out);
+            success = false;
+        }
+
+        /*
+         * kinit should succeed
+         * since realm should be picked up from principal name
+         */
+        command = new String[] {KINIT, "-k",
+            "-J-Djava.security.krb5.realm=" + ANOTHER_REALM,
+            "-J-Djava.security.krb5.kdc=" + HOST,
+            "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME,
+            "-t", KEYTAB_FILE,
+            "-c", CC_FILENAME,
+            USER_PRINCIPAL
+        };
+
+        try {
+            OutputAnalyzer out = ProcessTools.executeCommand(command);
+            out.shouldHaveExitValue(0);
+            out.shouldContain(CC_FILENAME);
+        } catch(Throwable e) {
+            System.out.println("Unexpected exception: " + e);
+            e.printStackTrace(System.out);
+            success = false;
+        }
+
+        success &= checkTicketFlags();
+
+        /*
+         * kinit should succeed
+         * since realm should be picked up from principal name,
+         * and other data should come from krb5 conf file
+         */
+        command = new String[] {KINIT, "-k",
+            "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME,
+            "-t", KEYTAB_FILE,
+            "-c", CC_FILENAME,
+            USER_PRINCIPAL
+        };
+
+        try {
+            OutputAnalyzer out = ProcessTools.executeCommand(command);
+            out.shouldHaveExitValue(0);
+            out.shouldContain(CC_FILENAME);
+        } catch(Throwable e) {
+            System.out.println("Unexpected exception: " + e);
+            e.printStackTrace(System.out);
+            success = false;
+        }
+
+        success &= checkTicketFlags();
+
+        // kinit should succeed even if a principal name doesn't have realm
+        command = new String[] {KINIT, "-k",
+            "-J-Djava.security.krb5.conf=" + KRB5_CONF_FILENAME,
+            "-t", KEYTAB_FILE,
+            "-c", CC_FILENAME,
+            USER
+        };
+
+        try {
+            OutputAnalyzer out = ProcessTools.executeCommand(command);
+            out.shouldHaveExitValue(0);
+            out.shouldContain(CC_FILENAME);
+        } catch(Throwable e) {
+            System.out.println("Unexpected exception: " + e);
+            e.printStackTrace(System.out);
+            success = false;
+        }
+
+        success &= checkTicketFlags();
+
+        if (!success) {
+            throw new RuntimeException("At least one test case failed");
+        }
+        System.out.println("Test passed");
+    }
+
+    // check if a ticket has forwardable and proxiable flags
+    private static boolean checkTicketFlags() {
+        String[] command = new String[] {KLIST, "-f", "-c", CC_FILENAME};
+
+        try {
+            OutputAnalyzer out = ProcessTools.executeCommand(command);
+            out.shouldHaveExitValue(0);
+            out.shouldContain("FORWARDABLE");
+            out.shouldContain("PROXIABLE");
+        } catch(Throwable e) {
+            System.out.println("Unexpected exception: " + e);
+            e.printStackTrace(System.out);
+            return false;
+        }
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/unbound.ssl.jaas.conf	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,40 @@
+com.sun.net.ssl.client {
+    com.sun.security.auth.module.Krb5LoginModule required
+    principal="USER@TEST.REALM"
+    doNotPrompt=true
+    useKeyTab=true
+    keyTab="krb5.keytab.data";
+};
+
+server_star {
+    com.sun.security.auth.module.Krb5LoginModule required
+    principal="*"
+    isInitiator=false
+    useKeyTab=true
+    keyTab="krb5.keytab.data"
+    storeKey=true;
+};
+
+server_multiple_principals {
+    com.sun.security.auth.module.Krb5LoginModule required
+    principal="host/service1.localhost@TEST.REALM"
+    isInitiator=false
+    useKeyTab=true
+    keyTab="krb5.keytab.data"
+    storeKey=true;
+
+    com.sun.security.auth.module.Krb5LoginModule required
+    principal="host/service2.localhost@TEST.REALM"
+    isInitiator=false
+    useKeyTab=true
+    keyTab="krb5.keytab.data"
+    storeKey=true;
+
+    com.sun.security.auth.module.Krb5LoginModule required
+    principal="host/service3.localhost@TEST.REALM"
+    isInitiator=false
+    useKeyTab=true
+    keyTab="krb5.keytab.data"
+    storeKey=true;
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/auto/unbound.ssl.policy	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,29 @@
+grant {
+    permission java.util.PropertyPermission "*", "read,write";
+    permission java.net.SocketPermission "*:*", "listen,resolve,accept,connect";
+    permission java.io.FilePermission "*", "read,write,delete";
+    permission java.lang.RuntimePermission "accessDeclaredMembers";
+    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+    permission java.lang.RuntimePermission "accessClassInPackage.*";
+    permission javax.security.auth.AuthPermission "doAs";
+    permission javax.security.auth.AuthPermission "getSubject";
+    permission javax.security.auth.AuthPermission
+                    "createLoginContext.server_star";
+    permission javax.security.auth.AuthPermission
+                    "createLoginContext.server_multiple_principals";
+    permission javax.security.auth.AuthPermission "modifyPrincipals";
+    permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab java.security.Principal \"krb5.keytab.data\"", "read";
+
+    // clients have a permission to use all service principals
+    permission javax.security.auth.kerberos.ServicePermission "*", "initiate";
+
+    // server has a service permission
+    // to accept only service1 and service3 principals
+    permission javax.security.auth.kerberos.ServicePermission
+                    "host/service1.localhost@TEST.REALM", "accept";
+    permission javax.security.auth.kerberos.ServicePermission
+                    "host/service3.localhost@TEST.REALM", "accept";
+
+    // permission to use SunJCE provider
+    permission java.security.SecurityPermission "putProviderProperty.SunJCE";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/config/Semicolon.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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 8160518
+ * @summary Semicolon is not recognized as comment starting character
+ * @run main/othervm Semicolon
+ */
+
+import sun.security.krb5.Config;
+
+public class Semicolon {
+    public static void main(String[] args) throws Throwable {
+        System.setProperty("java.security.krb5.conf",
+                System.getProperty("test.src", ".") + "/comments.conf");
+        Config config = Config.getInstance();
+        config.get("section", "value");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/krb5/config/comments.conf	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,12 @@
+[section]
+
+#           comment
+ #          comment
+	 #  comment
+ 	#   comment
+;           comment
+ ;          comment
+	 ;  comment
+ 	;   comment
+
+value = true
--- a/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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,7 +22,10 @@
  */
 
 import java.io.*;
+import java.net.*;
+import java.util.*;
 import java.security.*;
+import java.security.cert.*;
 import javax.net.*;
 import javax.net.ssl.*;
 
@@ -71,22 +74,34 @@
     void doServerSide() throws Exception {
 
         // load the key store
-        KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
-        ks.load(null, null);
+        serverKS = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
+        serverKS.load(null, null);
         System.out.println("Loaded keystore: Windows-MY");
 
         // check key size
-        checkKeySize(ks);
+        checkKeySize(serverKS);
 
         // initialize the SSLContext
         KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
-        kmf.init(ks, null);
+        kmf.init(serverKS, null);
 
         TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
-        tmf.init(ks);
+        tmf.init(serverKS);
+        TrustManager[] tms = tmf.getTrustManagers();
+        if (tms == null || tms.length == 0) {
+            throw new Exception("unexpected trust manager implementation");
+        } else {
+            if (!(tms[0] instanceof X509TrustManager)) {
+                throw new Exception("unexpected trust manager" +
+                        " implementation: " +
+                        tms[0].getClass().getCanonicalName());
+            }
+        }
+        serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);
+        tms = new TrustManager[] {serverTM};
 
         SSLContext ctx = SSLContext.getInstance("TLS");
-        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+        ctx.init(kmf.getKeyManagers(), tms, null);
 
         ServerSocketFactory ssf = ctx.getServerSocketFactory();
         SSLServerSocket sslServerSocket = (SSLServerSocket)
@@ -228,6 +243,8 @@
 
     Thread clientThread = null;
     Thread serverThread = null;
+    KeyStore serverKS;
+    MyExtendedX509TM serverTM;
 
     /*
      * Primary constructor, used to drive remainder of the test.
@@ -348,5 +365,60 @@
             }
         }
     }
+
+
+    class MyExtendedX509TM extends X509ExtendedTrustManager
+            implements X509TrustManager {
+
+        X509TrustManager tm;
+
+        MyExtendedX509TM(X509TrustManager tm) {
+            this.tm = tm;
+        }
+
+        public void checkClientTrusted(X509Certificate chain[], String authType)
+                throws CertificateException {
+            tm.checkClientTrusted(chain, authType);
+        }
+
+        public void checkServerTrusted(X509Certificate chain[], String authType)
+                throws CertificateException {
+            tm.checkServerTrusted(chain, authType);
+        }
+
+        public X509Certificate[] getAcceptedIssuers() {
+            List<X509Certificate> certs = new ArrayList<>();
+            try {
+                for (X509Certificate c : tm.getAcceptedIssuers()) {
+                    if (serverKS.getCertificateAlias(c).equals(keyAlias))
+                        certs.add(c);
+                }
+            } catch (KeyStoreException kse) {
+                throw new RuntimeException(kse);
+            }
+            return certs.toArray(new X509Certificate[certs.size()]);
+        }
+
+        public void checkClientTrusted(X509Certificate[] chain, String authType,
+                Socket socket) throws CertificateException {
+            tm.checkClientTrusted(chain, authType);
+        }
+
+        public void checkServerTrusted(X509Certificate[] chain, String authType,
+                Socket socket) throws CertificateException {
+            tm.checkServerTrusted(chain, authType);
+        }
+
+        public void checkClientTrusted(X509Certificate[] chain, String authType,
+            SSLEngine engine) throws CertificateException {
+            tm.checkClientTrusted(chain, authType);
+        }
+
+        public void checkServerTrusted(X509Certificate[] chain, String authType,
+            SSLEngine engine) throws CertificateException {
+            tm.checkServerTrusted(chain, authType);
+        }
+    }
+
 }
 
--- a/test/sun/security/pkcs11/PKCS11Test.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/pkcs11/PKCS11Test.java	Thu Jan 12 06:59:38 2017 +0000
@@ -34,6 +34,8 @@
 
 public abstract class PKCS11Test {
 
+    static final String PKCS11 = "PKCS11";
+
     // directory of the test source
     static final String BASE = System.getProperty("test.src", ".");
 
@@ -568,6 +570,14 @@
         }
     }
 
+    static byte[] generateData(int length) {
+        byte data[] = new byte[length];
+        for (int i=0; i<data.length; i++) {
+            data[i] = (byte) (i % 256);
+        }
+        return data;
+    }
+
     <T> T[] concat(T[] a, T[] b) {
         if ((b == null) || (b.length == 0)) {
             return a;
--- a/test/sun/security/pkcs11/Secmod/AddPrivateKey.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/pkcs11/Secmod/AddPrivateKey.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -42,6 +42,13 @@
 // all providers.
 public class AddPrivateKey extends SecmodTest {
 
+    private static final String ALIAS1 = "entry1";
+    private static final String ALIAS2 = "entry2";
+    private static final String ALIAS3 = "entry3";
+    private static final int MAX_LINE = 85;
+    private static final int DATA_LENGTH = 4096;
+    private static final byte[] DATA = generateData(DATA_LENGTH);
+
     public static void main(String[] args) throws Exception {
         if (initSecmod() == false) {
             return;
@@ -56,7 +63,7 @@
         System.out.println();
         Security.addProvider(p);
 
-        KeyStore ks = KeyStore.getInstance("PKCS11", p);
+        KeyStore ks = KeyStore.getInstance(PKCS11, p);
         ks.load(null, password);
         for (String alias : aliases(ks)) {
             System.out.println("Deleting: " + alias);
@@ -64,25 +71,28 @@
         }
 
         KeyStore jks = KeyStore.getInstance("JKS");
-        InputStream in = new FileInputStream(new File(BASE, "keystore.jks"));
-        char[] jkspass = "passphrase".toCharArray();
-        jks.load(in, jkspass);
-        List<PrivateKeyEntry> entries = new ArrayList<PrivateKeyEntry>();
-        for (String alias : Collections.list(jks.aliases())) {
-            if (jks.entryInstanceOf(alias, PrivateKeyEntry.class)) {
-                PrivateKeyEntry entry = (PrivateKeyEntry)jks.getEntry(alias, new PasswordProtection(jkspass));
-                String algorithm = entry.getPrivateKey().getAlgorithm();
-                System.out.println("-Entry " + alias + " (" + algorithm + ")");
-                if ((supportsEC == false) && algorithm.equals("EC")) {
-                    System.out.println("EC not supported by provider, skipping");
-                    continue;
-                }
-                if ((supportsEC == false) && algorithm.equals("DSA")) {
-                    System.out.println("Provider does not appear to have CKA_NETSCAPE_DB fix, skipping");
-                    continue;
-                }
-                test(p, entry);
-            } // else ignore
+        try (InputStream in = new FileInputStream(BASE + SEP + "keystore.jks")) {
+            char[] jkspass = "passphrase".toCharArray();
+            jks.load(in, jkspass);
+            for (String alias : Collections.list(jks.aliases())) {
+                if (jks.entryInstanceOf(alias, PrivateKeyEntry.class)) {
+                    PrivateKeyEntry entry = (PrivateKeyEntry)jks.getEntry(alias,
+                            new PasswordProtection(jkspass));
+                    String algorithm = entry.getPrivateKey().getAlgorithm();
+                    System.out.printf("-Entry %s (%s)%n", alias, algorithm);
+                    if ((supportsEC == false) && algorithm.equals("EC")) {
+                        System.out.println("EC not supported by provider, "
+                                + "skipping");
+                        continue;
+                    }
+                    if ((supportsEC == false) && algorithm.equals("DSA")) {
+                        System.out.println("Provider does not appear to have "
+                                + "CKA_NETSCAPE_DB fix, skipping");
+                        continue;
+                    }
+                    test(p, entry);
+                } // else ignore
+            }
         }
         System.out.println("OK");
     }
@@ -91,10 +101,6 @@
         return Collections.list(ks.aliases());
     }
 
-    private final static String ALIAS1 = "entry1";
-    private final static String ALIAS2 = "entry2";
-    private final static String ALIAS3 = "entry3";
-
     private static void test(Provider p, PrivateKeyEntry entry) throws Exception {
         PrivateKey key = entry.getPrivateKey();
         X509Certificate[] chain = (X509Certificate[])entry.getCertificateChain();
@@ -121,11 +127,8 @@
 
         PrivateKey key2 = (PrivateKey)ks.getKey(ALIAS1, null);
         System.out.println(toString(key2));
-        X509Certificate[] chain2 = (X509Certificate[])ks.getCertificateChain(ALIAS1);
-        // NSS makes token keys always sensitive, skip this check
-//      if (key.equals(key2) == false) {
-//          throw new Exception("key mismatch");
-//      }
+        X509Certificate[] chain2 =
+                (X509Certificate[]) ks.getCertificateChain(ALIAS1);
         if (Arrays.equals(chain, chain2) == false) {
             throw new Exception("chain mismatch");
         }
@@ -153,7 +156,8 @@
 
         PrivateKey key4 = (PrivateKey)ks.getKey(ALIAS2, null);
         System.out.println(toString(key4));
-        X509Certificate[] chain4 = (X509Certificate[])ks.getCertificateChain(ALIAS2);
+        X509Certificate[] chain4 = (X509Certificate[])
+                ks.getCertificateChain(ALIAS2);
         if (Arrays.equals(chain, chain4) == false) {
             throw new Exception("chain mismatch");
         }
@@ -171,7 +175,8 @@
 
         PrivateKey key5 = (PrivateKey)ks.getKey(ALIAS3, null);
         System.out.println(toString(key5));
-        X509Certificate[] chain5 = (X509Certificate[])ks.getCertificateChain(ALIAS3);
+        X509Certificate[] chain5 = (X509Certificate[])
+                ks.getCertificateChain(ALIAS3);
         if (Arrays.equals(chain, chain5) == false) {
             throw new Exception("chain mismatch");
         }
@@ -185,24 +190,22 @@
         System.out.println("OK");
     }
 
-    private final static byte[] DATA = new byte[4096];
-
-    static {
-        Random random = new Random();
-        random.nextBytes(DATA);
-    }
-
-    private static void sign(Provider p, PrivateKey privateKey, PublicKey publicKey) throws Exception {
+    private static void sign(Provider p, PrivateKey privateKey,
+            PublicKey publicKey) throws Exception {
         String keyAlg = privateKey.getAlgorithm();
         String alg;
-        if (keyAlg.equals("RSA")) {
-            alg = "SHA1withRSA";
-        } else if (keyAlg.equals("DSA")) {
-            alg = "SHA1withDSA";
-        } else if (keyAlg.equals("EC")) {
-            alg = "SHA1withECDSA";
-        } else {
-            throw new Exception("Unknown algorithm " + keyAlg);
+        switch (keyAlg) {
+            case "RSA":
+                alg = "SHA1withRSA";
+                break;
+            case "DSA":
+                alg = "SHA1withDSA";
+                break;
+            case "EC":
+                alg = "SHA1withECDSA";
+                break;
+            default:
+                throw new Exception("Unknown algorithm " + keyAlg);
         }
         Signature s = Signature.getInstance(alg, p);
         s.initSign(privateKey);
@@ -216,8 +219,6 @@
         }
     }
 
-    private final static int MAX_LINE = 85;
-
     private static String toString(Object o) {
         String s = String.valueOf(o).split("\n")[0];
         return (s.length() <= MAX_LINE) ? s : s.substring(0, MAX_LINE);
--- a/test/sun/security/pkcs11/Secmod/AddTrustedCert.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/pkcs11/Secmod/AddTrustedCert.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -44,29 +44,47 @@
             return;
         }
 
-        InputStream in = new FileInputStream(BASE + SEP + "anchor.cer");
-        CertificateFactory factory = CertificateFactory.getInstance("X.509");
-        X509Certificate cert = (X509Certificate)factory.generateCertificate(in);
-        in.close();
-//      System.out.println(cert);
+        X509Certificate cert;
+        try (InputStream in = new FileInputStream(BASE + SEP + "anchor.cer")) {
+            CertificateFactory factory =
+                    CertificateFactory.getInstance("X.509");
+            cert = (X509Certificate)factory.generateCertificate(in);
+        }
 
         String configName = BASE + SEP + "nss.cfg";
         Provider p = getSunPKCS11(configName);
 
         System.out.println(p);
         Security.addProvider(p);
-        KeyStore ks = KeyStore.getInstance("PKCS11", p);
+        KeyStore ks = KeyStore.getInstance(PKCS11, p);
         ks.load(null, password);
-        Collection<String> aliases = new TreeSet<String>(Collections.list(ks.aliases()));
+        Collection<String> aliases = new TreeSet<>(Collections.list(
+                ks.aliases()));
         System.out.println("entries: " + aliases.size());
         System.out.println(aliases);
         int size1 = aliases.size();
 
         String alias = "anchor";
-        ks.setCertificateEntry(alias, cert);
+        if (ks.containsAlias(alias)) {
+            throw new Exception("Alias exists: " + alias);
+        }
+
         ks.setCertificateEntry(alias, cert);
+        KeyStore.Entry first = ks.getEntry(alias, null);
+        System.out.println("first entry = " + first);
+        if (!ks.entryInstanceOf(alias, TrustedCertificateEntry.class)) {
+            throw new Exception("Unexpected first entry type: " + first);
+        }
 
-        aliases = new TreeSet<String>(Collections.list(ks.aliases()));
+        ks.setCertificateEntry(alias, cert);
+        KeyStore.Entry second = ks.getEntry(alias, null);
+        System.out.println("second entry = " + second);
+        if (!ks.entryInstanceOf(alias, TrustedCertificateEntry.class)) {
+            throw new Exception("Unexpected second entry type: "
+                    + second);
+        }
+
+        aliases = new TreeSet<>(Collections.list(ks.aliases()));
         System.out.println("entries: " + aliases.size());
         System.out.println(aliases);
         int size2 = aliases.size();
@@ -79,8 +97,12 @@
             throw new Exception("KeyStore returned incorrect certificate");
         }
 
+        ks.deleteEntry(alias);
+        if (ks.containsAlias(alias)) {
+            throw new Exception("Alias still exists: " + alias);
+        }
+
         System.out.println("OK");
-
     }
 
 }
--- a/test/sun/security/pkcs11/Secmod/Crypto.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/pkcs11/Secmod/Crypto.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -30,8 +30,6 @@
  * @run main/othervm Crypto
  */
 
-import java.util.*;
-
 import java.security.*;
 
 public class Crypto extends SecmodTest {
@@ -50,9 +48,7 @@
         System.out.println(kp.getPublic());
         System.out.println(kp.getPrivate());
 
-        SecureRandom random = new SecureRandom();
-        byte[] data = new byte[2048];
-        random.nextBytes(data);
+        byte[] data = generateData(2048);
 
         Signature sig = Signature.getInstance("SHA1withRSA", p);
         sig.initSign(kp.getPrivate());
--- a/test/sun/security/pkcs11/Secmod/GetPrivateKey.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/pkcs11/Secmod/GetPrivateKey.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -48,18 +48,17 @@
 
         System.out.println(p);
         Security.addProvider(p);
-        KeyStore ks = KeyStore.getInstance("PKCS11", p);
+        KeyStore ks = KeyStore.getInstance(PKCS11, p);
         ks.load(null, password);
-        Collection<String> aliases = new TreeSet<String>(Collections.list(ks.aliases()));
+        Collection<String> aliases = new TreeSet<>(
+                Collections.list(ks.aliases()));
         System.out.println("entries: " + aliases.size());
         System.out.println(aliases);
 
         PrivateKey privateKey = (PrivateKey)ks.getKey(keyAlias, password);
         System.out.println(privateKey);
 
-        byte[] data = new byte[1024];
-        Random random = new Random();
-        random.nextBytes(data);
+        byte[] data = generateData(1024);
 
         System.out.println("Signing...");
         Signature signature = Signature.getInstance("MD5withRSA");
@@ -67,7 +66,8 @@
         signature.update(data);
         byte[] sig = signature.sign();
 
-        X509Certificate[] chain = (X509Certificate[])ks.getCertificateChain(keyAlias);
+        X509Certificate[] chain =
+                (X509Certificate[]) ks.getCertificateChain(keyAlias);
         signature.initVerify(chain[0].getPublicKey());
         signature.update(data);
         boolean ok = signature.verify(sig);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/pkcs11/Secmod/LoadKeystore.java	Thu Jan 12 06:59:38 2017 +0000
@@ -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.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.util.Collections;
+
+/*
+ * @test
+ * @bug 8048622 8134232
+ * @summary Checks that PKCS#11 keystore can't be loaded with wrong password
+ * @library ../
+ * @run main/othervm LoadKeystore
+ */
+public class LoadKeystore extends SecmodTest {
+
+    public static void main(String[] args) throws Exception {
+        if (!initSecmod()) {
+            return;
+        }
+
+        String configName = BASE + SEP + "nss.cfg";
+        Provider p = getSunPKCS11(configName);
+
+        System.out.println("Add provider " + p);
+        System.out.println();
+        Security.addProvider(p);
+
+        try {
+            System.out.println("Load keystore with wrong type");
+            KeyStore.getInstance("unknown", p);
+            throw new RuntimeException("Expected exception not thrown");
+        } catch(KeyStoreException e) {
+            System.out.println("Expected exception: " + e);
+        }
+
+        KeyStore ks = KeyStore.getInstance("PKCS11", p);
+        if (!"PKCS11".equals(ks.getType())) {
+            throw new RuntimeException("Unexpected keystore type: "
+                    + ks.getType());
+        }
+        if (!p.equals(ks.getProvider())) {
+            throw new RuntimeException("Unexpected keystore provider: "
+                    + ks.getProvider());
+        }
+
+        try {
+            System.out.println("Load keystore with wrong password");
+            ks.load(null, "wrong".toCharArray());
+            throw new RuntimeException("Expected exception not thrown");
+        } catch(IOException e) {
+            System.out.println("Expected exception: " + e);
+            Throwable cause = e.getCause();
+            if (!(cause instanceof UnrecoverableKeyException)) {
+                e.printStackTrace(System.out);
+                throw new RuntimeException("Unexpected cause: " + cause);
+            }
+            System.out.println("Expected cause: " + cause);
+        }
+
+        System.out.println("Load keystore with correct password");
+        ks.load(null, password);
+        for (String alias : Collections.list(ks.aliases())) {
+            System.out.println("Alias: " + alias);
+        }
+
+        System.out.println("Test passed");
+    }
+
+}
--- a/test/sun/security/provider/KeyStore/DKSTest.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/provider/KeyStore/DKSTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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,8 +60,38 @@
                 new KeyStore.PasswordProtection("passphrase".toCharArray()));
         }};
 
+    private static final Map<String, KeyStore.ProtectionParameter>
+        WRONG_PASSWORDS = new HashMap<String, KeyStore.ProtectionParameter>() {{
+            put("policy_keystore",
+                new KeyStore.PasswordProtection(
+                    "wrong".toCharArray()));
+            put("pw_keystore",
+                new KeyStore.PasswordProtection("wrong".toCharArray()));
+            put("eckeystore1",
+                new KeyStore.PasswordProtection("wrong".toCharArray()));
+            put("eckeystore2",
+                new KeyStore.PasswordProtection("wrong".toCharArray()));
+        }};
+
     public static void main(String[] args) throws Exception {
         /*
+         * domain keystore: keystores with wrong passwords
+         */
+        try {
+            URI config = new URI(CONFIG + "#keystores");
+            KeyStore ks = KeyStore.getInstance("DKS");
+            ks.load(new DomainLoadStoreParameter(config, WRONG_PASSWORDS));
+            throw new RuntimeException("Expected exception not thrown");
+        } catch (IOException e) {
+            System.out.println("Expected exception: " + e);
+            if (!causedBy(e, UnrecoverableKeyException.class)) {
+                e.printStackTrace(System.out);
+                throw new RuntimeException("Unexpected cause");
+            }
+            System.out.println("Expected cause: " + e);
+        }
+
+        /*
          * domain keystore: system
          */
         URI config = new URI(CONFIG + "#system");
@@ -182,4 +212,15 @@
             return factory.generateCertificate(certStream);
         }
     }
+
+    // checks if an exception was caused by specified exception class
+    private static boolean causedBy(Exception e, Class klass) {
+        Throwable cause = e;
+        while ((cause = cause.getCause()) != null) {
+            if (cause.getClass().equals(klass)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
--- a/test/sun/security/tools/jarsigner/warnings/Test.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/security/tools/jarsigner/warnings/Test.java	Thu Jan 12 06:59:38 2017 +0000
@@ -22,11 +22,6 @@
  */
 
 import jdk.testlibrary.OutputAnalyzer;
-import jdk.testlibrary.ProcessTools;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 
 /**
  * Base class.
@@ -180,21 +175,4 @@
         }
         analyzer.shouldContain(JAR_SIGNED);
     }
-
-    protected OutputAnalyzer keytool(String... cmd) throws Throwable {
-        return tool(KEYTOOL, cmd);
-    }
-
-    protected OutputAnalyzer jarsigner(String... cmd) throws Throwable {
-        return tool(JARSIGNER, cmd);
-    }
-
-    private OutputAnalyzer tool(String tool, String... args) throws Throwable {
-        List<String> cmd = new ArrayList<>();
-        cmd.add(tool);
-        cmd.add("-J-Duser.language=en");
-        cmd.add("-J-Duser.country=US");
-        cmd.addAll(Arrays.asList(args));
-        return ProcessTools.executeCommand(cmd.toArray(new String[cmd.size()]));
-    }
 }
--- a/test/sun/tools/native2ascii/Native2AsciiTests.sh	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/sun/tools/native2ascii/Native2AsciiTests.sh	Thu Jan 12 06:59:38 2017 +0000
@@ -24,7 +24,7 @@
 #
 
 # @test
-# @bug 4630463 4630971 4636448 4701617 4721296 4710890 6247817 7021987
+# @bug 4630463 4630971 4636448 4701617 4721296 4710890 6247817 7021987 8067964
 # @summary Tests miscellaneous native2ascii bugfixes and regressions
 
 
--- a/test/tools/launcher/Arrrghs.java	Tue Nov 08 05:26:12 2016 +0000
+++ b/test/tools/launcher/Arrrghs.java	Thu Jan 12 06:59:38 2017 +0000
@@ -24,7 +24,7 @@
 /**
  * @test
  * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
- *      6894719 6968053 7151434 7146424 8007333 8077822
+ *      6894719 6968053 7151434 7146424 8007333 8077822 8143640
  * @summary Argument parsing validation.
  * @compile -XDignore.symbol.file Arrrghs.java
  * @run main/othervm Arrrghs
@@ -324,6 +324,8 @@
         // more treatment of  mixed slashes
         checkArgumentParsing("f1/ f3\\ f4/", "f1/", "f3\\", "f4/");
         checkArgumentParsing("f1/ f2\' ' f3/ f4/", "f1/", "f2\'", "'", "f3/", "f4/");
+
+        checkArgumentParsing("a\\*\\b", "a\\*\\b");
     }
 
     private void initEmptyDir(File emptyDir) throws IOException {