Merge
diff --git a/.hgtags b/.hgtags
index 195ba90..04432f9 100644
--- a/.hgtags
+++ b/.hgtags
@@ -641,3 +641,15 @@
1f15a299d2bf9a8bed33a2bdf36745c8238aafbb jdk8u111-b10
28e488c17b7a276e9ce00a0488bbc53094294e14 jdk8u111-b11
b1304d71a2ec04ae6fa0a46120a5beba40a6f5ba jdk8u111-b12
+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
diff --git a/LICENSE b/LICENSE
index b40a0f4..8b400c7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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.
diff --git a/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java b/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java
index d3ab6a6..59d0a74 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CAccessibility.java
@@ -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);
+ }
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java b/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java
index 0237ef9..6abf06e 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CAccessibleText.java
@@ -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;
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
index 591c16d..804d2d0 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
@@ -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.
@@ -171,6 +172,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) :
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index e449227..cdaae47 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -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);
diff --git a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java
index 800d76f..5962b7f 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CWarningWindow.java
@@ -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);
diff --git a/src/macosx/native/sun/awt/AWTView.h b/src/macosx/native/sun/awt/AWTView.h
index 592235b..1ba06fe 100644
--- a/src/macosx/native/sun/awt/AWTView.h
+++ b/src/macosx/native/sun/awt/AWTView.h
@@ -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;
diff --git a/src/macosx/native/sun/awt/AWTView.m b/src/macosx/native/sun/awt/AWTView.m
index 66ad514..ec33dd9 100644
--- a/src/macosx/native/sun/awt/AWTView.m
+++ b/src/macosx/native/sun/awt/AWTView.m
@@ -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:^(){
diff --git a/src/macosx/native/sun/awt/AWTWindow.h b/src/macosx/native/sun/awt/AWTWindow.h
index 7f7bac7..ee01181 100644
--- a/src/macosx/native/sun/awt/AWTWindow.h
+++ b/src/macosx/native/sun/awt/AWTWindow.h
@@ -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
diff --git a/src/macosx/native/sun/awt/AWTWindow.m b/src/macosx/native/sun/awt/AWTWindow.m
index 324f9d5..1194ad8 100644
--- a/src/macosx/native/sun/awt/AWTWindow.m
+++ b/src/macosx/native/sun/awt/AWTWindow.m
@@ -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 {
diff --git a/src/macosx/native/sun/awt/JavaAccessibilityAction.m b/src/macosx/native/sun/awt/JavaAccessibilityAction.m
index 9afd1ff..2078e1d 100644
--- a/src/macosx/native/sun/awt/JavaAccessibilityAction.m
+++ b/src/macosx/native/sun/awt/JavaAccessibilityAction.m
@@ -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];
diff --git a/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m b/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m
index 081c7f7..2b99936 100644
--- a/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m
+++ b/src/macosx/native/sun/awt/JavaAccessibilityUtilities.m
@@ -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)
diff --git a/src/macosx/native/sun/awt/JavaComponentAccessibility.m b/src/macosx/native/sun/awt/JavaComponentAccessibility.m
index ffea40f..d37a480 100644
--- a/src/macosx/native/sun/awt/JavaComponentAccessibility.m
+++ b/src/macosx/native/sun/awt/JavaComponentAccessibility.m
@@ -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);
}
}
diff --git a/src/macosx/native/sun/awt/JavaTextAccessibility.m b/src/macosx/native/sun/awt/JavaTextAccessibility.m
index 2809d8b..f7e17b0 100644
--- a/src/macosx/native/sun/awt/JavaTextAccessibility.m
+++ b/src/macosx/native/sun/awt/JavaTextAccessibility.m
@@ -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);
diff --git a/src/macosx/native/sun/java2d/opengl/CGLLayer.h b/src/macosx/native/sun/java2d/opengl/CGLLayer.h
index 43724c0..3d030e5 100644
--- a/src/macosx/native/sun/java2d/opengl/CGLLayer.h
+++ b/src/macosx/native/sun/java2d/opengl/CGLLayer.h
@@ -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
diff --git a/src/macosx/native/sun/java2d/opengl/CGLLayer.m b/src/macosx/native/sun/java2d/opengl/CGLLayer.m
index f300ea4..87dcf1d 100644
--- a/src/macosx/native/sun/java2d/opengl/CGLLayer.m
+++ b/src/macosx/native/sun/java2d/opengl/CGLLayer.m
@@ -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;
diff --git a/src/share/back/debugInit.c b/src/share/back/debugInit.c
index 25ffbff..3475397 100644
--- a/src/share/back/debugInit.c
+++ b/src/share/back/debugInit.c
@@ -1013,7 +1013,7 @@
atexit_finish_logging(void)
{
/* Normal exit(0) (not _exit()) may only reach here */
- finish_logging(0); /* Only first call matters */
+ finish_logging(); /* Only first call matters */
}
static jboolean
@@ -1301,39 +1301,49 @@
void
debugInit_exit(jvmtiError error, const char *msg)
{
- int exit_code = 0;
+ enum exit_codes { EXIT_NO_ERRORS = 0, EXIT_JVMTI_ERROR = 1, EXIT_TRANSPORT_ERROR = 2 };
- /* Pick an error code */
- if ( error != JVMTI_ERROR_NONE ) {
- exit_code = 1;
- if ( docoredump ) {
- finish_logging(exit_code);
- abort();
+ // Prepare to exit. Log error and finish logging
+ LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error,
+ ((msg == NULL) ? "" : msg)));
+
+ // coredump requested by command line. Keep JVMTI data dirty
+ if (error != JVMTI_ERROR_NONE && docoredump) {
+ LOG_MISC(("Dumping core as requested by command line"));
+ finish_logging();
+ abort();
+ }
+
+ finish_logging();
+
+ // Cleanup the JVMTI if we have one
+ if (gdata != NULL) {
+ gdata->vmDead = JNI_TRUE;
+ if (gdata->jvmti != NULL) {
+ // Dispose of jvmti (gdata->jvmti becomes NULL)
+ disposeEnvironment(gdata->jvmti);
}
}
- if ( msg==NULL ) {
- msg = "";
+
+ // We are here with no errors. Kill entire process and exit with zero exit code
+ if (error == JVMTI_ERROR_NONE) {
+ forceExit(EXIT_NO_ERRORS);
+ return;
}
- LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error, msg));
-
- gdata->vmDead = JNI_TRUE;
-
- /* Let's try and cleanup the JVMTI, if we even have one */
- if ( gdata->jvmti != NULL ) {
- /* Dispose of jvmti (gdata->jvmti becomes NULL) */
- disposeEnvironment(gdata->jvmti);
+ // No transport initilized.
+ // As we don't have any details here exiting with separate exit code
+ if (error == AGENT_ERROR_TRANSPORT_INIT) {
+ forceExit(EXIT_TRANSPORT_ERROR);
+ return;
}
- /* Finish up logging. We reach here if JDWP is doing the exiting. */
- finish_logging(exit_code); /* Only first call matters */
+ // We have JVMTI error. Call hotspot jni_FatalError handler
+ jniFatalError(NULL, msg, error, EXIT_JVMTI_ERROR);
- /* Let's give the JNI a FatalError if non-exit 0, which is historic way */
- if ( exit_code != 0 ) {
- JNIEnv *env = NULL;
- jniFatalError(env, msg, error, exit_code);
- }
+ // hotspot calls os:abort() so we should never reach code below,
+ // but guard against possible hotspot changes
- /* Last chance to die, this kills the entire process. */
- forceExit(exit_code);
+ // Last chance to die, this kills the entire process.
+ forceExit(EXIT_JVMTI_ERROR);
}
diff --git a/src/share/back/log_messages.c b/src/share/back/log_messages.c
index de8b69d..32bea29 100644
--- a/src/share/back/log_messages.c
+++ b/src/share/back/log_messages.c
@@ -230,7 +230,7 @@
/* Finish up logging, flush output to the logfile. */
void
-finish_logging(int exit_code)
+finish_logging()
{
#ifdef JDWP_LOGGING
MUTEX_LOCK(my_mutex);
diff --git a/src/share/back/log_messages.h b/src/share/back/log_messages.h
index 0a442e9..129fab6 100644
--- a/src/share/back/log_messages.h
+++ b/src/share/back/log_messages.h
@@ -29,7 +29,7 @@
/* LOG: Must be called like: LOG_category(("anything")) or LOG_category((format,args)) */
void setup_logging(const char *, unsigned);
-void finish_logging(int);
+void finish_logging();
#define LOG_NULL ((void)0)
diff --git a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
index 51d95c1..5154788 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherBlockChaining.java
@@ -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);
}
diff --git a/src/share/classes/com/sun/crypto/provider/CipherCore.java b/src/share/classes/com/sun/crypto/provider/CipherCore.java
index 79f66cd..592ec41 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java
@@ -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.
+ 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;
+ }
+ // process 'buffer'
if (decrypting) {
- outLen = cipher.decrypt(input, inputOffset, len, output, outputOffset);
+ outLen = cipher.decrypt(buffer, 0, buffered, output, outputOffset);
} else {
- outLen = cipher.encrypt(input, inputOffset, len, output, outputOffset);
+ outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
}
- 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;
- }
- 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(in, 0, len, output, outputOffset);
+ outLen += cipher.decrypt(input, inputOffset, inputConsumed,
+ output, outputOffset);
} else {
- outLen = cipher.encrypt(in, 0, len, output, outputOffset);
+ outLen += cipher.encrypt(input, inputOffset, inputConsumed,
+ 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;
}
diff --git a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java
index f8e6115..84b527e 100644
--- a/src/share/classes/com/sun/crypto/provider/CipherFeedback.java
+++ b/src/share/classes/com/sun/crypto/provider/CipherFeedback.java
@@ -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;
+
+ 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]);
+ }
+ }
+ return plainLen;
+ }
+
+ /**
+ * 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;
-
- 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]);
- }
- 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]);
-
- }
- 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]);
- }
+ 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;
diff --git a/src/share/classes/com/sun/crypto/provider/CounterMode.java b/src/share/classes/com/sun/crypto/provider/CounterMode.java
index 438998e..af52bd7 100644
--- a/src/share/classes/com/sun/crypto/provider/CounterMode.java
+++ b/src/share/classes/com/sun/crypto/provider/CounterMode.java
@@ -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);
}
diff --git a/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java b/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java
index c71d6ab..bd2ba6f 100644
--- a/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java
+++ b/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java
@@ -71,6 +71,17 @@
initialize(1024, null);
}
+ private static void checkKeySize(int keysize)
+ throws InvalidParameterException {
+
+ if ((keysize < 512) || (keysize > 2048) || ((keysize & 0x3F) != 0)) {
+ throw new InvalidParameterException(
+ "DH key size must be multiple of 64, and can only range " +
+ "from 512 to 2048 (inclusive). " +
+ "The specific key size " + keysize + " is not supported");
+ }
+ }
+
/**
* Initializes this key pair generator for a certain keysize and source of
* randomness.
@@ -80,12 +91,8 @@
* @param random the source of randomness
*/
public void initialize(int keysize, SecureRandom random) {
- if ((keysize < 512) || (keysize > 2048) || (keysize % 64 != 0)) {
- throw new InvalidParameterException("Keysize must be multiple "
- + "of 64, and can only range "
- + "from 512 to 2048 "
- + "(inclusive)");
- }
+ checkKeySize(keysize);
+
this.pSize = keysize;
this.lSize = 0;
this.random = random;
@@ -115,11 +122,10 @@
params = (DHParameterSpec)algParams;
pSize = params.getP().bitLength();
- if ((pSize < 512) || (pSize > 2048) ||
- (pSize % 64 != 0)) {
- throw new InvalidAlgorithmParameterException
- ("Prime size must be multiple of 64, and can only range "
- + "from 512 to 2048 (inclusive)");
+ try {
+ checkKeySize(pSize);
+ } catch (InvalidParameterException ipe) {
+ throw new InvalidAlgorithmParameterException(ipe.getMessage());
}
// exponent size is optional, could be 0
diff --git a/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java b/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java
index a12e945..92d4f6f 100644
--- a/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java
+++ b/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java
@@ -59,12 +59,13 @@
private SecureRandom random = null;
private static void checkKeySize(int keysize)
- throws InvalidAlgorithmParameterException {
- if ((keysize != 2048) &&
+ throws InvalidParameterException {
+ if ((keysize != 2048) &&
((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) {
- throw new InvalidAlgorithmParameterException(
- "Keysize must be multiple of 64 ranging from "
- + "512 to 1024 (inclusive), or 2048");
+ throw new InvalidParameterException(
+ "DH key size must be multiple of 64 and range " +
+ "from 512 to 1024 (inclusive), or 2048. " +
+ "The specific key size " + keysize + " is not supported");
}
}
@@ -78,11 +79,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;
}
@@ -111,7 +108,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) {
diff --git a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java
index a407b6a..334e424 100644
--- a/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java
+++ b/src/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java
@@ -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;
diff --git a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
index e4edbf0..4cb76ff 100644
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
+++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
@@ -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) {
diff --git a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
index cbbc54e..5ec36fd 100644
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
+++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java
@@ -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"));
}
}
}
diff --git a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java
index ea5890d..250e60e 100644
--- a/src/share/classes/com/sun/crypto/provider/OutputFeedback.java
+++ b/src/share/classes/com/sun/crypto/provider/OutputFeedback.java
@@ -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);
+ }
}
diff --git a/src/share/classes/com/sun/crypto/provider/PCBC.java b/src/share/classes/com/sun/crypto/provider/PCBC.java
index aefc45e..fd99bb0 100644
--- a/src/share/classes/com/sun/crypto/provider/PCBC.java
+++ b/src/share/classes/com/sun/crypto/provider/PCBC.java
@@ -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;
diff --git a/src/share/classes/com/sun/java/accessibility/util/package-info.java b/src/share/classes/com/sun/java/accessibility/util/package-info.java
index 2ae79d1..7d81ed6 100644
--- a/src/share/classes/com/sun/java/accessibility/util/package-info.java
+++ b/src/share/classes/com/sun/java/accessibility/util/package-info.java
@@ -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
diff --git a/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java b/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java
index 241105b..4b97591 100644
--- a/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java
+++ b/src/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java
@@ -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();
diff --git a/src/share/classes/com/sun/jndi/ldap/DigestClientId.java b/src/share/classes/com/sun/jndi/ldap/DigestClientId.java
index b4f19d0..6eac44a 100644
--- a/src/share/classes/com/sun/jndi/ldap/DigestClientId.java
+++ b/src/share/classes/com/sun/jndi/ldap/DigestClientId.java
@@ -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);
}
diff --git a/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java b/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java
index 65c8051..8d385d3 100644
--- a/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java
+++ b/src/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java
@@ -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);
}
}
diff --git a/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java b/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java
index 422ce79..c923fda 100644
--- a/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java
+++ b/src/share/classes/com/sun/jndi/ldap/LdapNamingEnumeration.java
@@ -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);
}
}
diff --git a/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java b/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java
index 329b1d2..24c421e 100644
--- a/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java
+++ b/src/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java
@@ -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
diff --git a/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java b/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java
index 6fa5471..2915110 100644
--- a/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java
+++ b/src/share/classes/com/sun/jndi/ldap/SimpleClientId.java
@@ -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) {
diff --git a/src/share/classes/com/sun/jndi/ldap/pool/Pool.java b/src/share/classes/com/sun/jndi/ldap/pool/Pool.java
index f9786ca..29c4d32 100644
--- a/src/share/classes/com/sun/jndi/ldap/pool/Pool.java
+++ b/src/share/classes/com/sun/jndi/ldap/pool/Pool.java
@@ -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());
- for (Map.Entry<Object, ConnectionsRef> entry : map.entrySet()) {
- id = entry.getKey();
- conns = entry.getValue().getConnections();
- out.println(" " + id + ":" + conns.getStats());
+ 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());
+ }
}
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) {
diff --git a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java
index fe6dd07..cd416cc 100644
--- a/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java
+++ b/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java
@@ -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 {
diff --git a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java
index 1958b9a..5338665 100644
--- a/src/share/classes/com/sun/tools/example/debug/tty/TTY.java
+++ b/src/share/classes/com/sun/tools/example/debug/tty/TTY.java
@@ -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";
}
diff --git a/src/share/classes/java/awt/SplashScreen.java b/src/share/classes/java/awt/SplashScreen.java
index 05a38e7..c51aa6f 100644
--- a/src/share/classes/java/awt/SplashScreen.java
+++ b/src/share/classes/java/awt/SplashScreen.java
@@ -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;
}
diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
index dfd8628..acac29b 100644
--- a/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -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);
diff --git a/src/share/classes/java/security/ProtectionDomain.java b/src/share/classes/java/security/ProtectionDomain.java
index ffd2def..9e597bc 100644
--- a/src/share/classes/java/security/ProtectionDomain.java
+++ b/src/share/classes/java/security/ProtectionDomain.java
@@ -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;
+ }
+ }
+ }
}
diff --git a/src/share/classes/java/security/SecureRandom.java b/src/share/classes/java/security/SecureRandom.java
index 3481e21..6848be5 100644
--- a/src/share/classes/java/security/SecureRandom.java
+++ b/src/share/classes/java/security/SecureRandom.java
@@ -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);
}
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java b/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java
index 95ea7f7..bc8a2ba 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java
@@ -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
@@ -377,10 +375,6 @@
comboBox.getModel().addListDataListener( listDataListener );
}
}
-
- if ((mouseWheelListener = createMouseWheelListener()) != null) {
- comboBox.addMouseWheelListener(mouseWheelListener);
- }
}
/**
@@ -427,9 +421,6 @@
comboBox.getModel().removeListDataListener( listDataListener );
}
}
- if (mouseWheelListener != null) {
- comboBox.removeMouseWheelListener(mouseWheelListener);
- }
}
/**
@@ -543,10 +534,6 @@
return handler;
}
- private MouseWheelListener createMouseWheelListener() {
- return getHandler();
- }
-
//
// end UI Initialization
//======================
@@ -1682,8 +1669,7 @@
//
private class Handler implements ActionListener, FocusListener,
KeyListener, LayoutManager,
- ListDataListener, PropertyChangeListener,
- MouseWheelListener {
+ ListDataListener, PropertyChangeListener {
//
// PropertyChangeListener
//
@@ -1967,10 +1953,6 @@
}
}
}
-
- public void mouseWheelMoved(MouseWheelEvent e) {
- e.consume();
- }
}
class DefaultKeySelectionManager implements JComboBox.KeySelectionManager, UIResource {
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java b/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
index 682e6c6..ae39867 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
@@ -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);
}
}
diff --git a/src/share/classes/javax/swing/plaf/nimbus/skin.laf b/src/share/classes/javax/swing/plaf/nimbus/skin.laf
index 208a3b0..da41a8b 100644
--- a/src/share/classes/javax/swing/plaf/nimbus/skin.laf
+++ b/src/share/classes/javax/swing/plaf/nimbus/skin.laf
@@ -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/>
diff --git a/src/share/classes/javax/swing/text/html/parser/Parser.java b/src/share/classes/javax/swing/text/html/parser/Parser.java
index 7912446..21f5703 100644
--- a/src/share/classes/javax/swing/text/html/parser/Parser.java
+++ b/src/share/classes/javax/swing/text/html/parser/Parser.java
@@ -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]);
- }
-
- 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();
- 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;
- }
- ch = readCh();
- break;
- } // switch
}
+
+ 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++;
+ }
+ 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();
+ 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();
+ crlfCount++;
+ } else {
+ crCount++;
+ }
+ addString('\n');
+ break;
+ default:
+ addString(ch);
+ ch = readCh();
+ break;
+ } // switch
} // while
}
diff --git a/src/share/classes/sun/font/CompositeFont.java b/src/share/classes/sun/font/CompositeFont.java
index 45480ca..a7df046 100644
--- a/src/share/classes/sun/font/CompositeFont.java
+++ b/src/share/classes/sun/font/CompositeFont.java
@@ -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;
diff --git a/src/share/classes/sun/font/FontFamily.java b/src/share/classes/sun/font/FontFamily.java
index 31f1425..e319886 100644
--- a/src/share/classes/sun/font/FontFamily.java
+++ b/src/share/classes/sun/font/FontFamily.java
@@ -335,9 +335,9 @@
case Font.BOLD|Font.ITALIC:
if (bolditalic != null) {
return bolditalic;
- } else if (italic != null && italic.canDoStyle(style)) {
- return italic;
} else if (bold != null && bold.canDoStyle(style)) {
+ return bold;
+ } else if (italic != null && italic.canDoStyle(style)) {
return italic;
} else if (plain != null && plain.canDoStyle(style)) {
return plain;
diff --git a/src/share/classes/sun/font/ScriptRunData.java b/src/share/classes/sun/font/ScriptRunData.java
index d894014..e72c856 100644
--- a/src/share/classes/sun/font/ScriptRunData.java
+++ b/src/share/classes/sun/font/ScriptRunData.java
@@ -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;
diff --git a/src/share/classes/sun/java2d/opengl/OGLMaskFill.java b/src/share/classes/sun/java2d/opengl/OGLMaskFill.java
index b75d5a4..ab053f1 100644
--- a/src/share/classes/sun/java2d/opengl/OGLMaskFill.java
+++ b/src/share/classes/sun/java2d/opengl/OGLMaskFill.java
@@ -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);
diff --git a/src/share/classes/sun/java2d/pipe/BufferedContext.java b/src/share/classes/sun/java2d/pipe/BufferedContext.java
index 4513c67..3475c43 100644
--- a/src/share/classes/sun/java2d/pipe/BufferedContext.java
+++ b/src/share/classes/sun/java2d/pipe/BufferedContext.java
@@ -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;
}
diff --git a/src/share/classes/sun/reflect/annotation/AnnotationType.java b/src/share/classes/sun/reflect/annotation/AnnotationType.java
index aa0cbe9..92f600d 100644
--- a/src/share/classes/sun/reflect/annotation/AnnotationType.java
+++ b/src/share/classes/sun/reflect/annotation/AnnotationType.java
@@ -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
diff --git a/src/share/classes/sun/security/jca/ProviderConfig.java b/src/share/classes/sun/security/jca/ProviderConfig.java
index 62f8bdd..7294269 100644
--- a/src/share/classes/sun/security/jca/ProviderConfig.java
+++ b/src/share/classes/sun/security/jca/ProviderConfig.java
@@ -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;
}
}
});
diff --git a/src/share/classes/sun/security/krb5/Config.java b/src/share/classes/sun/security/krb5/Config.java
index 129f774..7ee9231 100644
--- a/src/share/classes/sun/security/krb5/Config.java
+++ b/src/share/classes/sun/security/krb5/Config.java
@@ -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:
diff --git a/src/share/classes/sun/security/krb5/KrbKdcRep.java b/src/share/classes/sun/security/krb5/KrbKdcRep.java
index dd0e951..66ce73a 100644
--- a/src/share/classes/sun/security/krb5/KrbKdcRep.java
+++ b/src/share/classes/sun/security/krb5/KrbKdcRep.java
@@ -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) {
diff --git a/src/share/classes/sun/security/krb5/KrbTgsReq.java b/src/share/classes/sun/security/krb5/KrbTgsReq.java
index 798b78d..85b7cb2 100644
--- a/src/share/classes/sun/security/krb5/KrbTgsReq.java
+++ b/src/share/classes/sun/security/krb5/KrbTgsReq.java
@@ -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)))
diff --git a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
index b6a3677..14620e9 100644
--- a/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
+++ b/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java
@@ -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;
}
diff --git a/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java b/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java
index 4adac8c..068f00a 100644
--- a/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java
+++ b/src/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java
@@ -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 2048 bits. " +
+ "The specific key size " +
+ keySize + " is not supported");
}
}
}
diff --git a/src/share/classes/sun/security/pkcs11/P11KeyStore.java b/src/share/classes/sun/security/pkcs11/P11KeyStore.java
index 32002c2..e5b8fa8 100644
--- a/src/share/classes/sun/security/pkcs11/P11KeyStore.java
+++ b/src/share/classes/sun/security/pkcs11/P11KeyStore.java
@@ -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);
}
}
diff --git a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
index 25fc78c..dd3e060 100644
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
@@ -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) {
diff --git a/src/share/classes/sun/security/ssl/CipherBox.java b/src/share/classes/sun/security/ssl/CipherBox.java
index fa11bce..ec5880b 100644
--- a/src/share/classes/sun/security/ssl/CipherBox.java
+++ b/src/share/classes/sun/security/ssl/CipherBox.java
@@ -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.
*
diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java
index 740cdd6..677a7e1 100644
--- a/src/share/classes/sun/security/ssl/CipherSuite.java
+++ b/src/share/classes/sun/security/ssl/CipherSuite.java
@@ -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,86 +520,29 @@
/**
* Test if this bulk cipher is available. For use by CipherSuite.
- *
- * Currently all supported ciphers except AES are always available
- * via the JSSE internal implementations. We also assume AES/128 of
- * CBC mode is always available since it is shipped with the SunJCE
- * provider. However, AES/256 is unavailable when the default JCE
- * policy jurisdiction files are installed because of key length
- * restrictions, and AEAD is unavailable when the underlying providers
- * do not support AEAD/GCM mode.
*/
boolean isAvailable() {
- if (allowed == false) {
- return false;
+ return this.isAvailable;
+ }
+
+ private static boolean isUnlimited(int keySize, String transformation) {
+ int keySizeInBits = keySize * 8;
+ if (keySizeInBits > 128) { // need the JCE unlimited
+ // strength jurisdiction policy
+ try {
+ if (Cipher.getMaxAllowedKeyLength(
+ transformation) < keySizeInBits) {
+
+ return false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
}
- if ((this == B_AES_256) ||
- (this.cipherType == CipherType.AEAD_CIPHER)) {
- return isAvailable(this);
- }
-
- // always available
return true;
}
- // for use by CipherSuiteList.clearAvailableCache();
- static synchronized void clearAvailableCache() {
- if (DYNAMIC_AVAILABILITY) {
- availableCache.clear();
- }
- }
-
- private static synchronized boolean isAvailable(BulkCipher cipher) {
- Boolean b = availableCache.get(cipher);
- if (b == null) {
- int keySizeInBits = cipher.keySize * 8;
- if (keySizeInBits > 128) { // need the JCE unlimited
- // strength jurisdiction policy
- try {
- if (Cipher.getMaxAllowedKeyLength(
- cipher.transformation) < keySizeInBits) {
- b = Boolean.FALSE;
- }
- } catch (Exception e) {
- b = Boolean.FALSE;
- }
- }
-
- if (b == null) {
- b = Boolean.FALSE; // may be reset to TRUE if
- // the cipher is available
- CipherBox temporary = null;
- try {
- SecretKey key = new SecretKeySpec(
- new byte[cipher.expandedKeySize],
- cipher.algorithm);
- IvParameterSpec iv;
- if (cipher.cipherType == CipherType.AEAD_CIPHER) {
- iv = new IvParameterSpec(
- new byte[cipher.fixedIvSize]);
- } else {
- iv = new IvParameterSpec(new byte[cipher.ivSize]);
- }
- temporary = cipher.newCipher(
- ProtocolVersion.DEFAULT,
- key, iv, secureRandom, true);
- b = temporary.isAvailable();
- } catch (NoSuchAlgorithmException e) {
- // not available
- } finally {
- if (temporary != null) {
- temporary.dispose();
- }
- }
- }
-
- availableCache.put(cipher, b);
- }
-
- return b.booleanValue();
- }
-
@Override
public String toString() {
return description;
diff --git a/src/share/classes/sun/security/ssl/CipherSuiteList.java b/src/share/classes/sun/security/ssl/CipherSuiteList.java
index 19dc90f..491bffa 100644
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java
+++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,24 +74,12 @@
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();
- }
- }
}
diff --git a/src/share/classes/sun/security/ssl/JsseJce.java b/src/share/classes/sun/security/ssl/JsseJce.java
index 4c98772..923ae8e 100644
--- a/src/share/classes/sun/security/ssl/JsseJce.java
+++ b/src/share/classes/sun/security/ssl/JsseJce.java
@@ -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;
+ }
+ }
}
diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
index 783146c..a6439ef 100644
--- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
+++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
@@ -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;
diff --git a/src/share/classes/sun/security/ssl/SSLContextImpl.java b/src/share/classes/sun/security/ssl/SSLContextImpl.java
index b00a26d..c0cab21 100644
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java
+++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -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();
- return supportedProtocolList;
- }
+ // Get default ProtocolList for server mode.
+ abstract ProtocolList getServerDefaultProtocolList();
+
+ // Get default ProtocolList for client mode.
+ abstract ProtocolList getClientDefaultProtocolList();
+
+ // Get supported CipherSuiteList.
+ abstract CipherSuiteList getSupportedCipherSuiteList();
+
+ // Get default CipherSuiteList for server mode.
+ abstract CipherSuiteList getServerDefaultCipherSuiteList();
+
+ // Get default CipherSuiteList for client mode.
+ abstract CipherSuiteList getClientDefaultCipherSuiteList();
// Get default ProtocolList.
ProtocolList getDefaultProtocolList(boolean roleIsServer) {
- if (roleIsServer) {
- if (defaultServerProtocolList == null) {
- defaultServerProtocolList = new ProtocolList(
- getDefaultServerSSLParams().getProtocols());
- }
-
- return defaultServerProtocolList;
- } else {
- if (defaultClientProtocolList == null) {
- defaultClientProtocolList = new ProtocolList(
- getDefaultClientSSLParams().getProtocols());
- }
-
- return defaultClientProtocolList;
- }
- }
-
- // Get supported CipherSuiteList.
- CipherSuiteList getSupportedCipherSuiteList() {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (supportedCipherSuiteList == null) {
- supportedCipherSuiteList = getApplicableCipherSuiteList(
- getSuportedProtocolList(), false);
- }
-
- return supportedCipherSuiteList;
- }
+ return roleIsServer ? getServerDefaultProtocolList()
+ : getClientDefaultProtocolList();
}
// Get default CipherSuiteList.
CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
- // The maintenance of cipher suites needs to be synchronized.
- synchronized (this) {
- // Clear cache of available ciphersuites.
- clearAvailableCache();
-
- if (roleIsServer) {
- if (defaultServerCipherSuiteList == null) {
- defaultServerCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(true), true);
- }
-
- return defaultServerCipherSuiteList;
- } else {
- if (defaultClientCipherSuiteList == null) {
- defaultClientCipherSuiteList = getApplicableCipherSuiteList(
- getDefaultProtocolList(false), true);
- }
-
- return defaultClientCipherSuiteList;
- }
- }
+ return roleIsServer ? getServerDefaultCipherSuiteList()
+ : getClientDefaultCipherSuiteList();
}
/**
@@ -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;
}
- static List<String> getAvailableProtocols(
- ProtocolVersion[] protocolCandidates) {
+ @Override
+ ProtocolList getServerDefaultProtocolList() {
+ return serverDefaultProtocolList;
+ }
- 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
+ CipherSuiteList getServerDefaultCipherSuiteList() {
+ return serverDefaultCipherSuiteList;
+ }
- return availableProtocols;
+ @Override
+ SSLEngine createSSLEngineImpl() {
+ return new SSLEngineImpl(this);
+ }
+
+ @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
- SSLParameters getDefaultClientSSLParams() {
- return defaultClientSSLParams;
+ ProtocolList getClientDefaultProtocolList() {
+ return clientDefaultProtocolList;
+ }
+
+ @Override
+ 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);
- }
-
- String[] protocols = null;
- if (property != null && property.length() != 0) {
- protocols = property.split(",");
- } else {
- reservedException = new IllegalArgumentException(
- "No protocol specified in " +
- PROPERTY_NAME + " system property");
- protocols = new String[0];
- }
-
- 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();
+ reservedException = CustomizedSSLProtocols.reservedException;
if (reservedException == null) {
- defaultClientSSLParams.setProtocols(
- getAvailableProtocols(candidates).toArray(new String[0]));
+ ArrayList<ProtocolVersion>
+ customizedTLSProtocols = new ArrayList<>();
+ for (ProtocolVersion protocol :
+ CustomizedSSLProtocols.customizedProtocols) {
+ customizedTLSProtocols.add(protocol);
+ }
+
+ // 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 {
+ // Use the customized TLS protocols.
+ candidates =
+ new ProtocolVersion[customizedTLSProtocols.size()];
+ candidates = customizedTLSProtocols.toArray(candidates);
+ }
+
+ 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;
+ }
+ }
+
+
}
diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java
index 9caa64a..373dc57 100644
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java
@@ -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(
diff --git a/src/share/classes/sun/tools/native2ascii/Main.java b/src/share/classes/sun/tools/native2ascii/Main.java
index 1f02353..00e8332 100644
--- a/src/share/classes/sun/tools/native2ascii/Main.java
+++ b/src/share/classes/sun/tools/native2ascii/Main.java
@@ -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;
}
diff --git a/src/share/lib/security/sunpkcs11-solaris.cfg b/src/share/lib/security/sunpkcs11-solaris.cfg
index 4cade8e..29aae46 100644
--- a/src/share/lib/security/sunpkcs11-solaris.cfg
+++ b/src/share/lib/security/sunpkcs11-solaris.cfg
@@ -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
diff --git a/src/solaris/bin/jexec.c b/src/solaris/bin/jexec.c
index a30617d..13220cb 100644
--- a/src/solaris/bin/jexec.c
+++ b/src/solaris/bin/jexec.c
@@ -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);
diff --git a/src/solaris/classes/sun/java2d/xr/XRRenderer.java b/src/solaris/classes/sun/java2d/xr/XRRenderer.java
index 5eb84ed..9040018 100644
--- a/src/solaris/classes/sun/java2d/xr/XRRenderer.java
+++ b/src/solaris/classes/sun/java2d/xr/XRRenderer.java
@@ -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);
diff --git a/src/solaris/classes/sun/security/provider/NativePRNG.java b/src/solaris/classes/sun/security/provider/NativePRNG.java
index 1d275f0..bbb48c4 100644
--- a/src/solaris/classes/sun/security/provider/NativePRNG.java
+++ b/src/solaris/classes/sun/security/provider/NativePRNG.java
@@ -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);
}
- }
}
- }
+ }
}
diff --git a/src/solaris/native/java/net/NetworkInterface.c b/src/solaris/native/java/net/NetworkInterface.c
index 1788944..cb00494 100644
--- a/src/solaris/native/java/net/NetworkInterface.c
+++ b/src/solaris/native/java/net/NetworkInterface.c
@@ -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;
}
-/*
- * Enumerates and returns all IPv6 interfaces on Linux
- */
-
#if defined(AF_INET6) && defined(__linux__)
+
+/*
+ * Enumerates and returns all IPv6 interfaces on 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
-/*
- * Enumerates and returns all IPv6 interfaces on AIX
- */
-
#if defined(AF_INET6) && defined(_AIX)
+
+/*
+ * Enumerates and returns all IPv6 interfaces on 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;
+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);
- 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;
+ }
- /* 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;
- }
+ 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;
+ }
- 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;
- }
+ ret = brdcast_store;
+ memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+ }
- ret = brdcast_store;
- memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
- }
-
- return ret;
+ 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.
- */
- if (! alreadyV6 ){
- memset((char *) &if2, 0, sizeof(if2));
- strcpy(if2.lifr_name, ifname);
+ // 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));
+ 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));
+ strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
- memset((char *) &if2, 0, sizeof(if2));
- strcpy(if2.lifr_name, ifname);
-
- /* 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 lifr;
- memset((caddr_t)&lifr, 0, sizeof(lifr));
- strcpy((caddr_t)&(lifr.lifr_name), ifname);
+ struct lifreq if2;
+ memset((char *)&if2, 0, sizeof(if2));
+ strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1);
- if (ioctl(sock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
- return -1;
- }
+ if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) {
+ return -1;
+ }
- *flags = lifr.lifr_flags;
- return 0;
+ *flags = if2.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;
+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);
- memset((char *) &if2, 0, sizeof(if2));
- strcpy(if2.ifr_name, ifname);
+ // 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;
+ }
- /* 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;
- }
+ 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;
+ }
- 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;
- }
+ ret = brdcast_store;
+ memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
+ }
- ret = brdcast_store;
- memcpy(ret, &if2.ifr_broadaddr, sizeof(struct sockaddr));
- }
-
- return ret;
+ 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__ */
diff --git a/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/src/solaris/native/java/net/PlainDatagramSocketImpl.c
index 77899d6..406654d 100644
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c
+++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c
@@ -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));
diff --git a/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c b/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
index 962f5e4..6860a16 100644
--- a/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
+++ b/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
@@ -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;
diff --git a/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c b/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
index c7b391f..12b1c85 100644
--- a/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
+++ b/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
@@ -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);
diff --git a/src/windows/bin/cmdtoargs.c b/src/windows/bin/cmdtoargs.c
index 352b155..29e5e77 100644
--- a/src/windows/bin/cmdtoargs.c
+++ b/src/windows/bin/cmdtoargs.c
@@ -155,6 +155,7 @@
}
}
dest += copyCh(ch, dest);
+ slashes = 0;
break;
default:
diff --git a/src/windows/classes/sun/awt/windows/fontconfig.properties b/src/windows/classes/sun/awt/windows/fontconfig.properties
index 6e488ee..3a2e2b3 100644
--- a/src/windows/classes/sun/awt/windows/fontconfig.properties
+++ b/src/windows/classes/sun/awt/windows/fontconfig.properties
@@ -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
diff --git a/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java b/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java
index e5e3d25..dae1d08 100644
--- a/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java
+++ b/src/windows/classes/sun/java2d/d3d/D3DMaskFill.java
@@ -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);
diff --git a/src/windows/native/java/lang/ProcessEnvironment_md.c b/src/windows/native/java/lang/ProcessEnvironment_md.c
index 69bd50b..e14299a 100644
--- a/src/windows/native/java/lang/ProcessEnvironment_md.c
+++ b/src/windows/native/java/lang/ProcessEnvironment_md.c
@@ -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
diff --git a/src/windows/native/java/net/Inet4AddressImpl.c b/src/windows/native/java/net/Inet4AddressImpl.c
index bb7f110..f250c55 100644
--- a/src/windows/native/java/net/Inet4AddressImpl.c
+++ b/src/windows/native/java/net/Inet4AddressImpl.c
@@ -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);
}
}
diff --git a/src/windows/native/java/net/Inet6AddressImpl.c b/src/windows/native/java/net/Inet6AddressImpl.c
index ff24d7f..2ab1ded 100644
--- a/src/windows/native/java/net/Inet6AddressImpl.c
+++ b/src/windows/native/java/net/Inet6AddressImpl.c
@@ -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;
}
diff --git a/src/windows/native/sun/bridge/WinAccessBridge.cpp b/src/windows/native/sun/bridge/WinAccessBridge.cpp
index ed42631..20b5d7c 100644
--- a/src/windows/native/sun/bridge/WinAccessBridge.cpp
+++ b/src/windows/native/sun/bridge/WinAccessBridge.cpp
@@ -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) {
diff --git a/src/windows/native/sun/windows/awt_TrayIcon.cpp b/src/windows/native/sun/windows/awt_TrayIcon.cpp
index e9c74d7..fbf46ec 100644
--- a/src/windows/native/sun/windows/awt_TrayIcon.cpp
+++ b/src/windows/native/sun/windows/awt_TrayIcon.cpp
@@ -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) {
diff --git a/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp b/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp
index 825a69c..b7ab7e0 100644
--- a/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp
+++ b/src/windows/native/sun/windows/awt_Win32GraphicsDevice.cpp
@@ -875,6 +875,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;
}
diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index 825c985..37b3bca 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -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
diff --git a/test/com/sun/corba/cachedSocket/7056731.sh b/test/com/sun/corba/cachedSocket/7056731.sh
index 0d7c036..2e5e3fb 100644
--- a/test/com/sun/corba/cachedSocket/7056731.sh
+++ b/test/com/sun/corba/cachedSocket/7056731.sh
@@ -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=$?
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java
new file mode 100644
index 0000000..3aa6d29
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/Dynamic.java
@@ -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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java
new file mode 100644
index 0000000..132e79d
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithDefaultProvider.java
@@ -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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java
new file mode 100644
index 0000000..8dec9f1
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithProviderChange.java
@@ -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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java
new file mode 100644
index 0000000..81761a7
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/TestAESWithRemoveAddProvider.java
@@ -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);
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy
new file mode 100644
index 0000000..a138a57
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestAESCiphers/testAES.policy
@@ -0,0 +1,6 @@
+grant
+{
+ permission java.security.SecurityPermission "removeProvider.SunJCE";
+ permission java.security.SecurityPermission "insertProvider.SunJCE";
+ permission java.security.SecurityPermission "putProviderProperty.SunJCE";
+};
diff --git a/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java b/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java
index 20dff83..697da67 100644
--- a/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java
+++ b/test/com/sun/crypto/provider/Cipher/AES/TestCopySafe.java
@@ -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",
diff --git a/test/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java b/test/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java
new file mode 100644
index 0000000..7006abc
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/Blowfish/TestCipherBlowfish.java
@@ -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();
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java
new file mode 100644
index 0000000..ba219c2
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDES.java
@@ -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();
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java
new file mode 100644
index 0000000..ec95985
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/DES/TestCipherDESede.java
@@ -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();
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java
new file mode 100644
index 0000000..f304989
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/PBE/TestCipherPBE.java
@@ -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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/TestCipher.java b/test/com/sun/crypto/provider/Cipher/TestCipher.java
new file mode 100644
index 0000000..9cb25c7
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/TestCipher.java
@@ -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;
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/TextLength/DESCipherWrapper.java b/test/com/sun/crypto/provider/Cipher/TextLength/DESCipherWrapper.java
new file mode 100644
index 0000000..61551a47
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/TextLength/DESCipherWrapper.java
@@ -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");
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java b/test/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java
new file mode 100644
index 0000000..4af5215
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/TextLength/PBECipherWrapper.java
@@ -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);
+ }
+ }
+}
diff --git a/test/com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java b/test/com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java
new file mode 100644
index 0000000..1f38e44
--- /dev/null
+++ b/test/com/sun/crypto/provider/Cipher/TextLength/TestCipherTextLength.java
@@ -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);
+ }
+ }
+}
diff --git a/test/com/sun/jndi/ldap/SimpleClientIdHashCode.java b/test/com/sun/jndi/ldap/SimpleClientIdHashCode.java
new file mode 100644
index 0000000..956e2c4
--- /dev/null
+++ b/test/com/sun/jndi/ldap/SimpleClientIdHashCode.java
@@ -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");
+ }
+}
diff --git a/test/demo/jvmti/hprof/CpuOldTest.java b/test/demo/jvmti/hprof/CpuOldTest.java
index 8207044..0017b21 100644
--- a/test/demo/jvmti/hprof/CpuOldTest.java
+++ b/test/demo/jvmti/hprof/CpuOldTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/CpuSamplesTest.java b/test/demo/jvmti/hprof/CpuSamplesTest.java
index ad46618..986af43 100644
--- a/test/demo/jvmti/hprof/CpuSamplesTest.java
+++ b/test/demo/jvmti/hprof/CpuSamplesTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java b/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java
index 97c50eb..3cf96bb 100644
--- a/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java
+++ b/test/demo/jvmti/hprof/CpuTimesDefineClassTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/CpuTimesTest.java b/test/demo/jvmti/hprof/CpuTimesTest.java
index 7692d2a..4d67900 100644
--- a/test/demo/jvmti/hprof/CpuTimesTest.java
+++ b/test/demo/jvmti/hprof/CpuTimesTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/HeapAllTest.java b/test/demo/jvmti/hprof/HeapAllTest.java
index 0801559..d543f73 100644
--- a/test/demo/jvmti/hprof/HeapAllTest.java
+++ b/test/demo/jvmti/hprof/HeapAllTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/HeapBinaryFormatTest.java b/test/demo/jvmti/hprof/HeapBinaryFormatTest.java
index 94567cd..0bc0135 100644
--- a/test/demo/jvmti/hprof/HeapBinaryFormatTest.java
+++ b/test/demo/jvmti/hprof/HeapBinaryFormatTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/HeapDumpTest.java b/test/demo/jvmti/hprof/HeapDumpTest.java
index 32cc01c..1129e93 100644
--- a/test/demo/jvmti/hprof/HeapDumpTest.java
+++ b/test/demo/jvmti/hprof/HeapDumpTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/HeapSitesTest.java b/test/demo/jvmti/hprof/HeapSitesTest.java
index 3bdbe6c..855bfad 100644
--- a/test/demo/jvmti/hprof/HeapSitesTest.java
+++ b/test/demo/jvmti/hprof/HeapSitesTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/MonitorTest.java b/test/demo/jvmti/hprof/MonitorTest.java
index 2512efd..2e8261f 100644
--- a/test/demo/jvmti/hprof/MonitorTest.java
+++ b/test/demo/jvmti/hprof/MonitorTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/OptionsTest.java b/test/demo/jvmti/hprof/OptionsTest.java
index 397357c..ebd0922 100644
--- a/test/demo/jvmti/hprof/OptionsTest.java
+++ b/test/demo/jvmti/hprof/OptionsTest.java
@@ -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 */
diff --git a/test/demo/jvmti/hprof/StackMapTableTest.java b/test/demo/jvmti/hprof/StackMapTableTest.java
index eb3fae1..3e4629e 100644
--- a/test/demo/jvmti/hprof/StackMapTableTest.java
+++ b/test/demo/jvmti/hprof/StackMapTableTest.java
@@ -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 */
diff --git a/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java b/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
index ec42aa9..a22d51f 100644
--- a/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
+++ b/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
@@ -93,6 +93,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);
diff --git a/test/java/awt/Window/WindowJumpingTest/WindowJumpingTest.java b/test/java/awt/Window/WindowJumpingTest/WindowJumpingTest.java
new file mode 100644
index 0000000..f2e2100
--- /dev/null
+++ b/test/java/awt/Window/WindowJumpingTest/WindowJumpingTest.java
@@ -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");
+ }
+ }
+}
+
diff --git a/test/java/awt/Window/WindowsLeak/WindowsLeak.java b/test/java/awt/Window/WindowsLeak/WindowsLeak.java
index dd776a8..3f44687 100644
--- a/test/java/awt/Window/WindowsLeak/WindowsLeak.java
+++ b/test/java/awt/Window/WindowsLeak/WindowsLeak.java
@@ -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 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);
diff --git a/test/java/awt/im/8148984/bug8148984.html b/test/java/awt/im/8148984/bug8148984.html
new file mode 100644
index 0000000..c6eb7c2
--- /dev/null
+++ b/test/java/awt/im/8148984/bug8148984.html
@@ -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>
diff --git a/test/java/awt/im/8148984/bug8148984.java b/test/java/awt/im/8148984/bug8148984.java
new file mode 100644
index 0000000..3869b3c
--- /dev/null
+++ b/test/java/awt/im/8148984/bug8148984.java
@@ -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);
+ }
+ });
+ }
+}
+
diff --git a/test/java/awt/im/8154816/bug8154816.html b/test/java/awt/im/8154816/bug8154816.html
new file mode 100644
index 0000000..1fdb5fd
--- /dev/null
+++ b/test/java/awt/im/8154816/bug8154816.html
@@ -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>
diff --git a/test/java/awt/im/8154816/bug8154816.java b/test/java/awt/im/8154816/bug8154816.java
new file mode 100644
index 0000000..b3bda4f
--- /dev/null
+++ b/test/java/awt/im/8154816/bug8154816.java
@@ -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);
+ }
+ });
+ }
+}
+
diff --git a/test/java/lang/annotation/AnnotationWithLambda.java b/test/java/lang/annotation/AnnotationWithLambda.java
new file mode 100644
index 0000000..ac21352
--- /dev/null
+++ b/test/java/lang/annotation/AnnotationWithLambda.java
@@ -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");
+}
+
diff --git a/test/java/lang/invoke/ArrayConstructorTest.java b/test/java/lang/invoke/ArrayConstructorTest.java
new file mode 100644
index 0000000..1730dbd
--- /dev/null
+++ b/test/java/lang/invoke/ArrayConstructorTest.java
@@ -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);
+ }
+
+}
+
diff --git a/test/java/lang/invoke/CustomizedLambdaFormTest.java b/test/java/lang/invoke/CustomizedLambdaFormTest.java
index 3e24673..a0ecdcd 100644
--- a/test/java/lang/invoke/CustomizedLambdaFormTest.java
+++ b/test/java/lang/invoke/CustomizedLambdaFormTest.java
@@ -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 {
diff --git a/test/java/lang/invoke/PermuteArgsTest.java b/test/java/lang/invoke/PermuteArgsTest.java
index edb9ba3..a47e4d7 100644
--- a/test/java/lang/invoke/PermuteArgsTest.java
+++ b/test/java/lang/invoke/PermuteArgsTest.java
@@ -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()) {
diff --git a/test/java/lang/invoke/VarargsArrayTest.java b/test/java/lang/invoke/VarargsArrayTest.java
index a247fa5..468eb42 100644
--- a/test/java/lang/invoke/VarargsArrayTest.java
+++ b/test/java/lang/invoke/VarargsArrayTest.java
@@ -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;
diff --git a/test/java/security/KeyStore/TestKeyStoreBasic.java b/test/java/security/KeyStore/TestKeyStoreBasic.java
new file mode 100644
index 0000000..ea7c1f4
--- /dev/null
+++ b/test/java/security/KeyStore/TestKeyStoreBasic.java
@@ -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;
+ }
+
+}
diff --git a/test/java/security/KeyStore/TestKeyStoreEntry.java b/test/java/security/KeyStore/TestKeyStoreEntry.java
new file mode 100644
index 0000000..e98c73a
--- /dev/null
+++ b/test/java/security/KeyStore/TestKeyStoreEntry.java
@@ -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");
+ }
+ }
+ }
+ }
+
+}
diff --git a/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java
new file mode 100644
index 0000000..68d0451
--- /dev/null
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest.java
@@ -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);
+ }
+ }
+
+}
diff --git a/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy
new file mode 100644
index 0000000..3ac5df2
--- /dev/null
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest1.policy
@@ -0,0 +1,4 @@
+grant {
+ permission TVJar.TVPermission "channel:3-6", "watch";
+};
+
diff --git a/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy
new file mode 100644
index 0000000..7407704
--- /dev/null
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest2.policy
@@ -0,0 +1,3 @@
+grant {
+ permission TVJar.TVPermission "channel:4", "watch";
+};
diff --git a/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy
new file mode 100644
index 0000000..3553000
--- /dev/null
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyTest3.policy
@@ -0,0 +1,5 @@
+keystore "file:${user.dir}/epkeystore";
+
+grant {
+ permission TVJar.TVPermission "channel:5", "watch", SignedBy "duke2";
+};
\ No newline at end of file
diff --git a/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java
new file mode 100644
index 0000000..f3b77b9
--- /dev/null
+++ b/test/java/security/Policy/ExtensiblePolicy/ExtensiblePolicyWithJarTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+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);
+ }
+ }
+ }
+
+}
diff --git a/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java b/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java
new file mode 100644
index 0000000..e1ab763
--- /dev/null
+++ b/test/java/security/Policy/ExtensiblePolicy/TVJar/TVPermission.java
@@ -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);
+ }
+
+}
diff --git a/test/java/security/SecureRandom/DefaultProvider.java b/test/java/security/SecureRandom/DefaultProvider.java
index 50b4719..597f235 100644
--- a/test/java/security/SecureRandom/DefaultProvider.java
+++ b/test/java/security/SecureRandom/DefaultProvider.java
@@ -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,
diff --git a/test/java/security/Security/AddProvider.java b/test/java/security/Security/AddProvider.java
index 27559ff..b702221 100644
--- a/test/java/security/Security/AddProvider.java
+++ b/test/java/security/Security/AddProvider.java
@@ -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
diff --git a/test/java/security/Security/AddProvider.policy.1 b/test/java/security/Security/AddProvider.policy.1
index 17a49b4..64b43d7 100644
--- a/test/java/security/Security/AddProvider.policy.1
+++ b/test/java/security/Security/AddProvider.policy.1
@@ -1,7 +1,3 @@
-grant codeBase "file:${{java.ext.dirs}}/*" {
- permission java.security.AllPermission;
-};
-
grant {
permission java.security.SecurityPermission "insertProvider";
};
diff --git a/test/java/security/Security/AddProvider.policy.2 b/test/java/security/Security/AddProvider.policy.2
index d5a7ca9..e2a8677 100644
--- a/test/java/security/Security/AddProvider.policy.2
+++ b/test/java/security/Security/AddProvider.policy.2
@@ -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";
diff --git a/test/java/security/Security/AddProvider.policy.3 b/test/java/security/Security/AddProvider.policy.3
index 930b443..9a14db2 100644
--- a/test/java/security/Security/AddProvider.policy.3
+++ b/test/java/security/Security/AddProvider.policy.3
@@ -1,7 +1,3 @@
-grant codeBase "file:${{java.ext.dirs}}/*" {
- permission java.security.AllPermission;
-};
-
grant {
permission java.security.SecurityPermission "insertProvider.*";
};
diff --git a/test/java/security/Security/EmptyPolicy.policy b/test/java/security/Security/EmptyPolicy.policy
new file mode 100644
index 0000000..f764592
--- /dev/null
+++ b/test/java/security/Security/EmptyPolicy.policy
@@ -0,0 +1,2 @@
+// empty policy file for testing
+
diff --git a/test/java/security/Security/GetProviders.java b/test/java/security/Security/GetProviders.java
new file mode 100644
index 0000000..a796645
--- /dev/null
+++ b/test/java/security/Security/GetProviders.java
@@ -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");
+ }
+
+}
diff --git a/test/java/security/Security/removing/RemoveStaticProvider.java b/test/java/security/Security/removing/RemoveStaticProvider.java
index 6a03ec7..20d4435 100644
--- a/test/java/security/Security/removing/RemoveStaticProvider.java
+++ b/test/java/security/Security/removing/RemoveStaticProvider.java
@@ -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
*/
diff --git a/test/java/security/Security/removing/RemoveStaticProvider.policy b/test/java/security/Security/removing/RemoveStaticProvider.policy
index 3b186af..f31e587 100644
--- a/test/java/security/Security/removing/RemoveStaticProvider.policy
+++ b/test/java/security/Security/removing/RemoveStaticProvider.policy
@@ -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;
-};
-
diff --git a/test/javax/management/MBeanServer/ExceptionFactory.java b/test/javax/management/MBeanServer/ExceptionFactory.java
new file mode 100644
index 0000000..2315edf
--- /dev/null
+++ b/test/javax/management/MBeanServer/ExceptionFactory.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import javax.management.AttributeNotFoundException;
+import javax.management.BadAttributeValueExpException;
+import javax.management.BadBinaryOpValueExpException;
+import javax.management.BadStringOperationException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidApplicationException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMException;
+import javax.management.JMRuntimeException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.OperationsException;
+import javax.management.ReflectionException;
+import javax.management.RuntimeErrorException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
+import javax.management.ServiceNotFoundException;
+import javax.management.StringValueExp;
+import javax.management.modelmbean.InvalidTargetObjectTypeException;
+import javax.management.modelmbean.XMLParseException;
+import javax.management.monitor.MonitorSettingException;
+import javax.management.openmbean.InvalidKeyException;
+import javax.management.openmbean.InvalidOpenTypeException;
+import javax.management.openmbean.KeyAlreadyExistsException;
+import javax.management.openmbean.OpenDataException;
+import javax.management.relation.InvalidRelationIdException;
+import javax.management.relation.InvalidRelationServiceException;
+import javax.management.relation.InvalidRelationTypeException;
+import javax.management.relation.InvalidRoleInfoException;
+import javax.management.relation.InvalidRoleValueException;
+import javax.management.relation.RelationException;
+import javax.management.relation.RelationNotFoundException;
+import javax.management.relation.RelationServiceNotRegisteredException;
+import javax.management.relation.RelationTypeNotFoundException;
+import javax.management.relation.RoleInfoNotFoundException;
+import javax.management.relation.RoleNotFoundException;
+import javax.management.remote.JMXProviderException;
+import javax.management.remote.JMXServerErrorException;
+
+/**
+ * |----- Original Description Coming From Tonga Original Source Code -------|
+ * | |
+ * | That class creates an ArrayList and fill it with an instance of each of |
+ * | the Exception class of the JMX API. |
+ * | It's dedicated to use by ExceptionTest. |
+ * |-------------------------------------------------------------------------|
+ */
+public class ExceptionFactory {
+
+ public static final ArrayList<Exception> exceptions =
+ new ArrayList<Exception>();
+
+ static {
+ String mes = "SQE";
+ exceptions.add(new AttributeNotFoundException());
+ exceptions.add(new BadAttributeValueExpException(mes));
+ exceptions.add(new BadBinaryOpValueExpException(new StringValueExp(mes)));
+ exceptions.add(new BadStringOperationException(mes));
+ exceptions.add(new InstanceAlreadyExistsException());
+ exceptions.add(new InstanceNotFoundException());
+ exceptions.add(new IntrospectionException());
+ exceptions.add(new InvalidApplicationException(mes));
+ exceptions.add(new InvalidAttributeValueException());
+ exceptions.add(new JMException());
+ exceptions.add(new JMRuntimeException());
+ exceptions.add(new ListenerNotFoundException());
+ exceptions.add(new MalformedObjectNameException());
+ exceptions.add(new MBeanException(new Exception(mes), mes));
+ exceptions.add(new MBeanRegistrationException(new Exception(mes), mes));
+ exceptions.add(new NotCompliantMBeanException());
+ exceptions.add(new OperationsException());
+ exceptions.add(new ReflectionException(new Exception(mes), mes));
+ exceptions.add(new RuntimeErrorException(new Error(mes), mes));
+ exceptions.add(new RuntimeMBeanException(new RuntimeException(mes), mes));
+ exceptions.add(new RuntimeOperationsException(new RuntimeException(mes), mes));
+ exceptions.add(new ServiceNotFoundException());
+ exceptions.add(new InvalidTargetObjectTypeException());
+ exceptions.add(new XMLParseException());
+ exceptions.add(new MonitorSettingException());
+ exceptions.add(new InvalidKeyException());
+ exceptions.add(new InvalidOpenTypeException());
+ exceptions.add(new KeyAlreadyExistsException());
+ exceptions.add(new OpenDataException());
+ exceptions.add(new InvalidRelationIdException());
+ exceptions.add(new InvalidRelationServiceException());
+ exceptions.add(new InvalidRelationTypeException());
+ exceptions.add(new InvalidRoleInfoException());
+ exceptions.add(new InvalidRoleValueException());
+ exceptions.add(new RelationException());
+ exceptions.add(new RelationNotFoundException());
+ exceptions.add(new RelationServiceNotRegisteredException());
+ exceptions.add(new RelationTypeNotFoundException());
+ exceptions.add(new RoleInfoNotFoundException());
+ exceptions.add(new RoleNotFoundException());
+ exceptions.add(new JMXProviderException());
+ exceptions.add(new JMXServerErrorException(mes, new Error(mes)));
+ ExceptionTest.Utils.debug(ExceptionTest.Utils.DEBUG_STANDARD,
+ "DataFactory::updateMap: Initialized" +
+ " an ArrayList with the " +
+ exceptions.size() + " exceptions of the JMX API");
+ }
+}
diff --git a/test/javax/management/MBeanServer/ExceptionTest.java b/test/javax/management/MBeanServer/ExceptionTest.java
new file mode 100644
index 0000000..571e43d
--- /dev/null
+++ b/test/javax/management/MBeanServer/ExceptionTest.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks that exceptions are correctly wired (compared to reference).
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD ExceptionTest
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import java.lang.management.ManagementFactory;
+import javax.management.ObjectName;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+
+public class ExceptionTest {
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ ExceptionTest test = new ExceptionTest();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("ExceptionTest::run: Start");
+ int errorCount = 0;
+
+ JMXConnectorServer cs = null;
+ JMXConnector cc = null;
+
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ ObjectName objName =
+ new ObjectName(ExceptionThrower.EXCEPTION_THROWER_NAME);
+ System.out.println("ExceptionTest::run: Create and register MBean " + objName);
+ mbsc.createMBean("ExceptionThrower", objName);
+ System.out.println("---- OK\n");
+
+ // ----
+ System.out.println("ExceptionTest::run: Ask for exception(s)");
+ Object[] throwExceptionParam = new Object[1];
+ String[] throwExceptionSig = new String[]{"int"};
+
+ for (int i = 0; i < ExceptionFactory.exceptions.size(); i++) {
+ throwExceptionParam[0] = new Integer(i);
+
+ Exception ex =
+ (Exception)mbsc.invoke(objName,
+ "throwException", throwExceptionParam, throwExceptionSig);
+
+ if ( ! matches(ex, ExceptionFactory.exceptions.get(i)) ) {
+ errorCount++;
+ System.out.println("ExceptionTest::run: (ERROR) Received \n["
+ + ex + "]\nin place of\n["
+ + ExceptionFactory.exceptions.get(i) + "]");
+ } else {
+ System.out.println("OK [" + ex + "]");
+ }
+ }
+
+ System.out.println("---- DONE\n");
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ throw new RuntimeException();
+ } finally {
+ try {
+ // Close JMX Connector Client
+ cc.close();
+ // Stop connertor server
+ cs.stop();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ throw new RuntimeException(
+ "Unable to either close connector client or stop connector server");
+ }
+ }
+
+ if (errorCount == 0) {
+ System.out.println("ExceptionTest::run: Done without any error");
+ } else {
+ System.out.println("ExceptionTest::run: Done with " + errorCount
+ + " error(s)");
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ System.out.println("ExceptionTest::run: Done");
+ }
+
+ // Check both Exception are identical.
+ // That means:
+ // - none is null.
+ // - they are of the same Class.
+ // - if their respective messages aren't null they're equal.
+ // - if the message of one is null the message of the other is null too.
+ private boolean matches(Exception ex, Exception refex) {
+ if ( ex == null || refex == null ) {
+ System.out.println("(ERROR) Called with one or more null parameter; check "
+ + ex + " against " + refex);
+ return false;
+ }
+
+ String exClass = ex.getClass().getName();
+ String refexClass = refex.getClass().getName();
+
+ if ( ! exClass.equals(refexClass) ) {
+ System.out.println("(ERROR) Class names don't match; check ["
+ + exClass + "] against [" + refexClass + "]");
+ return false;
+ }
+
+ String exMes = ex.getMessage();
+ String refexMes = refex.getMessage();
+
+ if ( exMes != null && refexMes != null ) {
+ if ( ! exMes.equals(refexMes) ) {
+ System.out.println("(ERROR) Non null messages don't match; check ["
+ + exMes + "] against [" + refexMes + "]");
+ return false;
+ }
+ } else if ( (exMes == null && refexMes != null)
+ || (exMes != null && refexMes == null) ) {
+ System.out.println("(ERROR) Messages don't match; check [" + exMes
+ + "] against [" + refexMes + "]");
+ }
+
+ return true;
+ }
+
+ // Utility inner class coming from JMX Tonga test suite.
+ // Also used by ExceptionFactory.
+ static class Utils {
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+ }
+
+}
+
+
diff --git a/test/javax/management/MBeanServer/ExceptionThrower.java b/test/javax/management/MBeanServer/ExceptionThrower.java
new file mode 100644
index 0000000..37d661e
--- /dev/null
+++ b/test/javax/management/MBeanServer/ExceptionThrower.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This class defines a simple standard MBean.
+ */
+public class ExceptionThrower implements ExceptionThrowerMBean {
+
+ public static final String EXCEPTION_THROWER_NAME
+ = "sqe:type=ExceptionThrower";
+
+ public Exception throwException(int exceptionIndex) {
+ return ExceptionFactory.exceptions.get(exceptionIndex);
+ }
+}
diff --git a/test/javax/management/MBeanServer/ExceptionThrowerMBean.java b/test/javax/management/MBeanServer/ExceptionThrowerMBean.java
new file mode 100644
index 0000000..d5485d3
--- /dev/null
+++ b/test/javax/management/MBeanServer/ExceptionThrowerMBean.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This interface defines a simple standard MBean.
+ */
+public interface ExceptionThrowerMBean {
+ public Exception throwException(int exceptionIndex);
+}
diff --git a/test/javax/management/keystoreAgent b/test/javax/management/keystoreAgent
new file mode 100644
index 0000000..cfb02e0
--- /dev/null
+++ b/test/javax/management/keystoreAgent
Binary files differ
diff --git a/test/javax/management/keystoreClient b/test/javax/management/keystoreClient
new file mode 100644
index 0000000..f0e0b7f
--- /dev/null
+++ b/test/javax/management/keystoreClient
Binary files differ
diff --git a/test/javax/management/monitor/GaugeMonitorDeadlockTest.java b/test/javax/management/monitor/GaugeMonitorDeadlockTest.java
index c85c223..9e063a2 100644
--- a/test/javax/management/monitor/GaugeMonitorDeadlockTest.java
+++ b/test/javax/management/monitor/GaugeMonitorDeadlockTest.java
@@ -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();
diff --git a/test/javax/management/monitor/StringMonitorDeadlockTest.java b/test/javax/management/monitor/StringMonitorDeadlockTest.java
index 2f78ce6..72929c2 100644
--- a/test/javax/management/monitor/StringMonitorDeadlockTest.java
+++ b/test/javax/management/monitor/StringMonitorDeadlockTest.java
@@ -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);
- monitorProxy.start();
final int initGetCount = observedProxy.getGetCount();
+ monitorProxy.start();
+
int getCount = initGetCount;
for (int i = 0; i < 500; i++) { // 500 * 10 = 5 seconds
getCount = observedProxy.getGetCount();
diff --git a/test/javax/management/mxbean/Basic.java b/test/javax/management/mxbean/Basic.java
new file mode 100644
index 0000000..3f32af6
--- /dev/null
+++ b/test/javax/management/mxbean/Basic.java
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+
+/**
+ * Class Basic
+ * Basic Description
+ */
+public class Basic implements BasicMXBean, NotificationEmitter,
+ MBeanRegistration {
+
+ public static final String EXCEPTION_MESSAGE = "from Basic";
+ public static final String NOTIFICATION_MESSAGE = "from Basic";
+ /** Attribute : IntAtt */
+ private int intAtt = 0;
+ /** Attribute : IntegerAtt */
+ private Integer integerAtt = 0;
+ /** Attribute : BoolAtt */
+ private boolean boolAtt = false;
+ /** Attribute : BooleanAtt */
+ private Boolean booleanAtt = false;
+ /** Attribute : StringAtt */
+ private String stringAtt = null;
+ /** Attribute : DateAtt */
+ private Date dateAtt = null;
+ /** Attribute : ObjectNameAtt */
+ private ObjectName objectNameAtt = null;
+ /** Attribute : NotifDescriptorAsMapAtt */
+ private Map<String, String> notifDescriptorAsMapAtt = null;
+ /** Attribute : NotifDescriptorAtt */
+ private Descriptor notifDescriptorAtt = null;
+ /** Attribute : SqeParameter */
+ private SqeParameter sqeParameterAtt = null;
+
+ /* Creates a new instance of Basic */
+ @SqeDescriptorKey("CONSTRUCTOR Basic")
+ public Basic() {
+ }
+
+ /* Creates a new instance of Basic */
+ @SqeDescriptorKey("CONSTRUCTOR Basic")
+ public Basic(
+ @SqeDescriptorKey("CONSTRUCTOR PARAMETER SqeParameter") SqeParameter param) {
+ }
+
+ /**
+ * Get int attribute
+ */
+ public int getIntAtt() {
+ return intAtt;
+ }
+
+ /**
+ * Set int attribute
+ */
+ public void setIntAtt(int value) {
+ intAtt = value;
+ }
+
+ /**
+ * Get Integer attribute
+ */
+ public Integer getIntegerAtt() {
+ return integerAtt;
+ }
+
+ /**
+ * Set Integer attribute
+ */
+ public void setIntegerAtt(Integer value) {
+ integerAtt = value;
+ }
+
+ /**
+ * Get boolean attribute
+ */
+ public boolean getBoolAtt() {
+ return boolAtt;
+ }
+
+ /**
+ * Set boolean attribute
+ */
+ public void setBoolAtt(boolean value) {
+ boolAtt = value;
+ }
+
+ /**
+ * Get Boolean attribute
+ */
+ public Boolean getBooleanAtt() {
+ return booleanAtt;
+ }
+
+ /**
+ * Set Boolean attribute
+ */
+ public void setBooleanAtt(Boolean value) {
+ booleanAtt = value;
+ }
+
+ /**
+ * Get String attribute
+ */
+ public String getStringAtt() {
+ return stringAtt;
+ }
+
+ /**
+ * Set String attribute
+ */
+ public void setStringAtt(String value) {
+ stringAtt = value;
+ }
+
+ /**
+ * Get Date attribute
+ */
+ public Date getDateAtt() {
+ return dateAtt;
+ }
+
+ /**
+ * Set Date attribute
+ */
+ public void setDateAtt(Date value) {
+ dateAtt = value;
+ }
+
+ /**
+ * Get ObjectName attribute
+ */
+ public ObjectName getObjectNameAtt() {
+ return objectNameAtt;
+ }
+
+ /**
+ * Set ObjectName attribute
+ */
+ public void setObjectNameAtt(ObjectName value) {
+ objectNameAtt = value;
+ }
+
+ /**
+ * Get SqeParameter attribute
+ */
+ public SqeParameter getSqeParameterAtt() throws Exception {
+ if (sqeParameterAtt == null) {
+ sqeParameterAtt = new SqeParameter();
+ sqeParameterAtt.setGlop("INITIALIZED");
+ }
+
+ return sqeParameterAtt;
+ }
+
+ /**
+ * Set SqeParameter attribute
+ */
+ public void setSqeParameterAtt(SqeParameter value) {
+ sqeParameterAtt = value;
+ }
+
+ /**
+ * Get the Descriptor used to build the NotificationInfo
+ * of emitted notifications.
+ */
+ public Map<String, String> getNotifDescriptorAsMapAtt() {
+ if (notifDescriptorAsMapAtt == null) {
+ initNotifDescriptorAtt();
+ }
+
+ return notifDescriptorAsMapAtt;
+ }
+
+ /**
+ * Set the Descriptor used to build the NotificationInfo
+ * of emitted notifications.
+ * <br>A Map<String, Object> would better fit Descriptor needs but then
+ * it is not convertible according the MXBean specification so the MBean
+ * registration fails.
+ * As we plan to test our custom Descriptor finds its way into
+ * the metadata of emitted notifications, String is good enough.
+ */
+ public void setNotifDescriptorAsMapAtt(Map<String, String> value) {
+ notifDescriptorAsMapAtt = new HashMap<String, String>(value);
+ notifDescriptorAtt = new ImmutableDescriptor(value);
+ }
+
+ /**
+ * Do nothing
+ */
+ public void doNothing() {
+ // I said NOTHING !
+ }
+
+ /**
+ * Do take SqeParameter as a parameter
+ */
+ public void doWeird(SqeParameter param) {
+ }
+
+ /**
+ * Throw an Exception
+ */
+ public void throwException() throws Exception {
+ throw new Exception(EXCEPTION_MESSAGE);
+ }
+
+ /**
+ * Throw an Error
+ */
+ public void throwError() {
+ throw new InternalError(EXCEPTION_MESSAGE);
+ }
+
+ /**
+ * Reset all attributes
+ */
+ public void reset() {
+ intAtt = 0;
+ integerAtt = 0;
+ boolAtt = false;
+ booleanAtt = Boolean.FALSE;
+ stringAtt = null;
+ dateAtt = null;
+ objectNameAtt = null;
+ }
+
+ /**
+ * Returns the weather for the coming days
+ * @param verbose <code>boolean</code> verbosity
+ * @throws java.lang.Exception <code>storm</code>
+ * @return <code>ObjectName</code>
+ */
+ public Weather getWeather(boolean verbose)
+ throws java.lang.Exception {
+ return Weather.SUNNY;
+ }
+
+ // Starting here are the 4 methods of MBeanRegistration interface.
+ // We use that to grab the ObjectName the MBean is registered with.
+ //
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ // Grab a reference on the MBeanServer we're registered in.
+ mbs = server;
+ // Compute the name we're registered with.
+ if (name != null) {
+ mbeanName = name;
+ return name;
+ } else {
+ mbeanName =
+ new ObjectName("sqe:type=" + Basic.class.getName());
+ return mbeanName;
+ }
+ }
+
+ public void postRegister(Boolean registrationDone) {
+ // Do nothing
+ }
+
+ public void preDeregister() throws Exception {
+ // Do nothing
+ }
+
+ public void postDeregister() {
+ // Do nothing
+ }
+
+ /**
+ * Send one Notification of the provided notifType type.
+ */
+ public void sendNotification(String notifType) {
+ Notification notification = null;
+
+ if (notifType.equals(NOTIF_TYPE_0)) {
+ notification = new Notification(NOTIF_TYPE_0,
+ mbeanName,
+ seqNumber,
+ NOTIFICATION_MESSAGE);
+ } else if (notifType.equals(NOTIF_TYPE_1)) {
+ notification = new SqeNotification(NOTIF_TYPE_1,
+ mbeanName,
+ seqNumber,
+ NOTIFICATION_MESSAGE);
+ }
+
+ seqNumber++;
+ broadcaster.sendNotification(notification);
+ }
+
+ /**
+ * That method starts a set of threads, each thread sends a given number of
+ * notifications.
+ * The number of threads can be set via the attribute numOfNotificationSenders.
+ * The number of notification sent by each thread can be set via
+ * the attribute numOfNotificationSenderLoops.
+ * Depending on the parameter customNotification we send either custom
+ * notification(s) or MBeanServer registration and unregistration notification(s).
+ * When customNotification=true the total number of notification(s) sent is
+ * (numOfNotificationSenders * numOfNotificationSenderLoops). They are
+ * sequentially of type NOTIF_TYPE_0 then NOTIF_TYPE_1 and so on.
+ *
+ * When customNotification=false the total number of notification(s) sent is
+ * (numOfNotificationSenders * numOfNotificationSenderLoops) registration
+ * notification(s)
+ * +
+ * (numOfNotificationSenders * numOfNotificationSenderLoops) unregistration
+ * notification(s)
+ *
+ * @throws java.lang.Exception
+ */
+ public void sendNotificationWave(boolean customNotification) throws
+ Exception {
+ // Build the set of notification sender.
+ Collection<Callable<Integer>> tasks =
+ new HashSet<Callable<Integer>>(numOfNotificationSenders);
+
+ for (int i = 1; i <= numOfNotificationSenders; i++) {
+ tasks.add(new NotifSender(numOfNotificationSenderLoops,
+ customNotification, i));
+ }
+
+ // Start all notification sender in parallel.
+ ExecutorService execServ = null;
+ try {
+ execServ = Executors.newFixedThreadPool(numOfNotificationSenders);
+ List<Future<Integer>> taskHandlers = execServ.invokeAll(tasks);
+ checkNotifSenderThreadStatus(taskHandlers);
+ } finally {
+ if (!execServ.isShutdown()) {
+ execServ.shutdown();
+ }
+ }
+ }
+
+ public void setNumOfNotificationSenders(int value) {
+ numOfNotificationSenders = value;
+ }
+
+ public void setNumOfNotificationSenderLoops(int value) {
+ numOfNotificationSenderLoops = value;
+ }
+
+ /**
+ * MBean Notification support
+ * You shouldn't update these methods
+ */
+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">
+ public void addNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws IllegalArgumentException {
+ broadcaster.addNotificationListener(listener, filter, handback);
+ }
+
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ if (notifDescriptorAtt == null) {
+ initNotifDescriptorAtt();
+ }
+
+ return new MBeanNotificationInfo[]{
+ new MBeanNotificationInfo(new String[]{
+ NOTIF_TYPE_0
+ },
+ javax.management.Notification.class.getName(),
+ "Standard JMX Notification",
+ notifDescriptorAtt),
+ new MBeanNotificationInfo(new String[]{
+ NOTIF_TYPE_1
+ },
+ SqeNotification.class.getName(),
+ "SQE Notification",
+ notifDescriptorAtt)
+ };
+ }
+
+ public void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ broadcaster.removeNotificationListener(listener);
+ }
+
+ public void removeNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws ListenerNotFoundException {
+ broadcaster.removeNotificationListener(listener, filter, handback);
+ }
+ // </editor-fold>
+ private synchronized long getNextSeqNumber() {
+ return seqNumber++;
+ }
+
+ private void initNotifDescriptorAtt() {
+ String key = "CRABE";
+ String value = "TAMBOUR";
+ notifDescriptorAtt =
+ new ImmutableDescriptor(new String[]{key + "=" + value});
+ notifDescriptorAsMapAtt =
+ new HashMap<String, String>();
+ notifDescriptorAsMapAtt.put(key, value);
+ }
+
+ private void checkNotifSenderThreadStatus(
+ List<Future<Integer>> taskHandlers)
+ throws Exception {
+ String msgTag = "Basic::checkNotifSenderThreadStatus: ";
+ // Grab back status of each notification sender.
+ for (Future<Integer> f : taskHandlers) {
+ if (f.isCancelled()) {
+ String message = msgTag +
+ "---- ERROR : One thread has been cancelled";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ } else {
+ Integer effectiveNumOfLoops = f.get();
+
+ if (effectiveNumOfLoops != numOfNotificationSenderLoops) {
+ String message = msgTag + "---- ERROR : One thread did " +
+ effectiveNumOfLoops + " loops in place of " +
+ numOfNotificationSenderLoops;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+ }
+ }
+ //
+ private int numOfNotificationSenderLoops = 2;
+ private int numOfNotificationSenders = 13;
+
+ private class NotifSender implements Callable<Integer> {
+
+ private int cycles;
+ private boolean customNotification;
+ private int senderID;
+
+ public NotifSender(int cycles, boolean customNotification, int id) {
+ this.cycles = cycles;
+ this.customNotification = customNotification;
+ this.senderID = id;
+ }
+
+ public Integer call() throws Exception {
+ int callsDone = 0;
+
+ try {
+ for (int i = 1; i <= cycles; i++) {
+ if (customNotification) {
+ if (i % 2 == 0) {
+ sendNotification(NOTIF_TYPE_0);
+ } else {
+ sendNotification(NOTIF_TYPE_1);
+ }
+ } else {
+ ObjectName mbeanName = new ObjectName("SQE:type=" +
+ mbeanClassName + ",senderID=" + senderID);
+ mbs.createMBean(mbeanClassName, mbeanName);
+ mbs.unregisterMBean(mbeanName);
+ }
+ callsDone++;
+ }
+ } catch (Exception e) {
+ System.out.println("NotifSender::call: (ERROR) Thread [" + senderID +
+ "] failed after " + callsDone + " cycles");
+ throw e;
+ }
+
+ return Integer.valueOf(callsDone);
+ }
+ }
+
+ //
+ private long seqNumber;
+ private final NotificationBroadcasterSupport broadcaster =
+ new NotificationBroadcasterSupport();
+ private ObjectName mbeanName;
+ private MBeanServer mbs;
+ private String mbeanClassName = "Simple";
+
+ /**
+ * Notification types definitions. To use when creating JMX Notifications.
+ */
+ public static final String NOTIF_TYPE_0 =
+ "sqe.notification.a.type";
+ public static final String NOTIF_TYPE_1 =
+ "sqe.notification.b.type";
+}
diff --git a/test/javax/management/mxbean/BasicMXBean.java b/test/javax/management/mxbean/BasicMXBean.java
new file mode 100644
index 0000000..7693be9
--- /dev/null
+++ b/test/javax/management/mxbean/BasicMXBean.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Date;
+import java.util.Map;
+
+import javax.management.ObjectName;
+
+/**
+ * Interface BasicMBean
+ * Basic Description
+ */
+@SqeDescriptorKey("INTERFACE BasicMXBean")
+public interface BasicMXBean
+{
+ /**
+ * Get int attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE intAtt")
+ public int getIntAtt();
+
+ /**
+ * Set int attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE intAtt")
+ public void setIntAtt(int value);
+
+ /**
+ * Get Integer attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE integerAtt")
+ public Integer getIntegerAtt();
+
+ /**
+ * Set Integer attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE integerAtt")
+ public void setIntegerAtt(Integer value);
+
+ /**
+ * Get boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE boolAtt")
+ public boolean getBoolAtt();
+
+ /**
+ * Set boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE boolAtt")
+ public void setBoolAtt(boolean value);
+
+ /**
+ * Get Boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE booleanAtt")
+ public Boolean getBooleanAtt();
+
+ /**
+ * Set Boolean attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE booleanAtt")
+ public void setBooleanAtt(Boolean value);
+
+ /**
+ * Get String attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE stringAtt")
+ public String getStringAtt();
+
+ /**
+ * Set String attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE stringAtt")
+ public void setStringAtt(String value);
+
+ /**
+ * Get Date attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE dateAtt")
+ public Date getDateAtt();
+
+ /**
+ * Set Date attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE dateAtt")
+ public void setDateAtt(Date value);
+
+ /**
+ * Get ObjectName attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE objectNameAtt")
+ public ObjectName getObjectNameAtt();
+
+ /**
+ * Set ObjectName attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE objectNameAtt")
+ public void setObjectNameAtt(ObjectName value);
+
+ /**
+ * Get SqeParameter attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
+ public SqeParameter getSqeParameterAtt() throws Exception;
+
+ /**
+ * Set SqeParameter attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
+ public void setSqeParameterAtt(SqeParameter value);
+
+ /**
+ * Set NumOfNotificationSenders attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenders")
+ public void setNumOfNotificationSenders(int value);
+
+ /**
+ * Set NumOfNotificationSenderLoops attribute
+ */
+ @SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenderLoops")
+ public void setNumOfNotificationSenderLoops(int value);
+
+ /**
+ * do nothing
+ *
+ */
+ @SqeDescriptorKey("OPERATION doNothing")
+ public void doNothing();
+
+ /**
+ * Do take SqeParameter as a parameter
+ */
+ @SqeDescriptorKey("OPERATION doWeird")
+ public void doWeird(@SqeDescriptorKey("METHOD PARAMETER")SqeParameter param);
+
+ /**
+ * throw an Exception
+ *
+ */
+ @SqeDescriptorKey("OPERATION throwException")
+ public void throwException() throws Exception;
+
+ /**
+ * throw an Error
+ *
+ */
+ @SqeDescriptorKey("OPERATION throwError")
+ public void throwError();
+
+ /**
+ * reset all attributes
+ *
+ */
+ @SqeDescriptorKey("OPERATION reset")
+ public void reset();
+
+ /**
+ * returns the weather for the coming days
+ *
+ * @param verbose <code>boolean</code> verbosity
+ * @return <code>ObjectName</code>
+ */
+ @SqeDescriptorKey("OPERATION getWeather")
+ public Weather getWeather(@SqeDescriptorKey("METHOD PARAMETER")boolean verbose)
+ throws java.lang.Exception;
+
+ public enum Weather {
+ CLOUDY, SUNNY
+ }
+
+ @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
+ public Map<String, String> getNotifDescriptorAsMapAtt();
+
+ @SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
+ public void setNotifDescriptorAsMapAtt(Map<String, String> value);
+
+ @SqeDescriptorKey("OPERATION sendNotification")
+ public void sendNotification(@SqeDescriptorKey("METHOD PARAMETER")String notifType);
+
+ @SqeDescriptorKey("OPERATION sendNotificationWave")
+ public void sendNotificationWave(boolean customNotification) throws Exception;
+}
diff --git a/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java b/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java
new file mode 100644
index 0000000..9607198
--- /dev/null
+++ b/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks correct exception and error events from NotificationListener
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3
+ */
+
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.MBeanException;
+import javax.management.MBeanServerDelegate;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.RuntimeErrorException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanExceptionHandlingTest implements NotificationListener {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+ private long timeForNotificationInSeconds = 3L;
+ private int numOfNotifications = 2;
+ private BlockingQueue<Notification> notifList = null;
+
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanExceptionHandlingTest test = new MXBeanExceptionHandlingTest();
+ test.run(map);
+
+ }
+
+ protected void parseArgs(Map<String, Object> args) throws Exception {
+
+ String arg = null;
+
+ // Init timeForNotificationInSeconds
+ // It is the maximum time in seconds we wait for a notification.
+ arg = (String)args.get("-timeForNotificationInSeconds") ;
+ if (arg != null) {
+ timeForNotificationInSeconds = (new Long(arg)).longValue();
+ }
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanExceptionHandlingTest::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ parseArgs(args);
+ notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
+
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ System.out.println("Add me as notification listener");
+ mbsc.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
+ this, null, null);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("Create and register the MBean");
+ ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("Call method throwException on our MXBean");
+
+ try {
+ mbsc.invoke(objName, "throwException", null, null);
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited MBeanException") ;
+ } catch (MBeanException mbe) {
+ System.out.println("(OK) Got awaited MBeanException") ;
+ Throwable cause = mbe.getCause();
+
+ if ( cause instanceof java.lang.Exception ) {
+ System.out.println("(OK) Cause is of the right class") ;
+ String mess = cause.getMessage();
+
+ if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
+ System.out.println("(OK) Cause message is fine") ;
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause has message "
+ + cause.getMessage()
+ + " as we expect "
+ + Basic.EXCEPTION_MESSAGE) ;
+ }
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause is of class "
+ + cause.getClass().getName()
+ + " as we expect java.lang.Exception") ;
+ }
+ } catch (Exception e) {
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited MBeanException but "
+ + e) ;
+ Utils.printThrowable(e, true);
+ }
+ System.out.println("---- DONE\n") ;
+
+ // ----
+ System.out.println("Call method throwError on our MXBean");
+
+ try {
+ mbsc.invoke(objName, "throwError", null, null);
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited RuntimeErrorException") ;
+ } catch (RuntimeErrorException ree) {
+ System.out.println("(OK) Got awaited RuntimeErrorException") ;
+ Throwable cause = ree.getCause();
+
+ if ( cause instanceof java.lang.InternalError ) {
+ System.out.println("(OK) Cause is of the right class") ;
+ String mess = cause.getMessage();
+
+ if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
+ System.out.println("(OK) Cause message is fine") ;
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause has message "
+ + cause.getMessage()
+ + " as we expect "
+ + Basic.EXCEPTION_MESSAGE) ;
+ }
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) Cause is of class "
+ + cause.getClass().getName()
+ + " as we expect java.lang.InternalError") ;
+ }
+ } catch (Exception e) {
+ errorCount++;
+ System.out.println("(ERROR) Did not get awaited RuntimeErrorException but "
+ + e) ;
+ Utils.printThrowable(e, true);
+ }
+ System.out.println("---- DONE\n") ;
+
+ // ----
+ System.out.println("Unregister the MBean");
+ mbsc.unregisterMBean(objName);
+ System.out.println("---- OK\n") ;
+
+ Thread.sleep(timeForNotificationInSeconds * 1000);
+ int numOfReceivedNotif = notifList.size();
+
+ if ( numOfReceivedNotif == numOfNotifications ) {
+ System.out.println("(OK) We received "
+ + numOfNotifications
+ + " Notifications") ;
+ } else {
+ errorCount++;
+ System.out.println("(ERROR) We received "
+ + numOfReceivedNotif
+ + " Notifications in place of "
+ + numOfNotifications) ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanExceptionHandlingTest::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanExceptionHandlingTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+ public void handleNotification(Notification notification, Object handback) {
+ System.out.println("MXBeanExceptionHandlingTest::handleNotification: Received "
+ + notification);
+ notifList.add(notification);
+ }
+
+}
diff --git a/test/javax/management/mxbean/MXBeanInteropTest1.java b/test/javax/management/mxbean/MXBeanInteropTest1.java
new file mode 100644
index 0000000..5f0e834
--- /dev/null
+++ b/test/javax/management/mxbean/MXBeanInteropTest1.java
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Test all MXBeans available by default on the platform
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest1
+ */
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.CompilationMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanInteropTest1 {
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanInteropTest1 test = new MXBeanInteropTest1();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanInteropTest1::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ // MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // Print out registered java.lang.management MXBeans found
+ // in the remote jvm.
+ printMBeans(mbsc) ;
+
+ // For each possible kind of JDK 5 defined MXBean, we retrieve its
+ // MBeanInfo and print it and we call all getters and print
+ // their output.
+ errorCount += doClassLoadingMXBeanTest(mbsc) ;
+ errorCount += doMemoryMXBeanTest(mbsc) ;
+ errorCount += doThreadMXBeanTest(mbsc) ;
+ errorCount += doRuntimeMXBeanTest(mbsc) ;
+ errorCount += doOperatingSystemMXBeanTest(mbsc) ;
+ errorCount += doCompilationMXBeanTest(mbsc) ;
+ errorCount += doGarbageCollectorMXBeanTest(mbsc) ;
+ errorCount += doMemoryManagerMXBeanTest(mbsc) ;
+ errorCount += doMemoryPoolMXBeanTest(mbsc) ;
+
+ // Terminate the JMX Client
+ cc.close();
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanInteropTest1::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanInteropTest1::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+ /**
+ * Prints all MBeans of domain java.lang.
+ * They are MBeans related to the JSR 174 that defines
+ * package java.lang.management.
+ */
+ private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
+ ObjectName filterName = new ObjectName("java.lang:*");
+ Set<ObjectName> set = mbsc.queryNames(filterName, null);
+
+ if ( set.size() == 0 ) {
+ throw new RuntimeException("(ERROR) No MBean found with filter "
+ + filterName);
+ }
+
+ System.out.println("---- MBeans found in domain java.lang :");
+
+ for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
+ System.out.println(iter.next().toString());
+ }
+
+ System.out.println("\n") ;
+ }
+
+
+ private final int doClassLoadingMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- ClassLoadingMXBean") ;
+
+ try {
+ ObjectName classLoadingName =
+ new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(classLoadingName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t"
+ + mbInfo);
+ ClassLoadingMXBean classLoading = null;
+
+ classLoading = JMX.newMXBeanProxy(mbsc,
+ classLoadingName,
+ ClassLoadingMXBean.class) ;
+ System.out.println("getLoadedClassCount\t\t"
+ + classLoading.getLoadedClassCount());
+ System.out.println("getTotalLoadedClassCount\t\t"
+ + classLoading.getTotalLoadedClassCount());
+ System.out.println("getUnloadedClassCount\t\t"
+ + classLoading.getUnloadedClassCount());
+ System.out.println("isVerbose\t\t"
+ + classLoading.isVerbose());
+
+ System.out.println("---- OK\n") ;
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doMemoryMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- MemoryMXBean") ;
+
+ try {
+ ObjectName memoryName =
+ new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t"
+ + mbInfo);
+ MemoryMXBean memory = null ;
+
+ memory =
+ JMX.newMXBeanProxy(mbsc,
+ memoryName,
+ MemoryMXBean.class,
+ true) ;
+ System.out.println("getMemoryHeapUsage\t\t"
+ + memory.getHeapMemoryUsage());
+ System.out.println("getNonHeapMemoryHeapUsage\t\t"
+ + memory.getNonHeapMemoryUsage());
+ System.out.println("getObjectPendingFinalizationCount\t\t"
+ + memory.getObjectPendingFinalizationCount());
+ System.out.println("isVerbose\t\t"
+ + memory.isVerbose());
+
+ System.out.println("---- OK\n") ;
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doThreadMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- ThreadMXBean") ;
+
+ try {
+ ObjectName threadName =
+ new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(threadName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ ThreadMXBean thread = null ;
+
+ thread =
+ JMX.newMXBeanProxy(mbsc,
+ threadName,
+ ThreadMXBean.class) ;
+ System.out.println("findMonitorDeadlockedThreads\t\t"
+ + thread.findMonitorDeadlockedThreads());
+ long[] threadIDs = thread.getAllThreadIds() ;
+ System.out.println("getAllThreadIds\t\t"
+ + threadIDs);
+
+ for ( long threadID : threadIDs ) {
+ System.out.println("getThreadInfo long\t\t"
+ + thread.getThreadInfo(threadID));
+ System.out.println("getThreadInfo long, int\t\t"
+ + thread.getThreadInfo(threadID, 2));
+ }
+
+ System.out.println("getThreadInfo long[]\t\t"
+ + thread.getThreadInfo(threadIDs));
+ System.out.println("getThreadInfo long[], int\t\t"
+ + thread.getThreadInfo(threadIDs, 2));
+ System.out.println("getDaemonThreadCount\t\t"
+ + thread.getDaemonThreadCount());
+ System.out.println("getPeakThreadCount\t\t"
+ + thread.getPeakThreadCount());
+ System.out.println("getThreadCount\t\t"
+ + thread.getThreadCount());
+ System.out.println("getTotalStartedThreadCount\t\t"
+ + thread.getTotalStartedThreadCount());
+ boolean supported = thread.isThreadContentionMonitoringSupported() ;
+ System.out.println("isThreadContentionMonitoringSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("isThreadContentionMonitoringEnabled\t\t"
+ + thread.isThreadContentionMonitoringEnabled());
+ }
+
+ supported = thread.isThreadCpuTimeSupported() ;
+ System.out.println("isThreadCpuTimeSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("isThreadCpuTimeEnabled\t\t"
+ + thread.isThreadCpuTimeEnabled());
+
+ for (long id : threadIDs) {
+ System.out.println("getThreadCpuTime(" + id + ")\t\t"
+ + thread.getThreadCpuTime(id));
+ System.out.println("getThreadUserTime(" + id + ")\t\t"
+ + thread.getThreadUserTime(id));
+ }
+ }
+
+ supported = thread.isCurrentThreadCpuTimeSupported() ;
+ System.out.println("isCurrentThreadCpuTimeSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getCurrentThreadCpuTime\t\t"
+ + thread.getCurrentThreadCpuTime());
+ System.out.println("getCurrentThreadUserTime\t\t"
+ + thread.getCurrentThreadUserTime());
+ }
+
+ thread.resetPeakThreadCount() ;
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doRuntimeMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- RuntimeMXBean") ;
+
+ try {
+ ObjectName runtimeName =
+ new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(runtimeName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ RuntimeMXBean runtime = null;
+
+ runtime =
+ JMX.newMXBeanProxy(mbsc,
+ runtimeName,
+ RuntimeMXBean.class) ;
+ System.out.println("getClassPath\t\t"
+ + runtime.getClassPath());
+ System.out.println("getInputArguments\t\t"
+ + runtime.getInputArguments());
+ System.out.println("getLibraryPath\t\t"
+ + runtime.getLibraryPath());
+ System.out.println("getManagementSpecVersion\t\t"
+ + runtime.getManagementSpecVersion());
+ System.out.println("getName\t\t"
+ + runtime.getName());
+ System.out.println("getSpecName\t\t"
+ + runtime.getSpecName());
+ System.out.println("getSpecVendor\t\t"
+ + runtime.getSpecVendor());
+ System.out.println("getSpecVersion\t\t"
+ + runtime.getSpecVersion());
+ System.out.println("getStartTime\t\t"
+ + runtime.getStartTime());
+ System.out.println("getSystemProperties\t\t"
+ + runtime.getSystemProperties());
+ System.out.println("getUptime\t\t"
+ + runtime.getUptime());
+ System.out.println("getVmName\t\t"
+ + runtime.getVmName());
+ System.out.println("getVmVendor\t\t"
+ + runtime.getVmVendor());
+ System.out.println("getVmVersion\t\t"
+ + runtime.getVmVersion());
+ boolean supported = runtime.isBootClassPathSupported() ;
+ System.out.println("isBootClassPathSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getBootClassPath\t\t"
+ + runtime.getBootClassPath());
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doOperatingSystemMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- OperatingSystemMXBean") ;
+
+ try {
+ ObjectName operationName =
+ new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(operationName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ OperatingSystemMXBean operation = null ;
+
+ operation =
+ JMX.newMXBeanProxy(mbsc,
+ operationName,
+ OperatingSystemMXBean.class) ;
+ System.out.println("getArch\t\t"
+ + operation.getArch());
+ System.out.println("getAvailableProcessors\t\t"
+ + operation.getAvailableProcessors());
+ System.out.println("getName\t\t"
+ + operation.getName());
+ System.out.println("getVersion\t\t"
+ + operation.getVersion());
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doCompilationMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- CompilationMXBean") ;
+
+ try {
+ ObjectName compilationName =
+ new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
+
+ if ( mbsc.isRegistered(compilationName) ) {
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(compilationName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ CompilationMXBean compilation = null ;
+
+ compilation =
+ JMX.newMXBeanProxy(mbsc,
+ compilationName,
+ CompilationMXBean.class) ;
+ System.out.println("getName\t\t"
+ + compilation.getName());
+ boolean supported =
+ compilation.isCompilationTimeMonitoringSupported() ;
+ System.out.println("isCompilationTimeMonitoringSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getTotalCompilationTime\t\t"
+ + compilation.getTotalCompilationTime());
+ }
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doGarbageCollectorMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- GarbageCollectorMXBean") ;
+
+ try {
+ ObjectName filterName =
+ new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE
+ + ",*");
+ Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+ for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+ ObjectName garbageName = iter.next() ;
+ System.out.println("-------- " + garbageName) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(garbageName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ GarbageCollectorMXBean garbage = null ;
+
+ garbage =
+ JMX.newMXBeanProxy(mbsc,
+ garbageName,
+ GarbageCollectorMXBean.class) ;
+ System.out.println("getCollectionCount\t\t"
+ + garbage.getCollectionCount());
+ System.out.println("getCollectionTime\t\t"
+ + garbage.getCollectionTime());
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doMemoryManagerMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- MemoryManagerMXBean") ;
+
+ try {
+ ObjectName filterName =
+ new ObjectName(ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE
+ + ",*");
+ Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+ for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+ ObjectName memoryManagerName = iter.next() ;
+ System.out.println("-------- " + memoryManagerName) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryManagerName);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ errorCount += checkNonEmpty(mbInfo);
+ MemoryManagerMXBean memoryManager = null;
+
+ memoryManager =
+ JMX.newMXBeanProxy(mbsc,
+ memoryManagerName,
+ MemoryManagerMXBean.class) ;
+ System.out.println("getMemoryPoolNames\t\t"
+ + Arrays.deepToString(memoryManager.getMemoryPoolNames()));
+ System.out.println("getName\t\t"
+ + memoryManager.getName());
+ System.out.println("isValid\t\t"
+ + memoryManager.isValid());
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private final int doMemoryPoolMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- MemoryPoolMXBean") ;
+
+ try {
+ ObjectName filterName =
+ new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE
+ + ",*");
+ Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
+
+ for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
+ ObjectName memoryPoolName = iter.next() ;
+ System.out.println("-------- " + memoryPoolName) ;
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryPoolName);
+ errorCount += checkNonEmpty(mbInfo);
+ System.out.println("getMBeanInfo\t\t" + mbInfo);
+ MemoryPoolMXBean memoryPool = null;
+
+ memoryPool =
+ JMX.newMXBeanProxy(mbsc,
+ memoryPoolName,
+ MemoryPoolMXBean.class,
+ true) ;
+ System.out.println("getCollectionUsage\t\t"
+ + memoryPool.getCollectionUsage());
+ System.out.println("getMemoryManagerNames\t\t"
+ + Arrays.deepToString(memoryPool.getMemoryManagerNames()));
+ System.out.println("getName\t\t"
+ + memoryPool.getName());
+ System.out.println("getPeakUsage\t\t"
+ + memoryPool.getPeakUsage());
+ System.out.println("getType\t\t"
+ + memoryPool.getType());
+ System.out.println("getUsage\t\t"
+ + memoryPool.getUsage());
+ System.out.println("isValid\t\t"
+ + memoryPool.isValid());
+ boolean supported = memoryPool.isUsageThresholdSupported() ;
+ System.out.println("isUsageThresholdSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getUsageThreshold\t\t"
+ + memoryPool.getUsageThreshold());
+ System.out.println("isUsageThresholdExceeded\t\t"
+ + memoryPool.isUsageThresholdExceeded());
+ System.out.println("getUsageThresholdCount\t\t"
+ + memoryPool.getUsageThresholdCount());
+ }
+
+ supported = memoryPool.isCollectionUsageThresholdSupported() ;
+ System.out.println("isCollectionUsageThresholdSupported\t\t"
+ + supported);
+
+ if ( supported ) {
+ System.out.println("getCollectionUsageThreshold\t\t"
+ + memoryPool.getCollectionUsageThreshold());
+ System.out.println("getCollectionUsageThresholdCount\t\t"
+ + memoryPool.getCollectionUsageThresholdCount());
+ System.out.println("isCollectionUsageThresholdExceeded\t\t"
+ + memoryPool.isCollectionUsageThresholdExceeded());
+ }
+
+ memoryPool.resetPeakUsage();
+ }
+
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+
+ private int checkNonEmpty(MBeanInfo mbi) {
+ if ( mbi.toString().length() == 0 ) {
+ System.out.println("(ERROR) MBeanInfo is empty !");
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+}
diff --git a/test/javax/management/mxbean/MXBeanInteropTest2.java b/test/javax/management/mxbean/MXBeanInteropTest2.java
new file mode 100644
index 0000000..4c71357
--- /dev/null
+++ b/test/javax/management/mxbean/MXBeanInteropTest2.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks access to test MXBean
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest2
+ */
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanServer;
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class MXBeanInteropTest2 {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanInteropTest2 test = new MXBeanInteropTest2();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanInteropTest2::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // Prints all MBeans whatever the domain is.
+ printMBeans(mbsc) ;
+
+ // Call test body
+ errorCount += doBasicMXBeanTest(mbsc) ;
+
+ // Terminate the JMX Client
+ cc.close();
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanInteropTest2::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanInteropTest2::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+
+ /**
+ * Prints all MBeans whatever the domain is.
+ */
+ private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
+ Set<ObjectName> set = mbsc.queryNames(null, null);
+ System.out.println("---- MBeans found :");
+
+ for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
+ System.out.println(iter.next().toString());
+ }
+
+ System.out.println("\n") ;
+ }
+
+
+ private final int doBasicMXBeanTest(MBeanServerConnection mbsc) {
+ int errorCount = 0 ;
+ System.out.println("---- doBasicMXBeanTest") ;
+
+ try {
+ ObjectName objName =
+ new ObjectName("sqe:type=BasicMXBean") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
+ printMBeanInfo(mbInfo);
+ System.out.println("---- OK\n") ;
+ System.out.println("getMBeanInfo\t\t"
+ + mbInfo);
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Check mxbean field in the MBeanInfo");
+ String mxbeanField =
+ (String)mbInfo.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
+
+ if ( mxbeanField == null || ! mxbeanField.equals("true")) {
+ System.out.println("---- ERROR : Improper mxbean field value "
+ + mxbeanField);
+ errorCount++;
+ }
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Set attribute ObjectNameAtt");
+ Attribute att = new Attribute("ObjectNameAtt", objName);
+ mbsc.setAttribute(objName, att);
+ ObjectName value =
+ (ObjectName)mbsc.getAttribute(objName, "ObjectNameAtt");
+
+ if ( ! value.equals(objName) ) {
+ errorCount++;
+ System.out.println("---- ERROR : setAttribute failed, got "
+ + value
+ + " while expecting "
+ + objName);
+ }
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Call operation doNothing");
+ mbsc.invoke(objName, "doNothing", null, null);
+ System.out.println("---- OK\n") ;
+
+ System.out.println("Call operation getWeather");
+ Object weather = mbsc.invoke(objName,
+ "getWeather",
+ new Object[]{Boolean.TRUE},
+ new String[]{"boolean"});
+ System.out.println("Weather is " + weather);
+ System.out.println("---- OK\n") ;
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++ ;
+ System.out.println("---- ERROR\n") ;
+ }
+
+ return errorCount ;
+ }
+
+ private void printMBeanInfo(MBeanInfo mbInfo) {
+ System.out.println("Description " + mbInfo.getDescription());
+
+ for (MBeanConstructorInfo ctor : mbInfo.getConstructors()) {
+ System.out.println("Constructor " + ctor.getName());
+ }
+
+ for (MBeanAttributeInfo att : mbInfo.getAttributes()) {
+ System.out.println("Attribute " + att.getName()
+ + " [" + att.getType() + "]");
+ }
+
+ for (MBeanOperationInfo oper : mbInfo.getOperations()) {
+ System.out.println("Operation " + oper.getName());
+ }
+
+ for (MBeanNotificationInfo notif : mbInfo.getNotifications()) {
+ System.out.println("Notification " + notif.getName());
+ }
+ }
+}
diff --git a/test/javax/management/mxbean/MXBeanLoadingTest1.java b/test/javax/management/mxbean/MXBeanLoadingTest1.java
new file mode 100644
index 0000000..6992607
--- /dev/null
+++ b/test/javax/management/mxbean/MXBeanLoadingTest1.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks correct collection of MXBean's class after unregistration
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @run main/othervm/timeout=300 MXBeanLoadingTest1
+ */
+
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Map;
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MXBean;
+import javax.management.ObjectName;
+import javax.management.loading.PrivateMLet;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
+public class MXBeanLoadingTest1 {
+
+ public static void main(String[] args) throws Exception {
+ MXBeanLoadingTest1 test = new MXBeanLoadingTest1();
+ test.run((Map<String, Object>)null);
+ }
+
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanLoadingTest1::run: Start") ;
+
+ try {
+ System.out.println("We ensure no reference is retained on MXBean class"
+ + " after it is unregistered. We take time to perform"
+ + " some little extra check of Descriptors, MBean*Info.");
+
+ ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader();
+
+ if (!(myClassLoader instanceof URLClassLoader)) {
+ String message = "(ERROR) Test's class loader is not " +
+ "a URLClassLoader";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ URLClassLoader myURLClassLoader = (URLClassLoader) myClassLoader;
+ URL[] urls = myURLClassLoader.getURLs();
+ PrivateMLet mlet = new PrivateMLet(urls, null, false);
+ Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName());
+
+ if (shadowClass == TestMXBean.class) {
+ String message = "(ERROR) MLet got original TestMXBean, not shadow";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ shadowClass = null;
+
+ MBeanServer mbs = MBeanServerFactory.createMBeanServer();
+ ObjectName mletName = new ObjectName("x:type=mlet");
+ mbs.registerMBean(mlet, mletName);
+
+ ObjectName testName = new ObjectName("x:type=test");
+ mbs.createMBean(Test.class.getName(), testName, mletName);
+
+ // That test fails because the MXBean instance is accessed via
+ // a delegate OpenMBean which has
+ ClassLoader testLoader = mbs.getClassLoaderFor(testName);
+
+ if (testLoader != mlet) {
+ System.out.println("MLet " + mlet);
+ String message = "(ERROR) MXBean's class loader is not MLet: "
+ + testLoader;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ testLoader = null;
+
+
+ // Cycle get/set/get of the attribute of type Luis.
+ // We check the set is effective.
+ CompositeData cd_B = (CompositeData)mbs.getAttribute(testName, "B");
+ CompositeType compType_B = cd_B.getCompositeType();
+
+ CompositeDataSupport cds_B =
+ new CompositeDataSupport(compType_B,
+ new String[]{"something"},
+ new Object[]{Integer.valueOf(13)});
+ Attribute myAtt = new Attribute("B", cds_B);
+ mbs.setAttribute(testName, myAtt);
+
+ CompositeData cd_B2 = (CompositeData)mbs.getAttribute(testName, "B");
+
+ if ( ((Integer)cd_B2.get("something")).intValue() != 13 ) {
+ String message = "(ERROR) The setAttribute of att B did not work;"
+ + " expect Luis.something = 13 but got "
+ + cd_B2.get("something");
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ MBeanInfo info = mbs.getMBeanInfo(testName);
+ String mxbeanField =
+ (String)info.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
+
+ if ( mxbeanField == null || ! mxbeanField.equals("true")) {
+ String message = "(ERROR) Improper mxbean field value "
+ + mxbeanField;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check the 2 attributes.
+ MBeanAttributeInfo[] attrs = info.getAttributes();
+
+ if ( attrs.length == 2 ) {
+ for (MBeanAttributeInfo mbai : attrs) {
+ String originalTypeFieldValue =
+ (String)mbai.getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
+ OpenType<?> openTypeFieldValue =
+ (OpenType<?>)mbai.getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
+
+ if ( mbai.getName().equals("A") ) {
+ if ( !mbai.isReadable() || !mbai.isWritable()
+ || mbai.isIs()
+ || !mbai.getType().equals("int") ) {
+ String message = "(ERROR) Unexpected MBeanAttributeInfo for A "
+ + mbai;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! originalTypeFieldValue.equals("int") ) {
+ String message = "(ERROR) Unexpected originalType in Descriptor for A "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! openTypeFieldValue.equals(SimpleType.INTEGER) ) {
+ String message = "(ERROR) Unexpected openType in Descriptor for A "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ } else if ( mbai.getName().equals("B") ) {
+ if ( !mbai.isReadable() || !mbai.isWritable()
+ || mbai.isIs()
+ || !mbai.getType().equals("javax.management.openmbean.CompositeData") ) {
+ String message = "(ERROR) Unexpected MBeanAttributeInfo for B "
+ + mbai;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! originalTypeFieldValue.equals(Luis.class.getName()) ) {
+ String message = "(ERROR) Unexpected originalType in Descriptor for B "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! openTypeFieldValue.equals(compType_B) ) {
+ String message = "(ERROR) Unexpected openType in Descriptor for B "
+ + compType_B;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ } else {
+ String message = "(ERROR) Unknown attribute name";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+ } else {
+ String message = "(ERROR) Unexpected MBeanAttributeInfo array"
+ + Arrays.deepToString(attrs);
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check the MXBean operation.
+ MBeanOperationInfo[] ops = info.getOperations();
+ // The impact is ACTION_INFO as for a standard MBean it is UNKNOWN,
+ // logged 6320104.
+ if (ops.length != 1 || !ops[0].getName().equals("bogus")
+ || ops[0].getSignature().length > 0
+ || !ops[0].getReturnType().equals("void")) {
+ String message = "(ERROR) Unexpected MBeanOperationInfo array "
+ + Arrays.deepToString(ops);
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ String originalTypeFieldValue =
+ (String)ops[0].getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
+ OpenType<?> openTypeFieldValue =
+ (OpenType<?>)ops[0].getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
+
+ if ( ! originalTypeFieldValue.equals("void") ) {
+ String message = "(ERROR) Unexpected originalType in Descriptor for bogus "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ if ( ! openTypeFieldValue.equals(SimpleType.VOID) ) {
+ String message = "(ERROR) Unexpected openType in Descriptor for bogus "
+ + originalTypeFieldValue;
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check there is 2 constructors.
+ if (info.getConstructors().length != 2) {
+ String message = "(ERROR) Wrong number of constructors " +
+ "in introspected bean: " +
+ Arrays.asList(info.getConstructors());
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ // Check MXBean class name.
+ if (!info.getClassName().endsWith("Test")) {
+ String message = "(ERROR) Wrong info class name: " +
+ info.getClassName();
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+
+ mbs.unregisterMBean(testName);
+ mbs.unregisterMBean(mletName);
+
+ WeakReference<PrivateMLet> mletRef =
+ new WeakReference<PrivateMLet>(mlet);
+ mlet = null;
+
+ System.out.println("MXBean registered and unregistered, waiting for " +
+ "garbage collector to collect class loader");
+
+ for (int i = 0; i < 10000 && mletRef.get() != null; i++) {
+ System.gc();
+ Thread.sleep(1);
+ }
+
+ if (mletRef.get() == null)
+ System.out.println("(OK) class loader was GC'd");
+ else {
+ String message = "(ERROR) Class loader was not GC'd";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ System.out.println("MXBeanLoadingTest1::run: Done without any error") ;
+ }
+
+
+ // I agree the use of the MXBean annotation and the MXBean suffix for the
+ // interface name are redundant but however harmless.
+ //
+ @MXBean(true)
+ public static interface TestMXBean {
+ public void bogus();
+ public int getA();
+ public void setA(int a);
+ public Luis getB();
+ public void setB(Luis mi);
+ }
+
+
+ public static class Test implements TestMXBean {
+ private Luis luis = new Luis() ;
+ public Test() {}
+ public Test(int x) {}
+
+ public void bogus() {}
+ public int getA() {return 0;}
+ public void setA(int a) {}
+ public Luis getB() {return this.luis;}
+ public void setB(Luis luis) {this.luis = luis;}
+ }
+
+
+ public static class Luis {
+ private int something = 0;
+ public Luis() {}
+ public int getSomething() {return something;}
+ public void setSomething(int v) {something = v;}
+ public void doNothing() {}
+ }
+}
diff --git a/test/javax/management/mxbean/MXBeanNotifTest.java b/test/javax/management/mxbean/MXBeanNotifTest.java
new file mode 100644
index 0000000..021731e
--- /dev/null
+++ b/test/javax/management/mxbean/MXBeanNotifTest.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks MXBean proper registration both as its implementation class and interface
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanNotifTest -numOfNotifications 239 -timeForNotificationInSeconds 4
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.Attribute;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.MBeanServer;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+public class MXBeanNotifTest implements NotificationListener {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+ private static String BASIC_MXBEAN_INTERFACE_NAME = "BasicMXBean";
+
+ private long timeForNotificationInSeconds = 3L;
+ private int numOfNotifications = 1;
+ private BlockingQueue<Notification> notifList = null;
+ private int numOfNotifDescriptorElements = 13;
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanNotifTest test = new MXBeanNotifTest();
+ test.run(map);
+
+ }
+
+ protected void parseArgs(Map<String, Object> args) throws Exception {
+
+ String arg = null;
+
+ // Init numOfNotifications
+ // It is the number of notifications we should trigger and check.
+ arg = (String)args.get("-numOfNotifications") ;
+ if (arg != null) {
+ numOfNotifications = (new Integer(arg)).intValue();
+ }
+
+ // Init timeForNotificationInSeconds
+ // It is the maximum time in seconds we wait for each notification.
+ arg = (String)args.get("-timeForEachNotificationInSeconds") ;
+ if (arg != null) {
+ timeForNotificationInSeconds = (new Long(arg)).longValue();
+ }
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("MXBeanNotifTest::run: Start") ;
+ int errorCount = 0 ;
+
+ try {
+ parseArgs(args);
+ notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
+
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ JMXConnectorServer cs =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Create and register the MBean");
+ ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Add me as notification listener");
+ mbsc.addNotificationListener(objName, this, null, null);
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Retrieve the Descriptor"
+ + " that should be in MBeanNotificationInfo");
+ TabularData tabData =
+ (TabularData)mbsc.getAttribute(objName, "NotifDescriptorAsMapAtt");
+ Map<String, String> descrMap = new HashMap<>();
+
+ for (Iterator<?> it = tabData.values().iterator(); it.hasNext(); ) {
+ CompositeData compData = (CompositeData)it.next();
+ descrMap.put((String)compData.get("key"),
+ (String)compData.get("value"));
+ }
+
+ Descriptor refNotifDescriptor = new ImmutableDescriptor(descrMap);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ // Because the MBean holding the targeted attribute is MXBean, we
+ // should use for the setAttribute a converted form for the
+ // attribute value as described by the MXBean mapping rules.
+ // This explains all that lovely stuff for creating a
+ // TabularDataSupport.
+ //
+ // WARNING : the MBeanInfo of the MXBean used on opposite side
+ // is computed when the MBean is registered.
+ // It means the Descriptor considered for the MBeanNotificationInfo
+ // is not the one we set in the lines below, it is too late.
+ // However, we check that set is harmless when we check
+ // the MBeanNotificationInfo.
+ //
+ System.out.println("MXBeanNotifTest::run: Set a Map<String, String>"
+ + " attribute");
+ String typeName =
+ "java.util.Map<java.lang.String,java.lang.String>";
+ String[] keyValue = new String[] {"key", "value"};
+ OpenType<?>[] openTypes =
+ new OpenType<?>[] {SimpleType.STRING, SimpleType.STRING};
+ CompositeType rowType = new CompositeType(typeName, typeName,
+ keyValue, keyValue, openTypes);
+ TabularType tabType = new TabularType(typeName, typeName,
+ rowType, new String[]{"key"});
+ TabularDataSupport convertedDescrMap =
+ new TabularDataSupport(tabType);
+
+ for (int i = 0; i < numOfNotifDescriptorElements; i++) {
+ Object[] descrValue = {"field" + i, "value" + i};
+ CompositeData data =
+ new CompositeDataSupport(rowType, keyValue, descrValue);
+ convertedDescrMap.put(data);
+ }
+
+ Attribute descrAtt =
+ new Attribute("NotifDescriptorAsMapAtt", convertedDescrMap);
+ mbsc.setAttribute(objName, descrAtt);
+ System.out.println("---- OK\n") ;
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Compare the Descriptor from"
+ + " the MBeanNotificationInfo against a reference");
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
+ errorCount += checkMBeanInfo(mbInfo, refNotifDescriptor);
+ System.out.println("---- DONE\n") ;
+
+ // ----
+ System.out.println("Check isInstanceOf(Basic)");
+
+ if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_CLASS_NAME) ) {
+ errorCount++;
+ System.out.println("---- ERROR isInstanceOf returned false\n") ;
+ } else {
+ System.out.println("---- OK\n") ;
+ }
+
+ // ----
+ System.out.println("Check isInstanceOf(BasicMXBean)");
+
+ if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_INTERFACE_NAME) ) {
+ errorCount++;
+ System.out.println("---- ERROR isInstanceOf returned false\n") ;
+ } else {
+ System.out.println("---- OK\n") ;
+ }
+
+ // ----
+ System.out.println("MXBeanNotifTest::run: Ask for "
+ + numOfNotifications + " notification(s)");
+ Object[] sendNotifParam = new Object[1];
+ String[] sendNotifSig = new String[]{"java.lang.String"};
+
+ for (int i = 0; i < numOfNotifications; i++) {
+ // Select which type of notification we ask for
+ if ( i % 2 == 0 ) {
+ sendNotifParam[0] = Basic.NOTIF_TYPE_0;
+ } else {
+ sendNotifParam[0] = Basic.NOTIF_TYPE_1;
+ }
+
+ // Trigger notification emission
+ mbsc.invoke(objName,
+ "sendNotification",
+ sendNotifParam,
+ sendNotifSig);
+
+ // Wait for it then check it when it comes early enough
+ Notification notif =
+ notifList.poll(timeForNotificationInSeconds,
+ TimeUnit.SECONDS) ;
+ // The very first notification is likely to come in slower than
+ // all the others. Because that test isn't targeting the speed
+ // notifications are delivered with, we prefer to secure it.
+ if (i == 0 && notif == null) {
+ System.out.println("MXBeanNotifTest::run: Wait extra "
+ + timeForNotificationInSeconds + " second(s) the "
+ + " very first notification");
+ notif = notifList.poll(timeForNotificationInSeconds,
+ TimeUnit.SECONDS);
+ }
+
+ if ( notif == null ) {
+ errorCount++;
+ System.out.println("---- ERROR No notification received"
+ + " within allocated " + timeForNotificationInSeconds
+ + " second(s) !");
+ } else {
+ errorCount +=
+ checkNotification(notif,
+ (String)sendNotifParam[0],
+ Basic.NOTIFICATION_MESSAGE,
+ objName);
+ }
+ }
+
+ int toc = 0;
+ while ( notifList.size() < 2 && toc < 10 ) {
+ Thread.sleep(499);
+ toc++;
+ }
+ System.out.println("---- DONE\n") ;
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ throw new RuntimeException(e);
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanNotifTest::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanNotifTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+ }
+
+
+ private int checkMBeanInfo(MBeanInfo mbi, Descriptor refDescr) {
+ MBeanNotificationInfo[] notifsInfo = mbi.getNotifications();
+ int res = 0;
+
+ for (MBeanNotificationInfo mbni : notifsInfo) {
+ if ( mbni.getDescriptor().equals(refDescr) ) {
+ System.out.println("(OK)");
+ } else {
+ System.out.println("(ERROR) Descriptor of the notification is "
+ + mbni.getDescriptor()
+ + " as we expect "
+ + refDescr);
+ res++;
+ }
+ }
+
+ return res;
+ }
+
+
+ private int checkNotification(Notification notif,
+ String refType,
+ String refMessage,
+ ObjectName refSource) {
+ int res = 0;
+
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getSource " + notif.getSource());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getMessage " + notif.getMessage());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getSequenceNumber " + notif.getSequenceNumber());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getTimeStamp " + notif.getTimeStamp());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getType " + notif.getType());
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "\t getUserData " + notif.getUserData());
+
+ if ( ! notif.getType().equals(refType) ) {
+ res++;
+ System.out.println("(ERROR) Type is not "
+ + refType + " in notification\n" + notif);
+ } else {
+ if ( notif.getType().equals(Basic.NOTIF_TYPE_0)
+ && ! (notif instanceof javax.management.Notification) ) {
+ res++;
+ System.out.println("(ERROR) Notification is not instance of "
+ + " javax.management.Notification but rather "
+ + notif.getClass().getName());
+ } else if ( notif.getType().equals(Basic.NOTIF_TYPE_1)
+ && ! (notif instanceof SqeNotification) ) {
+ res++;
+ System.out.println("(ERROR) Notification is not instance of "
+ + " javasoft.sqe.jmx.share.SqeNotification but rather "
+ + notif.getClass().getName());
+ }
+ }
+
+ if ( ! notif.getMessage().equals(refMessage) ) {
+ res++;
+ System.out.println("(ERROR) Message is not "
+ + refMessage + " in notification\n" + notif);
+ }
+
+ if ( ! notif.getSource().equals(refSource) ) {
+ res++;
+ System.out.println("(ERROR) Source is not "
+ + refSource + " in notification\n" + notif);
+ }
+
+ return res;
+ }
+
+ public void handleNotification(Notification notification, Object handback) {
+ Utils.debug(Utils.DEBUG_VERBOSE,
+ "MXBeanNotifTest::handleNotification: Received "
+ + notification);
+ notifList.add(notification);
+ }
+
+}
diff --git a/test/javax/management/mxbean/MXBeanWeirdParamTest.java b/test/javax/management/mxbean/MXBeanWeirdParamTest.java
new file mode 100644
index 0000000..358233f
--- /dev/null
+++ b/test/javax/management/mxbean/MXBeanWeirdParamTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks that a serialized instance is not transmitted from an MXBean.
+ * All the communication should be done via Open Types
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Basic.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest
+ */
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.lang.Process;
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class MXBeanWeirdParamTest {
+
+ private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
+
+ private static final String CLIENT_CLASS_MAIN =
+ "MXBeanWeirdParamTest$ClientSide";
+
+ private JMXConnectorServer cs;
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ MXBeanWeirdParamTest test = new MXBeanWeirdParamTest();
+ test.run(map);
+
+ }
+
+ /*
+ * Create the MBeansServe side of the test and returns its address
+ */
+ private JMXServiceURL createServerSide() throws Exception {
+ final int NINETY_SECONDS = 90;
+
+ // We will use the platform mbean server
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ Utils.waitReady(cs, NINETY_SECONDS);
+
+ JMXServiceURL addr = cs.getAddress();
+ return addr;
+ }
+
+
+ /*
+ * Creating command-line for running subprocess JVM:
+ *
+ * JVM command line is like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ *
+ */
+ private List<String> buildCommandLine() {
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+ // We need to set WEIRD_PARAM propertty on the client-side
+ opts.add("-DWEIRD_PARAM");
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add(CLIENT_CLASS_MAIN);
+
+ return opts;
+ }
+
+ /**
+ * Runs MXBeanWeirdParamTest$ClientSide with the passed options and redirects
+ * subprocess standard I/O to the current (parent) process. This provides a
+ * trace of what happens in the subprocess while it is runnning (and before
+ * it terminates).
+ *
+ * @param serviceUrlStr string representing the JMX service Url to connect to.
+ */
+ private int runClientSide(String serviceUrlStr) throws Exception {
+
+ // Building command-line
+ List<String> opts = buildCommandLine();
+ opts.add(serviceUrlStr);
+
+ // Launch separate JVM subprocess
+ int exitCode = 0;
+ String[] optsArray = opts.toArray(new String[0]);
+ ProcessBuilder pb = new ProcessBuilder(optsArray);
+ Process p = ProcessTools.startProcess("MXBeanWeirdParamTest$ClientSide", pb);
+
+ // Handling end of subprocess
+ try {
+ exitCode = p.waitFor();
+ if (exitCode != 0) {
+ System.out.println(
+ "Subprocess unexpected exit value of [" + exitCode +
+ "]. Expected 0.\n");
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+ // Parent thread unknown state, killing subprocess.
+ p.destroyForcibly();
+
+ throw new RuntimeException(
+ "Parent process interrupted with exception : \n " + e + " :" );
+ } finally {
+ return exitCode;
+ }
+
+ }
+
+ public void run(Map<String, Object> args) throws Exception {
+
+ System.out.println("MXBeanWeirdParamTest::run: Start") ;
+ int errorCount = 0;
+
+ try {
+ // Initialise the server side
+ JMXServiceURL urlToUse = createServerSide();
+
+ // Run client side
+ errorCount = runClientSide(urlToUse.toString());
+
+ if ( errorCount == 0 ) {
+ System.out.println("MXBeanWeirdParamTest::run: Done without any error") ;
+ } else {
+ System.out.println("MXBeanWeirdParamTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ cs.stop();
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class ClientSide {
+ public static void main(String args[]) throws Exception {
+
+ int errorCount = 0 ;
+ String msgTag = "ClientSide::main: ";
+
+ try {
+
+ // Get a connection to remote mbean server
+ JMXServiceURL addr = new JMXServiceURL(args[0]);
+ JMXConnector cc = JMXConnectorFactory.connect(addr);
+ MBeanServerConnection mbsc = cc.getMBeanServerConnection();
+
+ // ----
+ System.out.println(msgTag + "Create and register the MBean");
+ ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
+ mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ System.out.println(msgTag +"Get attribute SqeParameterAtt on our MXBean");
+ Object result = mbsc.getAttribute(objName, "SqeParameterAtt");
+ System.out.println(msgTag +"(OK) Got result of class "
+ + result.getClass().getName());
+ System.out.println(msgTag +"Received CompositeData is " + result);
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ // We use the value returned by getAttribute to perform the invoke.
+ System.out.println(msgTag +"Call operation doWeird on our MXBean [1]");
+ mbsc.invoke(objName, "doWeird",
+ new Object[]{result},
+ new String[]{"javax.management.openmbean.CompositeData"});
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ // We build the CompositeData ourselves that time.
+ System.out.println(msgTag +"Call operation doWeird on our MXBean [2]");
+ String typeName = "SqeParameter";
+ String[] itemNames = new String[] {"glop"};
+ OpenType<?>[] openTypes = new OpenType<?>[] {SimpleType.STRING};
+ CompositeType rowType = new CompositeType(typeName, typeName,
+ itemNames, itemNames, openTypes);
+ Object[] itemValues = {"HECTOR"};
+ CompositeData data =
+ new CompositeDataSupport(rowType, itemNames, itemValues);
+ TabularType tabType = new TabularType(typeName, typeName,
+ rowType, new String[]{"glop"});
+ TabularDataSupport tds = new TabularDataSupport(tabType);
+ tds.put(data);
+ System.out.println(msgTag +"Source CompositeData is " + data);
+ mbsc.invoke(objName, "doWeird",
+ new Object[]{data},
+ new String[]{"javax.management.openmbean.CompositeData"});
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // ----
+ System.out.println(msgTag +"Unregister the MBean");
+ mbsc.unregisterMBean(objName);
+ System.out.println(msgTag +"---- OK\n") ;
+
+ // Terminate the JMX Client
+ cc.close();
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ throw new RuntimeException(e);
+ } finally {
+ System.exit(errorCount);
+ }
+ }
+ }
+}
diff --git a/test/javax/management/mxbean/SqeDescriptorKey.java b/test/javax/management/mxbean/SqeDescriptorKey.java
new file mode 100644
index 0000000..60e4926
--- /dev/null
+++ b/test/javax/management/mxbean/SqeDescriptorKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+ @DescriptorKey("sqeDescriptorKey")
+ String value();
+
+ // List descriptor fields that may be added or may be updated
+ // when retrieving an MBeanInfo using a JMXWS connection compared to the
+ // MBeanInfo returned by a local MBeanServer.
+ // The annotation format is :
+ // <descriptorFieldName>=<descriptorFieldValue>
+ // The values actually handled by the test suite are :
+ // openType=SimpleType.VOID
+ @DescriptorKey("descriptorFields")
+ String[] descriptorFields() default {};
+}
diff --git a/test/javax/management/mxbean/SqeNotification.java b/test/javax/management/mxbean/SqeNotification.java
new file mode 100644
index 0000000..7d0130e
--- /dev/null
+++ b/test/javax/management/mxbean/SqeNotification.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.management.Notification;
+
+/**
+ * Could hold someday a specific semantic.
+ * For now it is used to have a Notification which of another class, no more.
+ */
+public class SqeNotification extends Notification {
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber) {
+ super(type, source, sequenceNumber);
+ }
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber,
+ long timeStamp) {
+ super(type, source, sequenceNumber, timeStamp);
+ }
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber,
+ long timeStamp, String message) {
+ super(type, source, sequenceNumber, timeStamp, message);
+ }
+
+ /** Creates a new instance of SqeNotification */
+ public SqeNotification(String type, Object source, long sequenceNumber,
+ String message) {
+ super(type, source, sequenceNumber, message);
+ }
+}
diff --git a/test/javax/management/mxbean/SqeParameter.java b/test/javax/management/mxbean/SqeParameter.java
new file mode 100644
index 0000000..35a6ff0
--- /dev/null
+++ b/test/javax/management/mxbean/SqeParameter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable;
+
+/**
+ * That class is to use as an MBean operation parameter or returned value.
+ * The property Glop with its public getter + setter is only there to be
+ * reconstructible following MXBean specification, so that SqeParameter can be
+ * used for what it is designed to.
+ */
+public class SqeParameter implements Serializable {
+
+ private static boolean weird;
+ private String glop;
+
+ static {
+ if ( System.getProperty("WEIRD_PARAM") != null ) {
+ weird = true;
+ }
+ }
+
+ /**
+ * Creates a new instance of SqeParameter.
+ * <br>When the Java property WEIRD_PARAM is set, that constructor
+ * throws an exception.
+ * <br>That can be used to ensure the class is instantiated on server side
+ * but never on client side.
+ */
+ public SqeParameter() throws Exception {
+ if ( weird ) {
+ throw new Exception();
+ }
+ }
+
+ public String getGlop() {
+ return glop;
+ }
+
+ public void setGlop(String value) {
+ glop = value;
+ }
+}
diff --git a/test/javax/management/mxbean/Utils.java b/test/javax/management/mxbean/Utils.java
new file mode 100644
index 0000000..f77196b
--- /dev/null
+++ b/test/javax/management/mxbean/Utils.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.lang.reflect.Method;
+import javax.management.remote.JMXConnectorServerMBean;
+
+// utility class for MXBean* tests coming from JMX Tonga test suite
+class Utils {
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ private static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ private static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ public static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ public static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+
+ /**
+ * Wait up to maxTimeInSeconds second(s) the given JMX connector server
+ * comes up (which means isActive returns true).
+ * If it fails to do so we throw a RunTime exception.
+ */
+ public static void waitReady(JMXConnectorServerMBean server,
+ int maxTimeInSeconds) throws Exception {
+ int elapsed = 0;
+
+ while (!server.isActive() && elapsed < maxTimeInSeconds) {
+ Thread.sleep(1000);
+ elapsed++;
+ }
+
+ if (server.isActive()) {
+ String message = "Utils::waitReady: JMX connector server came up";
+ if ( elapsed == 0) {
+ message += " immediately";
+ } else {
+ message += " after " + elapsed + " seconds";
+ }
+ message += " [" + server.getAddress() + "]";
+ Utils.debug(DEBUG_STANDARD, message);
+ } else {
+ String message = "Utils::waitReady: (ERROR) JMX connector" +
+ " server didn't come up after " + elapsed + " seconds [" +
+ server.getAddress() + "]";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+}
diff --git a/test/javax/management/query/QueryData.java b/test/javax/management/query/QueryData.java
new file mode 100644
index 0000000..fadc6d3
--- /dev/null
+++ b/test/javax/management/query/QueryData.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public abstract class QueryData {
+ protected int intValue = 9;
+ protected long longValue = 9L;
+ protected Integer integerValue = Integer.valueOf(9);
+ protected boolean booleanValue = true;
+ protected double doubleValue = 9D;
+ protected float floatValue = 9.0F;
+ protected String stringValue = "9";
+}
diff --git a/test/javax/management/query/QueryFactory.java b/test/javax/management/query/QueryFactory.java
new file mode 100644
index 0000000..9639499
--- /dev/null
+++ b/test/javax/management/query/QueryFactory.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+
+import javax.management.Query;
+import javax.management.QueryExp;
+import javax.management.ValueExp;
+
+/**
+ * Class used for building QueryExp instances of all every possible type
+ * in terms of JMX API members; note that several JMX classes are private
+ * and appears in the JDK API only by their serial form.
+ * Comments in each case of the big switch in method getQuery() details which
+ * API member we cover with a given query.
+ */
+public class QueryFactory extends QueryData {
+
+ private String mbeanClassName = "";
+ private String primitiveIntAttName = "IntAtt";
+ private String primitiveLongAttName = "LongAtt";
+ private String integerAttName = "IntegerAtt";
+ private String primitiveBooleanAttName = "BooleanAtt";
+ private String primitiveDoubleAttName = "DoubleAtt";
+ private String primitiveFloatAttName = "FloatAtt";
+ private String stringAttName = "StringAtt";
+ private ArrayList<QueryExp> queries = new ArrayList<QueryExp>();
+
+ /**
+ * Creates a new instance of QueryFactory.
+ * The name is the fully qualified class name of an MBean.
+ * There is severe constraints on that MBean that must:
+ * <ul>
+ * <li>extend QueryData in order to inherit attribute values.
+ * <li>define a RW attribute IntAtt of type int
+ * initialized to QueryData.longValue
+ * <li>define a RW attribute LongAtt of type long
+ * initialized to QueryData.intValue
+ * <li>define a RW attribute IntegerAtt of type Integer
+ * initialized to QueryData.integerValue
+ * <li>define a RW attribute BooleanAtt of type boolean
+ * initialized to QueryData.booleanValue
+ * <li>define a RW attribute DoubleAtt of type double
+ * initialized to QueryData.doubleValue
+ * <li>define a RW attribute FloatAtt of type float
+ * initialized to QueryData.floatValue
+ * <li>define a RW attribute StringAtt of type String
+ * initialized to QueryData.stringValue
+ * </ul>
+ */
+ public QueryFactory(String name) {
+ this.mbeanClassName = name;
+ }
+
+ /**
+ * Returns the highest index value the method getQuery supports.
+ * WARNING : returns 0 if buildQueries haven't been called first !
+ */
+ public int getSize() {
+ return queries.size();
+ }
+
+ /**
+ * Populates an ArrayList of QueryExp.
+ * Lowest index is 1.
+ * Highest index is returned by getSize().
+ * <br>The queries numbered 1 to 23 allow to cover all the underlying
+ * Java classes of the JMX API used to build queries.
+ */
+ public void buildQueries() {
+ if ( queries.size() == 0 ) {
+ int smallerIntValue = intValue - 1;
+ int biggerIntValue = intValue + 1;
+
+ // case 1:
+ // True if the MBean is of class mbeanClassName
+ // We cover javax.management.InstanceOfQueryExp
+ queries.add(Query.isInstanceOf(Query.value(mbeanClassName)));
+
+ // case 2:
+ // True if the MBean is of class mbeanClassName
+ // We cover javax.management.MatchQueryExp and
+ // javax.management.ClassAttributeValueExp
+ queries.add(Query.match(Query.classattr(),
+ Query.value(mbeanClassName)));
+
+ // case 3:
+ // True if an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(intValue)));
+
+ // case 4:
+ // True if an attribute named primitiveLongAttName of type long has
+ // the value longValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveLongAttName),
+ Query.value(longValue)));
+
+ // case 5:
+ // True if an attribute named primitiveDoubleAttName of type double
+ // has the value doubleValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveDoubleAttName),
+ Query.value(doubleValue)));
+
+ // case 6:
+ // True if an attribute named primitiveFloatAttName of type float
+ // has the value floatValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(primitiveFloatAttName),
+ Query.value(floatValue)));
+
+ // case 7:
+ // True if an attribute named primitiveIntAttName of type int is
+ // hold by an MBean of class mbeanClassName and has
+ // the value intValue
+ // We cover javax.management.QualifiedAttributeValueExp
+ queries.add(Query.eq(Query.attr(mbeanClassName, primitiveIntAttName),
+ Query.value(intValue)));
+
+ // case 8:
+ // True if an attribute named stringAttName of type String has
+ // the value stringValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.StringValueExp
+ queries.add(Query.eq(Query.attr(stringAttName),
+ Query.value(stringValue)));
+
+ // case 9:
+ // True if an attribute named integerAttName of type Integer has
+ // the value integerValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.NumericValueExp
+ queries.add(Query.eq(Query.attr(integerAttName),
+ Query.value(integerValue)));
+
+ // case 10:
+ // True if an attribute named primitiveBooleanAttName of type boolean
+ // has the value booleanValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to EQ and javax.management.BooleanValueExp
+ queries.add(Query.eq(Query.attr(primitiveBooleanAttName),
+ Query.value(booleanValue)));
+
+ // case 11:
+ // True if an attribute named primitiveIntAttName of type int has
+ // not the value smallerIntValue
+ // We cover javax.management.NotQueryExp
+ queries.add(Query.not(Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue))));
+
+ // case 12:
+ // True if either
+ // an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // or
+ // an attribute named primitiveLongAttName of type long has
+ // the value longValue
+ // We cover javax.management.OrQueryExp
+ queries.add(Query.or(
+ Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(intValue)),
+ Query.eq(Query.attr(primitiveLongAttName),
+ Query.value(longValue))));
+
+ // case 13:
+ // True if
+ // an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // and
+ // an attribute named primitiveLongAttName of type long has
+ // the value longValue
+ // We cover javax.management.AndQueryExp
+ queries.add(Query.and(
+ Query.eq(Query.attr(primitiveIntAttName),
+ Query.value(intValue)),
+ Query.eq(Query.attr(primitiveLongAttName),
+ Query.value(longValue))));
+
+ // case 14:
+ // True if an attribute named primitiveIntAttName of type int has
+ // the value intValue
+ // We cover javax.management.InQueryExp
+ ValueExp[] inArray = {Query.value(intValue)};
+ queries.add(Query.in(Query.attr(primitiveIntAttName), inArray));
+
+ // case 15:
+ // True if an attribute named primitiveIntAttName of type int has
+ // its value in between smallerIntValue and biggerIntValue
+ // We cover javax.management.BetweenRelQueryExp
+ queries.add(Query.between(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue),
+ Query.value(biggerIntValue)));
+
+ // case 16:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value greater than smallerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to GT
+ queries.add(Query.gt(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue)));
+
+ // case 17:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value greater or equal to smallerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to GE
+ queries.add(Query.geq(Query.attr(primitiveIntAttName),
+ Query.value(smallerIntValue)));
+
+ // case 18:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value smaller than biggerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to LT
+ queries.add(Query.lt(Query.attr(primitiveIntAttName),
+ Query.value(biggerIntValue)));
+
+ // case 19:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value smaller or equal to biggerIntValue
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to LE
+ queries.add(Query.leq(Query.attr(primitiveIntAttName),
+ Query.value(biggerIntValue)));
+
+ // case 20:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue minus zero
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to MINUS
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.minus(Query.value(intValue), Query.value(0))));
+
+ // case 21:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue plus zero
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to PLUS
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.plus(Query.value(intValue), Query.value(0))));
+
+ // case 22:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue divided by one
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to DIV
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.div(Query.value(intValue), Query.value(1))));
+
+ // case 23:
+ // True if an attribute named primitiveIntAttName of type int has
+ // a value equal to intValue multiplicated by one
+ // We cover javax.management.BinaryRelQueryExp with
+ // a relOp equal to TIMES
+ queries.add(Query.eq(Query.attr(primitiveIntAttName),
+ Query.times(Query.value(intValue), Query.value(1))));
+
+ // case 24:
+ // That query is a complex one that combines within a big AND
+ // queries with index 2 to 23 inclusive. But because a List is
+ // zero based, we must decrement all indexes by 1 when retrieving
+ // any previously stored query.
+ QueryExp q2_3 = Query.and(queries.get(2-1), queries.get(3-1));
+ QueryExp q4_5 = Query.and(queries.get(4-1), queries.get(5-1));
+ QueryExp q6_7 = Query.and(queries.get(6-1), queries.get(7-1));
+ QueryExp q8_9 = Query.and(queries.get(8-1), queries.get(9-1));
+ QueryExp q10_11 = Query.and(queries.get(10-1), queries.get(11-1));
+ QueryExp q12_13 = Query.and(queries.get(12-1), queries.get(13-1));
+ QueryExp q14_15 = Query.and(queries.get(14-1), queries.get(15-1));
+ QueryExp q16_17 = Query.and(queries.get(16-1), queries.get(17-1));
+ QueryExp q18_19 = Query.and(queries.get(18-1), queries.get(19-1));
+ QueryExp q20_21 = Query.and(queries.get(20-1), queries.get(21-1));
+ QueryExp q22_23 = Query.and(queries.get(22-1), queries.get(23-1));
+ QueryExp q2_5 = Query.and(q2_3, q4_5);
+ QueryExp q6_9 = Query.and(q6_7, q8_9);
+ QueryExp q10_13 = Query.and(q10_11, q12_13);
+ QueryExp q14_17 = Query.and(q14_15, q16_17);
+ QueryExp q18_21 = Query.and(q18_19, q20_21);
+ QueryExp q2_9 = Query.and(q2_5, q6_9);
+ QueryExp q10_17 = Query.and(q10_13, q14_17);
+ QueryExp q18_23 = Query.and(q18_21, q22_23);
+ QueryExp q2_17 = Query.and(q2_9, q10_17);
+ queries.add(Query.and(q2_17, q18_23));
+
+ // case 25:
+ // Complex query mixing AND and OR.
+ queries.add(Query.or(q6_9, q18_23));
+ }
+ }
+
+ /**
+ * Returns a QueryExp taken is the ArrayList populated by buildQueries().
+ * Lowest index is 1.
+ * Highest index is returned by getSize().
+ * <br>The queries numbered 1 to 23 allow to cover all the underlying
+ * Java classes of the JMX API used to build queries.
+ */
+ public QueryExp getQuery(int index) {
+ return queries.get(index - 1);
+ }
+}
diff --git a/test/javax/management/query/ServerDelegate.java b/test/javax/management/query/ServerDelegate.java
new file mode 100644
index 0000000..6ce5fac
--- /dev/null
+++ b/test/javax/management/query/ServerDelegate.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * This class defines an MBean that can be registered and used on client side
+ * to handle informations or properties of the remote server.
+ *
+ * For example, this MBean can store IOR addresses
+ * of RMI/IIOP connector(s) used in a test.
+ *
+ * That MBean might not be used for testing purpose itself.
+ */
+public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
+
+ private MBeanServer mbeanServer = null;
+ private List<JMXServiceURL> addresses = null;
+ private String port;
+ private static String javaVersion = System.getProperty("java.version");
+ private int sqeJmxwsCredentialsProviderCallCount = 0;
+ private String jmxwsCredentialsProviderUrl = null;
+ private int testJMXAuthenticatorCallCount = 0;
+ private Principal testJMXAuthenticatorPrincipal = null;
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
+ public ServerDelegate() {
+ addresses = new ArrayList<JMXServiceURL>();
+ }
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ // Initialize MBeanServer attribute
+ mbeanServer = server;
+ return name;
+ }
+ public void postRegister(Boolean registrationDone) {
+ }
+ public void preDeregister() throws Exception {
+ }
+ public void postDeregister() {
+ }
+
+ public void addAddress(JMXServiceURL url) {
+ addresses.add(url) ;
+ }
+
+ public List<JMXServiceURL> getAddresses() {
+ return addresses ;
+ }
+
+ public void setPort(String p) {
+ port = p ;
+ }
+
+ public String getPort() {
+ return port ;
+ }
+
+ public String getJavaVersion() {
+ return javaVersion;
+ }
+
+ public void sqeJmxwsCredentialsProviderCalled() {
+ sqeJmxwsCredentialsProviderCallCount++;
+ }
+
+ public int getSqeJmxwsCredentialsProviderCallCount() {
+ return sqeJmxwsCredentialsProviderCallCount;
+ }
+
+ public void setJmxwsCredentialsProviderUrl(String url) {
+ jmxwsCredentialsProviderUrl = url;
+ }
+
+ public String getJmxwsCredentialsProviderUrl() {
+ return jmxwsCredentialsProviderUrl;
+ }
+
+ public void testJMXAuthenticatorCalled() {
+ testJMXAuthenticatorCallCount++;
+ }
+
+ public int getTestJMXAuthenticatorCallCount() {
+ return testJMXAuthenticatorCallCount;
+ }
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal) {
+ testJMXAuthenticatorPrincipal = principal;
+ }
+
+ public String getTestJMXAuthenticatorPrincipalString() {
+ if ( testJMXAuthenticatorPrincipal != null ) {
+ return testJMXAuthenticatorPrincipal.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ *
+ * @param implementationClassName
+ * The implementation class name of the MBean.
+ * @param interfaceClassName
+ * The management interface class name of the MBean.
+ * @param isMXBean
+ * If true, the resultant MBean is an MXBean.
+ * @param name
+ * The object name of the StandardMBean.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ Object implementation =
+ Class.forName(implementationClassName).newInstance();
+ Class<Object> interfaceClass = interfaceClassName == null ? null :
+ (Class<Object>)Class.forName(interfaceClassName);
+
+ // Create the StandardMBean
+ StandardMBean standardMBean = new StandardMBean(
+ implementation,
+ interfaceClass,
+ isMXBean);
+
+ // Register the StandardMBean
+ mbeanServer.registerMBean(standardMBean, name);
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ * The object will use standard JMX design pattern to determine
+ * the management interface associated with the given implementation.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ createStandardMBean(implementationClassName, null, isMXBean, name);
+ }
+}
diff --git a/test/javax/management/query/ServerDelegateMBean.java b/test/javax/management/query/ServerDelegateMBean.java
new file mode 100644
index 0000000..88f0b3f
--- /dev/null
+++ b/test/javax/management/query/ServerDelegateMBean.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.ObjectName;
+
+@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
+public interface ServerDelegateMBean {
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public void addAddress(JMXServiceURL url);
+
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public List<JMXServiceURL> getAddresses();
+
+ public String getPort();
+ public void setPort(String p);
+
+ public String getJavaVersion();
+
+ public void sqeJmxwsCredentialsProviderCalled();
+ public int getSqeJmxwsCredentialsProviderCallCount();
+
+ public void setJmxwsCredentialsProviderUrl(String url);
+ public String getJmxwsCredentialsProviderUrl();
+
+ public void testJMXAuthenticatorCalled();
+ public int getTestJMXAuthenticatorCallCount();
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal);
+ public String getTestJMXAuthenticatorPrincipalString();
+
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+}
diff --git a/test/javax/management/query/SqeDescriptorKey.java b/test/javax/management/query/SqeDescriptorKey.java
new file mode 100644
index 0000000..60e4926
--- /dev/null
+++ b/test/javax/management/query/SqeDescriptorKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+ @DescriptorKey("sqeDescriptorKey")
+ String value();
+
+ // List descriptor fields that may be added or may be updated
+ // when retrieving an MBeanInfo using a JMXWS connection compared to the
+ // MBeanInfo returned by a local MBeanServer.
+ // The annotation format is :
+ // <descriptorFieldName>=<descriptorFieldValue>
+ // The values actually handled by the test suite are :
+ // openType=SimpleType.VOID
+ @DescriptorKey("descriptorFields")
+ String[] descriptorFields() default {};
+}
diff --git a/test/javax/management/query/SupportedQueryTypesTest.java b/test/javax/management/query/SupportedQueryTypesTest.java
new file mode 100644
index 0000000..fab8128
--- /dev/null
+++ b/test/javax/management/query/SupportedQueryTypesTest.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Tests most of the existing query types.
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @compile TestQuery.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SupportedQueryTypesTest -mbeanClassName TestQuery
+ */
+
+import java.util.Map ;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.lang.reflect.Method;
+
+import java.lang.management.ManagementFactory;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName ;
+import javax.management.QueryExp;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+public class SupportedQueryTypesTest {
+
+ protected String mbeanClassName = null;
+
+ private MBeanServerConnection mbsc = null;
+
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+ Map<String, Object> map = Utils.parseParameters(args) ;
+
+ // Run test
+ SupportedQueryTypesTest test = new SupportedQueryTypesTest();
+ test.run(map);
+
+ }
+
+ public void run(Map<String, Object> args) {
+ int errorCount = 0;
+
+ ObjectName on = null;
+ ObjectName serverDelegateObjectName = null;
+
+ JMXConnectorServer cs = null;
+ JMXConnector cc = null;
+
+ System.out.println("SupportedQueryTypesTest::run: Start") ;
+ try {
+ // JMX MbeanServer used inside single VM as if remote.
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
+ cs.start();
+
+ JMXServiceURL addr = cs.getAddress();
+ cc = JMXConnectorFactory.connect(addr);
+ mbsc = cc.getMBeanServerConnection();
+
+
+ // Create and register the ServerDelegate MBean on the remote MBeanServer
+ String serverDelegateClassName = ServerDelegate.class.getName();
+ serverDelegateObjectName =
+ new ObjectName("defaultDomain:class=" + serverDelegateClassName);
+ mbsc.createMBean(serverDelegateClassName, serverDelegateObjectName);
+
+ // Retrieve the MBean class name
+ mbeanClassName = (String) args.get("-mbeanClassName") ;
+ on = new ObjectName("defaultDomain:class=" + mbeanClassName);
+
+ // Create and register the MBean on the remote MBeanServer
+ System.out.println("SupportedQueryTypesTest::run: CREATE " +
+ mbeanClassName + " on the remote MBeanServer with name "
+ + on);
+ mbsc.createMBean(mbeanClassName, on);
+
+ // Create a QueryFactory and setup which query we'll use.
+ QueryFactory queries = new QueryFactory(mbeanClassName);
+ queries.buildQueries();
+ int maxIndex = queries.getSize();
+ int minIndex = 1;
+
+ // Create a reference Set<ObjectName> to check later on
+ // the queryNames() results
+ Set<ObjectName> referenceNameSet = new HashSet<ObjectName>();
+ referenceNameSet.add(on);
+
+ // Create a reference Set<ObjectInstance> to check later on
+ // the queryMBeans() results
+ ObjectInstance oi = new ObjectInstance(on, mbeanClassName);
+ Set<ObjectInstance> referenceInstanceSet =
+ new HashSet<ObjectInstance>();
+ referenceInstanceSet.add(oi);
+
+ // Perform the queryNames and queryMBeans requests
+ for (int i = minIndex; i <= maxIndex; i++ ) {
+ QueryExp query = queries.getQuery(i);
+ System.out.println("----");
+ System.out.println("SupportedQueryTypesTest::run: Query # " + i);
+ System.out.println("query " + query);
+ errorCount +=
+ doQueryNames(query, referenceNameSet);
+ errorCount +=
+ doQueryMBeans(query, referenceInstanceSet);
+ }
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+
+ } finally {
+ // Do unregister the MBean
+ try {
+ if (mbsc.isRegistered(on)) {
+ mbsc.unregisterMBean(on);
+ }
+ if (mbsc.isRegistered(serverDelegateObjectName)) {
+ mbsc.unregisterMBean(serverDelegateObjectName);
+ }
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+
+ try {
+ // Close JMX Connector Client
+ cc.close();
+ // Stop connertor server
+ cs.stop();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+ }
+
+ System.out.println("");
+ System.out.println("SupportedQueryTypesTest::run: Done") ;
+
+ // Handle result
+ if (errorCount == 0) {
+ System.out.println("SupportedQueryTypesTest::run: (OK)");
+ } else {
+ String message = "SupportedQueryTypesTest::run: (ERROR) Got " +
+ + errorCount + " error(s)";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+
+
+ private int doQueryNames(QueryExp query, Set<ObjectName> referenceSet) {
+ int errorCount = 0;
+ System.out.println(" <*> Perform queryNames call ");
+
+ try {
+ // Call queryNames on the remote MBeanServer
+ Set<ObjectName> remoteSet = mbsc.queryNames(null, query);
+
+ // Compare the 2 Set<ObjectName>
+ errorCount += checkSet(remoteSet, referenceSet);
+
+ // Cleaning
+ remoteSet.clear();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("\t(OK)");
+ } else {
+ System.out.println("\t(ERROR) Query failed");
+ }
+
+ return errorCount;
+ }
+
+
+ private int doQueryMBeans(QueryExp query, Set<ObjectInstance> referenceSet) {
+ int errorCount = 0;
+ System.out.println(" <*> Perform queryMBeans call ");
+
+ try {
+ // Call queryMBeans on the remote MBeanServer
+ Set<ObjectInstance> remoteSet = mbsc.queryMBeans(null, query);
+
+ // Compare the 2 Set<ObjectInstance>
+ errorCount += checkSet(remoteSet, referenceSet);
+
+ // Cleaning
+ remoteSet.clear();
+
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+ }
+
+ if ( errorCount == 0 ) {
+ System.out.println("\t(OK)");
+ } else {
+ System.out.println("\t(ERROR) Query failed");
+ }
+
+ return errorCount;
+ }
+
+ /**
+ * Pretty print of a Set content.
+ * When the Set isn't empty, toString() is called on each element.
+ * <br>The variable's name used to hold that Set is given via the setName
+ * parameter and used in the output.
+ */
+ private static void printSet(Set<?> printableSet, String setName) {
+ if ( printableSet.size() == 0 ) {
+ System.out.println("The Set " + setName + " is empty");
+ } else {
+ System.out.println("The Set " + setName + " contains :");
+
+ for (Iterator<?> it = printableSet.iterator(); it.hasNext();) {
+ Object elem = it.next();
+ System.out.println("\t" + elem.toString());
+ }
+ }
+ }
+
+
+ /**
+ * This method check the Set remoteSet is equal to
+ * the reference Set referenceSet,
+ * which means same size and content (order doesn't matter).
+ * <br>It returns 0 when the check is fine, otherwise 1.
+ */
+ private int checkSet(Set<?> remoteSet, Set<?> referenceSet) {
+ if ( ! remoteSet.equals(referenceSet) ) {
+ System.out.println("SupportedQueryTypesTest::checkSet:"
+ + " (ERROR) Set aren't as expected");
+ printSet(remoteSet, "remoteSet");
+ printSet(referenceSet, "referenceSet");
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ // Utility inner class coming from JMX Tonga test suite.
+ private static class Utils {
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+ }
+
+}
diff --git a/test/javax/management/query/TestQuery.java b/test/javax/management/query/TestQuery.java
new file mode 100644
index 0000000..31b896e
--- /dev/null
+++ b/test/javax/management/query/TestQuery.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Class TestQuery
+ * MBean used for testing the types wired when using QueryExp.
+ * It is heavily linked to QueryFactory.
+ */
+public class TestQuery extends QueryData implements TestQueryMBean {
+
+ /**
+ * Attribute : BooleanAtt
+ */
+ private boolean booleanAtt = booleanValue;
+
+ /**
+ * Attribute : DoubleAtt
+ */
+ private double doubleAtt = doubleValue;
+
+ /**
+ * Attribute : FloatAtt
+ */
+ private float floatAtt = floatValue;
+
+ /**
+ * Attribute : IntAtt
+ */
+ private int intAtt = intValue;
+
+ /**
+ * Attribute : IntegerAtt
+ */
+ private Integer integerAtt = integerValue;
+
+ /**
+ * Attribute : LongAtt
+ */
+ private long longAtt = longValue;
+
+ /**
+ * Attribute : StringAtt
+ */
+ private String stringAtt = stringValue;
+
+ public TestQuery() {
+ }
+
+ /**
+ * Get Att of type boolean
+ */
+ public boolean getBooleanAtt() {
+ return booleanAtt;
+ }
+
+ /**
+ * Set Att of type boolean
+ */
+ public void setBooleanAtt(boolean value) {
+ booleanAtt = value;
+ }
+
+ /**
+ * Get Att of type double
+ */
+ public double getDoubleAtt() {
+ return doubleAtt;
+ }
+
+ /**
+ * Set Att of type double
+ */
+ public void setDoubleAtt(double value) {
+ doubleAtt = value;
+ }
+
+ /**
+ * Get Att of type float
+ */
+ public float getFloatAtt() {
+ return floatAtt;
+ }
+
+ /**
+ * Set Att of type float
+ */
+ public void setFloatAtt(float value) {
+ floatAtt = value;
+ }
+
+ /**
+ * Get Att of type int
+ */
+ public int getIntAtt() {
+ return intAtt;
+ }
+
+ /**
+ * Set Att of type int
+ */
+ public void setIntAtt(int value) {
+ intAtt = value;
+ }
+
+ /**
+ * Get Att of type Integer
+ */
+ public Integer getIntegerAtt() {
+ return integerAtt;
+ }
+
+ /**
+ * Set Att of type Integer
+ */
+ public void setIntegerAtt(Integer value) {
+ integerAtt = value;
+ }
+
+ /**
+ * Get Att of type long
+ */
+ public long getLongAtt() {
+ return longAtt;
+ }
+
+ /**
+ * Set Att of type long
+ */
+ public void setLongAtt(long value) {
+ longAtt = value;
+ }
+
+ /**
+ * Get Att of type String
+ */
+ public String getStringAtt() {
+ return stringAtt;
+ }
+
+ /**
+ * Set Att of type String
+ */
+ public void setStringAtt(String value) {
+ stringAtt = value;
+ }
+
+}
diff --git a/test/javax/management/query/TestQueryMBean.java b/test/javax/management/query/TestQueryMBean.java
new file mode 100644
index 0000000..9cf321f
--- /dev/null
+++ b/test/javax/management/query/TestQueryMBean.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Interface TestQueryMBean
+ * MBean used for testing the types wired when using QueryExp.
+ * It is heavily linked to QueryFactory.
+ */
+public interface TestQueryMBean
+{
+ /**
+ * Get Att of type boolean
+ */
+ public boolean getBooleanAtt();
+
+ /**
+ * Set Att of type boolean
+ */
+ public void setBooleanAtt(boolean value);
+
+ /**
+ * Get Att of type double
+ */
+ public double getDoubleAtt();
+
+ /**
+ * Set Att of type double
+ */
+ public void setDoubleAtt(double value);
+
+ /**
+ * Get Att of type float
+ */
+ public float getFloatAtt();
+
+ /**
+ * Set Att of type float
+ */
+ public void setFloatAtt(float value);
+
+ /**
+ * Get Att of type int
+ */
+ public int getIntAtt();
+
+ /**
+ * Set Att of type int
+ */
+ public void setIntAtt(int value);
+
+ /**
+ * Get Att of type Integer
+ */
+ public Integer getIntegerAtt();
+
+ /**
+ * Set Att of type Integer
+ */
+ public void setIntegerAtt(Integer value);
+
+ /**
+ * Get Att of type long
+ */
+ public long getLongAtt();
+
+ /**
+ * Set Att of type long
+ */
+ public void setLongAtt(long value);
+
+ /**
+ * Get Att of type String
+ */
+ public String getStringAtt();
+
+ /**
+ * Set Att of type String
+ */
+ public void setStringAtt(String value);
+
+}
diff --git a/test/javax/management/security/AuthorizationTest.java b/test/javax/management/security/AuthorizationTest.java
new file mode 100644
index 0000000..54309ab
--- /dev/null
+++ b/test/javax/management/security/AuthorizationTest.java
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks various authentication behavior from remote jmx client
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile Simple.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username4 -Dpassword=password4 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedGetException -expectedSetException
+ * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
+ */
+
+import java.io.File;
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory ;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.Attribute ;
+import javax.management.ObjectName ;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class AuthorizationTest {
+
+ static final String SERVER_CLASS_NAME = "AuthorizationTest";
+ static final String CLIENT_CLASS_NAME = "AuthorizationTest$ClientSide";
+ static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
+
+ static final String USERNAME_PROPERTY = "username";
+ static final String PASSWORD_PROPERTY = "password";
+
+ private JMXConnectorServer cs;
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is :
+ // "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> serverMap = new HashMap<>() ;
+ int clientArgsIndex =
+ Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
+
+ // Extract and records client params
+ String[] clientParams = null;
+ if (clientArgsIndex < args.length) {
+ int clientParamsSize = args.length - clientArgsIndex;
+ clientParams = new String[clientParamsSize];
+ System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
+ } else {
+ clientParams = new String[0];
+ }
+
+ // Run test
+ AuthorizationTest test = new AuthorizationTest();
+ test.run(serverMap, clientParams);
+
+ }
+
+ /*
+ * Create the MBeansServer side of the test and returns its address
+ */
+ private JMXServiceURL createServerSide(Map<String, Object> serverMap)
+ throws Exception {
+ final int NINETY_SECONDS = 90;
+
+ System.out.println("AuthorizationTest::createServerSide: Start") ;
+
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+
+ // Creates connection environment from server side params
+ HashMap<String, Object> env = new HashMap<>();
+ String value = null;
+
+ if ((value = (String)serverMap.get("-mapType")) != null) {
+ if (value.contains("x.access.file")) {
+ String accessFileStr = System.getProperty("test.src") +
+ File.separator + "access.properties";
+ env.put("jmx.remote.x.access.file", accessFileStr);
+ System.out.println("Added " + accessFileStr + " file as jmx.remote.x.access.file");
+ }
+ if (value.contains("x.password.file")) {
+ String passwordFileStr = System.getProperty("test.src") +
+ File.separator + "password.properties";
+ env.put("jmx.remote.x.password.file", passwordFileStr);
+ System.out.println("Added " + passwordFileStr + " file as jmx.remote.x.password.file");
+ }
+ }
+
+ if (serverMap.containsKey("-populate")) {
+ String populateClassName = "Simple";
+ ObjectName on =
+ new ObjectName("defaultDomain:class=Simple");
+
+ Utils.debug(Utils.DEBUG_STANDARD, "create and register Simple MBean") ;
+ mbs.createMBean(populateClassName, on);
+ }
+
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ cs.start();
+
+ Utils.waitReady(cs, NINETY_SECONDS);
+
+ JMXServiceURL addr = cs.getAddress();
+
+ System.out.println("AuthorizationTest::createServerSide: Done.") ;
+
+ return addr;
+ }
+
+ /*
+ * Creating command-line for running subprocess JVM:
+ *
+ * JVM command line is like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ *
+ */
+ private List<String> buildCommandLine(String args[]) {
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+
+ String usernameValue = System.getProperty(USERNAME_PROPERTY);
+ if (usernameValue != null) {
+ opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
+ }
+ String passwordValue = System.getProperty(PASSWORD_PROPERTY);
+ if (passwordValue != null) {
+ opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
+ }
+
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add(CLIENT_CLASS_MAIN);
+ opts.addAll(Arrays.asList(args));
+ return opts;
+ }
+
+ /**
+ * Runs AuthorizationTest$ClientSide with the passed options and redirects
+ * subprocess standard I/O to the current (parent) process. This provides a
+ * trace of what happens in the subprocess while it is runnning (and before
+ * it terminates).
+ *
+ * @param serviceUrlStr string representing the JMX service Url to connect to.
+ */
+ private int runClientSide(String args[], String serviceUrlStr) throws Exception {
+
+ // Building command-line
+ List<String> opts = buildCommandLine(args);
+ opts.add("-serviceUrl");
+ opts.add(serviceUrlStr);
+
+ // Launch separate JVM subprocess
+ int exitCode = 0;
+ String[] optsArray = opts.toArray(new String[0]);
+ ProcessBuilder pb = new ProcessBuilder(optsArray);
+ Process p = ProcessTools.startProcess("AuthorizationTest$ClientSide", pb);
+
+ // Handling end of subprocess
+ try {
+ exitCode = p.waitFor();
+ if (exitCode != 0) {
+ System.out.println(
+ "Subprocess unexpected exit value of [" + exitCode +
+ "]. Expected 0.\n");
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+ // Parent thread unknown state, killing subprocess.
+ p.destroyForcibly();
+
+ throw new RuntimeException(
+ "Parent process interrupted with exception : \n " + e + " :" );
+
+ } finally {
+ if (p.isAlive()) {
+ p.destroyForcibly();
+ }
+ return exitCode;
+ }
+
+ }
+
+ public void run(Map<String, Object> serverArgs, String clientArgs[]) {
+
+ System.out.println("AuthorizationTest::run: Start") ;
+ int errorCount = 0;
+
+ try {
+ // Initialise the server side
+ JMXServiceURL urlToUse = createServerSide(serverArgs);
+
+ // Run client side
+ errorCount = runClientSide(clientArgs, urlToUse.toString());
+
+ if ( errorCount == 0 ) {
+ System.out.println("AuthorizationTest::run: Done without any error") ;
+ } else {
+ System.out.println("AuthorizationTest::run: Done with "
+ + errorCount
+ + " error(s)") ;
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ cs.stop();
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class ClientSide {
+
+ private JMXConnector cc = null;
+ private MBeanServerConnection mbsc = null;
+
+ public static void main(String args[]) throws Exception {
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is : "MainClass [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> clientMap = new HashMap<>() ;
+ Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
+
+ // Run test
+ ClientSide test = new ClientSide();
+ test.run(clientMap);
+
+ }
+
+ public void run(Map<String, Object> args) {
+
+ int errorCount = 0 ;
+
+ try {
+ boolean expectedCreateException =
+ (args.containsKey("-expectedCreateException")) ? true : false ;
+ boolean expectedGetException =
+ (args.containsKey("-expectedGetException")) ? true : false ;
+ boolean expectedSetException =
+ (args.containsKey("-expectedSetException")) ? true : false ;
+ boolean expectedInvokeException =
+ (args.containsKey("-expectedInvokeException")) ? true : false ;
+ // JSR262 (see bug 6440374)
+ // There is no special JSR262 protocol operation for connect.
+ // The first request sent initiate the connection.
+ // In the JSR262 current implementation, getDefaultDomain is sent to
+ // the server in order to get the server part of the connection ID.
+ // => the connection may fail if no access permission on get requests.
+ boolean expectedConnectException =
+ (args.containsKey("-expectedConnectException")) ? true : false ;
+ // Before connection,
+ // remove the element of the Map with null values (not supported by RMI)
+ // See bug 4982668
+ args.remove("-expectedCreateException");
+ args.remove("-expectedGetException");
+ args.remove("-expectedSetException");
+ args.remove("-expectedInvokeException");
+ args.remove("-expectedConnectException");
+
+
+ // Here do connect to the JMX Server
+ String username = System.getProperty("username");
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: CONNECT on behalf of \"" + username + "\"");
+ doConnect(args, expectedConnectException);
+
+ // If the connection did not fail, perform some requests.
+ // At this stage the mbeanserver connection is up and running
+ if (mbsc != null) {
+ ObjectName on = new ObjectName("defaultDomain:class=Simple");
+
+ // Create request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: CREATE on behalf of \"" +
+ username + "\"");
+ errorCount += doCreateRequest(mbsc,
+ new ObjectName("defaultDomain:class=Simple,user=" + username),
+ expectedCreateException);
+
+ // Get request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: GET on behalf of \"" +
+ username + "\"");
+ errorCount += doGetRequest(mbsc, on, expectedGetException);
+
+ // Set request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: SET on behalf of \"" +
+ username + "\"");
+ errorCount += doSetRequest(mbsc, on, expectedSetException);
+
+ // Invoke request
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::run: INVOKE on behalf of \"" +
+ username + "\"");
+ errorCount += doInvokeRequest(mbsc, on, expectedInvokeException);
+ }
+
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ } finally {
+ // Terminate the JMX Client
+ try {
+ cc.close();
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+ }
+
+ System.out.println("ClientSide::run: Done") ;
+
+ // Handle result
+ if (errorCount == 0) {
+ System.out.println("ClientSide::run: (OK) authorization test succeeded.");
+ } else {
+ String message = "AuthorizationTest$ClientSide::run: (ERROR) " +
+ " authorization test failed with " +
+ errorCount + " error(s)";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+
+ protected void doConnect(Map<String, Object> args,
+ boolean expectedException) {
+
+ String msgTag = "ClientSide::doConnect";
+ boolean throwRuntimeException = false;
+ String message = "";
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doConnect: Connect the client");
+
+ // Collect connection environment
+ HashMap<String, Object> env = new HashMap<>();
+
+ Object value = args.get("-mapType");
+ if (value != null) {
+ String username = System.getProperty("username");
+ String password = System.getProperty("password");
+ Utils.debug(Utils.DEBUG_STANDARD,
+ msgTag + "add \"jmx.remote.credentials\" = \"" +
+ username + "\", \"" + password + "\"");
+ env.put("jmx.remote.credentials",
+ new String[] { username , password });
+ }
+
+ // Get a connection to remote mbean server
+ JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
+ cc = JMXConnectorFactory.connect(addr,env);
+ mbsc = cc.getMBeanServerConnection();
+
+ if (expectedException) {
+ message = "ClientSide::doConnect: (ERROR) " +
+ "Connect did not fail with expected SecurityException";
+ System.out.println(message);
+ throwRuntimeException = true;
+ } else {
+ System.out.println("ClientSide::doConnect: (OK) Connect succeed");
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true);
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doConnect: (OK) " +
+ "Connect failed with expected SecurityException");
+ } else {
+ message = "ClientSide::doConnect: (ERROR) " +
+ "Create failed with " + e.getClass() +
+ " instead of expected SecurityException";
+ System.out.println(message);
+ throwRuntimeException = true;
+ }
+ } else {
+ message = "ClientSide::doConnect: (ERROR) " +
+ "Connect failed";
+ System.out.println(message);
+ throwRuntimeException = true;
+ }
+ }
+
+ // If the connection failed, or if the connection succeeded but should not,
+ // no need to go further => throw RuntimeException and exit the test
+ if (throwRuntimeException) {
+ throw new RuntimeException(message);
+ }
+ }
+
+ protected int doCreateRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doCreateRequest: Create and register the MBean") ;
+
+ mbsc.createMBean("Simple", on) ;
+
+ if (expectedException) {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(ERROR) Create did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doCreateRequest: (OK) Create succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(OK) Create failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(ERROR) Create failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doCreateRequest: " +
+ "(ERROR) Create failed");
+ errorCount++;
+ }
+ }
+ return errorCount;
+ }
+
+ protected int doGetRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doGetRequest: Get attributes of the MBean") ;
+
+ mbsc.getAttribute(on, "Attribute");
+
+ if (expectedException) {
+ System.out.println("ClientSide::doGetRequest: " +
+ "(ERROR) Get did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doGetRequest: (OK) Get succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doGetRequest: " +
+ "(OK) Get failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doGetRequest: " +
+ "(ERROR) Get failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doGetRequest: (ERROR) Get failed");
+ errorCount++;
+ }
+ }
+
+ return errorCount;
+ }
+
+ protected int doSetRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doSetRequest: Set attributes of the MBean") ;
+
+ Attribute attribute = new Attribute("Attribute", "My value") ;
+ mbsc.setAttribute(on, attribute) ;
+
+ if (expectedException) {
+ System.out.println("ClientSide::doSetRequest: " +
+ "(ERROR) Set did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doSetRequest: (OK) Set succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doSetRequest: " +
+ "(OK) Set failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doSetRequest: " +
+ "(ERROR) Set failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doSetRequest: (ERROR) Set failed");
+ errorCount++;
+ }
+ }
+ return errorCount;
+ }
+
+ protected int doInvokeRequest(MBeanServerConnection mbsc,
+ ObjectName on,
+ boolean expectedException) {
+ int errorCount = 0;
+
+ try {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doInvokeRequest: Invoke operations on the MBean") ;
+
+ mbsc.invoke(on, "operation", null, null) ;
+
+ if (expectedException) {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ "(ERROR) Invoke did not fail with expected SecurityException");
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::doInvokeRequest: (OK) Invoke succeed") ;
+ }
+ } catch(Exception e) {
+ Utils.printThrowable(e, true) ;
+ if (expectedException) {
+ if (e instanceof java.lang.SecurityException) {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ "(OK) Invoke failed with expected SecurityException") ;
+ } else {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ " (ERROR) Invoke failed with " +
+ e.getClass() + " instead of expected SecurityException");
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::doInvokeRequest: " +
+ "(ERROR) Invoke failed");
+ errorCount++;
+ }
+ }
+ return errorCount;
+ }
+
+ }
+}
diff --git a/test/javax/management/security/MBS_Light.java b/test/javax/management/security/MBS_Light.java
new file mode 100644
index 0000000..1ed459e
--- /dev/null
+++ b/test/javax/management/security/MBS_Light.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import javax.security.auth.Subject;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.management.MBeanRegistration ;
+import javax.management.MBeanServer ;
+import javax.management.ObjectName ;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationListener;
+import javax.management.Notification;
+
+public class MBS_Light extends NotificationBroadcasterSupport
+ implements MBS_LightMBean, MBeanRegistration, NotificationListener
+{
+ private RjmxMBeanParameter param = null ;
+ private String aString = "notset" ;
+ private int anInt = 0 ;
+ private MBeanServer mbs = null ;
+ private ObjectName objname = null ;
+ private Exception anException = null ;
+ private Error anError = null ;
+ private int count = 0;
+ private SimpleListener listener = new SimpleListener();
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR MBS_Light")
+ public MBS_Light() {
+ }
+
+ @SqeDescriptorKey("ONE RjmxMBeanParameter PARAMETER CONSTRUCTOR MBS_Light")
+ public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")
+ RjmxMBeanParameter param) {
+ this.param = param ;
+ }
+
+ @SqeDescriptorKey("ONE String PARAMETER CONSTRUCTOR MBS_Light")
+ public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")String param) {
+ this.aString = param ;
+ }
+
+ // Getter for property param
+ public RjmxMBeanParameter getParam() {
+ return this.param ;
+ }
+
+ // Setter for property param
+ public void setParam(RjmxMBeanParameter param) {
+ this.param = param ;
+ }
+
+ // Getter for property aString
+ public String getAstring() {
+ return this.aString ;
+ }
+
+ // Setter for property aString
+ public void setAstring(String aString) {
+ this.aString = aString ;
+ }
+
+ // Getter for property anInt
+ public int getAnInt() {
+ return this.anInt ;
+ }
+
+ // Setter for property anInt
+ public void setAnInt(int anInt) {
+ this.anInt = anInt ;
+ }
+
+ // Getter for property anException
+ public Exception getAnException() {
+ return this.anException ;
+ }
+
+ // Setter for property anException
+ public void setAnException(Exception anException) {
+ this.anException = anException ;
+ }
+
+ // Getter for property anError
+ public Error getAnError() {
+ return this.anError ;
+ }
+
+ // Setter for property anError
+ public void setAnError(Error anError) {
+ this.anError = anError ;
+ }
+
+ // An operation
+ public RjmxMBeanParameter operate1(String name) {
+ return new RjmxMBeanParameter(name) ;
+ }
+
+ // An operation
+ public String operate2(RjmxMBeanParameter param) {
+ return param.name ;
+ }
+
+ // An operation
+ public void throwError() {
+ throw new Error("JSR-160-ERROR");
+ }
+
+ // An operation
+ public void throwException() throws Exception {
+ throw new Exception("JSR-160-EXCEPTION");
+ }
+
+ // MBeanRegistration method
+ public void postDeregister() {
+ }
+
+ // MBeanRegistration method
+ public void postRegister(Boolean registrationDone) {
+ }
+
+ // MBeanRegistration method
+ public void preDeregister()
+ throws Exception
+ {
+ }
+
+ // MBeanRegistration method
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception
+ {
+ this.mbs = server ;
+ if ( name == null ) {
+ this.objname = new ObjectName("protocol:class=MBS_Light") ;
+ }
+ else {
+ this.objname = name ;
+ }
+ return this.objname ;
+ }
+
+ public synchronized void handleNotification(Notification notification,
+ Object handback) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "MBS_Light::handleNotification: " + notification);
+ listener.handleNotification(notification, handback);
+ }
+
+ // Send a notification
+ public void sendNotification() {
+ Notification notification =
+ new Notification("JSR160-TCK-NOTIFICATION", this, count++);
+ sendNotification(notification);
+ }
+
+ public Object waitForNotificationHB() {
+ return listener.waitForNotificationHB();
+ }
+
+ // Receive multi notifications and send back handbacks
+ public synchronized Object[] waitForMultiNotifications(String nb) {
+ return listener.waitForMultiNotifications(Integer.valueOf(nb).intValue());
+ }
+
+ // Receive a notification
+ public synchronized String waitForNotification() {
+ return listener.waitForNotification();
+ }
+
+ // Is the notification received
+ public synchronized Boolean notificationReceived() {
+ return Boolean.valueOf(listener.isNotificationReceived());
+ }
+
+ // The authorization Id
+ public String getAuthorizationId() {
+ AccessControlContext acc = AccessController.getContext();
+ Subject subject = Subject.getSubject(acc);
+ Set<Principal> principals = subject.getPrincipals();
+ Iterator<Principal> i = principals.iterator();
+ StringBuffer buffer = new StringBuffer();
+ while(i.hasNext()) {
+ Principal p = i.next();
+ buffer.append(p.getName());
+ if(i.hasNext())
+ buffer.append(" ");
+ }
+
+ return buffer.toString();
+ }
+}
diff --git a/test/javax/management/security/MBS_LightMBean.java b/test/javax/management/security/MBS_LightMBean.java
new file mode 100644
index 0000000..a380af9
--- /dev/null
+++ b/test/javax/management/security/MBS_LightMBean.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+@SqeDescriptorKey("INTERFACE MBS_LightMBean")
+public interface MBS_LightMBean {
+ // Getter for property param
+ @SqeDescriptorKey("ATTRIBUTE Param")
+ public RjmxMBeanParameter getParam() ;
+
+ // Setter for property param
+ @SqeDescriptorKey("ATTRIBUTE Param")
+ public void setParam(RjmxMBeanParameter param) ;
+
+ // Getter for property aString
+ @SqeDescriptorKey("ATTRIBUTE Astring")
+ public String getAstring() ;
+
+ // Setter for property aString
+ @SqeDescriptorKey("ATTRIBUTE Astring")
+ public void setAstring(String aString) ;
+
+ // Getter for property anInt
+ @SqeDescriptorKey("ATTRIBUTE AnInt")
+ public int getAnInt() ;
+
+ // Setter for property anInt
+ @SqeDescriptorKey("ATTRIBUTE AnInt")
+ public void setAnInt(int anInt) ;
+
+ // Getter for property anException
+ @SqeDescriptorKey("ATTRIBUTE AnException")
+ public Exception getAnException() ;
+
+ // Setter for property anException
+ @SqeDescriptorKey("ATTRIBUTE AnException")
+ public void setAnException(Exception anException) ;
+
+ // Getter for property anError
+ @SqeDescriptorKey("ATTRIBUTE AnError")
+ public Error getAnError() ;
+
+ // Setter for property anError
+ @SqeDescriptorKey("ATTRIBUTE AnError")
+ public void setAnError(Error anError) ;
+
+ // An operation
+ @SqeDescriptorKey("OPERATION operate1")
+ public RjmxMBeanParameter operate1(
+ @SqeDescriptorKey("OPERATION PARAMETER name")String name) ;
+
+ // An operation
+ @SqeDescriptorKey("OPERATION operate2")
+ public String operate2(
+ @SqeDescriptorKey("OPERATION PARAMETER param")RjmxMBeanParameter param) ;
+
+ // Throws an error
+ @SqeDescriptorKey("OPERATION throwError")
+ public void throwError();
+
+ // Throws an exception
+ @SqeDescriptorKey("OPERATION throwException")
+ public void throwException() throws Exception;
+
+ // Send a notification
+ @SqeDescriptorKey("OPERATION sendNotification")
+ public void sendNotification();
+
+ // Receive a notification and return the type
+ @SqeDescriptorKey("OPERATION waitForNotification")
+ public String waitForNotification();
+
+ // Receive a notification and return the HandBack
+ @SqeDescriptorKey("OPERATION waitForNotificationHB")
+ public Object waitForNotificationHB();
+
+ // Receive multi notifications and return the HandBacks
+ @SqeDescriptorKey("OPERATION waitForMultiNotifications")
+ public Object[] waitForMultiNotifications(
+ @SqeDescriptorKey("OPERATION PARAMETER nb")String nb);
+
+ // Is the notification received
+ @SqeDescriptorKey("OPERATION notificationReceived")
+ public Boolean notificationReceived();
+
+ // Return the current authorization Id
+ @SqeDescriptorKey("OPERATION getAuthorizationId")
+ public String getAuthorizationId();
+}
diff --git a/test/javax/management/security/RjmxMBeanParameter.java b/test/javax/management/security/RjmxMBeanParameter.java
new file mode 100644
index 0000000..c96e9a1
--- /dev/null
+++ b/test/javax/management/security/RjmxMBeanParameter.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable ;
+
+/**
+ * That class is used to modelize a parameter to be used as MBean property
+ * value or MBean operation parameter or returned value.
+ */
+public class RjmxMBeanParameter implements Serializable {
+ public String name = "unset" ;
+
+ public RjmxMBeanParameter() {
+ }
+
+ public RjmxMBeanParameter(String name) {
+ this.name = name ;
+ }
+
+ public boolean equals(Object obj) {
+ if ( this.name.equals(((RjmxMBeanParameter)obj).name) ) {
+ return true ;
+ } else {
+ return false ;
+ }
+ }
+}
diff --git a/test/javax/management/security/SecurityTest.java b/test/javax/management/security/SecurityTest.java
new file mode 100644
index 0000000..6d245bd
--- /dev/null
+++ b/test/javax/management/security/SecurityTest.java
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8058865
+ * @summary Checks various secure ways of connecting from remote jmx client
+ * @author Olivier Lagneau
+ * @modules java.management
+ * @library /lib/testlibrary
+ * @compile MBS_Light.java ServerDelegate.java TestSampleLoginModule.java
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=UNKNOWN_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=WRONG_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=TestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=AnotherTestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config.UNKNOWN -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentialss -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.UnknownAuthentication -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=usernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=AnotherUsernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials -expectedThrowable java.lang.SecurityException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword WRONG_password -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword WRONG_password -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.sha -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=TLSv1 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.tlsv1 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
+ */
+
+import java.io.File;
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory ;
+import javax.management.MBeanServerConnection;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import javax.management.Attribute ;
+import javax.management.ObjectName ;
+
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+
+import java.security.Security;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JDKToolFinder;
+
+public class SecurityTest {
+
+ static final String SERVER_CLASS_NAME = "SecurityTest";
+ static final String CLIENT_CLASS_NAME = "SecurityTest$ClientSide";
+ static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
+
+ static final String USERNAME_PROPERTY = "username";
+ static final String PASSWORD_PROPERTY = "password";
+
+ static final String SERVER_DELEGATE_MBEAN_NAME =
+ "defaultDomain:class=ServerDelegate";
+
+ static final String RMI_SERVER_SOCKET_FACTORY_SSL = "rmi.server.socket.factory.ssl";
+ static final String RMI_CLIENT_SOCKET_FACTORY_SSL = "rmi.client.socket.factory.ssl";
+ static final String KEYSTORE_PROPNAME = "javax.net.ssl.keyStore";
+ static final String KEYSTORE_PWD_PROPNAME = "javax.net.ssl.keyStorePassword";
+ static final String TRUSTSTORE_PROPNAME = "javax.net.ssl.trustStore";
+ static final String TRUSTSTORE_PWD_PROPNAME = "javax.net.ssl.trustStorePassword";
+
+ static final String RMI_SSL_CLIENT_ENABLEDCIPHERSUITES =
+ "javax.rmi.ssl.client.enabledCipherSuites";
+ static final String RMI_SSL_CLIENT_ENABLEDPROTOCOLS =
+ "javax.rmi.ssl.client.enabledProtocols";
+
+ private JMXConnectorServer cs;
+
+ // Construct and set keyStore properties from given map
+ static void setKeyStoreProperties(Map<String, Object> map) {
+
+ String keyStore = (String) map.get("-keystore");
+ keyStore = buildSourcePath(keyStore);
+ System.setProperty(KEYSTORE_PROPNAME, keyStore);
+ System.out.println("keyStore location = \"" + keyStore + "\"");
+
+ String password = (String) map.get("-keystorepassword");
+ System.setProperty(KEYSTORE_PWD_PROPNAME, password);
+ System.out.println("keyStore password = " + password);
+
+ }
+
+ // Construct and set trustStore properties from given map
+ static void setTrustStoreProperties(Map<String, Object> map) {
+
+ String trustStore = (String) map.get("-truststore");
+ trustStore = buildSourcePath(trustStore);
+ System.setProperty(TRUSTSTORE_PROPNAME, trustStore);
+ System.out.println("trustStore location = \"" + trustStore + "\"");
+
+ String password = (String) map.get("-truststorepassword");
+ System.setProperty(TRUSTSTORE_PWD_PROPNAME, password);
+ System.out.println("trustStore password = " + password);
+
+ }
+
+ /*
+ * First Debug properties and arguments are collect in expected
+ * map (argName, value) format, then calls original test's run method.
+ */
+ public static void main(String args[]) throws Exception {
+
+ System.out.println("=================================================");
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is :
+ // "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> serverMap = new HashMap<>() ;
+ int clientArgsIndex =
+ Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
+
+ // Extract and records client params
+ String[] clientParams = null;
+ if (clientArgsIndex < args.length) {
+ int clientParamsSize = args.length - clientArgsIndex;
+ clientParams = new String[clientParamsSize];
+ System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
+ } else {
+ clientParams = new String[0];
+ }
+
+ // Run test
+ SecurityTest test = new SecurityTest();
+ test.run(serverMap, clientParams);
+
+ }
+
+ // Return full path of filename in the test sopurce directory
+ private static String buildSourcePath(String filename) {
+ return System.getProperty("test.src") + File.separator + filename;
+ }
+
+ /*
+ * Collects security run params for server side.
+ */
+ private HashMap<String, Object> setServerSecurityEnv(Map<String, Object> map)
+ throws Exception {
+
+ // Creates Authentication environment from server side params
+ HashMap<String, Object> env = new HashMap<>();
+
+ // Retrieve and set keystore and truststore config if any
+ if (map.containsKey("-keystore") &&
+ map.get("-keystore") != null) {
+ setKeyStoreProperties(map);
+ }
+ System.out.println("Done keystore properties");
+
+ if (map.containsKey("-truststore") &&
+ map.get("-truststore") != null) {
+ setTrustStoreProperties(map);
+ }
+ System.out.println("Done truststore properties");
+
+ String value = null;
+ if ((value = (String)map.get("-mapType")) != null) {
+
+ // Case of remote password file with all authorized credentials
+ if (value.contains("x.password.file")) {
+ String passwordFileStr = buildSourcePath("password.properties");
+ env.put("jmx.remote.x.password.file", passwordFileStr);
+ System.out.println("Added " + passwordFileStr +
+ " file as jmx.remote.x.password.file");
+ }
+
+ // Case of dedicated authenticator class : TestJMXAuthenticator
+ if (value.contains("x.authenticator")) {
+ env.put("jmx.remote.authenticator", new TestJMXAuthenticator()) ;
+ System.out.println(
+ "Added \"jmx.remote.authenticator\" = TestJMXAuthenticator");
+ }
+
+ // Case of security config file with standard Authentication
+ if (value.contains("x.login.config.PasswordFileAuthentication")) {
+ String loginConfig = System.getProperty("login.config.file");
+
+ // Override the default JAAS configuration
+ System.setProperty("java.security.auth.login.config",
+ "file:" + loginConfig);
+ System.out.println("Overrided default JAAS configuration with " +
+ "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+ env.put("jmx.remote.x.login.config", "PasswordFileAuthentication") ;
+ System.out.println(
+ "Added \"jmx.remote.x.login.config\" = " +
+ "\"PasswordFileAuthentication\"") ;
+
+ // redirects "password.file" property to file in ${test.src}
+ String passwordFileStr =
+ buildSourcePath(System.getProperty("password.file"));
+ System.setProperty("password.file", passwordFileStr);
+ System.out.println(
+ "Redirected \"password.file\" property value to = " +
+ passwordFileStr) ;
+ }
+
+ // Case of security config file with unexisting athentication config
+ if (value.contains("x.login.config.UnknownAuthentication")) {
+ String loginConfig = System.getProperty("login.config.file");
+
+ // Override the default JAAS configuration
+ System.setProperty("java.security.auth.login.config",
+ "file:" + loginConfig);
+ System.out.println("Overrided default JAAS configuration with " +
+ "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+ env.put("jmx.remote.x.login.config", "UnknownAuthentication") ;
+ System.out.println(
+ "Added \"jmx.remote.x.login.config\" = " +
+ "\"UnknownAuthentication\"") ;
+
+ // redirects "password.file" property to file in ${test.src}
+ String passwordFileStr =
+ buildSourcePath(System.getProperty("password.file"));
+ System.setProperty("password.file", passwordFileStr);
+ System.out.println(
+ "Redirected \"password.file\" property value to = " +
+ passwordFileStr) ;
+ }
+
+ // Case of security config file with dedicated login module
+ if (value.contains("x.login.config.SampleLoginModule")) {
+ String loginConfig = System.getProperty("login.config.file");
+
+ // Override the default JAAS configuration
+ System.setProperty("java.security.auth.login.config",
+ "file:" + loginConfig);
+ System.out.println("Overrided default JAAS configuration with " +
+ "\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
+
+ env.put("jmx.remote.x.login.config", "SampleLoginModule") ;
+ System.out.println(
+ "Added \"jmx.remote.x.login.config\" = " +
+ "\"SampleLoginModule\"") ;
+ }
+
+ // Simple rmi ssl authentication
+ if (value.contains(RMI_CLIENT_SOCKET_FACTORY_SSL)) {
+ env.put("jmx.remote.rmi.client.socket.factory",
+ new SslRMIClientSocketFactory()) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.client.socket.factory\"" +
+ " = SslRMIClientSocketFactory") ;
+ }
+
+ if (value.contains(RMI_SERVER_SOCKET_FACTORY_SSL)) {
+ if (value.contains(
+ "rmi.server.socket.factory.ssl.need.client.authentication")) {
+ // rmi ssl authentication with client authentication
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(null, null, true)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with client authentication") ;
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.md5")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(
+ new String[] {"SSL_RSA_WITH_RC4_128_MD5"}, null, false));
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_MD5 cipher suite");
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.sha")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(
+ new String[] { "SSL_RSA_WITH_RC4_128_SHA" }, null, false)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_SHA cipher suite") ;
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.sslv3")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(null, new String[] {"SSLv3"}, false)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with SSLv3 protocol") ;
+
+ } else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.tlsv1")) {
+ // Allows all ciphering and protocols for testing purpose
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory(null, new String[] {"TLSv1"}, false)) ;
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory with TLSv1 protocol") ;
+
+ } else {
+ env.put("jmx.remote.rmi.server.socket.factory",
+ new SslRMIServerSocketFactory());
+ System.out.println(
+ "Added \"jmx.remote.rmi.server.socket.factory\"" +
+ " = SslRMIServerSocketFactory");
+ }
+ }
+ }
+
+ return env;
+ }
+
+ /*
+ * Create the MBeansServer side of the test and returns its address
+ */
+ private JMXServiceURL createServerSide(Map<String, Object> serverMap)
+ throws Exception {
+ final int NINETY_SECONDS = 90;
+
+ System.out.println("SecurityTest::createServerSide: Start") ;
+
+ // Prepare server side security env
+ HashMap<String, Object> env = setServerSecurityEnv(serverMap);
+
+ // Create and start mbean server and connector server
+ MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+ JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ cs.start();
+
+ // Waits availibility of connector server
+ Utils.waitReady(cs, NINETY_SECONDS);
+
+ JMXServiceURL addr = cs.getAddress();
+
+ System.out.println("SecurityTest::createServerSide: Done.") ;
+
+ return addr;
+ }
+
+ /*
+ * Creating command-line for running subprocess JVM:
+ *
+ * JVM command line is like:
+ * {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
+ *
+ * {defaultopts} are the default java options set by the framework.
+ *
+ */
+ private List<String> buildCommandLine(String args[]) {
+
+ System.out.println("SecurityTest::buildCommandLine: Start") ;
+
+ List<String> opts = new ArrayList<>();
+ opts.add(JDKToolFinder.getJDKTool("java"));
+ opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
+
+ // We need to forward some properties to the client side
+ opts.add("-Dtest.src=" + System.getProperty("test.src"));
+
+ String usernameValue = System.getProperty(USERNAME_PROPERTY);
+ if (usernameValue != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward username property to client side");
+ opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
+ }
+ String passwordValue = System.getProperty(PASSWORD_PROPERTY);
+ if (passwordValue != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward password property to client side");
+ opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
+ }
+
+ String enabledCipherSuites =
+ System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES);
+ if (enabledCipherSuites != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward enabledCipherSuites property to client side");
+ opts.add("-D" + RMI_SSL_CLIENT_ENABLEDCIPHERSUITES +
+ "=" + enabledCipherSuites);
+ }
+
+ String enabledProtocols =
+ System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS);
+ if (enabledProtocols != null) {
+ System.out.println("SecurityTest::buildCommandLine: "+
+ " forward enabledProtocols property to client side");
+ opts.add("-D" + RMI_SSL_CLIENT_ENABLEDPROTOCOLS +
+ "=" + enabledProtocols);
+ }
+
+ opts.add("-cp");
+ opts.add(System.getProperty("test.class.path", "test.class.path"));
+ opts.add(CLIENT_CLASS_MAIN);
+ opts.addAll(Arrays.asList(args));
+
+ System.out.println("SecurityTest::buildCommandLine: Done.") ;
+
+ return opts;
+ }
+
+ /**
+ * Runs SecurityTest$ClientSide with the passed options and redirects
+ * subprocess standard I/O to the current (parent) process. This provides a
+ * trace of what happens in the subprocess while it is runnning (and before
+ * it terminates).
+ *
+ * @param serviceUrlStr string representing the JMX service Url to connect to.
+ */
+ private int runClientSide(String args[], String serviceUrlStr) throws Exception {
+
+ System.out.println("SecurityTest::runClientSide: Start") ;
+
+ // Building command-line
+ List<String> opts = buildCommandLine(args);
+ opts.add("-serviceUrl");
+ opts.add(serviceUrlStr);
+
+ // Launch separate JVM subprocess
+ int exitCode = 0;
+ String[] optsArray = opts.toArray(new String[0]);
+ ProcessBuilder pb = new ProcessBuilder(optsArray);
+ Process p = ProcessTools.startProcess("SecurityTest$ClientSide", pb);
+
+ // Handling end of subprocess
+ try {
+ exitCode = p.waitFor();
+ if (exitCode != 0) {
+ System.out.println(
+ "Subprocess unexpected exit value of [" + exitCode +
+ "]. Expected 0.\n");
+ }
+ } catch (InterruptedException e) {
+ System.out.println("Parent process interrupted with exception : \n " + e + " :" );
+
+ // Parent thread unknown state, killing subprocess.
+ p.destroyForcibly();
+
+ throw new RuntimeException(
+ "Parent process interrupted with exception : \n " + e + " :" );
+
+ } finally {
+ if (p.isAlive()) {
+ p.destroyForcibly();
+ }
+
+ System.out.println("SecurityTest::runClientSide: Done") ;
+
+ return exitCode;
+ }
+
+ }
+
+ public void run(Map<String, Object> serverArgs, String clientArgs[]) {
+
+ System.out.println("SecurityTest::run: Start") ;
+ int errorCount = 0;
+
+ try {
+ // Initialise the server side
+ JMXServiceURL urlToUse = createServerSide(serverArgs);
+
+ // Run client side
+ errorCount = runClientSide(clientArgs, urlToUse.toString());
+
+ if ( errorCount == 0 ) {
+ System.out.println("SecurityTest::run: Done without any error") ;
+ } else {
+ System.out.println(
+ "SecurityTest::run: Done with " + errorCount + " error(s)");
+ throw new RuntimeException("errorCount = " + errorCount);
+ }
+
+ cs.stop();
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ private static class ClientSide {
+
+ private JMXConnector cc = null;
+ private MBeanServerConnection mbsc = null;
+
+ public static void main(String args[]) throws Exception {
+
+ // Parses parameters
+ Utils.parseDebugProperties();
+
+ // Supported parameters list format is : "MainClass [-client <param-spec> ...]
+ // with <param-spec> either "-parami valuei" or "-parami"
+ HashMap<String, Object> clientMap = new HashMap<>() ;
+ Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
+
+ // Run test
+ ClientSide test = new ClientSide();
+ test.run(clientMap);
+ }
+
+ public void run(Map<String, Object> args) {
+
+ System.out.println("ClientSide::run: Start");
+ int errorCount = 0;
+
+ try {
+ // Setup client side parameters
+ HashMap<String, Object> env = new HashMap<>();
+
+ // If needed allows all ciphering and protocols for testing purpose
+ if (System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES) != null) {
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ }
+
+ // If needed allows all ciphering and protocols for testing purpose
+ if (System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS) != null) {
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+ }
+
+ // Retrieve and set keystore and truststore config if any
+ if (args.containsKey("-keystore") &&
+ args.get("-keystore") != null) {
+ SecurityTest.setKeyStoreProperties(args);
+ }
+ if (args.containsKey("-truststore") &&
+ args.get("-truststore") != null) {
+ SecurityTest.setTrustStoreProperties(args);
+ }
+
+ Object value = args.get("-mapType");
+ if ((value != null) &&
+ value.equals("credentials")) {
+ String username = System.getProperty("username");
+ String password = System.getProperty("password");
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "add \"jmx.remote.credentials\" = \"" +
+ username + "\", \"" + password + "\"");
+ env.put("jmx.remote.credentials",
+ new String[] { username , password });
+ }
+
+ String expectedThrowable = (String) args.get("-expectedThrowable");
+
+ String authCallCountName = "-expectedAuthenticatorCallCount";
+ int authCallCountValue = 0;
+ if (args.containsKey(authCallCountName)) {
+ authCallCountValue =
+ (new Integer((String) args.get(authCallCountName))).intValue();
+ }
+
+ try {
+ // Get a connection to remote mbean server
+ JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
+ cc = JMXConnectorFactory.connect(addr,env);
+ mbsc = cc.getMBeanServerConnection();
+
+ // In case we should have got an exception
+ if (expectedThrowable != null) {
+ System.out.println("ClientSide::run: (ERROR) " +
+ " Connect did not fail with expected " + expectedThrowable);
+ errorCount++;
+ } else {
+ System.out.println("ClientSide::run: (OK) Connect succeed");
+ }
+ } catch (Throwable e) {
+ Utils.printThrowable(e, true);
+ if (expectedThrowable != null) {
+ if (Utils.compareThrowable(e, expectedThrowable)) {
+ System.out.println("ClientSide::run: (OK) " +
+ "Connect failed with expected " + expectedThrowable);
+ } else {
+ System.out.println("ClientSide::run: (ERROR) Connect failed with " +
+ e.getClass() + " instead of expected " +
+ expectedThrowable);
+ errorCount++;
+ }
+ } else {
+ System.out.println("ClientSide::run: (ERROR) " +
+ "Connect failed with exception");
+ errorCount++;
+ }
+ }
+
+ // Depending on the client state,
+ // perform some requests
+ if (mbsc != null && errorCount == 0) {
+ // Perform some little JMX requests
+ System.out.println("ClientSide::run: Start sending requests");
+
+ doRequests();
+
+ // In case authentication has been used we check how it did.
+ if (authCallCountValue != 0) {
+ errorCount += checkAuthenticator(mbsc, authCallCountValue);
+ }
+ }
+ } catch (Exception e) {
+ Utils.printThrowable(e, true);
+ errorCount++;
+ } finally {
+ // Terminate the JMX Client if any
+ if (cc != null) {
+ try {
+ cc.close();
+ } catch (Exception e) {
+ Utils.printThrowable(e, true) ;
+ errorCount++;
+ }
+ }
+ }
+
+ System.out.println("ClientSide::run: Done");
+
+ // Handle result
+ if (errorCount != 0) {
+ throw new RuntimeException();
+ }
+ }
+
+ private void doRequests() throws Exception {
+
+ // Send some requests to the remote JMX server
+ ObjectName objName1 =
+ new ObjectName("TestDomain:class=MBS_Light,rank=1");
+ String mbeanClass = "MBS_Light";
+ Exception exception = new Exception("MY TEST EXCEPTION");
+ Attribute attException = new Attribute("AnException", exception);
+ Error error = new Error("MY TEST ERROR");
+ Attribute attError = new Attribute("AnError", error);
+ String opParamString = "TOTORO";
+ RjmxMBeanParameter opParam = new RjmxMBeanParameter(opParamString);
+ Object[] params1 = {opParamString};
+ String[] sig1 = {"java.lang.String"};
+ Object[] params2 = {opParam};
+ String[] sig2 = {"RjmxMBeanParameter"};
+
+ // Create and register the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Create and register the MBean");
+ mbsc.createMBean(mbeanClass, objName1);
+ if (!mbsc.isRegistered(objName1)) {
+ throw new Exception("Unable to register an MBean");
+ }
+
+ // Set attributes of the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Set attributes of the MBean");
+ mbsc.setAttribute(objName1, attException);
+ mbsc.setAttribute(objName1, attError);
+
+ // Get attributes of the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Get attributes of the MBean");
+ Exception retException =
+ (Exception) mbsc.getAttribute(objName1,"AnException");
+ if (!retException.getMessage().equals(exception.getMessage())) {
+ System.out.println("Expected = " + exception);
+ System.out.println("Got = " + retException);
+ throw new Exception("Attribute AnException not as expected");
+ }
+ Error retError = (Error) mbsc.getAttribute(objName1, "AnError");
+ if (!retError.getMessage().equals(error.getMessage())) {
+ System.out.println("Expected = " + error);
+ System.out.println("Got = " + retError);
+ throw new Exception("Attribute AnError not as expected");
+ }
+
+ // Invoke operations on the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Invoke operations on the MBean");
+ RjmxMBeanParameter res1 =
+ (RjmxMBeanParameter) mbsc.invoke(objName1, "operate1", params1, sig1);
+ if (!res1.equals(opParam)) {
+ System.out.println("Expected = " + opParam);
+ System.out.println("Got = " + res1);
+ throw new Exception("Operation operate1 behaved badly");
+ }
+ String res2 =
+ (String) mbsc.invoke(objName1, "operate2", params2, sig2);
+ if (!res2.equals(opParamString)) {
+ System.out.println("Expected = " + opParamString);
+ System.out.println("Got = " + res2);
+ throw new Exception("Operation operate2 behaved badly");
+ }
+
+ // Unregister the MBean
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "ClientSide::doRequests: Unregister the MBean");
+ mbsc.unregisterMBean(objName1);
+ if (mbsc.isRegistered(objName1)) {
+ throw new Exception("Unable to unregister an MBean");
+ }
+ }
+
+ /**
+ * Make some check about the instance of TestJMXAuthenticator.
+ * The authenticator is supposed to have set some properties on
+ * a ServerDelegate MBean.
+ * We compare the number of times it has been called with the expected value.
+ * We also check the Principal that has been given to the authenticator
+ * was not null.
+ * That method is of use to authentication with the JSR 262.
+ * @param mbs
+ * @param expectedAuthenticatorCallCount
+ * @return The number of errors encountered.
+ * @throws java.lang.Exception
+ */
+ protected int checkAuthenticator(MBeanServerConnection mbs,
+ int expectedAuthenticatorCallCount) throws Exception {
+ int errorCount = 0;
+
+ // Ensure the authenticator has been called the right number
+ // of times.
+ int callCount =
+ ((Integer) mbs.getAttribute(
+ new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
+ "TestJMXAuthenticatorCallCount")).intValue();
+
+ if (callCount == expectedAuthenticatorCallCount) {
+ System.out.println("---- OK Authenticator has been called "
+ + expectedAuthenticatorCallCount + " time");
+ } else {
+ errorCount++;
+ System.out.println("---- ERROR Authenticator has been called " + callCount
+ + " times in place of " + expectedAuthenticatorCallCount);
+ }
+
+ // Ensure the provider has been called with
+ // a non null Principal.
+ String principalString =
+ (String) mbs.getAttribute(
+ new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
+ "TestJMXAuthenticatorPrincipalString");
+
+ if (principalString == null) {
+ errorCount++;
+ System.out.println("---- ERROR Authenticator has been called"
+ + " with a null Principal");
+ } else {
+ if (principalString.length() > 0) {
+ System.out.println("---- OK Authenticator has been called"
+ + " with the Principal " + principalString);
+ } else {
+ errorCount++;
+ System.out.println("---- ERROR Authenticator has been called"
+ + " with an empty Principal");
+ }
+ }
+
+ return errorCount;
+ }
+
+ }
+
+}
diff --git a/test/javax/management/security/ServerDelegate.java b/test/javax/management/security/ServerDelegate.java
new file mode 100644
index 0000000..6ce5fac
--- /dev/null
+++ b/test/javax/management/security/ServerDelegate.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+/**
+ * This class defines an MBean that can be registered and used on client side
+ * to handle informations or properties of the remote server.
+ *
+ * For example, this MBean can store IOR addresses
+ * of RMI/IIOP connector(s) used in a test.
+ *
+ * That MBean might not be used for testing purpose itself.
+ */
+public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
+
+ private MBeanServer mbeanServer = null;
+ private List<JMXServiceURL> addresses = null;
+ private String port;
+ private static String javaVersion = System.getProperty("java.version");
+ private int sqeJmxwsCredentialsProviderCallCount = 0;
+ private String jmxwsCredentialsProviderUrl = null;
+ private int testJMXAuthenticatorCallCount = 0;
+ private Principal testJMXAuthenticatorPrincipal = null;
+
+ @SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
+ public ServerDelegate() {
+ addresses = new ArrayList<JMXServiceURL>();
+ }
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ // Initialize MBeanServer attribute
+ mbeanServer = server;
+ return name;
+ }
+ public void postRegister(Boolean registrationDone) {
+ }
+ public void preDeregister() throws Exception {
+ }
+ public void postDeregister() {
+ }
+
+ public void addAddress(JMXServiceURL url) {
+ addresses.add(url) ;
+ }
+
+ public List<JMXServiceURL> getAddresses() {
+ return addresses ;
+ }
+
+ public void setPort(String p) {
+ port = p ;
+ }
+
+ public String getPort() {
+ return port ;
+ }
+
+ public String getJavaVersion() {
+ return javaVersion;
+ }
+
+ public void sqeJmxwsCredentialsProviderCalled() {
+ sqeJmxwsCredentialsProviderCallCount++;
+ }
+
+ public int getSqeJmxwsCredentialsProviderCallCount() {
+ return sqeJmxwsCredentialsProviderCallCount;
+ }
+
+ public void setJmxwsCredentialsProviderUrl(String url) {
+ jmxwsCredentialsProviderUrl = url;
+ }
+
+ public String getJmxwsCredentialsProviderUrl() {
+ return jmxwsCredentialsProviderUrl;
+ }
+
+ public void testJMXAuthenticatorCalled() {
+ testJMXAuthenticatorCallCount++;
+ }
+
+ public int getTestJMXAuthenticatorCallCount() {
+ return testJMXAuthenticatorCallCount;
+ }
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal) {
+ testJMXAuthenticatorPrincipal = principal;
+ }
+
+ public String getTestJMXAuthenticatorPrincipalString() {
+ if ( testJMXAuthenticatorPrincipal != null ) {
+ return testJMXAuthenticatorPrincipal.toString();
+ }
+
+ return null;
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ *
+ * @param implementationClassName
+ * The implementation class name of the MBean.
+ * @param interfaceClassName
+ * The management interface class name of the MBean.
+ * @param isMXBean
+ * If true, the resultant MBean is an MXBean.
+ * @param name
+ * The object name of the StandardMBean.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ Object implementation =
+ Class.forName(implementationClassName).newInstance();
+ Class<Object> interfaceClass = interfaceClassName == null ? null :
+ (Class<Object>)Class.forName(interfaceClassName);
+
+ // Create the StandardMBean
+ StandardMBean standardMBean = new StandardMBean(
+ implementation,
+ interfaceClass,
+ isMXBean);
+
+ // Register the StandardMBean
+ mbeanServer.registerMBean(standardMBean, name);
+ }
+
+ /**
+ * Instantiates and registers a StandardMBean in the MBean server.
+ * The object will use standard JMX design pattern to determine
+ * the management interface associated with the given implementation.
+ */
+ @SuppressWarnings("unchecked")
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception {
+
+ createStandardMBean(implementationClassName, null, isMXBean, name);
+ }
+}
diff --git a/test/javax/management/security/ServerDelegateMBean.java b/test/javax/management/security/ServerDelegateMBean.java
new file mode 100644
index 0000000..88f0b3f
--- /dev/null
+++ b/test/javax/management/security/ServerDelegateMBean.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.management.remote.JMXServiceURL ;
+import javax.management.ObjectName;
+
+@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
+public interface ServerDelegateMBean {
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public void addAddress(JMXServiceURL url);
+
+ @SqeDescriptorKey("ATTRIBUTE Address")
+ public List<JMXServiceURL> getAddresses();
+
+ public String getPort();
+ public void setPort(String p);
+
+ public String getJavaVersion();
+
+ public void sqeJmxwsCredentialsProviderCalled();
+ public int getSqeJmxwsCredentialsProviderCallCount();
+
+ public void setJmxwsCredentialsProviderUrl(String url);
+ public String getJmxwsCredentialsProviderUrl();
+
+ public void testJMXAuthenticatorCalled();
+ public int getTestJMXAuthenticatorCallCount();
+
+ public void setTestJMXAuthenticatorPrincipal(Principal principal);
+ public String getTestJMXAuthenticatorPrincipalString();
+
+ public void createStandardMBean(
+ String implementationClassName,
+ String interfaceClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+
+ public void createStandardMBean(
+ String implementationClassName,
+ boolean isMXBean,
+ ObjectName name)
+ throws Exception;
+}
diff --git a/test/javax/management/security/Simple.java b/test/javax/management/security/Simple.java
new file mode 100644
index 0000000..2265ed0
--- /dev/null
+++ b/test/javax/management/security/Simple.java
@@ -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;
+ }
+}
diff --git a/test/javax/management/security/SimpleListener.java b/test/javax/management/security/SimpleListener.java
new file mode 100644
index 0000000..0510150
--- /dev/null
+++ b/test/javax/management/security/SimpleListener.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// JDK
+import java.util.Vector;
+
+// JMX
+import javax.management.NotificationListener;
+import javax.management.Notification;
+
+public class SimpleListener implements NotificationListener {
+ private boolean received = false;
+ private String type = null;
+ private Object handback = null;
+ private Vector<Object> handbacks = new Vector<Object>();
+ private int nbrec = 0;
+
+ public synchronized void handleNotification(Notification notification,
+ Object handback) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::handleNotification :" + notification);
+ try {
+ received = true;
+ type = notification.getType();
+ this.handback = handback;
+ handbacks.add(handback);
+ nbrec++;
+ notify();
+ } catch(Exception e) {
+ System.out.println("(ERROR) SimpleListener::handleNotification :"
+ + " Caught exception "
+ + e) ;
+ }
+ }
+
+ public synchronized boolean isNotificationReceived() {
+ boolean ret = received;
+ reset();
+ return ret;
+ }
+
+ public synchronized Object[] waitForMultiNotifications(int nb) {
+ while(true) {
+ if(nbrec < nb) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForMultiNotifications wait");
+ try {
+ wait();
+ } catch(InterruptedException ie) {
+ // OK : we wait for being interrupted
+ }
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForMultiNotifications wait over");
+ }
+ else
+ break;
+ }
+ Object[] ret = handbacks.toArray();
+ reset();
+ return ret;
+ }
+
+ private void reset() {
+ received = false;
+ handback = null;
+ handbacks.removeAllElements();
+ type = null;
+ }
+
+ public synchronized Object waitForNotificationHB() {
+ while(true) {
+ if(!received) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotificationHB wait");
+ try {
+ wait();
+ } catch(InterruptedException ie) {
+ // OK : we wait for being interrupted
+ }
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotificationHB received");
+ }
+ else
+ break;
+ }
+ Object ret = handback;
+ reset();
+ return ret;
+ }
+
+ public synchronized String waitForNotification() {
+ while(true) {
+ if(!received) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotification wait");
+ try {
+ wait();
+ } catch(InterruptedException ie) {
+ // OK : we wait for being interrupted
+ }
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "SimpleListener::waitForNotification received");
+ }
+ else
+ break;
+ }
+ String ret = type;
+ reset();
+ return ret;
+ }
+}
diff --git a/test/javax/management/security/SimpleMBean.java b/test/javax/management/security/SimpleMBean.java
new file mode 100644
index 0000000..676ac4a
--- /dev/null
+++ b/test/javax/management/security/SimpleMBean.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This interface defines a simple standard MBean.
+ */
+@SqeDescriptorKey("INTERFACE SimpleMBean")
+public interface SimpleMBean {
+
+ @SqeDescriptorKey("ATTRIBUTE Attribute")
+ public String getAttribute();
+
+ @SqeDescriptorKey("ATTRIBUTE Attribute")
+ public void setAttribute(String s);
+
+ @SqeDescriptorKey("ATTRIBUTE OperationInvoked")
+ public boolean getOperationInvoked();
+
+ @SqeDescriptorKey("ATTRIBUTE Operation2Invoked")
+ public boolean getOperation2Invoked();
+
+ // Void operation
+ // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
+ // => openType is added to the descriptor
+ @SqeDescriptorKey(value = "OPERATION operation",
+ descriptorFields = {"openType=SimpleType.VOID"})
+ public void operation();
+
+ @SqeDescriptorKey("OPERATION operation2")
+ public String operation2(int i);
+
+ // Void operation
+ // The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
+ // => openType is added to the descriptor
+ @SqeDescriptorKey(value = "OPERATION reset",
+ descriptorFields = {"openType=SimpleType.VOID"})
+ public void reset();
+}
diff --git a/test/javax/management/security/SqeDescriptorKey.java b/test/javax/management/security/SqeDescriptorKey.java
new file mode 100644
index 0000000..60e4926
--- /dev/null
+++ b/test/javax/management/security/SqeDescriptorKey.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import javax.management.DescriptorKey;
+
+/**
+ * That annotation is usable everywhere DescriptorKey is (and even more).
+ * It is for use to test that you can retrieve the SqeDescriptorKey into the
+ * appropriate Descriptor instances as built by the JMX runtime.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SqeDescriptorKey {
+ @DescriptorKey("sqeDescriptorKey")
+ String value();
+
+ // List descriptor fields that may be added or may be updated
+ // when retrieving an MBeanInfo using a JMXWS connection compared to the
+ // MBeanInfo returned by a local MBeanServer.
+ // The annotation format is :
+ // <descriptorFieldName>=<descriptorFieldValue>
+ // The values actually handled by the test suite are :
+ // openType=SimpleType.VOID
+ @DescriptorKey("descriptorFields")
+ String[] descriptorFields() default {};
+}
diff --git a/test/javax/management/security/TestJMXAuthenticator.java b/test/javax/management/security/TestJMXAuthenticator.java
new file mode 100644
index 0000000..cdea05d
--- /dev/null
+++ b/test/javax/management/security/TestJMXAuthenticator.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Principal;
+
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+
+public final class TestJMXAuthenticator implements JMXAuthenticator {
+
+ private String protocol = "";
+ private MBeanServer mbs = null;
+
+ public TestJMXAuthenticator() {
+ }
+
+ public TestJMXAuthenticator(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public TestJMXAuthenticator(String protocol, MBeanServer mbs) {
+ this.protocol = protocol;
+ this.mbs = mbs;
+ }
+
+ public Subject authenticate(Object credentials) {
+
+ String credentials_username = "";
+ String credentials_password = "";
+ Principal aPrincipal = null;
+
+ credentials_username = ((String[]) credentials)[0];
+ credentials_password = ((String[]) credentials)[1];
+
+ String authenticated_username = System.getProperty("susername");
+ String authenticated_password = System.getProperty("spassword");
+ String principal = System.getProperty("principal");
+
+ System.out.println("TestJMXAuthenticator::authenticate: Start");
+ System.out.println("TestJMXAuthenticator::authenticate: credentials username = " +
+ credentials_username);
+ System.out.println("TestJMXAuthenticator::authenticate: credentials password = " +
+ credentials_password);
+ System.out.println("TestJMXAuthenticator::authenticate: authenticated username = " +
+ authenticated_username);
+ System.out.println("TestJMXAuthenticator::authenticate: authenticated password = " +
+ authenticated_password);
+ System.out.println("TestJMXAuthenticator::authenticate: principal used for " +
+ "authorization = " + principal);
+
+ if (credentials_username.equals(authenticated_username) &&
+ credentials_password.equals(authenticated_password)) {
+ System.out.println("TestJMXAuthenticator::authenticate: " +
+ "Authenticator should succeed");
+ } else {
+ System.out.println("TestJMXAuthenticator::authenticate: " +
+ "Authenticator should reject");
+ throw new SecurityException("TestJMXAuthenticator throws EXCEPTION");
+ }
+
+ // At this point, authentication has succeeded
+ // (no SecurityException thrown).
+ //
+ // If no authorization is required, the returned subject (empty or not)
+ // is useless.
+ // Otherwise, the returned subject must define a principal
+ // and authorization will be performed against this principal.
+ //
+ // Note that this custom JMXAuthenticator is used for test purpose and
+ // the username used to perform authentication may be different from the
+ // username used to perform authorization.
+ //
+ Subject subject = new Subject();
+
+ if (principal != null) {
+ System.out.println("TestJMXAuthenticator::authenticate: " +
+ "Add " + principal + " principal to the returned subject");
+ subject.getPrincipals().add(new JMXPrincipal(principal));
+ }
+
+ return subject;
+ }
+}
diff --git a/test/javax/management/security/TestSampleLoginModule.java b/test/javax/management/security/TestSampleLoginModule.java
new file mode 100644
index 0000000..81d342d
--- /dev/null
+++ b/test/javax/management/security/TestSampleLoginModule.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+
+public final class TestSampleLoginModule implements LoginModule {
+
+ private Subject subject;
+ private CallbackHandler callbackHandler;
+ private Map<String, ?> sharedState;
+ private Map<String, ?> options;
+
+ public TestSampleLoginModule() {
+ }
+
+ public void initialize(Subject subject,
+ CallbackHandler callbackHandler,
+ Map<String,?> sharedState,
+ Map<String,?> options) {
+
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.sharedState = sharedState;
+ this.options = options;
+ }
+
+ /*
+ * Authenticate the user by comparing the values of the java properties
+ * (username and password) against the values of the credentials.
+ * */
+ public boolean login() throws LoginException {
+
+ String credentials_username = null;
+ String credentials_password = null;
+ String authenticated_username = System.getProperty("susername");
+ String authenticated_password = System.getProperty("spassword");
+
+ System.out.println("TestSampleLoginModule::login: Start");
+
+ // First retreive the credentials {username, password} from
+ // the callback handler
+ Callback[] callbacks = new Callback[2];
+ callbacks[0] = new NameCallback("username");
+ callbacks[1] = new PasswordCallback("password", false);
+ try {
+ callbackHandler.handle(callbacks);
+ credentials_username = ((NameCallback)callbacks[0]).getName();
+ credentials_password = new String(((PasswordCallback)callbacks[1]).
+ getPassword());
+ } catch (Exception e) {
+ throw new LoginException(e.toString());
+ }
+
+ System.out.println("TestSampleLoginModule::login: credentials username = " +
+ credentials_username);
+ System.out.println("TestSampleLoginModule::login: credentials password = " +
+ credentials_password);
+ System.out.println("TestSampleLoginModule::login: authenticated username = " +
+ authenticated_username);
+ System.out.println("TestSampleLoginModule::login: authenticated password = " +
+ authenticated_password);
+
+ if (credentials_username.equals(authenticated_username) &&
+ credentials_password.equals(authenticated_password)) {
+ System.out.println("TestSampleLoginModule::login: " +
+ "Authentication should succeed");
+ return true;
+ } else {
+ System.out.println("TestSampleLoginModule::login: " +
+ "Authentication should reject");
+ throw new LoginException("TestSampleLoginModule throws EXCEPTION");
+ }
+ }
+
+ public boolean commit() throws LoginException {
+ return true;
+ }
+
+ public boolean abort() throws LoginException {
+ return true;
+ }
+
+ public boolean logout() throws LoginException {
+ return true;
+ }
+}
diff --git a/test/javax/management/security/Utils.java b/test/javax/management/security/Utils.java
new file mode 100644
index 0000000..c0af037
--- /dev/null
+++ b/test/javax/management/security/Utils.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.lang.reflect.Method;
+import javax.management.remote.JMXConnectorServerMBean;
+
+// utility class for MXBean* tests coming from JMX Tonga test suite
+class Utils {
+
+ private static final String SERVER_SIDE_NAME = "-server";
+ private static final String CLIENT_SIDE_NAME = "-client";
+
+ // DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
+ private static final String DEBUG_HEADER = "[debug] ";
+
+ // DEBUG levels
+ private static int selectedDebugLevel = 0;
+ static final int DEBUG_STANDARD = 1;
+ static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
+ static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
+
+ static void parseDebugProperties() {
+ int level = 0;
+ Properties p = System.getProperties();
+
+ // get selected levels
+ if (p.getProperty("DEBUG_STANDARD") != null) {
+ level |= DEBUG_STANDARD;
+ }
+
+ if (p.getProperty("DEBUG_VERBOSE") != null) {
+ level |= DEBUG_VERBOSE;
+ }
+
+ if (p.getProperty("DEBUG_ALL") != null) {
+ level |= DEBUG_ALL;
+ }
+
+ selectedDebugLevel = level;
+ }
+
+ /**
+ * Reproduces the original parsing and collection of test parameters
+ * from the DTonga JMX test suite.
+ *
+ * Collects passed args and returns them in a map(argname, value) structure,
+ * which will be then propagated as necessary to various called methods.
+ */
+ static Map<String, Object> parseParameters(String args[])
+ throws Exception {
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
+ HashMap<String, Object> map = new HashMap<>();
+
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[i].trim().startsWith("-") ) {
+ if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with value " +
+ args[i+1]) ;
+ map.put(args[i].trim(), args[i+1].trim()) ;
+ } else if ((i+1) < args.length && args[i+1].startsWith("-") ||
+ (i+1) == args.length ) {
+ Utils.debug(DEBUG_STANDARD,
+ "TestRoot::parseParameters: added in map = " +
+ args[i] +
+ " with null value") ;
+ map.put(args[i].trim(), null) ;
+ } else {
+ System.out.println(
+ "TestRoot::parseParameters: (WARNING) not added in map = " +
+ args[i]) ;
+ }
+ }
+ }
+
+ Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
+ return map ;
+ }
+
+ // Parse server parameters and put them in passed serverMap
+ static int parseServerParameters(String args[],
+ String serverSideName,
+ Map<String, Object> serverMap )
+ throws Exception {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseServerParameters: Start");
+
+ int nextIndex = 0;
+ boolean seenServerFlag = false;
+
+ for ( int i = 0; i < args.length; i++ ) {
+ // Case of reaching "-server" flag parameter
+ if (args[i].equals(SERVER_SIDE_NAME)) {
+ if (!seenServerFlag) {
+ seenServerFlag = true;
+ continue;
+ } else {
+ // Already parsing server params, invalid params list
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseParameters: Invalid " +
+ args[i] + " parameter detected in " +
+ SERVER_SIDE_NAME + " parameters list");
+ nextIndex = -1;
+ throw new RuntimeException("Invalid Parameter list");
+ }
+ }
+
+ // Case of reaching "-client" flag parameter
+ if (args[i].equals(CLIENT_SIDE_NAME)) {
+ // While parsing server parameters, then parsing is done.
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseServerParameters: Parsing of " +
+ SERVER_SIDE_NAME + " parameters done.");
+ return i;
+ }
+
+ i = parseParamAtIndex(args, i, serverMap);
+ nextIndex = i;
+ }
+
+ Utils.debug(Utils.DEBUG_STANDARD,
+ serverSideName + "::parseServerParameters: Parsing of parameters done");
+
+ return nextIndex;
+ }
+
+ // Parse client parameters and put them in passed clientMap
+ static void parseClientParameters(String args[],
+ String clientSideName,
+ Map<String, Object> clientMap )
+ throws Exception {
+
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Start");
+
+ boolean seenClientFlag = false;
+
+ for ( int i = 0; i < args.length; i++ ) {
+ // Case of reaching "-client" flag parameter
+ if (args[i].equals(CLIENT_SIDE_NAME)) {
+ if (!seenClientFlag) {
+ seenClientFlag = true;
+ continue;
+ } else {
+ // Already parsing client params, invalid params list
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Invalid " +
+ CLIENT_SIDE_NAME + " parameter detected in " +
+ CLIENT_SIDE_NAME + " parameters list.");
+ throw new RuntimeException("Invalid parameter in " +
+ clientSideName + " parameter list");
+ }
+ }
+
+ // Case of reaching "-server" flag parameter
+ if (args[i].equals(SERVER_SIDE_NAME)) {
+ // While parsing client parameters, invalid parameter list.
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Invalid " +
+ SERVER_SIDE_NAME + " parameter inside " +
+ CLIENT_SIDE_NAME + " parameters list.");
+ throw new RuntimeException("Invalid parameter in " +
+ clientSideName + " parameter list");
+ }
+
+ i = parseParamAtIndex(args, i, clientMap);
+ }
+
+ Utils.debug(Utils.DEBUG_STANDARD,
+ clientSideName + "::parseClientParameters: Parsing of parameters done.");
+ }
+
+ // Add param found at index to passed map
+ // We only accept either "-param value" or "-param" form.
+ // The "value" form is invalid but just ignored.
+ private static int parseParamAtIndex(String args[],
+ int index,
+ Map<String, Object> map) {
+
+ if (args[index].trim().startsWith("-") ) {
+ // Case of a "-param value" form
+ if ((index+1) < args.length && !args[index+1].startsWith("-") ) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "TestRoot::parseParamAtIndex: added in map = "
+ + args[index]
+ + " with value "
+ + args[index+1]) ;
+ // adding ("param", value) to the passed map
+ map.put(args[index].trim(), args[index+1].trim()) ;
+ // value should not be parsed a second time
+ return index+1;
+ }
+ // Case of a "-param" form (flag parameter)
+ else if (((index+1) < args.length && args[index+1].startsWith("-")) ||
+ (index+1) == args.length ) {
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "TestRoot::parseParamAtIndex: added in map = "
+ + args[index]
+ + " with null value") ;
+ // adding ("param", null) to passed map
+ map.put(args[index].trim(), null) ;
+ }
+ } else {
+ // Unsupported "value" alone parameter
+ Utils.debug(Utils.DEBUG_STANDARD,
+ "TestRoot::parseParamAtIndex: invalid " +
+ " value-alone \"" + args[index] + "\" parameter." +
+ " Parameter ignored.");
+ }
+
+ return index;
+ }
+
+ /**
+ * This method is to be used in all tests to print anything
+ * that is temporary.
+ * Printing is done only when debug is activated by the property DEBUG.
+ * Printing depends also on the DEBUG_LEVEL property.
+ * Here it encapsulates a System.out.println.
+ */
+ static void debug(int level, String line) {
+ if ((selectedDebugLevel & level) != 0) {
+ System.out.println(DEBUG_HEADER + line);
+ }
+ }
+
+ /**
+ * Do print stack trace when withStack is true.
+ * Does try to call getTargetException() and getTargetError() then
+ * print embedded stacks in the case of an Exception wrapping
+ * another Exception or an Error. Recurse until no more wrapping
+ * is found.
+ */
+ static void printThrowable(Throwable theThro, boolean withStack) {
+ try {
+ if (withStack) {
+ theThro.printStackTrace(System.out);
+ }
+ if (theThro instanceof Exception) {
+ Exception t = (Exception) theThro;
+ Method target = null;
+ String blank = " ";
+ try {
+ target = t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not
+ }
+ System.out.println(blank + t.getClass() + "==>" + t.getMessage());
+ while (target != null) {
+ try {
+ t = (Exception) target.invoke(t,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ t = null;
+ }
+ try {
+ if (t != null) {
+ blank = blank + " ";
+ System.out.println(blank + t.getClass() + "==>" +
+ t.getMessage());
+ try {
+ target =
+ t.getClass().getMethod("getTargetException",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetException method could be there or not }
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+
+ // We may have exceptions wrapping an Error then it is
+ // getTargetError that is likely to be called
+ try {
+ target = ((Exception) theThro).getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ Throwable err = theThro;
+ while (target != null) {
+ try {
+ err = (Error) target.invoke(err,
+ (java.lang.Object[]) null);
+ } catch (Exception ee) {
+ err = null;
+ }
+ try {
+ if (err != null) {
+ blank = blank + " ";
+ System.out.println(blank + err.getClass() + "==>" +
+ err.getMessage());
+ if (withStack) {
+ err.printStackTrace(System.out);
+ }
+ try {
+ target = err.getClass().getMethod("getTargetError",
+ (java.lang.Class<?>[]) null);
+ } catch (Exception ee) {
+ // OK: getTargetError method could be there or not
+ }
+ } else {
+ target = null;
+ }
+ } catch (Exception ee) {
+ target = null;
+ }
+ }
+ } else {
+ System.out.println("Throwable is : " + theThro);
+ }
+ } catch (Throwable x) {
+ System.out.println("Exception : raised in printException : " + x);
+ }
+ }
+
+ /**
+ * Wait up to maxTimeInSeconds second(s) the given JMX connector server
+ * comes up (which means isActive returns true).
+ * If it fails to do so we throw a RunTime exception.
+ */
+ static void waitReady(JMXConnectorServerMBean server,
+ int maxTimeInSeconds) throws Exception {
+ int elapsed = 0;
+
+ while (!server.isActive() && elapsed < maxTimeInSeconds) {
+ Thread.sleep(1000);
+ elapsed++;
+ }
+
+ if (server.isActive()) {
+ String message = "Utils::waitReady: JMX connector server came up";
+ if ( elapsed == 0) {
+ message += " immediately";
+ } else {
+ message += " after " + elapsed + " seconds";
+ }
+ message += " [" + server.getAddress() + "]";
+ Utils.debug(DEBUG_STANDARD, message);
+ } else {
+ String message = "Utils::waitReady: (ERROR) JMX connector" +
+ " server didn't come up after " + elapsed + " seconds [" +
+ server.getAddress() + "]";
+ System.out.println(message);
+ throw new RuntimeException(message);
+ }
+ }
+
+ /**
+ * This method is used to compare the specified Throwable and possibly
+ * the derived causes to the specified String argument.
+ * The expected String argument format is :
+ * throwable_1;throwable_2;...;throwable_N
+ * where throwable_i can be :
+ * - either a throwable class name
+ * - or the "*" character meaning several unknown throwable class names
+ * This character must be followed by a throwable class name
+ */
+ static boolean compareThrowable(
+ Throwable t,
+ String expectedThrowable) {
+
+ // First parse the expectedThrowable String
+ StringTokenizer tokenizer = new StringTokenizer(expectedThrowable, ";");
+ String token = null;
+
+ try {
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ if (!token.equals("*")) {
+ if (!Class.forName(token).isInstance(t)) {
+ return false;
+ }
+ } else {
+ token = tokenizer.nextToken();
+ while (!Class.forName(token).isInstance(t)) {
+ t = t.getCause();
+ if (t == null) {
+ return false;
+ }
+ }
+ }
+ t = t.getCause();
+ }
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "Expected throwable class(es) " + expectedThrowable +
+ " cannot be located";
+ System.out.println(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ return true;
+ }
+}
diff --git a/test/javax/management/security/access.properties b/test/javax/management/security/access.properties
new file mode 100644
index 0000000..eaf89a8
--- /dev/null
+++ b/test/javax/management/security/access.properties
@@ -0,0 +1,11 @@
+# Access control file for SQE tests.
+
+# Default username
+SQE_username readwrite create Simple
+
+# Functional authorization tests
+username1 readwrite create Simple
+username2 readonly
+username3 readonly
+username4 readwrite create Simple
+username5 readwrite create Simple
diff --git a/test/javax/management/security/java.policy.authorization b/test/javax/management/security/java.policy.authorization
new file mode 100644
index 0000000..8b71276
--- /dev/null
+++ b/test/javax/management/security/java.policy.authorization
@@ -0,0 +1,98 @@
+// Standard extensions get all permissions by default
+
+grant codeBase "file:${java.home}/lib/ext/*" {
+ permission java.security.AllPermission;
+};
+
+// default permissions granted to all domains
+grant {
+ // Allows any thread to stop itself using the java.lang.Thread.stop()
+ // method that takes no argument.
+ // Note that this permission is granted by default only to remain
+ // backwards compatible.
+ // It is strongly recommended that you either remove this permission
+ // from this policy file or further restrict it to code sources
+ // that you specify, because Thread.stop() is potentially unsafe.
+ // See "http://java.sun.com/notes" for more information.
+ permission java.lang.RuntimePermission "stopThread";
+
+ // allows anyone to listen on un-privileged ports
+ permission java.net.SocketPermission "localhost:1024-", "listen";
+
+ // "standard" properies that can be read by anyone
+
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
+
+ permission java.io.FilePermission "*","read,write";
+
+};
+
+grant codeBase "file:/-" {
+ permission java.security.AllPermission;
+ permission java.io.FilePermission "*","read,write";
+};
+
+grant principal javax.management.remote.JMXPrincipal "SQE_username" {
+ permission javax.management.MBeanServerPermission "*";
+ permission javax.management.MBeanPermission "Simple", "instantiate";
+ permission javax.management.MBeanPermission "Simple", "registerMBean";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username1" {
+ //
+ // JMXPrincipals "username1" has all permissions.
+ //
+ permission java.security.AllPermission;
+};
+
+grant principal javax.management.remote.JMXPrincipal "username2" {
+ //
+ // JMXPrincipals "username2" has all permissions.
+ //
+ permission java.security.AllPermission;
+};
+
+grant principal javax.management.remote.JMXPrincipal "username3" {
+ //
+ // JMXPrincipals "username3" has some permissions.
+ //
+ permission javax.management.MBeanPermission "Simple", "instantiate";
+ permission javax.management.MBeanPermission "Simple", "registerMBean";
+ permission javax.management.MBeanPermission "Simple", "setAttribute";
+ permission javax.management.MBeanPermission "Simple", "invoke";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username4" {
+ //
+ // JMXPrincipals "username4" has all permissions.
+ //
+ permission javax.management.MBeanPermission "Simple", "instantiate";
+ permission javax.management.MBeanPermission "Simple", "registerMBean";
+ permission javax.management.MBeanPermission "Simple", "invoke";
+};
+
+grant principal javax.management.remote.JMXPrincipal "username5" {
+ //
+ // JMXPrincipals "username5" has no permissions.
+ //
+};
diff --git a/test/javax/management/security/login.config b/test/javax/management/security/login.config
new file mode 100644
index 0000000..8cd1502
--- /dev/null
+++ b/test/javax/management/security/login.config
@@ -0,0 +1,8 @@
+PasswordFileAuthentication {
+ com.sun.jmx.remote.security.FileLoginModule required
+ passwordFile="${password.file}";
+};
+
+SampleLoginModule {
+ TestSampleLoginModule required;
+};
diff --git a/test/javax/management/security/password.properties b/test/javax/management/security/password.properties
new file mode 100644
index 0000000..755099b
--- /dev/null
+++ b/test/javax/management/security/password.properties
@@ -0,0 +1,12 @@
+# Password file for default SQE username.
+SQE_username SQE_password
+
+# Functional authorization tests
+username1 password1
+username2 password2
+username3 password3
+username4 password4
+username5 password5
+username6 password6
+
+usernameFileLoginModule passwordFileLoginModule
diff --git a/test/javax/management/truststoreAgent b/test/javax/management/truststoreAgent
new file mode 100644
index 0000000..5b5f698
--- /dev/null
+++ b/test/javax/management/truststoreAgent
Binary files differ
diff --git a/test/javax/management/truststoreClient b/test/javax/management/truststoreClient
new file mode 100644
index 0000000..f6a6a00
--- /dev/null
+++ b/test/javax/management/truststoreClient
Binary files differ
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/HelloClient.java b/test/javax/rmi/PortableRemoteObject/8146975/HelloClient.java
new file mode 100644
index 0000000..9b4ef08
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloClient.java
@@ -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();
+ }
+ }
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/HelloImpl.java b/test/javax/rmi/PortableRemoteObject/8146975/HelloImpl.java
new file mode 100644
index 0000000..e9d05fa
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloImpl.java
@@ -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;
+ }
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/HelloInterface.java b/test/javax/rmi/PortableRemoteObject/8146975/HelloInterface.java
new file mode 100644
index 0000000..81d53fa
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloInterface.java
@@ -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;
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/HelloServer.java b/test/javax/rmi/PortableRemoteObject/8146975/HelloServer.java
new file mode 100644
index 0000000..cb1f463
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/HelloServer.java
@@ -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();
+ }
+ }
+ }
+ }
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java b/test/javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java
new file mode 100644
index 0000000..7c0d1b7
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java
@@ -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;
+ }
+ }
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/Test.java b/test/javax/rmi/PortableRemoteObject/8146975/Test.java
new file mode 100644
index 0000000..510331f
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test.java
@@ -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 {
+
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/Test2.java b/test/javax/rmi/PortableRemoteObject/8146975/Test2.java
new file mode 100644
index 0000000..228f0af
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test2.java
@@ -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;
+ }
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/Test3.java b/test/javax/rmi/PortableRemoteObject/8146975/Test3.java
new file mode 100644
index 0000000..d96cc122
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test3.java
@@ -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;
+ }
+
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/Test4.java b/test/javax/rmi/PortableRemoteObject/8146975/Test4.java
new file mode 100644
index 0000000..47d5ff2
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/Test4.java
@@ -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;
+
+
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/_HelloImpl_Tie.java b/test/javax/rmi/PortableRemoteObject/8146975/_HelloImpl_Tie.java
new file mode 100644
index 0000000..57b856b
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloImpl_Tie.java
@@ -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);
+ }
+ }
+}
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/_HelloInterface_Stub.java b/test/javax/rmi/PortableRemoteObject/8146975/_HelloInterface_Stub.java
new file mode 100644
index 0000000..dc05873
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/_HelloInterface_Stub.java
@@ -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);
+ }
+ }
+ }
+ }
diff --git a/test/javax/rmi/PortableRemoteObject/8146975/jtreg.test.policy b/test/javax/rmi/PortableRemoteObject/8146975/jtreg.test.policy
new file mode 100644
index 0000000..9bde0d4
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/8146975/jtreg.test.policy
@@ -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";
+};
diff --git a/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java b/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java
index 382f201..27b5782 100644
--- a/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java
+++ b/test/javax/rmi/PortableRemoteObject/ConcurrentHashMapTest.java
@@ -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
*/
diff --git a/test/javax/rmi/PortableRemoteObject/jtreg.test.policy b/test/javax/rmi/PortableRemoteObject/jtreg.test.policy
new file mode 100644
index 0000000..9bde0d4
--- /dev/null
+++ b/test/javax/rmi/PortableRemoteObject/jtreg.test.policy
@@ -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";
+};
diff --git a/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.java b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.java
new file mode 100644
index 0000000..09f7f01
--- /dev/null
+++ b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.java
@@ -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}};
+ }
+
+}
diff --git a/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.policy b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.policy
new file mode 100644
index 0000000..8756900
--- /dev/null
+++ b/test/javax/security/auth/PrivateCredentialPermission/MoreThenOnePrincipals.policy
@@ -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";
+};
diff --git a/test/javax/smartcardio/CommandAPDUTest.java b/test/javax/smartcardio/CommandAPDUTest.java
new file mode 100644
index 0000000..a6ce5c6
--- /dev/null
+++ b/test/javax/smartcardio/CommandAPDUTest.java
@@ -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}};
+ }
+
+}
diff --git a/test/javax/smartcardio/ResponseAPDUTest.java b/test/javax/smartcardio/ResponseAPDUTest.java
new file mode 100644
index 0000000..995cd12
--- /dev/null
+++ b/test/javax/smartcardio/ResponseAPDUTest.java
@@ -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);
+ }
+}
diff --git a/test/javax/smartcardio/TerminalFactorySpiTest.java b/test/javax/smartcardio/TerminalFactorySpiTest.java
new file mode 100644
index 0000000..cec4c44
--- /dev/null
+++ b/test/javax/smartcardio/TerminalFactorySpiTest.java
@@ -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;
+ }
+
+ }
+}
diff --git a/test/javax/smartcardio/policy b/test/javax/smartcardio/policy
new file mode 100644
index 0000000..1df892e
--- /dev/null
+++ b/test/javax/smartcardio/policy
@@ -0,0 +1,4 @@
+grant {
+ permission java.security.SecurityPermission "insertProvider.MyProvider";
+ permission java.security.SecurityPermission "putProviderProperty.MyProvider";
+};
diff --git a/test/javax/swing/JComboBox/8136998/bug8136998.java b/test/javax/swing/JComboBox/8136998/bug8136998.java
new file mode 100644
index 0000000..e7d9e0a
--- /dev/null
+++ b/test/javax/swing/JComboBox/8136998/bug8136998.java
@@ -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");
+ }
+}
diff --git a/test/javax/swing/plaf/basic/BasicComboPopup/8154069/Bug8154069.java b/test/javax/swing/plaf/basic/BasicComboPopup/8154069/Bug8154069.java
new file mode 100644
index 0000000..35250a5
--- /dev/null
+++ b/test/javax/swing/plaf/basic/BasicComboPopup/8154069/Bug8154069.java
@@ -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();
+ });
+ }
+ }
+
+}
diff --git a/test/javax/swing/plaf/nimbus/8057791/bug8057791.java b/test/javax/swing/plaf/nimbus/8057791/bug8057791.java
new file mode 100644
index 0000000..cc31544
--- /dev/null
+++ b/test/javax/swing/plaf/nimbus/8057791/bug8057791.java
@@ -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);
+ }
+ }
+}
diff --git a/test/javax/swing/text/html/parser/Parser/8078268/bug8078268.java b/test/javax/swing/text/html/parser/Parser/8078268/bug8078268.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/javax/swing/text/html/parser/Parser/8078268/bug8078268.java
diff --git a/test/javax/swing/text/html/parser/Parser/8078268/slowparse.html b/test/javax/swing/text/html/parser/Parser/8078268/slowparse.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/javax/swing/text/html/parser/Parser/8078268/slowparse.html
diff --git a/test/javax/xml/crypto/dsig/GenerationTests.java b/test/javax/xml/crypto/dsig/GenerationTests.java
index 6cc7bbb..89fd46a 100644
--- a/test/javax/xml/crypto/dsig/GenerationTests.java
+++ b/test/javax/xml/crypto/dsig/GenerationTests.java
@@ -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();
+ }
+ }
}
diff --git a/test/javax/xml/jaxp/stream/8153781/SkipDTDTest.java b/test/javax/xml/jaxp/stream/8153781/SkipDTDTest.java
new file mode 100644
index 0000000..b69bfba
--- /dev/null
+++ b/test/javax/xml/jaxp/stream/8153781/SkipDTDTest.java
@@ -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());
+ }
+ }
+}
diff --git a/test/sun/java2d/ClassCastExceptionForInvalidSurface.java b/test/sun/java2d/ClassCastExceptionForInvalidSurface.java
new file mode 100644
index 0000000..956815e
--- /dev/null
+++ b/test/sun/java2d/ClassCastExceptionForInvalidSurface.java
@@ -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;
+ }
+}
diff --git a/test/sun/security/krb5/auto/BogusKDC.java b/test/sun/security/krb5/auto/BogusKDC.java
new file mode 100644
index 0000000..15d9add
--- /dev/null
+++ b/test/sun/security/krb5/auto/BogusKDC.java
@@ -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");
+ }
+}
diff --git a/test/sun/security/krb5/auto/Context.java b/test/sun/security/krb5/auto/Context.java
index 715a1ad..f664605 100644
--- a/test/sun/security/krb5/auto/Context.java
+++ b/test/sun/security/krb5/auto/Context.java
@@ -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;
+ }
}
}
diff --git a/test/sun/security/krb5/auto/ForwardableCheck.java b/test/sun/security/krb5/auto/ForwardableCheck.java
new file mode 100644
index 0000000..df6e49e
--- /dev/null
+++ b/test/sun/security/krb5/auto/ForwardableCheck.java
@@ -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();
+ }
+ }
+}
diff --git a/test/sun/security/krb5/auto/Helper.java b/test/sun/security/krb5/auto/Helper.java
new file mode 100644
index 0000000..ff43c0b
--- /dev/null
+++ b/test/sun/security/krb5/auto/Helper.java
@@ -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);
+ }
+ }
+ }
+ }
+}
diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java
index e3d63d0..b2f7d57 100644
--- a/test/sun/security/krb5/auto/KDC.java
+++ b/test/sun/security/krb5/auto/KDC.java
@@ -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})
};
diff --git a/test/sun/security/krb5/auto/KrbTicket.java b/test/sun/security/krb5/auto/KrbTicket.java
new file mode 100644
index 0000000..daed1cc
--- /dev/null
+++ b/test/sun/security/krb5/auto/KrbTicket.java
@@ -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;
+ }
+}
diff --git a/test/sun/security/krb5/auto/RefreshKrb5Config.java b/test/sun/security/krb5/auto/RefreshKrb5Config.java
new file mode 100644
index 0000000..c32258f
--- /dev/null
+++ b/test/sun/security/krb5/auto/RefreshKrb5Config.java
@@ -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");
+ }
+
+}
diff --git a/test/sun/security/krb5/auto/UnboundSSL.java b/test/sun/security/krb5/auto/UnboundSSL.java
new file mode 100644
index 0000000..5df24f8
--- /dev/null
+++ b/test/sun/security/krb5/auto/UnboundSSL.java
@@ -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");
+ }
+}
diff --git a/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java b/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java
new file mode 100644
index 0000000..aa1ea2b3
--- /dev/null
+++ b/test/sun/security/krb5/auto/UnboundSSLMultipleKeys.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+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");
+ }
+
+}
diff --git a/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java b/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java
new file mode 100644
index 0000000..ab8549e
--- /dev/null
+++ b/test/sun/security/krb5/auto/UnboundSSLPrincipalProperty.java
@@ -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");
+ }
+}
diff --git a/test/sun/security/krb5/auto/UnboundSSLUtils.java b/test/sun/security/krb5/auto/UnboundSSLUtils.java
new file mode 100644
index 0000000..1aefac2
--- /dev/null
+++ b/test/sun/security/krb5/auto/UnboundSSLUtils.java
@@ -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);
+ }
+
+}
+
diff --git a/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java b/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java
new file mode 100644
index 0000000..262e1da
--- /dev/null
+++ b/test/sun/security/krb5/auto/principalProperty/PrincipalSystemPropTest.java
@@ -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.");
+ }
+
+ }
+
+}
diff --git a/test/sun/security/krb5/auto/principalProperty/jaas.conf b/test/sun/security/krb5/auto/principalProperty/jaas.conf
new file mode 100644
index 0000000..0a5b794
--- /dev/null
+++ b/test/sun/security/krb5/auto/principalProperty/jaas.conf
@@ -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;
+};
diff --git a/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy b/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy
new file mode 100644
index 0000000..ac9ef48
--- /dev/null
+++ b/test/sun/security/krb5/auto/principalProperty/principalSystemPropTest.policy
@@ -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";
+};
+
diff --git a/test/sun/security/krb5/auto/refreshKrb5Config.jaas b/test/sun/security/krb5/auto/refreshKrb5Config.jaas
new file mode 100644
index 0000000..fd3b60d
--- /dev/null
+++ b/test/sun/security/krb5/auto/refreshKrb5Config.jaas
@@ -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;
+};
diff --git a/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java b/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java
new file mode 100644
index 0000000..d80224b
--- /dev/null
+++ b/test/sun/security/krb5/auto/tools/KinitConfPlusProps.java
@@ -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;
+ }
+}
diff --git a/test/sun/security/krb5/auto/unbound.ssl.jaas.conf b/test/sun/security/krb5/auto/unbound.ssl.jaas.conf
new file mode 100644
index 0000000..bee0a67
--- /dev/null
+++ b/test/sun/security/krb5/auto/unbound.ssl.jaas.conf
@@ -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;
+};
+
diff --git a/test/sun/security/krb5/auto/unbound.ssl.policy b/test/sun/security/krb5/auto/unbound.ssl.policy
new file mode 100644
index 0000000..0df839c
--- /dev/null
+++ b/test/sun/security/krb5/auto/unbound.ssl.policy
@@ -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";
+};
diff --git a/test/sun/security/krb5/config/Semicolon.java b/test/sun/security/krb5/config/Semicolon.java
new file mode 100644
index 0000000..6a3920c
--- /dev/null
+++ b/test/sun/security/krb5/config/Semicolon.java
@@ -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");
+ }
+}
diff --git a/test/sun/security/krb5/config/comments.conf b/test/sun/security/krb5/config/comments.conf
new file mode 100644
index 0000000..21879de
--- /dev/null
+++ b/test/sun/security/krb5/config/comments.conf
@@ -0,0 +1,12 @@
+[section]
+
+# comment
+ # comment
+ # comment
+ # comment
+; comment
+ ; comment
+ ; comment
+ ; comment
+
+value = true
diff --git a/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java b/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java
index f2a7525..4a66abb 100644
--- a/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java
+++ b/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java
@@ -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);
+ }
+ }
+
}
diff --git a/test/sun/security/pkcs11/PKCS11Test.java b/test/sun/security/pkcs11/PKCS11Test.java
index c8a147a..9155c83 100644
--- a/test/sun/security/pkcs11/PKCS11Test.java
+++ b/test/sun/security/pkcs11/PKCS11Test.java
@@ -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;
diff --git a/test/sun/security/pkcs11/Secmod/AddPrivateKey.java b/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
index c99c498..56833bd 100644
--- a/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
+++ b/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
@@ -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);
diff --git a/test/sun/security/pkcs11/Secmod/AddTrustedCert.java b/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
index 1b3ff81..6b2b545 100644
--- a/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
+++ b/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
@@ -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);
- ks.setCertificateEntry(alias, cert);
+ if (ks.containsAlias(alias)) {
+ throw new Exception("Alias exists: " + alias);
+ }
- aliases = new TreeSet<String>(Collections.list(ks.aliases()));
+ 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);
+ }
+
+ 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");
}
- System.out.println("OK");
+ ks.deleteEntry(alias);
+ if (ks.containsAlias(alias)) {
+ throw new Exception("Alias still exists: " + alias);
+ }
+ System.out.println("OK");
}
}
diff --git a/test/sun/security/pkcs11/Secmod/Crypto.java b/test/sun/security/pkcs11/Secmod/Crypto.java
index c44ab87..735149f 100644
--- a/test/sun/security/pkcs11/Secmod/Crypto.java
+++ b/test/sun/security/pkcs11/Secmod/Crypto.java
@@ -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());
diff --git a/test/sun/security/pkcs11/Secmod/GetPrivateKey.java b/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
index a41bef9..beb07b6 100644
--- a/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
+++ b/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
@@ -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);
diff --git a/test/sun/security/pkcs11/Secmod/LoadKeystore.java b/test/sun/security/pkcs11/Secmod/LoadKeystore.java
new file mode 100644
index 0000000..fd1aa69
--- /dev/null
+++ b/test/sun/security/pkcs11/Secmod/LoadKeystore.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.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");
+ }
+
+}
diff --git a/test/sun/security/provider/KeyStore/DKSTest.java b/test/sun/security/provider/KeyStore/DKSTest.java
index a11210e..39e4e18 100644
--- a/test/sun/security/provider/KeyStore/DKSTest.java
+++ b/test/sun/security/provider/KeyStore/DKSTest.java
@@ -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;
+ }
}
diff --git a/test/sun/security/tools/jarsigner/warnings/Test.java b/test/sun/security/tools/jarsigner/warnings/Test.java
index 999789a..6018a6d 100644
--- a/test/sun/security/tools/jarsigner/warnings/Test.java
+++ b/test/sun/security/tools/jarsigner/warnings/Test.java
@@ -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()]));
- }
}
diff --git a/test/sun/tools/native2ascii/Native2AsciiTests.sh b/test/sun/tools/native2ascii/Native2AsciiTests.sh
index f656bbc..5c886c2 100644
--- a/test/sun/tools/native2ascii/Native2AsciiTests.sh
+++ b/test/sun/tools/native2ascii/Native2AsciiTests.sh
@@ -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
diff --git a/test/tools/launcher/Arrrghs.java b/test/tools/launcher/Arrrghs.java
index 89893e4..73d8689 100644
--- a/test/tools/launcher/Arrrghs.java
+++ b/test/tools/launcher/Arrrghs.java
@@ -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 {