Mercurial > hg > icedtea7-forest > jdk
changeset 7436:9b6aff2241bf icedtea-2.6pre01
Merge
author | andrew |
---|---|
date | Thu, 03 Apr 2014 00:39:02 +0100 |
parents | 7cf294070617 (current diff) 1a4618c1f1bb (diff) |
children | ac30c0e7bfa6 |
files | .hgtags make/com/sun/nio/Makefile make/com/sun/nio/sctp/Makefile src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java src/share/classes/java/lang/System.java src/share/classes/sun/misc/SharedSecrets.java src/share/classes/sun/security/provider/certpath/ForwardBuilder.java src/solaris/native/java/lang/java_props_md.c src/solaris/native/java/net/PlainDatagramSocketImpl.c src/solaris/native/java/net/PlainSocketImpl.c src/solaris/native/java/net/linux_close.c src/solaris/native/sun/awt/awt_LoadLibrary.c test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh test/java/rmi/registry/readTest/readTest.sh test/javax/xml/jaxp/transform/jdk8004476/SecureProcessingTest.xml test/javax/xml/jaxp/transform/jdk8004476/TestBase.java test/javax/xml/jaxp/transform/jdk8004476/XPathExFuncTest.java test/javax/xml/jaxp/transform/jdk8004476/XSLTExFuncTest.java test/javax/xml/jaxp/transform/jdk8004476/tokenize.xml test/javax/xml/jaxp/transform/jdk8004476/tokenize.xsl test/sun/net/www/protocol/jar/jarbug/run.sh |
diffstat | 174 files changed, 6703 insertions(+), 1954 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri Mar 21 17:54:04 2014 +0000 +++ b/.hgtags Thu Apr 03 00:39:02 2014 +0100 @@ -401,3 +401,5 @@ ff67c89658525e8903fb870861ed3645befd6bc5 jdk7u60-b02 7d5b758810c20af12c6576b7d570477712360744 icedtea-2.5pre01 3162252ff26b4e6788b0c79405b035b535afa018 icedtea-2.5pre02 +b1bcc999a8f1b4b4452b59c6636153bb0154cf5a jdk7u60-b03 +efc8886310cbccb941f826acfad2ad51a2891be5 jdk7u60-b04
--- a/make/com/sun/nio/Makefile Fri Mar 21 17:54:04 2014 +0000 +++ b/make/com/sun/nio/Makefile Thu Apr 03 00:39:02 2014 +0100 @@ -31,7 +31,7 @@ include $(BUILDDIR)/common/Defs.gmk # MMM: disable for now -ifeq (, $(findstring $(PLATFORM), macosx aix)) +ifeq (, $(findstring $(PLATFORM), aix)) include $(BUILDDIR)/common/Subdirs.gmk SUBDIRS = sctp endif
--- a/make/com/sun/nio/sctp/Exportedfiles.gmk Fri Mar 21 17:54:04 2014 +0000 +++ b/make/com/sun/nio/sctp/Exportedfiles.gmk Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ -28,6 +28,7 @@ # ifneq ($(PLATFORM), windows) +ifneq ($(PLATFORM), macosx) FILES_export = \ sun/nio/ch/SctpAssocChange.java \ sun/nio/ch/SctpChannelImpl.java \ @@ -37,3 +38,4 @@ sun/nio/ch/SctpServerChannelImpl.java \ sun/nio/ch/SctpStdSocketOption.java endif +endif
--- a/make/com/sun/nio/sctp/FILES_c.gmk Fri Mar 21 17:54:04 2014 +0000 +++ b/make/com/sun/nio/sctp/FILES_c.gmk Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ -24,8 +24,10 @@ # ifneq ($(PLATFORM),windows) +ifneq ($(PLATFORM),macosx) FILES_c = \ SctpNet.c \ SctpChannelImpl.c \ SctpServerChannelImpl.c endif +endif
--- a/make/com/sun/nio/sctp/FILES_java.gmk Fri Mar 21 17:54:04 2014 +0000 +++ b/make/com/sun/nio/sctp/FILES_java.gmk Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ # questions. # FILES_java = \ - com/sun/nio/sctp/AbstractNotificationHandler.java \ + com/sun/nio/sctp/AbstractNotificationHandler.java \ com/sun/nio/sctp/Association.java \ com/sun/nio/sctp/AssociationChangeNotification.java \ com/sun/nio/sctp/HandlerResult.java \ @@ -43,9 +43,13 @@ com/sun/nio/sctp/ShutdownNotification.java \ \ sun/nio/ch/SctpMessageInfoImpl.java \ - sun/nio/ch/SctpStdSocketOption.java + sun/nio/ch/SctpStdSocketOption.java \ + sun/nio/ch/SctpChannelImpl.java \ + sun/nio/ch/SctpMultiChannelImpl.java \ + sun/nio/ch/SctpServerChannelImpl.java ifneq ($(PLATFORM), windows) +ifneq ($(PLATFORM), macosx) FILES_java += \ sun/nio/ch/SctpAssocChange.java \ sun/nio/ch/SctpAssociationImpl.java \ @@ -58,9 +62,5 @@ sun/nio/ch/SctpSendFailed.java \ sun/nio/ch/SctpServerChannelImpl.java \ sun/nio/ch/SctpShutdown.java -else -FILES_java += \ - sun/nio/ch/SctpChannelImpl.java \ - sun/nio/ch/SctpMultiChannelImpl.java \ - sun/nio/ch/SctpServerChannelImpl.java endif +endif
--- a/make/com/sun/nio/sctp/Makefile Fri Mar 21 17:54:04 2014 +0000 +++ b/make/com/sun/nio/sctp/Makefile Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 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 @@ -41,7 +41,15 @@ include FILES_java.gmk include Exportedfiles.gmk +ifeq ($(PLATFORM), windows) +include $(BUILDDIR)/common/Classes.gmk +endif +ifeq ($(PLATFORM), macosx) +include $(BUILDDIR)/common/Classes.gmk +endif + ifneq ($(PLATFORM), windows) +ifneq ($(PLATFORM), macosx) include $(BUILDDIR)/common/Mapfile-vers.gmk include $(BUILDDIR)/common/Library.gmk @@ -69,12 +77,9 @@ ifeq ($(PLATFORM), solaris) #LIBSCTP = -lsctp OTHER_LDLIBS += $(LIBSOCKET) -L$(LIBDIR)/$(LIBARCH) -lnet -lnio -endif # PLATFORM - -else # windows -include $(BUILDDIR)/common/Classes.gmk -endif # ifneq windows - +endif +endif # macosx +endif # windows clean clobber:: $(RM) -r $(CLASSDESTDIR)/com/sun/nio/sctp
--- a/make/common/Defs-embedded.gmk Fri Mar 21 17:54:04 2014 +0000 +++ b/make/common/Defs-embedded.gmk Thu Apr 03 00:39:02 2014 +0100 @@ -71,7 +71,9 @@ # and it must be linked after fdlibm - this places it at the end after libc # -z muldefs avoids linker errors for duplicate symbols. ifeq ($(CROSS_COMPILE_ARCH), arm) - EXTRA_LIBS += $(EXT_LIBS_PATH)/sflt_glibc_jdk.a -Xlinker -z -Xlinker muldefs + ifneq ($(EXT_LIBS_PATH),) + EXTRA_LIBS += $(EXT_LIBS_PATH)/sflt_glibc_jdk.a -Xlinker -z -Xlinker muldefs + endif endif endif
--- a/make/common/Defs-macosx.gmk Fri Mar 21 17:54:04 2014 +0000 +++ b/make/common/Defs-macosx.gmk Thu Apr 03 00:39:02 2014 +0100 @@ -397,12 +397,10 @@ INCLUDE_SA = true endif -ifdef CROSS_COMPILE_ARCH - # X11 headers are not under /usr/include - OTHER_CFLAGS += -I$(OPENWIN_HOME)/include - OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include - OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include -endif +# X11 headers are not under /usr/include +OTHER_CFLAGS += -I$(OPENWIN_HOME)/include +OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include +OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include # Use unlimited select OTHER_CFLAGS += -D_DARWIN_UNLIMITED_SELECT
--- a/make/java/java/Makefile Fri Mar 21 17:54:04 2014 +0000 +++ b/make/java/java/Makefile Thu Apr 03 00:39:02 2014 +0100 @@ -102,6 +102,7 @@ java/util/prefs/MacOSXPreferencesFactory.java CFLAGS_$(VARIANT)/java_props_md.o = -Os -x objective-c +CFLAGS_$(VARIANT)/java_props_macosx.o = -Os -x objective-c endif # @@ -222,6 +223,7 @@ ifeq ($(PLATFORM), macosx) OTHER_LDLIBS += \ -framework CoreFoundation \ + -framework Foundation \ -framework Security \ -framework SystemConfiguration endif
--- a/make/sun/javazic/tzdata/VERSION Fri Mar 21 17:54:04 2014 +0000 +++ b/make/sun/javazic/tzdata/VERSION Thu Apr 03 00:39:02 2014 +0100 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2013h +tzdata2013i
--- a/make/sun/javazic/tzdata/africa Fri Mar 21 17:54:04 2014 +0000 +++ b/make/sun/javazic/tzdata/africa Thu Apr 03 00:39:02 2014 +0100 @@ -500,14 +500,13 @@ Rule Libya 1997 only - Oct 4 0:00 0 - Rule Libya 2013 only - Mar lastFri 1:00 1:00 S Rule Libya 2013 only - Oct lastFri 2:00 0 - - -# The 1996 and 1997 entries are from Shanks & Pottenger; -# the IATA SSIM data contain some obvious errors. # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Tripoli 0:52:44 - LMT 1920 1:00 Libya CE%sT 1959 2:00 - EET 1982 1:00 Libya CE%sT 1990 May 4 +# The 1996 and 1997 entries are from Shanks & Pottenger; +# the IATA SSIM data contain some obvious errors. 2:00 - EET 1996 Sep 30 1:00 Libya CE%sT 1997 Oct 4 2:00 - EET 2012 Nov 10 2:00
--- a/make/sun/javazic/tzdata/asia Fri Mar 21 17:54:04 2014 +0000 +++ b/make/sun/javazic/tzdata/asia Thu Apr 03 00:39:02 2014 +0100 @@ -1403,12 +1403,22 @@ # switch back to standard time this winter, so the will stay on DST # until about the same time next year (at least). # http://www.petra.gov.jo/Public_News/Nws_NewsDetails.aspx?NewsID=88950 -# -# From Paul Eggert (2013-09-21): -# It's looking like this change will be permanent; see -# Petra News Agency, Cancelling winter saved Jordan $7 million (2013-02-20) -# <http://www.albawaba.com/business/jordan-winter-electricity--472005>. -# So move Jordan to UTC+3 as of the abovementioned date. + +# From Steffen Thorsen (2013-12-11): +# Jordan Times and other sources say that Jordan is going back to +# UTC+2 on 2013-12-19 at midnight: +# http://jordantimes.com/govt-decides-to-switch-back-to-wintertime +# Official, in Arabic: +# http://www.petra.gov.jo/public_news/Nws_NewsDetails.aspx?Menu_ID=&Site_Id=2&lang=1&NewsID=133230&CatID=14 +# ... Our background/permalink about it +# http://www.timeanddate.com/news/time/jordan-reverses-dst-decision.html +# ... +# http://www.petra.gov.jo/Public_News/Nws_NewsDetails.aspx?lang=2&site_id=1&NewsID=133313&Type=P +# ... says midnight for the coming one and 1:00 for the ones in the future +# (and they will use DST again next year, using the normal schedule). + +# From Paul Eggert (2013-12-11): +# As Steffen suggested, consider the past 21-month experiment to be DST. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Jordan 1973 only - Jun 6 0:00 1:00 S @@ -1438,11 +1448,13 @@ Rule Jordan 2003 only - Oct 24 0:00s 0 - Rule Jordan 2004 only - Oct 15 0:00s 0 - Rule Jordan 2005 only - Sep lastFri 0:00s 0 - -Rule Jordan 2006 2012 - Oct lastFri 0:00s 0 - +Rule Jordan 2006 2011 - Oct lastFri 0:00s 0 - +Rule Jordan 2013 only - Dec 20 0:00 0 - +Rule Jordan 2014 max - Mar lastThu 24:00 1:00 S +Rule Jordan 2014 max - Oct lastFri 0:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Amman 2:23:44 - LMT 1931 - 2:00 Jordan EE%sT 2012 Oct 26 0:00s - 3:00 - AST + 2:00 Jordan EE%sT # Kazakhstan
--- a/make/sun/javazic/tzdata/northamerica Fri Mar 21 17:54:04 2014 +0000 +++ b/make/sun/javazic/tzdata/northamerica Thu Apr 03 00:39:02 2014 +0100 @@ -2688,6 +2688,11 @@ # to DST--and one more hour on 1999-04-04--when the announcers will have # returned to Baltimore, which switches on that date.) +# From Steffen Thorsen (2013-11-11): +# DST start in Cuba in 2004 ... does not follow the same rules as the +# years before. The correct date should be Sunday 2004-03-28 00:00 ... +# https://web.archive.org/web/20040402060750/http://www.granma.cu/espanol/2004/marzo/sab27/reloj.html + # From Evert van der Veer via Steffen Thorsen (2004-10-28): # Cuba is not going back to standard time this year. # From Paul Eggert (2006-03-22): @@ -2877,7 +2882,8 @@ Rule Cuba 1997 only - Oct 12 0:00s 0 S Rule Cuba 1998 1999 - Mar lastSun 0:00s 1:00 D Rule Cuba 1998 2003 - Oct lastSun 0:00s 0 S -Rule Cuba 2000 2004 - Apr Sun>=1 0:00s 1:00 D +Rule Cuba 2000 2003 - Apr Sun>=1 0:00s 1:00 D +Rule Cuba 2004 only - Mar lastSun 0:00s 1:00 D Rule Cuba 2006 2010 - Oct lastSun 0:00s 0 S Rule Cuba 2007 only - Mar Sun>=8 0:00s 1:00 D Rule Cuba 2008 only - Mar Sun>=15 0:00s 1:00 D
--- a/make/sun/lwawt/FILES_export_macosx.gmk Fri Mar 21 17:54:04 2014 +0000 +++ b/make/sun/lwawt/FILES_export_macosx.gmk Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -141,7 +141,6 @@ sun/lwawt/macosx/CMenuBar.java \ sun/lwawt/macosx/CMenuComponent.java \ sun/lwawt/macosx/CMenuItem.java \ - sun/lwawt/macosx/CMouseInfoPeer.java \ sun/lwawt/macosx/CPlatformView.java \ sun/lwawt/macosx/CPlatformWindow.java \ sun/lwawt/macosx/CPlatformComponent.java \
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -89,10 +89,15 @@ private volatile int windowState = Frame.NORMAL; + // check that the mouse is over the window + private volatile boolean isMouseOver = false; + // A peer where the last mouse event came to. Used by cursor manager to + // find the component under cursor + private static volatile LWComponentPeer lastCommonMouseEventPeer = null; + // A peer where the last mouse event came to. Used to generate - // MOUSE_ENTERED/EXITED notifications and by cursor manager to - // find the component under cursor - private static volatile LWComponentPeer lastMouseEventPeer = null; + // MOUSE_ENTERED/EXITED notifications + private volatile LWComponentPeer lastMouseEventPeer; // Peers where all dragged/released events should come to, // depending on what mouse button is being dragged according to Cocoa @@ -750,7 +755,7 @@ public void notifyNCMouseDown() { // Ungrab except for a click on a Dialog with the grabbing owner if (grabbingWindow != null && - grabbingWindow != getOwnerFrameDialog(this)) + !grabbingWindow.isOneOfOwnersOf(this)) { grabbingWindow.ungrab(); } @@ -773,59 +778,62 @@ Rectangle r = getBounds(); // findPeerAt() expects parent coordinates LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y); - LWWindowPeer lastWindowPeer = - (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null; - LWWindowPeer curWindowPeer = - (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null; if (id == MouseEvent.MOUSE_EXITED) { - // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched - // to a peer from another window. So we must first check if this peer is - // the same as lastWindowPeer - if (lastWindowPeer == this) { - if (isEnabled()) { + isMouseOver = false; + if (lastMouseEventPeer != null) { + if (lastMouseEventPeer.isEnabled()) { Point lp = lastMouseEventPeer.windowToLocal(x, y, - lastWindowPeer); + this); Component target = lastMouseEventPeer.getTarget(); postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, lp, screenX, screenY, clickCount, popupTrigger, button); } + + // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched + // to a peer from another window. So we must first check if this peer is + // the same as lastWindowPeer + if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) { + lastCommonMouseEventPeer = null; + } lastMouseEventPeer = null; } + } else if (id == MouseEvent.MOUSE_ENTERED) { + isMouseOver = true; + if (targetPeer != null) { + if (targetPeer.isEnabled()) { + Point lp = targetPeer.windowToLocal(x, y, this); + Component target = targetPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, lp, + screenX, screenY, clickCount, popupTrigger, button); + } + lastCommonMouseEventPeer = targetPeer; + lastMouseEventPeer = targetPeer; + } } else { - if (targetPeer != lastMouseEventPeer) { - // lastMouseEventPeer may be null if mouse was out of Java windows - if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { - // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit - // later), in which case lastWindowPeer is another window - if (lastWindowPeer != this) { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer); - // Additionally translate from this to lastWindowPeer coordinates - Rectangle lr = lastWindowPeer.getBounds(); - oldp.x += r.x - lr.x; - oldp.y += r.y - lr.y; - Component target = lastMouseEventPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, - when, modifiers, oldp, - screenX, screenY, clickCount, popupTrigger, button); - } else { - Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); - Component target = lastMouseEventPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, - when, modifiers, oldp, - screenX, screenY, clickCount, popupTrigger, button); - } - } - lastMouseEventPeer = targetPeer; - if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) { - Point newp = targetPeer.windowToLocal(x, y, curWindowPeer); - Component target = targetPeer.getTarget(); - postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, - when, modifiers, newp, - screenX, screenY, clickCount, popupTrigger, button); - } + PlatformWindow topmostPlatformWindow = + platformWindow.getTopmostPlatformWindowUnderMouse(); + + LWWindowPeer topmostWindowPeer = + topmostPlatformWindow != null ? topmostPlatformWindow.getPeer() : null; + + // topmostWindowPeer == null condition is added for the backword + // compatibility with applets. It can be removed when the + // getTopmostPlatformWindowUnderMouse() method will be properly + // implemented i CPlatformEmbeddedFrame class + if (topmostWindowPeer == this || topmostWindowPeer == null) { + generateMouseEnterExitEventsForComponents(when, button, x, y, + screenX, screenY, modifiers, clickCount, popupTrigger, + targetPeer); + } else { + LWComponentPeer topmostTargetPeer = + topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null; + topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y, + screenX, screenY, modifiers, clickCount, popupTrigger, + topmostTargetPeer); } + // TODO: fill "bdata" member of AWTEvent int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0; @@ -843,7 +851,7 @@ // Ungrab only if this window is not an owned window of the grabbing one. if (!isGrabbing() && grabbingWindow != null && - grabbingWindow != getOwnerFrameDialog(this)) + !grabbingWindow.isOneOfOwnersOf(this)) { grabbingWindow.ungrab(); } @@ -875,19 +883,13 @@ // mouseClickButtons is updated below, after MOUSE_CLICK is sent } - // check if we receive mouseEvent from outside the window's bounds - // it can be either mouseDragged or mouseReleased - if (curWindowPeer == null) { - //TODO This can happen if this window is invisible. this is correct behavior in this case? - curWindowPeer = this; - } if (targetPeer == null) { //TODO This can happen if this window is invisible. this is correct behavior in this case? targetPeer = this; } - Point lp = targetPeer.windowToLocal(x, y, curWindowPeer); + Point lp = targetPeer.windowToLocal(x, y, this); if (targetPeer.isEnabled()) { if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) { postMouseEnteredExitedEvent(targetPeer.getTarget(), id, @@ -918,6 +920,33 @@ notifyUpdateCursor(); } + private void generateMouseEnterExitEventsForComponents(long when, + int button, int x, int y, int screenX, int screenY, + int modifiers, int clickCount, boolean popupTriger, + LWComponentPeer targetPeer) { + if (!isMouseOver || targetPeer == lastMouseEventPeer) { + return; + } + + // Generate Mouse Exit for components + if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) { + Point oldp = lastMouseEventPeer.windowToLocal(x, y, this); + Component target = lastMouseEventPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, + oldp, screenX, screenY, clickCount, popupTriger, button); + } + lastCommonMouseEventPeer = targetPeer; + lastMouseEventPeer = targetPeer; + + // Genrate Mouse Enter for Componetns + if (targetPeer != null && targetPeer.isEnabled()) { + Point newp = targetPeer.windowToLocal(x, y, this); + Component target = targetPeer.getTarget(); + postMouseEnteredExitedEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, + newp, screenX, screenY, clickCount, popupTriger, button); + } + } + private void postMouseEnteredExitedEvent( Component target, int id, long when, int modifiers, Point loc, int xAbs, int yAbs, @@ -1198,11 +1227,11 @@ } public static LWWindowPeer getWindowUnderCursor() { - return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null; + return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null; } public static LWComponentPeer<?, ?> getPeerUnderCursor() { - return lastMouseEventPeer; + return lastCommonMouseEventPeer; } /* @@ -1292,6 +1321,17 @@ return !(window instanceof Dialog || window instanceof Frame); } + private boolean isOneOfOwnersOf(LWWindowPeer peer) { + Window owner = (peer != null ? peer.getTarget().getOwner() : null); + while (owner != null) { + if ((LWWindowPeer)owner.getPeer() == this) { + return true; + } + owner = owner.getOwner(); + } + return false; + } + /* * Changes focused window on java level. */ @@ -1323,7 +1363,7 @@ // - when the opposite (gaining focus) window is an owned/owner window. // - for a simple window in any case. if (!becomesFocused && - (isGrabbing() || getOwnerFrameDialog(grabbingWindow) == this)) + (isGrabbing() || this.isOneOfOwnersOf(grabbingWindow))) { focusLog.fine("ungrabbing on " + grabbingWindow); // ungrab a simple window if its owner looses activation. @@ -1340,6 +1380,11 @@ postEvent(windowEvent); } + /* + * Retrieves the owner of the peer. + * Note: this method returns the owner which can be activated, (i.e. the instance + * of Frame or Dialog may be returned). + */ static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) { Window owner = (peer != null ? peer.getTarget().getOwner() : null); while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
--- a/src/macosx/classes/sun/lwawt/PlatformWindow.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/classes/sun/lwawt/PlatformWindow.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,6 +118,8 @@ public void setAlwaysOnTop(boolean value); + public PlatformWindow getTopmostPlatformWindowUnderMouse(); + public void updateFocusableWindowState(); public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
--- a/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt.macosx; - -import java.awt.Window; -import sun.lwawt.LWMouseInfoPeer; -import sun.lwawt.LWWindowPeer; - -public class CMouseInfoPeer extends LWMouseInfoPeer -{ - //If a new window is to appear under the cursor, - //we get wrong window. - //This is a workaround for macosx. - @Override - public boolean isWindowUnderMouse(Window w) { - if (w == null) { - return false; - } - - return ((LWWindowPeer)w.getPeer()).getPlatformWindow().isUnderMouse(); - } -}
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -151,6 +151,11 @@ @Override public void setAlwaysOnTop(boolean value) {} + // This method should be properly implemented for applets. + // It returns null just as a stub. + @Override + public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; } + @Override public void updateFocusableWindowState() {}
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,8 +61,9 @@ private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage); private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename); private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled); - private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr); + private static native void nativeSynthesizeMouseEnteredExitedEvents(); private static native void nativeDispose(long nsWindowPtr); + private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse(); // Loger to report issues happened during execution but that do not affect functionality private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow"); @@ -579,7 +580,12 @@ if (visible) { // Apply the extended state as expected in shared code if (target instanceof Frame) { - switch (((Frame)target).getExtendedState()) { + int frameState = ((Frame)target).getExtendedState(); + if ((frameState & Frame.ICONIFIED) != 0) { + // Treat all state bit masks with ICONIFIED bit as ICONIFIED state. + frameState = Frame.ICONIFIED; + } + switch (frameState) { case Frame.ICONIFIED: CWrapper.NSWindow.miniaturize(nsWindowPtr); break; @@ -593,7 +599,7 @@ } } - nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + nativeSynthesizeMouseEnteredExitedEvents(); // Configure stuff #2 updateFocusabilityForAutoRequestFocus(true); @@ -738,6 +744,9 @@ setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop); } + public PlatformWindow getTopmostPlatformWindowUnderMouse() { + return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse(); + } @Override public void setOpacity(float opacity) { CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity); @@ -802,6 +811,10 @@ if (prevWindowState == windowState) return; final long nsWindowPtr = getNSWindowPtr(); + if ((windowState & Frame.ICONIFIED) != 0) { + // Treat all state bit masks with ICONIFIED bit as ICONIFIED state. + windowState = Frame.ICONIFIED; + } switch (windowState) { case Frame.ICONIFIED: if (prevWindowState == Frame.MAXIMIZED_BOTH) { @@ -830,7 +843,7 @@ throw new RuntimeException("Unknown window state: " + windowState); } - nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr); + nativeSynthesizeMouseEnteredExitedEvents(); // NOTE: the SWP.windowState field gets updated to the newWindowState // value when the native notification comes to us
--- a/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -148,6 +148,11 @@ } @Override + public PlatformWindow getTopmostPlatformWindowUnderMouse() { + return null; + } + + @Override public void updateFocusableWindowState() { }
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -300,11 +300,6 @@ } @Override - protected MouseInfoPeer createMouseInfoPeerImpl() { - return new CMouseInfoPeer(); - } - - @Override protected int getScreenHeight() { return GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice().getDefaultConfiguration().getBounds().height;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/macosx/classes/sun/nio/ch/SctpChannelImpl.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2009, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.nio.ch; + +import java.net.SocketAddress; +import java.net.InetAddress; +import java.io.IOException; +import java.util.Set; +import java.nio.ByteBuffer; +import java.nio.channels.spi.SelectorProvider; +import com.sun.nio.sctp.Association; +import com.sun.nio.sctp.MessageInfo; +import com.sun.nio.sctp.NotificationHandler; +import com.sun.nio.sctp.SctpChannel; +import com.sun.nio.sctp.SctpSocketOption; + +/** + * Unimplemented. + */ +public class SctpChannelImpl extends SctpChannel +{ + private static final String message = "SCTP not supported on this platform"; + + public SctpChannelImpl(SelectorProvider provider) { + super(provider); + throw new UnsupportedOperationException(message); + } + + @Override + public Association association() { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpChannel bind(SocketAddress local) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpChannel bindAddress(InetAddress address) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpChannel unbindAddress(InetAddress address) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public boolean connect(SocketAddress remote) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public boolean connect(SocketAddress remote, int maxOutStreams, + int maxInStreams) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public boolean isConnectionPending() { + throw new UnsupportedOperationException(message); + } + + @Override + public boolean finishConnect() throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SocketAddress> getAllLocalAddresses() + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SocketAddress> getRemoteAddresses() + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpChannel shutdown() throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> T getOption(SctpSocketOption<T> name) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> SctpChannel setOption(SctpSocketOption<T> name, T value) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SctpSocketOption<?>> supportedOptions() { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> MessageInfo receive(ByteBuffer dst, T attachment, + NotificationHandler<T> handler) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public int send(ByteBuffer src, MessageInfo messageInfo) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + protected void implConfigureBlocking(boolean block) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public void implCloseSelectableChannel() throws IOException { + throw new UnsupportedOperationException(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/macosx/classes/sun/nio/ch/SctpMultiChannelImpl.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2009, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.nio.ch; + +import java.net.SocketAddress; +import java.net.InetAddress; +import java.io.IOException; +import java.util.Set; +import java.nio.ByteBuffer; +import java.nio.channels.spi.SelectorProvider; +import com.sun.nio.sctp.Association; +import com.sun.nio.sctp.SctpChannel; +import com.sun.nio.sctp.MessageInfo; +import com.sun.nio.sctp.NotificationHandler; +import com.sun.nio.sctp.SctpMultiChannel; +import com.sun.nio.sctp.SctpSocketOption; + +/** + * Unimplemented. + */ +public class SctpMultiChannelImpl extends SctpMultiChannel +{ + private static final String message = "SCTP not supported on this platform"; + + public SctpMultiChannelImpl(SelectorProvider provider) { + super(provider); + throw new UnsupportedOperationException(message); + } + + @Override + public Set<Association> associations() { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpMultiChannel bind(SocketAddress local, + int backlog) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpMultiChannel bindAddress(InetAddress address) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpMultiChannel unbindAddress(InetAddress address) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SocketAddress> getAllLocalAddresses() + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SocketAddress> getRemoteAddresses + (Association association) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpMultiChannel shutdown(Association association) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> T getOption(SctpSocketOption<T> name, + Association association) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> SctpMultiChannel setOption(SctpSocketOption<T> name, + T value, Association association) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SctpSocketOption<?>> supportedOptions() { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> MessageInfo receive(ByteBuffer buffer, T attachment, + NotificationHandler<T> handler) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public int send(ByteBuffer buffer, MessageInfo messageInfo) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpChannel branch(Association association) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + protected void implConfigureBlocking(boolean block) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public void implCloseSelectableChannel() throws IOException { + throw new UnsupportedOperationException(message); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/macosx/classes/sun/nio/ch/SctpServerChannelImpl.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2009, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.nio.ch; + +import java.net.SocketAddress; +import java.net.InetAddress; +import java.io.IOException; +import java.util.Set; +import java.nio.channels.spi.SelectorProvider; +import com.sun.nio.sctp.SctpChannel; +import com.sun.nio.sctp.SctpServerChannel; +import com.sun.nio.sctp.SctpSocketOption; + +/** + * Unimplemented. + */ +public class SctpServerChannelImpl extends SctpServerChannel +{ + private static final String message = "SCTP not supported on this platform"; + + public SctpServerChannelImpl(SelectorProvider provider) { + super(provider); + throw new UnsupportedOperationException(message); + } + + @Override + public SctpChannel accept() throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpServerChannel bind(SocketAddress local, + int backlog) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpServerChannel bindAddress(InetAddress address) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public SctpServerChannel unbindAddress(InetAddress address) + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SocketAddress> getAllLocalAddresses() + throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> T getOption(SctpSocketOption<T> name) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public <T> SctpServerChannel setOption(SctpSocketOption<T> name, + T value) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public Set<SctpSocketOption<?>> supportedOptions() { + throw new UnsupportedOperationException(message); + } + + @Override + protected void implConfigureBlocking(boolean block) throws IOException { + throw new UnsupportedOperationException(message); + } + + @Override + public void implCloseSelectableChannel() throws IOException { + throw new UnsupportedOperationException(message); + } +}
--- a/src/macosx/native/sun/awt/AWTView.h Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/native/sun/awt/AWTView.h Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,8 @@ @private jobject m_cPlatformView; - // Handler for the tracking rect needed for Enter/Exit events management. - NSTrackingRectTag rolloverTrackingRectTag; + // Handler for the tracking area needed for Enter/Exit events management. + NSTrackingArea* rolloverTrackingArea; // TODO: NSMenu *contextualMenu; @@ -61,7 +61,7 @@ - (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer; - (void) deliverJavaMouseEvent: (NSEvent *) event; -- (void) resetTrackingRect; +- (void) resetTrackingArea; - (void) deliverJavaKeyEventHelper: (NSEvent *) event; - (jobject) awtComponent:(JNIEnv *)env;
--- a/src/macosx/native/sun/awt/AWTView.m Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/native/sun/awt/AWTView.m Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,6 +82,7 @@ fPAHNeedsToSelect = NO; mouseIsOver = NO; + [self resetTrackingArea]; if (windowLayer != nil) { self.cglLayer = windowLayer; @@ -149,7 +150,7 @@ [[self window] makeFirstResponder: self]; }]; if ([self window] != NULL) { - [self resetTrackingRect]; + [self resetTrackingArea]; } } @@ -380,30 +381,31 @@ JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent); } - -- (void) clearTrackingRect { - if (rolloverTrackingRectTag > 0) { - [self removeTrackingRect:rolloverTrackingRectTag]; - rolloverTrackingRectTag = 0; +- (void) resetTrackingArea { + if (rolloverTrackingArea != nil) { + [self removeTrackingArea:rolloverTrackingArea]; + [rolloverTrackingArea release]; } -} + + int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited | + NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag); -- (void) resetTrackingRect { - [self clearTrackingRect]; - rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect] - owner:self - userData:NULL - assumeInside:NO]; + rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect] + options:options + owner:self + userInfo:nil + ]; + [self addTrackingArea:rolloverTrackingArea]; } - (void)updateTrackingAreas { [super updateTrackingAreas]; - [self resetTrackingRect]; + [self resetTrackingArea]; } - (void) resetCursorRects { [super resetCursorRects]; - [self resetTrackingRect]; + [self resetTrackingArea]; } -(void) deliverJavaKeyEventHelper: (NSEvent *) event {
--- a/src/macosx/native/sun/awt/AWTWindow.m Fri Mar 21 17:54:04 2014 +0000 +++ b/src/macosx/native/sun/awt/AWTWindow.m Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -314,10 +314,8 @@ return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]; } -// checks that this window is under the mouse cursor and this point is not overlapped by others windows -- (BOOL) isTopmostWindowUnderMouse { - - int currentWinID = [self.nsWindow windowNumber]; +// return id for the topmost window under mouse ++ (NSInteger) getTopmostWindowUnderMouseID { NSRect screenRect = [[NSScreen mainScreen] frame]; NSPoint nsMouseLocation = [NSEvent mouseLocation]; @@ -327,51 +325,75 @@ for (NSDictionary *window in windows) { - int layer = [[window objectForKey:(id)kCGWindowLayer] intValue]; + NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue]; if (layer == 0) { - int winID = [[window objectForKey:(id)kCGWindowNumber] intValue]; CGRect rect; CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect); if (CGRectContainsPoint(rect, cgMouseLocation)) { - return currentWinID == winID; - } else if (currentWinID == winID) { - return NO; + return [[window objectForKey:(id)kCGWindowNumber] integerValue]; } } } - return NO; + return -1; +} + +// checks that this window is under the mouse cursor and this point is not overlapped by other windows +- (BOOL) isTopmostWindowUnderMouse { + return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID]; } -- (void) synthesizeMouseEnteredExitedEvents { ++ (AWTWindow *) getTopmostWindowUnderMouse { + NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator]; + NSWindow *window; - int eventType = 0; - BOOL isUnderMouse = [self isTopmostWindowUnderMouse]; - BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver]; + NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID]; - if (isUnderMouse && !mouseIsOver) { - eventType = NSMouseEntered; - } else if (!isUnderMouse && mouseIsOver) { - eventType = NSMouseExited; - } else { - return; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([window windowNumber] == topmostWindowUnderMouseID) { + BOOL isAWTWindow = [AWTWindow isAWTWindow: window]; + return isAWTWindow ? (AWTWindow *) [window delegate] : nil; + } } + return nil; +} + ++ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType { NSPoint screenLocation = [NSEvent mouseLocation]; - NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation]; + NSPoint windowLocation = [window convertScreenToBase: screenLocation]; int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask; NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType location: windowLocation modifierFlags: modifierFlags timestamp: 0 - windowNumber: [self.nsWindow windowNumber] + windowNumber: [window windowNumber] context: nil eventNumber: 0 trackingNumber: 0 userData: nil ]; - [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent]; + [[window contentView] deliverJavaMouseEvent: mouseEvent]; +} + ++(void) synthesizeMouseEnteredExitedEventsForAllWindows { + NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID]; + NSArray *windows = [NSApp windows]; + NSWindow *window; + + NSEnumerator *windowEnumerator = [windows objectEnumerator]; + while ((window = [windowEnumerator nextObject]) != nil) { + if ([AWTWindow isAWTWindow: window]) { + BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID); + BOOL mouseIsOver = [[window contentView] mouseIsOver]; + if (isUnderMouse && !mouseIsOver) { + [AWTWindow synthesizeMouseEnteredExitedEvents: window withType:NSMouseEntered]; + } else if (!isUnderMouse && mouseIsOver) { + [AWTWindow synthesizeMouseEnteredExitedEvents: window withType:NSMouseExited]; + } + } + } } + (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window { @@ -979,7 +1001,7 @@ // (this will also re-enable screen updates, which were disabled above) // TODO: send PaintEvent - [window synthesizeMouseEnteredExitedEvents]; + [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows]; }]; JNF_COCOA_EXIT(env); @@ -1158,19 +1180,40 @@ /* * Class: sun_lwawt_macosx_CPlatformWindow + * Method: nativeGetTopMostWindowUnderMouse + * Signature: (J)V + */ +JNIEXPORT jobject +JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse +(JNIEnv *env, jclass clazz) +{ + jobject topmostWindowUnderMouse = nil; + + JNF_COCOA_ENTER(env); + AWT_ASSERT_APPKIT_THREAD; + + AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse]; + if (awtWindow != nil) { + topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject]; + } + + JNF_COCOA_EXIT(env); + + return topmostWindowUnderMouse; +} + +/* + * Class: sun_lwawt_macosx_CPlatformWindow * Method: nativeSynthesizeMouseEnteredExitedEvents * Signature: (J)V */ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents -(JNIEnv *env, jclass clazz, jlong windowPtr) +(JNIEnv *env, jclass clazz) { JNF_COCOA_ENTER(env); - NSWindow *nsWindow = OBJC(windowPtr); [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ - AWTWindow *window = (AWTWindow*)[nsWindow delegate]; - - [window synthesizeMouseEnteredExitedEvents]; + [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows]; }]; JNF_COCOA_EXIT(env);
--- a/src/share/classes/java/lang/Class.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/lang/Class.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -2338,44 +2338,110 @@ } /** + * Atomic operations support. + */ + private static class Atomic { + // initialize Unsafe machinery here, since we need to call Class.class instance method + // and have to avoid calling it in the static initializer of the Class class... + private static final Unsafe unsafe = Unsafe.getUnsafe(); + // offset of Class.reflectionData instance field + private static final long reflectionDataOffset; + // offset of Class.annotationType instance field + private static final long annotationTypeOffset; + + static { + Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches + reflectionDataOffset = objectFieldOffset(fields, "reflectionData"); + annotationTypeOffset = objectFieldOffset(fields, "annotationType"); + } + + private static long objectFieldOffset(Field[] fields, String fieldName) { + Field field = searchFields(fields, fieldName); + if (field == null) { + throw new Error("No " + fieldName + " field found in java.lang.Class"); + } + return unsafe.objectFieldOffset(field); + } + + static <T> boolean casReflectionData(Class<?> clazz, + SoftReference<ReflectionData<T>> oldData, + SoftReference<ReflectionData<T>> newData) { + return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData); + } + + static <T> boolean casAnnotationType(Class<?> clazz, + AnnotationType oldType, + AnnotationType newType) { + return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType); + } + } + + /** * Reflection support. */ // Caches for certain reflective results private static boolean useCaches = true; - private volatile transient SoftReference<Field[]> declaredFields; - private volatile transient SoftReference<Field[]> publicFields; - private volatile transient SoftReference<Method[]> declaredMethods; - private volatile transient SoftReference<Method[]> publicMethods; - private volatile transient SoftReference<Constructor<T>[]> declaredConstructors; - private volatile transient SoftReference<Constructor<T>[]> publicConstructors; - // Intermediate results for getFields and getMethods - private volatile transient SoftReference<Field[]> declaredPublicFields; - private volatile transient SoftReference<Method[]> declaredPublicMethods; + + // reflection data that might get invalidated when JVM TI RedefineClasses() is called + static class ReflectionData<T> { + volatile Field[] declaredFields; + volatile Field[] publicFields; + volatile Method[] declaredMethods; + volatile Method[] publicMethods; + volatile Constructor<T>[] declaredConstructors; + volatile Constructor<T>[] publicConstructors; + // Intermediate results for getFields and getMethods + volatile Field[] declaredPublicFields; + volatile Method[] declaredPublicMethods; + // Value of classRedefinedCount when we created this ReflectionData instance + final int redefinedCount; + + ReflectionData(int redefinedCount) { + this.redefinedCount = redefinedCount; + } + } + + private volatile transient SoftReference<ReflectionData<T>> reflectionData; // Incremented by the VM on each call to JVM TI RedefineClasses() // that redefines this class or a superclass. private volatile transient int classRedefinedCount = 0; - // Value of classRedefinedCount when we last cleared the cached values - // that are sensitive to class redefinition. - private volatile transient int lastRedefinedCount = 0; + // Lazily create and cache ReflectionData + private ReflectionData<T> reflectionData() { + SoftReference<ReflectionData<T>> reflectionData = this.reflectionData; + int classRedefinedCount = this.classRedefinedCount; + ReflectionData<T> rd; + if (useCaches && + reflectionData != null && + (rd = reflectionData.get()) != null && + rd.redefinedCount == classRedefinedCount) { + return rd; + } + // else no SoftReference or cleared SoftReference or stale ReflectionData + // -> create and replace new instance + return newReflectionData(reflectionData, classRedefinedCount); + } - // Clears cached values that might possibly have been obsoleted by - // a class redefinition. - private void clearCachesOnClassRedefinition() { - if (lastRedefinedCount != classRedefinedCount) { - declaredFields = publicFields = declaredPublicFields = null; - declaredMethods = publicMethods = declaredPublicMethods = null; - declaredConstructors = publicConstructors = null; - annotations = declaredAnnotations = null; + private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData, + int classRedefinedCount) { + if (!useCaches) return null; - // Use of "volatile" (and synchronization by caller in the case - // of annotations) ensures that no thread sees the update to - // lastRedefinedCount before seeing the caches cleared. - // We do not guard against brief windows during which multiple - // threads might redundantly work to fill an empty cache. - lastRedefinedCount = classRedefinedCount; + while (true) { + ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount); + // try to CAS it... + if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) { + return rd; + } + // else retry + oldReflectionData = this.reflectionData; + classRedefinedCount = this.classRedefinedCount; + if (oldReflectionData != null && + (rd = oldReflectionData.get()) != null && + rd.redefinedCount == classRedefinedCount) { + return rd; + } } } @@ -2403,7 +2469,7 @@ } // Annotations handling - private native byte[] getRawAnnotations(); + native byte[] getRawAnnotations(); native ConstantPool getConstantPool(); @@ -2418,27 +2484,19 @@ // via ReflectionFactory.copyField. private Field[] privateGetDeclaredFields(boolean publicOnly) { checkInitted(); - Field[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicOnly) { - if (declaredPublicFields != null) { - res = declaredPublicFields.get(); - } - } else { - if (declaredFields != null) { - res = declaredFields.get(); - } - } + Field[] res; + ReflectionData<T> rd = reflectionData(); + if (rd != null) { + res = publicOnly ? rd.declaredPublicFields : rd.declaredFields; if (res != null) return res; } // No cached value available; request value from VM res = Reflection.filterFields(this, getDeclaredFields0(publicOnly)); - if (useCaches) { + if (rd != null) { if (publicOnly) { - declaredPublicFields = new SoftReference<>(res); + rd.declaredPublicFields = res; } else { - declaredFields = new SoftReference<>(res); + rd.declaredFields = res; } } return res; @@ -2449,12 +2507,10 @@ // via ReflectionFactory.copyField. private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) { checkInitted(); - Field[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicFields != null) { - res = publicFields.get(); - } + Field[] res; + ReflectionData<T> rd = reflectionData(); + if (rd != null) { + res = rd.publicFields; if (res != null) return res; } @@ -2487,8 +2543,8 @@ res = new Field[fields.size()]; fields.toArray(res); - if (useCaches) { - publicFields = new SoftReference<>(res); + if (rd != null) { + rd.publicFields = res; } return res; } @@ -2511,18 +2567,10 @@ // instead be copied via ReflectionFactory.copyConstructor. private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) { checkInitted(); - Constructor<T>[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicOnly) { - if (publicConstructors != null) { - res = publicConstructors.get(); - } - } else { - if (declaredConstructors != null) { - res = declaredConstructors.get(); - } - } + Constructor<T>[] res; + ReflectionData<T> rd = reflectionData(); + if (rd != null) { + res = publicOnly ? rd.publicConstructors : rd.declaredConstructors; if (res != null) return res; } // No cached value available; request value from VM @@ -2531,11 +2579,11 @@ } else { res = getDeclaredConstructors0(publicOnly); } - if (useCaches) { + if (rd != null) { if (publicOnly) { - publicConstructors = new SoftReference<>(res); + rd.publicConstructors = res; } else { - declaredConstructors = new SoftReference<>(res); + rd.declaredConstructors = res; } } return res; @@ -2552,27 +2600,19 @@ // via ReflectionFactory.copyMethod. private Method[] privateGetDeclaredMethods(boolean publicOnly) { checkInitted(); - Method[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicOnly) { - if (declaredPublicMethods != null) { - res = declaredPublicMethods.get(); - } - } else { - if (declaredMethods != null) { - res = declaredMethods.get(); - } - } + Method[] res; + ReflectionData<T> rd = reflectionData(); + if (rd != null) { + res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods; if (res != null) return res; } // No cached value available; request value from VM res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly)); - if (useCaches) { + if (rd != null) { if (publicOnly) { - declaredPublicMethods = new SoftReference<>(res); + rd.declaredPublicMethods = res; } else { - declaredMethods = new SoftReference<>(res); + rd.declaredMethods = res; } } return res; @@ -2674,12 +2714,10 @@ // via ReflectionFactory.copyMethod. private Method[] privateGetPublicMethods() { checkInitted(); - Method[] res = null; - if (useCaches) { - clearCachesOnClassRedefinition(); - if (publicMethods != null) { - res = publicMethods.get(); - } + Method[] res; + ReflectionData<T> rd = reflectionData(); + if (rd != null) { + res = rd.publicMethods; if (res != null) return res; } @@ -2727,8 +2765,8 @@ methods.addAllIfNotPresent(inheritedMethods); methods.compactAndTrim(); res = methods.getArray(); - if (useCaches) { - publicMethods = new SoftReference<>(res); + if (rd != null) { + rd.publicMethods = res; } return res; } @@ -2738,7 +2776,7 @@ // Helpers for fetchers of one field, method, or constructor // - private Field searchFields(Field[] fields, String name) { + private static Field searchFields(Field[] fields, String name) { String internedName = name.intern(); for (int i = 0; i < fields.length; i++) { if (fields[i].getName() == internedName) { @@ -2756,7 +2794,7 @@ // of Field objects which have to be created for the common // case where the field being requested is declared in the // class which is being queried. - Field res = null; + Field res; // Search declared public fields if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) { return res; @@ -2808,7 +2846,7 @@ // number of Method objects which have to be created for the // common case where the method being requested is declared in // the class which is being queried. - Method res = null; + Method res; // Search declared public methods if ((res = searchMethods(privateGetDeclaredMethods(true), name, @@ -3209,9 +3247,20 @@ // Annotations cache private transient Map<Class<? extends Annotation>, Annotation> annotations; private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; + // Value of classRedefinedCount when we last cleared the cached annotations and declaredAnnotations fields + private transient int lastAnnotationsRedefinedCount = 0; + + // Clears cached values that might possibly have been obsoleted by + // a class redefinition. + private void clearAnnotationCachesOnClassRedefinition() { + if (lastAnnotationsRedefinedCount != classRedefinedCount) { + annotations = declaredAnnotations = null; + lastAnnotationsRedefinedCount = classRedefinedCount; + } + } private synchronized void initAnnotationsIfNecessary() { - clearCachesOnClassRedefinition(); + clearAnnotationCachesOnClassRedefinition(); if (annotations != null) return; declaredAnnotations = AnnotationParser.parseAnnotations( @@ -3233,10 +3282,11 @@ // Annotation types cache their internal (AnnotationType) form - private AnnotationType annotationType; + @SuppressWarnings("UnusedDeclaration") + private volatile transient AnnotationType annotationType; - void setAnnotationType(AnnotationType type) { - annotationType = type; + boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) { + return Atomic.casAnnotationType(this, oldType, newType); } AnnotationType getAnnotationType() {
--- a/src/share/classes/java/lang/System.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/lang/System.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -1178,12 +1178,15 @@ public sun.reflect.ConstantPool getConstantPool(Class klass) { return klass.getConstantPool(); } - public void setAnnotationType(Class klass, AnnotationType type) { - klass.setAnnotationType(type); + public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) { + return klass.casAnnotationType(oldType, newType); } public AnnotationType getAnnotationType(Class klass) { return klass.getAnnotationType(); } + public byte[] getRawClassAnnotations(Class<?> klass) { + return klass.getRawAnnotations(); + } public <E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass) { return klass.getEnumConstantsShared();
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java Thu Apr 03 00:39:02 2014 +0100 @@ -53,7 +53,8 @@ if (!member.isResolved()) throw new InternalError(); - if (member.getDeclaringClass().isInterface() && !member.isAbstract()) { + if (member.getDeclaringClass().isInterface() && + member.isMethod() && !member.isAbstract()) { // Check for corner case: invokeinterface of Object method MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind()); m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Apr 03 00:39:02 2014 +0100 @@ -742,7 +742,8 @@ GuardWithCatch gguard = new GuardWithCatch(gtarget, exType, gcatcher); if (gtarget == null || gcatcher == null) throw new InternalError(); MethodHandle ginvoker = GuardWithCatch.VARARGS_INVOKE.bindReceiver(gguard); - return makeCollectArguments(ginvoker, ValueConversions.varargsArray(nargs), 0, false); + MethodHandle gcollect = makeCollectArguments(ginvoker, ValueConversions.varargsArray(nargs), 0, false); + return makePairwiseConvert(gcollect, type, 2); } }
--- a/src/share/classes/java/net/CookieManager.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/net/CookieManager.java Thu Apr 03 00:39:02 2014 +0100 @@ -310,7 +310,10 @@ // there is no dot at the beginning of effective request-host, // the default Domain can only domain-match itself.) if (cookie.getDomain() == null) { - cookie.setDomain(uri.getHost()); + String host = uri.getHost(); + if (host != null && !host.contains(".")) + host += ".local"; + cookie.setDomain(host); } String ports = cookie.getPortlist(); if (ports != null) {
--- a/src/share/classes/java/net/IDN.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/net/IDN.java Thu Apr 03 00:39:02 2014 +0100 @@ -271,13 +271,17 @@ if (useSTD3ASCIIRules) { for (int i = 0; i < dest.length(); i++) { int c = dest.charAt(i); - if (!isLDHChar(c)) { - throw new IllegalArgumentException("Contains non-LDH characters"); + if (isNonLDHAsciiCodePoint(c)) { + throw new IllegalArgumentException( + "Contains non-LDH ASCII characters"); } } - if (dest.charAt(0) == '-' || dest.charAt(dest.length() - 1) == '-') { - throw new IllegalArgumentException("Has leading or trailing hyphen"); + if (dest.charAt(0) == '-' || + dest.charAt(dest.length() - 1) == '-') { + + throw new IllegalArgumentException( + "Has leading or trailing hyphen"); } } @@ -380,26 +384,20 @@ // // LDH stands for "letter/digit/hyphen", with characters restricted to the // 26-letter Latin alphabet <A-Z a-z>, the digits <0-9>, and the hyphen - // <-> - // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x56..0x60, 0x7B..0x7F + // <->. + // Non LDH refers to characters in the ASCII range, but which are not + // letters, digits or the hypen. + // + // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F // - private static boolean isLDHChar(int ch){ - // high runner case - if(ch > 0x007A){ - return false; - } - //['-' '0'..'9' 'A'..'Z' 'a'..'z'] - if((ch == 0x002D) || - (0x0030 <= ch && ch <= 0x0039) || - (0x0041 <= ch && ch <= 0x005A) || - (0x0061 <= ch && ch <= 0x007A) - ){ - return true; - } - return false; + private static boolean isNonLDHAsciiCodePoint(int ch){ + return (0x0000 <= ch && ch <= 0x002C) || + (0x002E <= ch && ch <= 0x002F) || + (0x003A <= ch && ch <= 0x0040) || + (0x005B <= ch && ch <= 0x0060) || + (0x007B <= ch && ch <= 0x007F); } - // // search dots in a string and return the index of that character; // or if there is no dots, return the length of input string
--- a/src/share/classes/java/nio/file/Files.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/nio/file/Files.java Thu Apr 03 00:39:02 2014 +0100 @@ -2978,13 +2978,13 @@ * method is invoked to check read access to the file. */ public static byte[] readAllBytes(Path path) throws IOException { - try (FileChannel fc = FileChannel.open(path); - InputStream is = Channels.newInputStream(fc)) { - long size = fc.size(); + try (SeekableByteChannel sbc = Files.newByteChannel(path); + InputStream in = Channels.newInputStream(sbc)) { + long size = sbc.size(); if (size > (long)MAX_BUFFER_SIZE) throw new OutOfMemoryError("Required array size too large"); - return read(is, (int)size); + return read(in, (int)size); } }
--- a/src/share/classes/java/util/ComparableTimSort.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/util/ComparableTimSort.java Thu Apr 03 00:39:02 2014 +0100 @@ -131,7 +131,7 @@ */ int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : - len < 119151 ? 19 : 40); + len < 119151 ? 24 : 40); runBase = new int[stackLen]; runLen = new int[stackLen]; }
--- a/src/share/classes/java/util/TimSort.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/util/TimSort.java Thu Apr 03 00:39:02 2014 +0100 @@ -158,7 +158,7 @@ */ int stackLen = (len < 120 ? 5 : len < 1542 ? 10 : - len < 119151 ? 19 : 40); + len < 119151 ? 24 : 40); runBase = new int[stackLen]; runLen = new int[stackLen]; }
--- a/src/share/classes/java/util/jar/JarFile.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/util/jar/JarFile.java Thu Apr 03 00:39:02 2014 +0100 @@ -38,6 +38,7 @@ import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.misc.SharedSecrets; +import sun.security.util.SignatureFileVerifier; /** * The <code>JarFile</code> class is used to read the contents of a jar file @@ -329,11 +330,13 @@ String[] names = getMetaInfEntryNames(); if (names != null) { for (int i = 0; i < names.length; i++) { - JarEntry e = getJarEntry(names[i]); - if (e == null) { - throw new JarException("corrupted jar file"); - } - if (!e.isDirectory()) { + String uname = names[i].toUpperCase(Locale.ENGLISH); + if (MANIFEST_NAME.equals(uname) + || SignatureFileVerifier.isBlockOrSF(uname)) { + JarEntry e = getJarEntry(names[i]); + if (e == null) { + throw new JarException("corrupted jar file"); + } if (mev == null) { mev = new ManifestEntryVerifier (getManifestFromReference());
--- a/src/share/classes/java/util/logging/LogManager.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/util/logging/LogManager.java Thu Apr 03 00:39:02 2014 +0100 @@ -149,7 +149,15 @@ // The global LogManager object private static LogManager manager; - private Properties props = new Properties(); + // 'props' is assigned within a lock but accessed without it. + // Declaring it volatile makes sure that another thread will not + // be able to see a partially constructed 'props' object. + // (seeing a partially constructed 'props' object can result in + // NPE being thrown in Hashtable.get(), because it leaves the door + // open for props.getProperties() to be called before the construcor + // of Hashtable is actually completed). + private volatile Properties props = new Properties(); + private PropertyChangeSupport changes = new PropertyChangeSupport(LogManager.class); private final static Level defaultLevel = Level.INFO; @@ -363,6 +371,9 @@ changes.removePropertyChangeListener(l); } + // LoggerContext maps from AppContext + private static WeakHashMap<Object, LoggerContext> contextsMap = null; + // Returns the LoggerContext for the user code (i.e. application or AppContext). // Loggers are isolated from each AppContext. private LoggerContext getUserContext() { @@ -371,33 +382,28 @@ SecurityManager sm = System.getSecurityManager(); JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess(); if (sm != null && javaAwtAccess != null) { + // for each applet, it has its own LoggerContext isolated from others synchronized (javaAwtAccess) { - // AppContext.getAppContext() returns the system AppContext if called - // from a system thread but Logger.getLogger might be called from - // an applet code. Instead, find the AppContext of the applet code - // from the execution stack. - Object ecx = javaAwtAccess.getExecutionContext(); - if (ecx == null) { - // fall back to thread group seach of AppContext - ecx = javaAwtAccess.getContext(); - } + // find the AppContext of the applet code + // will be null if we are in the main app context. + final Object ecx = javaAwtAccess.getAppletContext(); if (ecx != null) { - context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class); + if (contextsMap == null) { + contextsMap = new WeakHashMap<>(); + } + context = contextsMap.get(ecx); if (context == null) { - if (javaAwtAccess.isMainAppContext()) { - context = userContext; - } else { - // Create a new LoggerContext for the applet. - // The new logger context has its requiresDefaultLoggers - // flag set to true - so that these loggers will be - // lazily added when the context is firt accessed. - context = new LoggerContext(true); - } - javaAwtAccess.put(ecx, LoggerContext.class, context); + // Create a new LoggerContext for the applet. + // The new logger context has its requiresDefaultLoggers + // flag set to true - so that these loggers will be + // lazily added when the context is firt accessed. + context = new LoggerContext(true); + contextsMap.put(ecx, context); } } } } + // for standalone app, return userContext return context != null ? context : userContext; } @@ -542,7 +548,7 @@ if (logger == null) { // Hashtable holds stale weak reference // to a logger which has been GC-ed. - removeLogger(name); + ref.dispose(); } return logger; } @@ -629,7 +635,7 @@ // It's possible that the Logger was GC'ed after a // drainLoggerRefQueueBounded() call so allow // a new one to be registered. - removeLogger(name); + ref.dispose(); } else { // We already have a registered logger with the given name. return false; @@ -675,10 +681,10 @@ return true; } - // note: all calls to removeLogger are synchronized on LogManager's - // intrinsic lock - void removeLogger(String name) { - namedLoggers.remove(name); + synchronized void removeLoggerRef(String name, LoggerWeakRef ref) { + if (namedLoggers.get(name) == ref) { + namedLoggers.remove(name); + } } synchronized Enumeration<String> getLoggerNames() { @@ -856,6 +862,7 @@ private String name; // for namedLoggers cleanup private LogNode node; // for loggerRef cleanup private WeakReference<Logger> parentRef; // for kids cleanup + private boolean disposed = false; // avoid calling dispose twice LoggerWeakRef(Logger logger) { super(logger, loggerRefQueue); @@ -865,14 +872,45 @@ // dispose of this LoggerWeakRef object void dispose() { - if (node != null) { - // if we have a LogNode, then we were a named Logger - // so clear namedLoggers weak ref to us - node.context.removeLogger(name); - name = null; // clear our ref to the Logger's name + // Avoid calling dispose twice. When a Logger is gc'ed, its + // LoggerWeakRef will be enqueued. + // However, a new logger of the same name may be added (or looked + // up) before the queue is drained. When that happens, dispose() + // will be called by addLocalLogger() or findLogger(). + // Later when the queue is drained, dispose() will be called again + // for the same LoggerWeakRef. Marking LoggerWeakRef as disposed + // avoids processing the data twice (even though the code should + // now be reentrant). + synchronized(this) { + // Note to maintainers: + // Be careful not to call any method that tries to acquire + // another lock from within this block - as this would surely + // lead to deadlocks, given that dispose() can be called by + // multiple threads, and from within different synchronized + // methods/blocks. + if (disposed) return; + disposed = true; + } - node.loggerRef = null; // clear LogNode's weak ref to us - node = null; // clear our ref to LogNode + final LogNode n = node; + if (n != null) { + // n.loggerRef can only be safely modified from within + // a lock on LoggerContext. removeLoggerRef is already + // synchronized on LoggerContext so calling + // n.context.removeLoggerRef from within this lock is safe. + synchronized (n.context) { + // if we have a LogNode, then we were a named Logger + // so clear namedLoggers weak ref to us + n.context.removeLoggerRef(name, this); + name = null; // clear our ref to the Logger's name + + // LogNode may have been reused - so only clear + // LogNode.loggerRef if LogNode.loggerRef == this + if (n.loggerRef == this) { + n.loggerRef = null; // clear LogNode's weak ref to us + } + node = null; // clear our ref to LogNode + } } if (parentRef != null) { @@ -925,7 +963,7 @@ // - maximum: 10.9 ms // private final static int MAX_ITERATIONS = 400; - final synchronized void drainLoggerRefQueueBounded() { + final void drainLoggerRefQueueBounded() { for (int i = 0; i < MAX_ITERATIONS; i++) { if (loggerRefQueue == null) { // haven't finished loading LogManager yet
--- a/src/share/classes/java/util/logging/Logger.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/java/util/logging/Logger.java Thu Apr 03 00:39:02 2014 +0100 @@ -174,11 +174,11 @@ public class Logger { private static final Handler emptyHandlers[] = new Handler[0]; private static final int offValue = Level.OFF.intValue(); - private LogManager manager; + private volatile LogManager manager; private String name; private final CopyOnWriteArrayList<Handler> handlers = new CopyOnWriteArrayList<>(); - private String resourceBundleName; + private volatile String resourceBundleName; private volatile boolean useParentHandlers = true; private volatile Filter filter; private boolean anonymous;
--- a/src/share/classes/javax/swing/text/html/parser/Parser.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/javax/swing/text/html/parser/Parser.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -2081,6 +2081,13 @@ // null end tag. endTag(false); continue; + } else if (textpos == 0) { + if (!legalElementContext(dtd.pcdata)) { + error("unexpected.pcdata"); + } + if (last.breaksFlow()) { + space = false; + } } break;
--- a/src/share/classes/sun/awt/AppContext.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/awt/AppContext.java Thu Apr 03 00:39:02 2014 +0100 @@ -837,21 +837,68 @@ public boolean isMainAppContext() { return (numAppContexts.get() == 1 && mainAppContext != null); } - public Object getContext() { - return getAppContext(); - } - public Object getExecutionContext() { - return getExecutionAppContext(); + + private boolean hasRootThreadGroup(final AppContext ecx) { + return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + @Override + public Boolean run() { + return ecx.threadGroup.getParent() == null; + } + }); } - public Object get(Object context, Object key) { - return ((AppContext)context).get(key); + + /** + * Returns the AppContext used for applet logging isolation, or null if + * the default global context can be used. + * If there's no applet, or if the caller is a stand alone application, + * or running in the main app context, returns null. + * Otherwise, returns the AppContext of the calling applet. + * @return null if the global default context can be used, + * an AppContext otherwise. + **/ + public Object getAppletContext() { + // There's no AppContext: return null. + // No need to call getAppContext() if numAppContext == 0: + // it means that no AppContext has been created yet, and + // we don't want to trigger the creation of a main app + // context since we don't need it. + if (numAppContexts.get() == 0) return null; + + // Get the context from the security manager + AppContext ecx = getExecutionAppContext(); + + // Not sure we really need to re-check numAppContexts here. + // If all applets have gone away then we could have a + // numAppContexts coming back to 0. So we recheck + // it here because we don't want to trigger the + // creation of a main AppContext in that case. + // This is probably not 100% MT-safe but should reduce + // the window of opportunity in which that issue could + // happen. + if (numAppContexts.get() > 0) { + // Defaults to thread group caching. + // This is probably not required as we only really need + // isolation in a deployed applet environment, in which + // case ecx will not be null when we reach here + // However it helps emulate the deployed environment, + // in tests for instance. + ecx = ecx != null ? ecx : getAppContext(); + } + + // getAppletContext() may be called when initializing the main + // app context - in which case mainAppContext will still be + // null. To work around this issue we simply use + // AppContext.threadGroup.getParent() == null instead, since + // mainAppContext is the only AppContext which should have + // the root TG as its thread group. + // See: JDK-8023258 + final boolean isMainAppContext = ecx == null + || mainAppContext == ecx + || mainAppContext == null && hasRootThreadGroup(ecx); + + return isMainAppContext ? null : ecx; } - public void put(Object context, Object key, Object value) { - ((AppContext)context).put(key, value); - } - public void remove(Object context, Object key) { - ((AppContext)context).remove(key); - } + }); } }
--- a/src/share/classes/sun/awt/FontConfiguration.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/awt/FontConfiguration.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -867,7 +867,7 @@ return descriptors; } - private FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { + protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { String fontName = fontNames[fontIndex]; String styleName = styleNames[styleIndex];
--- a/src/share/classes/sun/misc/JavaAWTAccess.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/misc/JavaAWTAccess.java Thu Apr 03 00:39:02 2014 +0100 @@ -26,14 +26,16 @@ package sun.misc; public interface JavaAWTAccess { - public Object getContext(); - public Object getExecutionContext(); - public Object get(Object context, Object key); - public void put(Object context, Object key, Object value); - public void remove(Object context, Object key); + // Returns the AppContext used for applet logging isolation, or null if + // no isolation is required. + // If there's no applet, or if the caller is a stand alone application, + // or running in the main app context, returns null. + // Otherwise, returns the AppContext of the calling applet. + public Object getAppletContext(); - // convenience methods whose context is the object returned by getContext() + // convenience methods to cache objects in the current thread group's + // AppContext public Object get(Object key); public void put(Object key, Object value); public void remove(Object key);
--- a/src/share/classes/sun/misc/JavaLangAccess.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/misc/JavaLangAccess.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, 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 @@ -35,10 +35,10 @@ ConstantPool getConstantPool(Class klass); /** - * Set the AnnotationType instance corresponding to this class. + * Compare-And-Swap the AnnotationType instance corresponding to this class. * (This method only applies to annotation types.) */ - void setAnnotationType(Class klass, AnnotationType annotationType); + boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType); /** * Get the AnnotationType instance corresponding to this class. @@ -47,6 +47,12 @@ AnnotationType getAnnotationType(Class klass); /** + * Get the array of bytes that is the class-file representation + * of this Class' annotations. + */ + byte[] getRawClassAnnotations(Class<?> klass); + + /** * Returns the elements of an enum class or null if the * Class object does not represent an enum type; * the result is uncloned, cached, and shared by all callers.
--- a/src/share/classes/sun/misc/SharedSecrets.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/misc/SharedSecrets.java Thu Apr 03 00:39:02 2014 +0100 @@ -198,9 +198,6 @@ public static JavaAWTAccess getJavaAWTAccess() { // this may return null in which case calling code needs to // provision for. - if (javaAWTAccess == null || javaAWTAccess.getContext() == null) { - return null; - } return javaAWTAccess; } }
--- a/src/share/classes/sun/net/www/http/ChunkedOutputStream.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/net/www/http/ChunkedOutputStream.java Thu Apr 03 00:39:02 2014 +0100 @@ -125,7 +125,7 @@ completeHeader = getHeader(preferredChunkDataSize); /* start with an initial buffer */ - buf = new byte[preferredChunkDataSize + 32]; + buf = new byte[preferredChunkGrossSize]; reset(); }
--- a/src/share/classes/sun/reflect/annotation/AnnotationParser.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/reflect/annotation/AnnotationParser.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -67,7 +67,35 @@ return Collections.emptyMap(); try { - return parseAnnotations2(rawAnnotations, constPool, container); + return parseAnnotations2(rawAnnotations, constPool, container, null); + } catch(BufferUnderflowException e) { + throw new AnnotationFormatError("Unexpected end of annotations."); + } catch(IllegalArgumentException e) { + // Type mismatch in constant pool + throw new AnnotationFormatError(e); + } + } + + /** + * Like {@link #parseAnnotations(byte[], sun.reflect.ConstantPool, Class)} + * with an additional parameter {@code selectAnnotationClasses} which selects the + * annotation types to parse (other than selected are quickly skipped).<p> + * This method is only used to parse select meta annotations in the construction + * phase of {@link AnnotationType} instances to prevent infinite recursion. + * + * @param selectAnnotationClasses an array of annotation types to select when parsing + */ + @SafeVarargs + static Map<Class<? extends Annotation>, Annotation> parseSelectAnnotations( + byte[] rawAnnotations, + ConstantPool constPool, + Class<?> container, + Class<? extends Annotation> ... selectAnnotationClasses) { + if (rawAnnotations == null) + return Collections.emptyMap(); + + try { + return parseAnnotations2(rawAnnotations, constPool, container, selectAnnotationClasses); } catch(BufferUnderflowException e) { throw new AnnotationFormatError("Unexpected end of annotations."); } catch(IllegalArgumentException e) { @@ -79,22 +107,23 @@ private static Map<Class<? extends Annotation>, Annotation> parseAnnotations2( byte[] rawAnnotations, ConstantPool constPool, - Class<?> container) { + Class<?> container, + Class<? extends Annotation>[] selectAnnotationClasses) { Map<Class<? extends Annotation>, Annotation> result = new LinkedHashMap<Class<? extends Annotation>, Annotation>(); ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); int numAnnotations = buf.getShort() & 0xFFFF; for (int i = 0; i < numAnnotations; i++) { - Annotation a = parseAnnotation(buf, constPool, container, false); + Annotation a = parseAnnotation2(buf, constPool, container, false, selectAnnotationClasses); if (a != null) { Class<? extends Annotation> klass = a.annotationType(); - AnnotationType type = AnnotationType.getInstance(klass); - if (type.retention() == RetentionPolicy.RUNTIME) - if (result.put(klass, a) != null) + if (AnnotationType.getInstance(klass).retention() == RetentionPolicy.RUNTIME && + result.put(klass, a) != null) { throw new AnnotationFormatError( "Duplicate annotation for class: "+klass+": " + a); } } + } return result; } @@ -191,6 +220,15 @@ ConstantPool constPool, Class<?> container, boolean exceptionOnMissingAnnotationClass) { + return parseAnnotation2(buf, constPool, container, exceptionOnMissingAnnotationClass, null); + } + + @SuppressWarnings("unchecked") + private static Annotation parseAnnotation2(ByteBuffer buf, + ConstantPool constPool, + Class<?> container, + boolean exceptionOnMissingAnnotationClass, + Class<? extends Annotation>[] selectAnnotationClasses) { int typeIndex = buf.getShort() & 0xFFFF; Class<? extends Annotation> annotationClass = null; String sig = "[unknown]"; @@ -216,6 +254,10 @@ skipAnnotation(buf, false); return null; } + if (selectAnnotationClasses != null && !contains(selectAnnotationClasses, annotationClass)) { + skipAnnotation(buf, false); + return null; + } AnnotationType type = null; try { type = AnnotationType.getInstance(annotationClass); @@ -791,6 +833,17 @@ skipMemberValue(buf); } + /** + * Searches for given {@code element} in given {@code array} by identity. + * Returns {@code true} if found {@code false} if not. + */ + private static boolean contains(Object[] array, Object element) { + for (Object e : array) + if (e == element) + return true; + return false; + } + /* * This method converts the annotation map returned by the parseAnnotations() * method to an array. It is called by Field.getDeclaredAnnotations(),
--- a/src/share/classes/sun/reflect/annotation/AnnotationType.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/reflect/annotation/AnnotationType.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, 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 @@ -25,6 +25,8 @@ package sun.reflect.annotation; +import sun.misc.JavaLangAccess; + import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; @@ -45,29 +47,28 @@ * types. This matches the return value that must be used for a * dynamic proxy, allowing for a simple isInstance test. */ - private final Map<String, Class<?>> memberTypes = new HashMap<String,Class<?>>(); + private final Map<String, Class<?>> memberTypes; /** * Member name -> default value mapping. */ - private final Map<String, Object> memberDefaults = - new HashMap<String, Object>(); + private final Map<String, Object> memberDefaults; /** - * Member name -> Method object mapping. This (and its assoicated + * Member name -> Method object mapping. This (and its associated * accessor) are used only to generate AnnotationTypeMismatchExceptions. */ - private final Map<String, Method> members = new HashMap<String, Method>(); + private final Map<String, Method> members; /** * The retention policy for this annotation type. */ - private RetentionPolicy retention = RetentionPolicy.RUNTIME;; + private final RetentionPolicy retention; /** * Whether this annotation type is inherited. */ - private boolean inherited = false; + private final boolean inherited; /** * Returns an AnnotationType instance for the specified annotation type. @@ -75,13 +76,20 @@ * @throw IllegalArgumentException if the specified class object for * does not represent a valid annotation type */ - public static synchronized AnnotationType getInstance( + public static AnnotationType getInstance( Class<? extends Annotation> annotationClass) { - AnnotationType result = sun.misc.SharedSecrets.getJavaLangAccess(). - getAnnotationType(annotationClass); - if (result == null) - result = new AnnotationType((Class<? extends Annotation>) annotationClass); + JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess(); + AnnotationType result = jla.getAnnotationType(annotationClass); // volatile read + if (result == null) { + result = new AnnotationType(annotationClass); + // try to CAS the AnnotationType: null -> result + if (!jla.casAnnotationType(annotationClass, null, result)) { + // somebody was quicker -> read it's result + result = jla.getAnnotationType(annotationClass); + assert result != null; + } + } return result; } @@ -105,6 +113,9 @@ } }); + memberTypes = new HashMap<String,Class<?>>(methods.length+1, 1.0f); + memberDefaults = new HashMap<String, Object>(0); + members = new HashMap<String, Method>(methods.length+1, 1.0f); for (Method method : methods) { if (method.getParameterTypes().length != 0) @@ -117,20 +128,27 @@ Object defaultValue = method.getDefaultValue(); if (defaultValue != null) memberDefaults.put(name, defaultValue); - - members.put(name, method); } - sun.misc.SharedSecrets.getJavaLangAccess(). - setAnnotationType(annotationClass, this); - // Initialize retention, & inherited fields. Special treatment // of the corresponding annotation types breaks infinite recursion. if (annotationClass != Retention.class && annotationClass != Inherited.class) { - Retention ret = annotationClass.getAnnotation(Retention.class); + JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess(); + Map<Class<? extends Annotation>, Annotation> metaAnnotations = + AnnotationParser.parseSelectAnnotations( + jla.getRawClassAnnotations(annotationClass), + jla.getConstantPool(annotationClass), + annotationClass, + Retention.class, Inherited.class + ); + Retention ret = (Retention) metaAnnotations.get(Retention.class); retention = (ret == null ? RetentionPolicy.CLASS : ret.value()); - inherited = annotationClass.isAnnotationPresent(Inherited.class); + inherited = metaAnnotations.containsKey(Inherited.class); + } + else { + retention = RetentionPolicy.RUNTIME; + inherited = false; } } @@ -205,11 +223,10 @@ * For debugging. */ public String toString() { - StringBuffer s = new StringBuffer("Annotation Type:" + "\n"); - s.append(" Member types: " + memberTypes + "\n"); - s.append(" Member defaults: " + memberDefaults + "\n"); - s.append(" Retention policy: " + retention + "\n"); - s.append(" Inherited: " + inherited); - return s.toString(); + return "Annotation Type:\n" + + " Member types: " + memberTypes + "\n" + + " Member defaults: " + memberDefaults + "\n" + + " Retention policy: " + retention + "\n" + + " Inherited: " + inherited; } }
--- a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Thu Apr 03 00:39:02 2014 +0100 @@ -375,20 +375,22 @@ boolean add = false; for (AccessDescription ad : adList) { CertStore cs = URICertStore.getInstance(ad); - try { - if (certs.addAll((Collection<X509Certificate>) - cs.getCertificates(caSelector))) { - add = true; - if (!searchAllCertStores) { - return true; + if (cs != null) { + try { + if (certs.addAll((Collection<X509Certificate>) + cs.getCertificates(caSelector))) { + add = true; + if (!searchAllCertStores) { + return true; + } } + } catch (CertStoreException cse) { + if (debug != null) { + debug.println("exception getting certs from CertStore:"); + cse.printStackTrace(); + } + continue; } - } catch (CertStoreException cse) { - if (debug != null) { - debug.println("exception getting certs from CertStore:"); - cse.printStackTrace(); - } - continue; } } return add;
--- a/src/share/classes/sun/tools/jconsole/Messages.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/Messages.java Thu Apr 03 00:39:02 2014 +0100 @@ -36,7 +36,7 @@ Resources.initializeMessages(Messages.class, BUNDLE_NAME); } // TODO: - // The names of some of the constants below looks strange. + // The names of some of the constants below look strange. // That's because they were generated programmatically // from the messages. They should be cleaned up, // ___ should be removed etc. @@ -265,6 +265,7 @@ public static String SUMMARY_TAB_TAB_NAME; public static String SUMMARY_TAB_VM_VERSION; public static String THREADS; + public static String THREAD_TAB_INFO_LABEL_FORMAT; public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME; public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME; public static String THRESHOLD; @@ -304,9 +305,9 @@ public static String WRITABLE; public static String CONNECTION_FAILED1; public static String CONNECTION_FAILED2; + public static String CONNECTION_FAILED_SSL1; + public static String CONNECTION_FAILED_SSL2; public static String CONNECTION_LOST1; - public static String CONNECTION_INSECURE1; - public static String CONNECTION_INSECURE2; public static String CONNECTING_TO1; public static String CONNECTING_TO2; public static String DEADLOCK_TAB;
--- a/src/share/classes/sun/tools/jconsole/SummaryTab.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/SummaryTab.java Thu Apr 03 00:39:02 2014 +0100 @@ -213,8 +213,8 @@ String[] strings2 = formatKByteStrings(u.getCommitted()); append(Messages.COMMITTED_MEMORY, strings2[0]); append(Messages.SUMMARY_TAB_PENDING_FINALIZATION_LABEL, - Messages.SUMMARY_TAB_PENDING_FINALIZATION_VALUE, - memoryBean.getObjectPendingFinalizationCount()); + Resources.format(Messages.SUMMARY_TAB_PENDING_FINALIZATION_VALUE, + memoryBean.getObjectPendingFinalizationCount())); append(endTable); append(newTable);
--- a/src/share/classes/sun/tools/jconsole/ThreadTab.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/ThreadTab.java Thu Apr 03 00:39:02 2014 +0100 @@ -66,9 +66,6 @@ private static final Border thinEmptyBorder = new EmptyBorder(2, 2, 2, 2); - private static final String infoLabelFormat = "ThreadTab.infoLabelFormat"; - - /* Hierarchy of panels and layouts for this tab: @@ -690,7 +687,7 @@ private void updateThreadsInfo(long tlCount, long tpCount, long ttCount, long timeStamp) { getPlotter().addValues(timeStamp, tlCount); - getInfoLabel().setText(Resources.format(infoLabelFormat, tlCount, tpCount, ttCount)); + getInfoLabel().setText(Resources.format(Messages.THREAD_TAB_INFO_LABEL_FORMAT, tlCount, tpCount, ttCount)); } } }
--- a/src/share/classes/sun/tools/jconsole/VMPanel.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/VMPanel.java Thu Apr 03 00:39:02 2014 +0100 @@ -469,8 +469,8 @@ msgExplanation = Resources.format(Messages.CONNECTING_TO2, getConnectionName()); buttonStr = Messages.RECONNECT; } else if (shouldUseSSL) { - msgTitle = Messages.CONNECTION_INSECURE1; - msgExplanation = Resources.format(Messages.CONNECTION_INSECURE2, getConnectionName()); + msgTitle = Messages.CONNECTION_FAILED_SSL1; + msgExplanation = Resources.format(Messages.CONNECTION_FAILED_SSL2, getConnectionName()); buttonStr = Messages.INSECURE; } else { msgTitle = Messages.CONNECTION_FAILED1;
--- a/src/share/classes/sun/tools/jconsole/resources/messages.properties Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/resources/messages.properties Thu Apr 03 00:39:02 2014 +0100 @@ -223,6 +223,7 @@ SUMMARY_TAB_TAB_NAME=VM Summary SUMMARY_TAB_VM_VERSION={0} version {1} THREADS=Threads +THREAD_TAB_INFO_LABEL_FORMAT=<html>Live: {0} Peak: {1} Total: {2}</html> THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=Thread Information THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=Chart for number of threads. THRESHOLD=Threshold @@ -244,7 +245,7 @@ UNREGISTER=Unregister UPTIME=Uptime USAGE_THRESHOLD=Usage Threshold -REMOTE_TF_USAGE=<b>Usage</b>: <hostname>:<port> OR service:jmx:<protocol>:<sap> +REMOTE_TF_USAGE=<b>Usage</b>: &<hostname&>:&<port&> OR service:jmx:&<protocol&>:&<sap&> USED=Used USERNAME_COLON_=&Username: USERNAME_ACCESSIBLE_NAME=User Name @@ -262,9 +263,9 @@ WRITABLE=Writable CONNECTION_FAILED1=Connection Failed: Retry? CONNECTION_FAILED2=The connection to {0} did not succeed.<br>Would you like to try again? +CONNECTION_FAILED_SSL1=Secure connection failed. Retry insecurely? +CONNECTION_FAILED_SSL2=The connection to {0} could not be made using SSL.<br>Would you like to try without SSL?<br>(Username and password will be sent in plain text.) CONNECTION_LOST1=Connection Lost: Reconnect? -CONNECTION_INSECURE1=ConnectionFailedSSL1 -CONNECTION_INSECURE2=ConnectionFailedSSL2 CONNECTING_TO1=Connecting to {0} CONNECTING_TO2=You are currently being connected to {0}.<br>This will take a few moments. DEADLOCK_TAB=Deadlock
--- a/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties Thu Apr 03 00:39:02 2014 +0100 @@ -222,6 +222,7 @@ SUMMARY_TAB_TAB_NAME=VM\u30B5\u30DE\u30EA\u30FC SUMMARY_TAB_VM_VERSION={0}\u30D0\u30FC\u30B8\u30E7\u30F3{1} THREADS=\u30B9\u30EC\u30C3\u30C9 +THREAD_TAB_INFO_LABEL_FORMAT=<html>\u5B9F\u884C\u4E2D: {0} \u30D4\u30FC\u30AF: {1} \u5408\u8A08: {2}</html> THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=\u30B9\u30EC\u30C3\u30C9\u60C5\u5831 THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=\u30B9\u30EC\u30C3\u30C9\u6570\u306E\u30C1\u30E3\u30FC\u30C8\u3002 THRESHOLD=\u3057\u304D\u3044\u5024 @@ -243,7 +244,7 @@ UNREGISTER=\u767B\u9332\u89E3\u9664 UPTIME=\u7A3C\u50CD\u6642\u9593 USAGE_THRESHOLD=\u4F7F\u7528\u3057\u304D\u3044\u5024 -REMOTE_TF_USAGE=<b>\u4F7F\u7528\u65B9\u6CD5</b>: <hostname>:<port>\u307E\u305F\u306Fservice:jmx:<protocol>:<sap> +REMOTE_TF_USAGE=<b>\u4F7F\u7528\u65B9\u6CD5</b>: &<hostname&>:&<port&>\u307E\u305F\u306Fservice:jmx:&<protocol&>:&<sap&> USED=\u4F7F\u7528\u6E08 USERNAME_COLON_=\u30E6\u30FC\u30B6\u30FC\u540D(&U): USERNAME_ACCESSIBLE_NAME=\u30E6\u30FC\u30B6\u30FC\u540D
--- a/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/tools/jconsole/resources/messages_zh_CN.properties Thu Apr 03 00:39:02 2014 +0100 @@ -222,6 +222,7 @@ SUMMARY_TAB_TAB_NAME=VM \u6982\u8981 SUMMARY_TAB_VM_VERSION={0}\u7248\u672C {1} THREADS=\u7EBF\u7A0B +THREAD_TAB_INFO_LABEL_FORMAT=<html>\u6D3B\u52A8: {0} \u5CF0\u503C: {1} \u603B\u8BA1: {2}</html> THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=\u7EBF\u7A0B\u4FE1\u606F THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=\u8868\u793A\u7EBF\u7A0B\u6570\u7684\u56FE\u8868\u3002 THRESHOLD=\u9608\u503C @@ -243,7 +244,7 @@ UNREGISTER=\u6CE8\u9500 UPTIME=\u8FD0\u884C\u65F6\u95F4 USAGE_THRESHOLD=\u7528\u6CD5\u9608\u503C -REMOTE_TF_USAGE=<b>\u7528\u6CD5</b>: <hostname>:<port> \u6216 service:jmx:<protocol>:<sap> +REMOTE_TF_USAGE=<b>\u7528\u6CD5</b>: &<hostname&>:&<port&> \u6216 service:jmx:&<protocol&>:&<sap&> USED=\u5DF2\u7528 USERNAME_COLON_=\u7528\u6237\u540D(&U): USERNAME_ACCESSIBLE_NAME=\u7528\u6237\u540D
--- a/src/share/classes/sun/util/resources/TimeZoneNames.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Alma-Ata Time", "ALMT", "Alma-Ata Summer Time", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Anadyr Time", "ANAT", "Anadyr Summer Time", "ANAST"}}, {"Asia/Aqtau", new String[] {"Aqtau Time", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_de.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_de.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Alma Ata Zeit", "ALMT", "Alma-Ata Sommerzeit", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Anadyr Zeit", "ANAT", "Anadyr Sommerzeit", "ANAST"}}, {"Asia/Aqtau", new String[] {"Aqtau Zeit", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_es.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_es.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Hora de Alma-Ata", "ALMT", "Hora de verano de Alma-Ata", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Hora de Anadyr", "ANAT", "Hora de verano de Anadyr", "ANAST"}}, {"Asia/Aqtau", new String[] {"Hora de Aqtau", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_fr.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_fr.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Heure d'Alma-Ata", "ALMT", "Heure d'\u00e9t\u00e9 d'Alma-Ata", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Heure d'Anadyr", "ANAT", "Heure d'\u00e9t\u00e9 d'Anadyr", "ANAST"}}, {"Asia/Aqtau", new String[] {"Heure d'Aqtau", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_it.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_it.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Ora di Alma-Ata", "ALMT", "Ora estiva di Alma-Ata", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Ora di Anadyr", "ANAT", "Ora estiva di Anadyr", "ANAST"}}, {"Asia/Aqtau", new String[] {"Ora di Aqtau", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ja.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_ja.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"\u30a2\u30eb\u30de\u30a2\u30bf\u6642\u9593", "ALMT", "\u30a2\u30eb\u30de\u30a2\u30bf\u590f\u6642\u9593", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"\u30a2\u30ca\u30c9\u30a5\u30a4\u30ea\u6642\u9593", "ANAT", "\u30a2\u30ca\u30c9\u30a5\u30a4\u30ea\u590f\u6642\u9593", "ANAST"}}, {"Asia/Aqtau", new String[] {"\u30a2\u30af\u30bf\u30a6\u6642\u9593", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_ko.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_ko.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"\uc54c\ub9c8\uc544\ud0c0 \uc2dc\uac04", "ALMT", "\uc54c\ub9c8\uc544\ud0c0 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"\uc544\ub098\ub514\ub974 \uc2dc\uac04", "ANAT", "\uc544\ub098\ub514\ub974 \uc77c\uad11\uc808\uc57d\uc2dc\uac04", "ANAST"}}, {"Asia/Aqtau", new String[] {"\uc545\ud0c0\uc6b0 \uc2dc\uac04", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_pt_BR.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Fuso hor\u00e1rio de Alma-Ata", "ALMT", "Fuso hor\u00e1rio de ver\u00e3o de Alma-Ata", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Fuso hor\u00e1rio de Anadyr", "ANAT", "Fuso hor\u00e1rio de ver\u00e3o de Anadyr", "ANAST"}}, {"Asia/Aqtau", new String[] {"Fuso hor\u00e1rio de Aqtau", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_sv.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_sv.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Alma-Ata, normaltid", "ALMT", "Alma-Ata, sommartid", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"Anadyr, normaltid", "ANAT", "Anadyr, sommartid", "ANAST"}}, {"Asia/Aqtau", new String[] {"Aqtau, normaltid", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_CN.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Alma-Ata \u65f6\u95f4", "ALMT", "Alma-Ata \u590f\u4ee4\u65f6", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"\u963f\u90a3\u5e95\u6cb3\u65f6\u95f4", "ANAT", "\u963f\u90a3\u5e95\u6cb3\u590f\u4ee4\u65f6", "ANAST"}}, {"Asia/Aqtau", new String[] {"Aqtau \u65f6\u95f4", "AQTT",
--- a/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/share/classes/sun/util/resources/TimeZoneNames_zh_TW.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, 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 @@ -483,7 +483,7 @@ {"Asia/Aden", ARAST}, {"Asia/Almaty", new String[] {"Alma-Ata \u6642\u9593", "ALMT", "Alma-Ata \u590f\u4ee4\u6642\u9593", "ALMST"}}, - {"Asia/Amman", ARAST}, + {"Asia/Amman", EET}, {"Asia/Anadyr", new String[] {"\u963f\u90a3\u5e95\u6cb3\u6642\u9593", "ANAT", "\u963f\u90a3\u5e95\u6cb3\u590f\u4ee4\u6642\u9593", "ANAST"}}, {"Asia/Aqtau", new String[] {"Aqtau \u6642\u9593", "AQTT",
--- a/src/solaris/classes/sun/font/FcFontConfiguration.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/classes/sun/font/FcFontConfiguration.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -33,6 +33,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.HashMap; import java.util.HashSet; @@ -173,8 +174,16 @@ } @Override - public FontDescriptor[] getFontDescriptors(String fontName, int style) { - return new FontDescriptor[0]; + protected FontDescriptor[] buildFontDescriptors(int fontIndex, int styleIndex) { + CompositeFontDescriptor[] cfi = get2DCompositeFontInfo(); + int idx = fontIndex * NUM_STYLES + styleIndex; + String[] componentFaceNames = cfi[idx].getComponentFaceNames(); + FontDescriptor[] ret = new FontDescriptor[componentFaceNames.length]; + for (int i = 0; i < componentFaceNames.length; i++) { + ret[i] = new FontDescriptor(componentFaceNames[i], StandardCharsets.UTF_8.newEncoder(), new int[0]); + } + + return ret; } @Override @@ -250,10 +259,12 @@ } String[] fileNames = new String[numFonts]; + String[] faceNames = new String[numFonts]; int index; for (index = 0; index < fcFonts.length; index++) { fileNames[index] = fcFonts[index].fontFile; + faceNames[index] = fcFonts[index].familyName; } if (installedFallbackFontFiles != null) { @@ -266,7 +277,7 @@ = new CompositeFontDescriptor( faceName, 1, - null, + faceNames, fileNames, null, null); }
--- a/src/solaris/native/java/lang/java_props_macosx.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/lang/java_props_macosx.c Thu Apr 03 00:39:02 2014 +0100 @@ -31,6 +31,7 @@ #include <Security/AuthSession.h> #include <CoreFoundation/CoreFoundation.h> #include <SystemConfiguration/SystemConfiguration.h> +#include <Foundation/Foundation.h> #include "java_props_macosx.h" @@ -262,9 +263,20 @@ return c_exception; } +/* + * Method for fetching the user.home path and storing it in the property list. + * For signed .apps running in the Mac App Sandbox, user.home is set to the + * app's sandbox container. + */ +void setUserHome(java_props_t *sprops) { + if (sprops == NULL) { return; } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + sprops->user_home = createUTF8CString((CFStringRef)NSHomeDirectory()); + [pool drain]; +} /* - * Method for fetching proxy info and storing it in the propery list. + * Method for fetching proxy info and storing it in the property list. */ void setProxyProperties(java_props_t *sProps) { if (sProps == NULL) return;
--- a/src/solaris/native/java/lang/java_props_macosx.h Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/lang/java_props_macosx.h Thu Apr 03 00:39:02 2014 +0100 @@ -27,6 +27,7 @@ char *setupMacOSXLocale(int cat); void setOSNameAndVersion(java_props_t *sprops); +void setUserHome(java_props_t *sprops); void setProxyProperties(java_props_t *sProps); enum PreferredToolkit_enum {
--- a/src/solaris/native/java/lang/java_props_md.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/lang/java_props_md.c Thu Apr 03 00:39:02 2014 +0100 @@ -325,6 +325,25 @@ *std_encoding = "Big5-HKSCS-2001"; } #endif +#ifdef MACOSX + /* + * For the case on MacOS X where encoding is set to US-ASCII, but we + * don't have any encoding hints from LANG/LC_ALL/LC_CTYPE, use UTF-8 + * instead. + * + * The contents of ASCII files will still be read and displayed + * correctly, but so will files containing UTF-8 characters beyond the + * standard ASCII range. + * + * Specifically, this allows apps launched by double-clicking a .jar + * file to correctly read UTF-8 files using the default encoding (see + * 8011194). + */ + if (strcmp(p,"US-ASCII") == 0 && getenv("LANG") == NULL && + getenv("LC_ALL") == NULL && getenv("LC_CTYPE") == NULL) { + *std_encoding = "UTF-8"; + } +#endif } @@ -532,7 +551,14 @@ { struct passwd *pwent = getpwuid(getuid()); sprops.user_name = pwent ? strdup(pwent->pw_name) : "?"; - sprops.user_home = pwent ? strdup(pwent->pw_dir) : "?"; +#ifdef MACOSX + setUserHome(&sprops); +#else + sprops.user_home = pwent ? strdup(pwent->pw_dir) : NULL; +#endif + if (sprops.user_home == NULL) { + sprops.user_home = "?"; + } } /* User TIMEZONE */
--- a/src/solaris/native/java/net/PlainDatagramSocketImpl.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/net/PlainDatagramSocketImpl.c Thu Apr 03 00:39:02 2014 +0100 @@ -574,6 +574,8 @@ } else if (ret == JVM_IO_ERR) { if (errno == EBADF) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); + } else if (errno == ENOMEM) { + JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed"); } else { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Peek failed"); } @@ -674,15 +676,18 @@ "Receive timed out"); return -1; } else if (ret == JVM_IO_ERR) { + if (errno == ENOMEM) { + JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed"); #ifdef __linux__ - if (errno == EBADF) { + } else if (errno == EBADF) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); } else { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed"); +#else + } else { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); +#endif } -#else - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); -#endif return -1; } else if (ret == JVM_IO_INTR) { JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", @@ -910,15 +915,18 @@ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "Receive timed out"); } else if (ret == JVM_IO_ERR) { + if (errno == ENOMEM) { + JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed"); #ifdef __linux__ - if (errno == EBADF) { + } else if (errno == EBADF) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); } else { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed"); +#else + } else { + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); +#endif } -#else - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); -#endif } else if (ret == JVM_IO_INTR) { JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", "operation interrupted");
--- a/src/solaris/native/java/net/PlainSocketImpl.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/net/PlainSocketImpl.c Thu Apr 03 00:39:02 2014 +0100 @@ -708,7 +708,6 @@ } else { ret = NET_Timeout(fd, timeout); } - if (ret == 0) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "Accept timed out"); @@ -716,6 +715,8 @@ } else if (ret == JVM_IO_ERR) { if (errno == EBADF) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); + } else if (errno == ENOMEM) { + JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed"); } else { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed"); }
--- a/src/solaris/native/java/net/SocketInputStream.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/net/SocketInputStream.c Thu Apr 03 00:39:02 2014 +0100 @@ -108,6 +108,8 @@ } else if (nread == JVM_IO_ERR) { if (errno == EBADF) { JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed"); + } else if (errno == ENOMEM) { + JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed"); } else { NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "select/poll failed");
--- a/src/solaris/native/java/net/bsd_close.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/net/bsd_close.c Thu Apr 03 00:39:02 2014 +0100 @@ -25,6 +25,7 @@ #include <stdio.h> #include <stdlib.h> +#include <sys/param.h> #include <signal.h> #include <pthread.h> #include <sys/types.h> @@ -35,7 +36,6 @@ #include <sys/uio.h> #include <unistd.h> #include <errno.h> - #include <sys/poll.h> /* @@ -347,6 +347,10 @@ int NET_Timeout(int s, long timeout) { long prevtime = 0, newtime; struct timeval t, *tp = &t; + fd_set fds; + fd_set* fdsp = NULL; + int allocated = 0; + threadEntry_t self; fdEntry_t *fdEntry = getFdEntry(s); /* @@ -376,20 +380,29 @@ t.tv_usec = 0; } + if (s < FD_SETSIZE) { + fdsp = &fds; + FD_ZERO(fdsp); + } else { + int length = (howmany(s+1, NFDBITS)) * sizeof(int); + fdsp = (fd_set *) calloc(1, length); + if (fdsp == NULL) { + return -1; // errno will be set to ENOMEM + } + allocated = 1; + } + FD_SET(s, fdsp); + for(;;) { - fd_set rfds; int rv; - threadEntry_t self; /* * call select on the fd. If interrupted by our wakeup signal * errno will be set to EBADF. */ - FD_ZERO(&rfds); - FD_SET(s, &rfds); startOp(fdEntry, &self); - rv = select(s+1, &rfds, 0, 0, tp); + rv = select(s+1, fdsp, 0, 0, tp); endOp(fdEntry, &self); /* @@ -403,6 +416,8 @@ newtime = now.tv_sec * 1000 + now.tv_usec / 1000; timeout -= newtime - prevtime; if (timeout <= 0) { + if (allocated != 0) + free(fdsp); return 0; } prevtime = newtime; @@ -410,6 +425,8 @@ t.tv_usec = (timeout % 1000) * 1000; } } else { + if (allocated != 0) + free(fdsp); return rv; }
--- a/src/solaris/native/java/net/linux_close.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/java/net/linux_close.c Thu Apr 03 00:39:02 2014 +0100 @@ -50,7 +50,6 @@ #include <sys/uio.h> #include <unistd.h> #include <errno.h> - #include <sys/poll.h> /*
--- a/src/solaris/native/sun/awt/awt_LoadLibrary.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/solaris/native/sun/awt/awt_LoadLibrary.c Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -154,7 +154,7 @@ propname = NULL; #else /* Get address of this library and the directory containing it. */ - dladdr((void *)JNI_OnLoad, &dlinfo); + dladdr((void *)AWT_OnLoad, &dlinfo); realpath((char *)dlinfo.dli_fname, buf); len = strlen(buf); p = strrchr(buf, '/');
--- a/src/windows/classes/java/net/DualStackPlainSocketImpl.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/classes/java/net/DualStackPlainSocketImpl.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -162,8 +162,9 @@ if (!fd.valid()) return; - close0(fdAccess.get(fd)); + final int nativefd = fdAccess.get(fd); fdAccess.set(fd, -1); + close0(nativefd); } void socketShutdown(int howto) throws IOException {
--- a/src/windows/classes/sun/nio/fs/WindowsConstants.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/classes/sun/nio/fs/WindowsConstants.java Thu Apr 03 00:39:02 2014 +0100 @@ -100,6 +100,7 @@ public static final int ERROR_INVALID_LEVEL = 124; public static final int ERROR_DIR_NOT_EMPTY = 145; public static final int ERROR_ALREADY_EXISTS = 183; + public static final int ERROR_MORE_DATA = 234; public static final int ERROR_DIRECTORY = 267; public static final int ERROR_NOTIFY_ENUM_DIR = 1022; public static final int ERROR_NONE_MAPPED = 1332;
--- a/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Thu Apr 03 00:39:02 2014 +0100 @@ -973,19 +973,19 @@ * HANDLE CreateIoCompletionPort ( * HANDLE FileHandle, * HANDLE ExistingCompletionPort, - * DWORD CompletionKey, + * ULONG_PTR CompletionKey, * DWORD NumberOfConcurrentThreads * ) */ static native long CreateIoCompletionPort(long fileHandle, long existingPort, - int completionKey) throws WindowsException; + long completionKey) throws WindowsException; /** * GetQueuedCompletionStatus( * HANDLE CompletionPort, * LPDWORD lpNumberOfBytesTransferred, - * LPDWORD lpCompletionKey, + * PULONG_PTR lpCompletionKey, * LPOVERLAPPED *lpOverlapped, * DWORD dwMilliseconds */ @@ -999,12 +999,12 @@ static class CompletionStatus { private int error; private int bytesTransferred; - private int completionKey; + private long completionKey; private CompletionStatus() { } int error() { return error; } int bytesTransferred() { return bytesTransferred; } - int completionKey() { return completionKey; } + long completionKey() { return completionKey; } } private static native void GetQueuedCompletionStatus0(long completionPort, CompletionStatus status) throws WindowsException; @@ -1013,12 +1013,12 @@ * PostQueuedCompletionStatus( * HANDLE CompletionPort, * DWORD dwNumberOfBytesTransferred, - * DWORD dwCompletionKey, + * ULONG_PTR dwCompletionKey, * LPOVERLAPPED lpOverlapped * ) */ static native void PostQueuedCompletionStatus(long completionPort, - int completionKey) throws WindowsException; + long completionKey) throws WindowsException; /** * ReadDirectoryChangesW(
--- a/src/windows/classes/sun/nio/fs/WindowsWatchService.java Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/classes/sun/nio/fs/WindowsWatchService.java Thu Apr 03 00:39:02 2014 +0100 @@ -41,6 +41,7 @@ class WindowsWatchService extends AbstractWatchService { + private final static int WAKEUP_COMPLETION_KEY = 0; private final Unsafe unsafe = Unsafe.getUnsafe(); // background thread to service I/O completion port @@ -83,7 +84,7 @@ */ private class WindowsWatchKey extends AbstractWatchKey { // file key (used to detect existing registrations) - private FileKey fileKey; + private final FileKey fileKey; // handle to directory private volatile long handle = INVALID_HANDLE_VALUE; @@ -223,8 +224,7 @@ FileKey other = (FileKey)obj; if (this.volSerialNumber != other.volSerialNumber) return false; if (this.fileIndexHigh != other.fileIndexHigh) return false; - if (this.fileIndexLow != other.fileIndexLow) return false; - return true; + return this.fileIndexLow == other.fileIndexLow; } } @@ -268,6 +268,7 @@ private static final short OFFSETOF_FILENAME = 12; // size of per-directory buffer for events (FIXME - make this configurable) + // Need to be less than 4*16384 = 65536. DWORD align. private static final int CHANGES_BUFFER_SIZE = 16 * 1024; private final WindowsFileSystem fs; @@ -275,27 +276,28 @@ private final long port; // maps completion key to WatchKey - private final Map<Integer,WindowsWatchKey> int2key; + private final Map<Integer,WindowsWatchKey> ck2key; // maps file key to WatchKey private final Map<FileKey,WindowsWatchKey> fk2key; // unique completion key for each directory + // native completion key capacity is 64 bits on Win64. private int lastCompletionKey; Poller(WindowsFileSystem fs, WindowsWatchService watcher, long port) { this.fs = fs; this.watcher = watcher; this.port = port; - this.int2key = new HashMap<Integer,WindowsWatchKey>(); - this.fk2key = new HashMap<FileKey,WindowsWatchKey>(); + this.ck2key = new HashMap<>(); + this.fk2key = new HashMap<>(); this.lastCompletionKey = 0; } @Override void wakeup() throws IOException { try { - PostQueuedCompletionStatus(port, 0); + PostQueuedCompletionStatus(port, WAKEUP_COMPLETION_KEY); } catch (WindowsException x) { throw new IOException(x.getMessage()); } @@ -322,7 +324,6 @@ for (WatchEvent.Modifier modifier: modifiers) { if (modifier == ExtendedWatchEventModifier.FILE_TREE) { watchSubtree = true; - continue; } else { if (modifier == null) return new NullPointerException(); @@ -333,7 +334,7 @@ } // open directory - long handle = -1L; + long handle; try { handle = CreateFile(dir.getPathForWin32Calls(), FILE_LIST_DIRECTORY, @@ -347,7 +348,7 @@ boolean registered = false; try { // read attributes and check file is a directory - WindowsFileAttributes attrs = null; + WindowsFileAttributes attrs; try { attrs = WindowsFileAttributes.readAttributes(handle); } catch (WindowsException x) { @@ -370,9 +371,10 @@ return existing; } - // unique completion key (skip 0) + // Can overflow the int type capacity. + // Skip WAKEUP_COMPLETION_KEY value. int completionKey = ++lastCompletionKey; - if (completionKey == 0) + if (completionKey == WAKEUP_COMPLETION_KEY) completionKey = ++lastCompletionKey; // associate handle with completion port @@ -418,13 +420,13 @@ // 1. remove mapping from old completion key to existing watch key // 2. release existing key's resources (handle/buffer) // 3. re-initialize key with new handle/buffer - int2key.remove(existing.completionKey()); + ck2key.remove(existing.completionKey()); existing.releaseResources(); watchKey = existing.init(handle, events, watchSubtree, buffer, countAddress, overlappedAddress, completionKey); } // map completion map to watch key - int2key.put(completionKey, watchKey); + ck2key.put(completionKey, watchKey); registered = true; return watchKey; @@ -440,7 +442,7 @@ WindowsWatchKey key = (WindowsWatchKey)obj; if (key.isValid()) { fk2key.remove(key.fileKey()); - int2key.remove(key.completionKey()); + ck2key.remove(key.completionKey()); key.invalidate(); } } @@ -449,11 +451,11 @@ @Override void implCloseAll() { // cancel all keys - for (Map.Entry<Integer,WindowsWatchKey> entry: int2key.entrySet()) { + for (Map.Entry<Integer, WindowsWatchKey> entry: ck2key.entrySet()) { entry.getValue().invalidate(); } fk2key.clear(); - int2key.clear(); + ck2key.clear(); // close I/O completion port CloseHandle(port); @@ -517,7 +519,7 @@ @Override public void run() { for (;;) { - CompletionStatus info = null; + CompletionStatus info; try { info = GetQueuedCompletionStatus(port); } catch (WindowsException x) { @@ -527,7 +529,7 @@ } // wakeup - if (info.completionKey() == 0) { + if (info.completionKey() == WAKEUP_COMPLETION_KEY) { boolean shutdown = processRequests(); if (shutdown) { return; @@ -536,7 +538,7 @@ } // map completionKey to get WatchKey - WindowsWatchKey key = int2key.get(info.completionKey()); + WindowsWatchKey key = ck2key.get((int)info.completionKey()); if (key == null) { // We get here when a registration is changed. In that case // the directory is closed which causes an event with the @@ -544,38 +546,44 @@ continue; } - // ReadDirectoryChangesW failed - if (info.error() != 0) { + boolean criticalError = false; + int errorCode = info.error(); + int messageSize = info.bytesTransferred(); + if (errorCode == ERROR_NOTIFY_ENUM_DIR) { // buffer overflow - if (info.error() == ERROR_NOTIFY_ENUM_DIR) { - key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); - } else { - // other error so cancel key - implCancelKey(key); - key.signal(); - } - continue; - } + key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); + } else if (errorCode != 0 && errorCode != ERROR_MORE_DATA) { + // ReadDirectoryChangesW failed + criticalError = true; + } else { + // ERROR_MORE_DATA is a warning about incomplite + // data transfer over TCP/UDP stack. For the case + // [messageSize] is zero in the most of cases. - // process the events - if (info.bytesTransferred() > 0) { - processEvents(key, info.bytesTransferred()); - } else { - // insufficient buffer size - key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); - } + if (messageSize > 0) { + // process non-empty events. + processEvents(key, messageSize); + } else if (errorCode == 0) { + // insufficient buffer size + // not described, but can happen. + key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); + } - // start read for next batch of changes - try { - ReadDirectoryChangesW(key.handle(), - key.buffer().address(), - CHANGES_BUFFER_SIZE, - key.watchSubtree(), - ALL_FILE_NOTIFY_EVENTS, - key.countAddress(), - key.overlappedAddress()); - } catch (WindowsException x) { - // no choice but to cancel key + // start read for next batch of changes + try { + ReadDirectoryChangesW(key.handle(), + key.buffer().address(), + CHANGES_BUFFER_SIZE, + key.watchSubtree(), + ALL_FILE_NOTIFY_EVENTS, + key.countAddress(), + key.overlappedAddress()); + } catch (WindowsException x) { + // no choice but to cancel key + criticalError = true; + } + } + if (criticalError) { implCancelKey(key); key.signal(); }
--- a/src/windows/native/java/lang/java_props_md.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/native/java/lang/java_props_md.c Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -448,6 +448,7 @@ case 0: sprops.os_name = "Windows Vista"; break; case 1: sprops.os_name = "Windows 7"; break; case 2: sprops.os_name = "Windows 8"; break; + case 3: sprops.os_name = "Windows 8.1"; break; default: sprops.os_name = "Windows NT (unknown)"; } } else { @@ -455,6 +456,7 @@ case 0: sprops.os_name = "Windows Server 2008"; break; case 1: sprops.os_name = "Windows Server 2008 R2"; break; case 2: sprops.os_name = "Windows Server 2012"; break; + case 3: sprops.os_name = "Windows Server 2012 R2"; break; default: sprops.os_name = "Windows NT (unknown)"; } }
--- a/src/windows/native/java/net/NetworkInterface_winXP.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/native/java/net/NetworkInterface_winXP.c Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -145,8 +145,12 @@ ptr = adapterInfo; ret = NULL; while (ptr != NULL) { - // IPv4 interface - if (ptr->Ipv6IfIndex == index) { + // in theory the IPv4 index and the IPv6 index can be the same + // where an interface is enabled for v4 and v6 + // IfIndex == 0 IPv4 not available on this interface + // Ipv6IfIndex == 0 IPv6 not available on this interface + if (((ptr->IfIndex != 0)&&(ptr->IfIndex == index)) || + ((ptr->Ipv6IfIndex !=0) && (ptr->Ipv6IfIndex == index))) { ret = (IP_ADAPTER_ADDRESSES *) malloc(sizeof(IP_ADAPTER_ADDRESSES)); memcpy(ret, ptr, sizeof(IP_ADAPTER_ADDRESSES)); } @@ -241,7 +245,7 @@ * set the index to the IPv6 index and add the * IPv6 addresses */ - nif->index = ptr->Ipv6IfIndex; + nif->ipv6Index = ptr->Ipv6IfIndex; c = getAddrsFromAdapter(ptr, &nif->addrs); nif->naddrs += c; break; @@ -286,6 +290,9 @@ strcpy (nif->name, newname); wcscpy ((PWCHAR)nif->displayName, ptr->FriendlyName); nif->dNameIsUnicode = TRUE; + + // the java.net.NetworkInterface abstraction only has index + // so the Ipv6IfIndex needs to map onto index nif->index = ptr->Ipv6IfIndex; nif->ipv6Index = ptr->Ipv6IfIndex; nif->hasIpv6Address = TRUE; @@ -442,7 +449,6 @@ (*env)->SetObjectField(env, netifObj, ni_nameID, name); (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName); (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index); - /* * Get the IP addresses for this interface if necessary * Note that 0 is a valid number of addresses.
--- a/src/windows/native/java/net/SocketInputStream.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/native/java/net/SocketInputStream.c Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003, 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 @@ -134,32 +134,34 @@ (*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP); } else { if (nread < 0) { - /* - * Recv failed. - */ - switch (WSAGetLastError()) { - case WSAEINTR: - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", - "socket closed"); - break; + // Check if the socket has been closed since we last checked. + // This could be a reason for recv failing. + if ((*env)->GetIntField(env, fdObj, IO_fd_fdID) == -1) { + NET_ThrowSocketException(env, "Socket closed"); + } else { + switch (WSAGetLastError()) { + case WSAEINTR: + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", + "socket closed"); + break; + case WSAECONNRESET: + case WSAESHUTDOWN: + /* + * Connection has been reset - Windows sometimes reports + * the reset as a shutdown error. + */ + JNU_ThrowByName(env, "sun/net/ConnectionResetException", + ""); + break; - case WSAECONNRESET: - case WSAESHUTDOWN: - /* - * Connection has been reset - Windows sometimes reports - * the reset as a shutdown error. - */ - JNU_ThrowByName(env, "sun/net/ConnectionResetException", - ""); - break; + case WSAETIMEDOUT : + JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", + "Read timed out"); + break; - case WSAETIMEDOUT : - JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", - "Read timed out"); - break; - - default: - NET_ThrowCurrent(env, "recv failed"); + default: + NET_ThrowCurrent(env, "recv failed"); + } } } }
--- a/src/windows/native/java/net/TwoStacksPlainSocketImpl.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/native/java/net/TwoStacksPlainSocketImpl.c Thu Apr 03 00:39:02 2014 +0100 @@ -576,6 +576,7 @@ { /* fields on this */ jint port; + jint scope; jint timeout = (*env)->GetIntField(env, this, psi_timeoutID); jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID); jobject fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID); @@ -751,9 +752,12 @@ return; } setInet6Address_ipaddress(env, socketAddressObj, (const char *)&him.him6.sin6_addr); - setInetAddress_family(env, socketAddressObj, IPv6); - setInet6Address_scopeid(env, socketAddressObj, him.him6.sin6_scope_id); + scope = him.him6.sin6_scope_id; + (*env)->SetIntField(env, socketAddressObj, ia6_scopeidID, scope); + if(scope>0) { + (*env)->SetBooleanField(env, socketAddressObj, ia6_scopeidsetID, JNI_TRUE); + } } /* fields common to AF_INET and AF_INET6 */
--- a/src/windows/native/sun/nio/ch/SocketDispatcher.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/native/sun/nio/ch/SocketDispatcher.c Thu Apr 03 00:39:02 2014 +0100 @@ -192,45 +192,66 @@ jobject fdo, jlong address, jint len) { /* set up */ - int i = 0; + int next_index, next_offset, ret=0; DWORD written = 0; jint fd = fdval(env, fdo); struct iovec *iovp = (struct iovec *)address; WSABUF *bufs = malloc(len * sizeof(WSABUF)); - jint rem = MAX_BUFFER_SIZE; + jlong count = 0; if (bufs == 0) { JNU_ThrowOutOfMemoryError(env, 0); return IOS_THROWN; } - /* copy iovec into WSABUF */ - for(i=0; i<len; i++) { - jint iov_len = iovp[i].iov_len; - if (iov_len > rem) - iov_len = rem; - bufs[i].buf = (char *)iovp[i].iov_base; - bufs[i].len = (u_long)iov_len; - rem -= iov_len; - if (rem == 0) { - len = i+1; + // next buffer and offset to consume + next_index = 0; + next_offset = 0; + + while (next_index < len) { + DWORD buf_count = 0; + + /* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */ + jint rem = MAX_BUFFER_SIZE; + while (next_index < len && rem > 0) { + jint iov_len = iovp[next_index].iov_len - next_offset; + char* ptr = (char *)iovp[next_index].iov_base; + ptr += next_offset; + if (iov_len > rem) { + iov_len = rem; + next_offset += rem; + } else { + next_index ++; + next_offset = 0; + } + + bufs[buf_count].buf = ptr; + bufs[buf_count].len = (u_long)iov_len; + buf_count++; + + rem -= iov_len; + } + + /* write the buffers */ + ret = WSASend((SOCKET)fd, /* Socket */ + bufs, /* pointers to the buffers */ + buf_count, /* number of buffers to process */ + &written, /* receives number of bytes written */ + 0, /* no flags */ + 0, /* no overlapped sockets */ + 0); /* no completion routine */ + + if (ret == SOCKET_ERROR) { break; } + + count += written; } - /* read into the buffers */ - i = WSASend((SOCKET)fd, /* Socket */ - bufs, /* pointers to the buffers */ - (DWORD)len, /* number of buffers to process */ - &written, /* receives number of bytes written */ - 0, /* no flags */ - 0, /* no overlapped sockets */ - 0); /* no completion routine */ - /* clean up */ free(bufs); - if (i != 0) { + if (ret == SOCKET_ERROR && count == 0) { int theErr = (jint)WSAGetLastError(); if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; @@ -239,7 +260,7 @@ return IOS_THROWN; } - return convertLongReturnVal(env, (jlong)written, JNI_FALSE); + return convertLongReturnVal(env, count, JNI_FALSE); } JNIEXPORT void JNICALL
--- a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Thu Apr 03 00:39:02 2014 +0100 @@ -162,7 +162,7 @@ } completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I"); completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I"); - completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "I"); + completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J"); clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult"); if (clazz == NULL) { @@ -1169,12 +1169,11 @@ JNIEXPORT jlong JNICALL Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this, - jlong fileHandle, jlong existingPort, jint completionKey) + jlong fileHandle, jlong existingPort, jlong completionKey) { - ULONG_PTR ck = completionKey; HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle), (HANDLE)jlong_to_ptr(existingPort), - ck, + (ULONG_PTR)completionKey, 0); if (port == NULL) { throwWindowsException(env, GetLastError()); @@ -1203,21 +1202,20 @@ (*env)->SetIntField(env, obj, completionStatus_error, ioResult); (*env)->SetIntField(env, obj, completionStatus_bytesTransferred, (jint)bytesTransferred); - (*env)->SetIntField(env, obj, completionStatus_completionKey, - (jint)completionKey); - + (*env)->SetLongField(env, obj, completionStatus_completionKey, + (jlong)completionKey); } } JNIEXPORT void JNICALL Java_sun_nio_fs_WindowsNativeDispatcher_PostQueuedCompletionStatus(JNIEnv* env, jclass this, - jlong completionPort, jint completionKey) + jlong completionPort, jlong completionKey) { BOOL res; res = PostQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort), (DWORD)0, /* dwNumberOfBytesTransferred */ - (DWORD)completionKey, + (ULONG_PTR)completionKey, NULL); /* lpOverlapped */ if (res == 0) { throwWindowsException(env, GetLastError()); @@ -1232,7 +1230,17 @@ BOOL res; BOOL subtree = (watchSubTree == JNI_TRUE) ? TRUE : FALSE; - ((LPOVERLAPPED)jlong_to_ptr(pOverlapped))->hEvent = NULL; + /* Any unused members of [OVERLAPPED] structure should always be initialized to zero + before the structure is used in a function call. + Otherwise, the function may fail and return ERROR_INVALID_PARAMETER. + http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx + + The [Offset] and [OffsetHigh] members of this structure are not used. + http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx + + [hEvent] should be zero, other fields are the return values. */ + ZeroMemory((LPOVERLAPPED)jlong_to_ptr(pOverlapped), sizeof(OVERLAPPED)); + res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory), (LPVOID)jlong_to_ptr(bufferAddress), (DWORD)bufferLength,
--- a/src/windows/resource/java.manifest Fri Mar 21 17:54:04 2014 +0000 +++ b/src/windows/resource/java.manifest Thu Apr 03 00:39:02 2014 +0100 @@ -44,9 +44,15 @@ <!-- Indicate this JDK version is Windows 7 compatible --> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!-- Windows Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!-- Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!-- Windows 8 --> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <!-- Windows 8.1 --> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> </application> - </compatibility> + </compatibility> </assembly>
--- a/test/ProblemList.txt Fri Mar 21 17:54:04 2014 +0000 +++ b/test/ProblemList.txt Thu Apr 03 00:39:02 2014 +0100 @@ -405,10 +405,6 @@ # 7132203 sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all -# 8001118 -sun/tools/jcmd/jcmd-f.sh generic-all -sun/tools/jcmd/jcmd-help-help.sh generic-all - # 7175775 sun/tools/jinfo/Basic.sh macosx-all @@ -453,9 +449,6 @@ # Problems on windows, jmap.exe hangs? (these run jmap), fails on Solaris 10 x86 java/util/concurrent/locks/Lock/TimedAcquireLeak.java generic-all -# 7041639, Solaris DSA keypair generation bug -java/util/TimeZone/TimeZoneDatePermissionCheck.sh solaris-all - # 8026772: test/sun/util/resources/TimeZone/Bug6317929.java failing sun/util/resources/TimeZone/Bug6317929.java generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/corba/5036554/JavaBug.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 bug; + +public class JavaBug { + public static void main(String[] args) { + try { + org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); + org.omg.CORBA.Any any = orb.create_any(); + myStringHelper.insert(any, "hello"); + System.out.println("Any: " + myStringHelper.extract(any)); + } catch( Exception e ) { + e.printStackTrace(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/corba/5036554/README Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +Bug # 5036554 unmarshal error on CORBA alias type in CORBA any + +Platform : ALL + +Testcase directory : <.../corba> + +Test Procedure : <STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : +Step 1: create a file bug.idl with the following content: + +// IDL file bug.idl +module bug { + typedef string myString; +}; + +Step 2: Translate bug.idl with the command: idlj bug.idl +This will create the file bug/myStringHelper.java + +Step 3: +Create the file JavaBug.java in directory bug with the following content: + +// Java file JavaBug.java +package bug; + +public class JavaBug { + public static void main(String[] args) { + try { + org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); + org.omg.CORBA.Any any = orb.create_any(); + myStringHelper.insert(any, "hello"); + System.out.println("Any: " + myStringHelper.extract(any)); + } catch( Exception e ) { + e.printStackTrace(); + } + } +} + +Step 4: +Compile all java files with the command: javac -d . bug\*.java + +Step 5: +Execute the program with the command: java -cp . bug/JavaBug + +Step 6: Note the null pointer exception in the the output! + + +Without Fix behaviour : <java.lang.NullPointerException + at com.sun.corba.se.internal.corba.TCUtility.unmarshalIn(TCUtility.java:290) + at com.sun.corba.se.internal.corba.AnyImpl.read_value(AnyImpl.java:561) + at bug.myStringHelper.insert(myStringHelper.java:20) + at bug.JavaBug.main(JavaBug.java:8)> + +With Fix behaviour : <The output message printed on the console: "Any: hello"> + +Other Comments : <Test case is automated.>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/corba/5036554/TestCorbaBug.sh Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,112 @@ +#!/bin/sh +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please 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 5036554 6357706 +# @summary unmarshal error on CORBA alias type in CORBA any +# @run shell TestCorbaBug.sh + +if [ "${TESTSRC}" = "" ] +then TESTSRC=. +fi + +if [ "${TESTJAVA}" = "" ] +then + PARENT=`dirname \`which java\`` + TESTJAVA=`dirname ${PARENT}` + echo "TESTJAVA not set, selecting " ${TESTJAVA} + echo "If this is incorrect, try setting the variable manually." +fi + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASSES not set. Test cannot execute. Failed." + exit 1 +fi + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + SunOS | Linux | Darwin ) + PS=":" + FS="/" + ;; + CYGWIN* ) + PS=";" + FS="/" + ;; + Windows* ) + PS=";" + FS="\\" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +CLASSPATH=.${PS}${TESTCLASSES}; export CLASSPATH + +THIS_DIR=`pwd` + +${TESTJAVA}${FS}bin${FS}java -version + +mkdir bug + +cp ${TESTSRC}${FS}bug.idl . +${TESTJAVA}${FS}bin${FS}idlj bug.idl + +cp ${TESTSRC}${FS}JavaBug.java bug + +chmod -fR 777 bug + +${TESTJAVA}${FS}bin${FS}javac -d . bug${FS}*.java + +${TESTJAVA}${FS}bin${FS}java -cp . bug/JavaBug > test.out 2>&1 + +grep "NullPointerException" test.out + +ERROR=$? + +cat test.out + +if [ $ERROR = 0 ] +then + echo "Test Failed" + exit 1 +fi + +grep "Any: hello" test.out + +STATUS=$? + +if [ $STATUS = 0 ] +then + echo "Test Passed" + exit 0 +else + echo "Invalid output" + cat test.out + exit 2 +fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/corba/5036554/bug.idl Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,4 @@ +// IDL file bug.idl +module bug { + typedef string myString; +};
--- a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/InterprocessMessages.java Thu Apr 03 00:39:02 2014 +0100 @@ -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 @@ -24,5 +24,6 @@ interface InterprocessMessages { final static int EXECUTION_IS_SUCCESSFULL = 0; final static int DATA_IS_CORRUPTED = 212; + final static int NO_DROP_HAPPENED = 112; }
--- a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html Thu Apr 03 00:39:02 2014 +0100 @@ -1,7 +1,30 @@ <html> <!-- + 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 + under the terms of the GNU General Public License version 2 only, as + published by the Free Software Foundation. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please 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 8005932 + @bug 8005932 8017456 @summary Java 7 on mac os x only provides text clipboard formats @author mikhail.cherkasov@oracle.com @library ../../regtesthelpers
--- a/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java Thu Apr 03 00:39:02 2014 +0100 @@ -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 @@ -42,6 +42,7 @@ import static java.lang.Thread.sleep; public class MissedHtmlAndRtfBug extends Applet { + public void init() { setLayout(new BorderLayout()); }//End init() @@ -77,9 +78,6 @@ args.add(concatStrings(DataFlavorSearcher.RICH_TEXT_NAMES)); ProcessResults processResults = -// ProcessCommunicator.executeChildProcess(this.getClass(), "/Users/mcherkasov/ws/clipboard/DataFlover/out/production/DataFlover" + -// " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 ", -// args.toArray(new String[0])); ProcessCommunicator.executeChildProcess(this.getClass(), "." + File.separator + System.getProperty("java.class.path"), args.toArray(new String[]{})); @@ -112,6 +110,13 @@ throw new RuntimeException("TEST IS FAILED: Target has received" + " corrupted data."); } + if (InterprocessMessages.NO_DROP_HAPPENED == + processResults.getExitValue()) { + processResults.printProcessErrorOutput(System.err); + throw new RuntimeException("Error. Drop did not happen." + + " Target frame is possibly covered by a window of other application." + + " Please, rerun the test with all windows minimized."); + } processResults.verifyStdErr(System.err); processResults.verifyProcessExitValue(System.err); processResults.printProcessStandartOutput(System.out); @@ -179,7 +184,7 @@ } } - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { Point dragSourcePoint = new Point(InterprocessArguments.DRAG_SOURCE_POINT_X_ARGUMENT.extractInt(args), InterprocessArguments.DRAG_SOURCE_POINT_Y_ARGUMENT.extractInt(args)); Point targetFrameLocation = new Point(InterprocessArguments.TARGET_FRAME_X_POSITION_ARGUMENT.extractInt(args), @@ -192,6 +197,8 @@ } catch (InterruptedException e) { e.printStackTrace(); } + sleep(5000); + System.exit(InterprocessMessages.NO_DROP_HAPPENED); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Frame/ExceptionOnSetExtendedStateTest/ExceptionOnSetExtendedStateTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,104 @@ +/* + * 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 8032078 + @summary Frame.setExtendedState throws RuntimeException, if + windowState=ICONIFIED|MAXIMIZED_BOTH, on OS X + @author Anton Litvinov +*/ + +import java.awt.*; + +import sun.awt.SunToolkit; + +public class ExceptionOnSetExtendedStateTest { + private static final int[] frameStates = { Frame.NORMAL, Frame.ICONIFIED, Frame.MAXIMIZED_BOTH }; + private static final SunToolkit toolkit = (SunToolkit)Toolkit.getDefaultToolkit(); + + private static boolean validatePlatform() { + String osName = System.getProperty("os.name"); + if (osName == null) { + throw new RuntimeException("Name of the current OS could not be retrieved."); + } + return osName.startsWith("Mac"); + } + + private static void testStateChange(int oldState, int newState, boolean decoratedFrame) { + System.out.println(String.format( + "testStateChange: oldState='%d', newState='%d', decoratedFrame='%b'", + oldState, newState, decoratedFrame)); + + Frame frame = new Frame("ExceptionOnSetExtendedStateTest"); + frame.setSize(200, 200); + frame.setUndecorated(!decoratedFrame); + frame.setVisible(true); + toolkit.realSync(); + + frame.setExtendedState(oldState); + sleep(1000); + frame.setExtendedState(newState); + + boolean stateWasNotChanged = true; + int currentState = 0; + for (int i = 0; (i < 3) && stateWasNotChanged; i++) { + sleep(1000); + currentState = frame.getExtendedState(); + if ((currentState == newState) || + (((newState & Frame.ICONIFIED) != 0) && ((currentState & Frame.ICONIFIED) != 0))) { + stateWasNotChanged = false; + } + } + frame.dispose(); + + if (stateWasNotChanged) { + throw new RuntimeException(String.format( + "Frame state was not changed. currentState='%d'", currentState)); + } + } + + private static void sleep(int millis) { + try { + Thread.sleep(millis); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + if (!validatePlatform()) { + System.out.println("This test is only for OS X."); + return; + } + + // Verify that changing states of decorated/undecorated frame to/from supported states + // and the state bit mask ICONIFIED | MAXIMIZED_BOTH does not raise RuntimeException. + for (int i = 0; i < frameStates.length; i++) { + testStateChange(frameStates[i], Frame.ICONIFIED | Frame.MAXIMIZED_BOTH, true); + testStateChange(frameStates[i], Frame.ICONIFIED | Frame.MAXIMIZED_BOTH, false); + testStateChange(Frame.ICONIFIED | Frame.MAXIMIZED_BOTH, frameStates[i], true); + // Uncomment the line below, when 8026143 is ported to JDK 7. + //testStateChange(Frame.ICONIFIED | Frame.MAXIMIZED_BOTH, frameStates[i], false); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 7154048 + * @summary Window created under a mouse does not receive mouse enter event. + * Mouse Entered/Exited events are wrongly generated during dragging the window + * from one component to another + * @library ../../regtesthelpers + * @build Util + * @author alexandr.scherbatiy area=awt.event + * @run main DragWindowTest + */ + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +import java.util.concurrent.*; +import sun.awt.SunToolkit; + +import test.java.awt.regtesthelpers.Util; + +public class DragWindowTest { + + private static volatile int dragWindowMouseEnteredCount = 0; + private static volatile int dragWindowMouseReleasedCount = 0; + private static volatile int buttonMouseEnteredCount = 0; + private static volatile int labelMouseReleasedCount = 0; + private static MyDragWindow dragWindow; + private static JLabel label; + private static JButton button; + + public static void main(String[] args) throws Exception { + + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + Robot robot = new Robot(); + robot.setAutoDelay(50); + + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + createAndShowGUI(); + } + }); + + toolkit.realSync(); + + Point pointToClick = Util.invokeOnEDT(new Callable<Point>() { + + @Override + public Point call() throws Exception { + return getCenterPoint(label); + } + }); + + + robot.mouseMove(pointToClick.x, pointToClick.y); + robot.mousePress(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (dragWindowMouseEnteredCount != 1) { + throw new RuntimeException("No MouseEntered event on Drag Window!"); + } + + Point pointToDrag = Util.invokeOnEDT(new Callable<Point>() { + + @Override + public Point call() throws Exception { + button.addMouseListener(new ButtonMouseListener()); + return getCenterPoint(button); + } + }); + + robot.mouseMove(pointToDrag.x, pointToDrag.y); + toolkit.realSync(); + + if (buttonMouseEnteredCount != 0) { + throw new RuntimeException("Extra MouseEntered event on button!"); + } + + robot.mouseRelease(InputEvent.BUTTON1_MASK); + toolkit.realSync(); + + if (labelMouseReleasedCount != 1) { + throw new RuntimeException("No MouseReleased event on label!"); + } + + } + + private static Point getCenterPoint(Component comp) { + Point p = comp.getLocationOnScreen(); + Rectangle rect = comp.getBounds(); + return new Point(p.x + rect.width / 2, p.y + rect.height / 2); + } + + private static void createAndShowGUI() { + + JFrame frame = new JFrame("Main Frame"); + frame.setSize(300, 200); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + label = new JLabel("Label"); + + LabelMouseListener listener = new LabelMouseListener(frame); + label.addMouseListener(listener); + label.addMouseMotionListener(listener); + + button = new JButton("Button"); + Panel panel = new Panel(new BorderLayout()); + + panel.add(label, BorderLayout.NORTH); + panel.add(button, BorderLayout.CENTER); + + frame.getContentPane().add(panel); + frame.setVisible(true); + + } + + private static Point getAbsoluteLocation(MouseEvent e) { + return new Point(e.getXOnScreen(), e.getYOnScreen()); + } + + static class MyDragWindow extends Window { + + static int d = 30; + + public MyDragWindow(Window parent, Point location) { + super(parent); + setSize(150, 150); + setVisible(true); + JPanel panel = new JPanel(); + add(panel); + setLocation(location.x - d, location.y - d); + addMouseListener(new DragWindowMouseListener()); + } + + void dragTo(Point point) { + setLocation(point.x - d, point.y - d); + } + } + + static class LabelMouseListener extends MouseAdapter { + + Point origin; + Window parent; + + public LabelMouseListener(Window parent) { + this.parent = parent; + } + + @Override + public void mousePressed(MouseEvent e) { + if (dragWindow == null) { + dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e)); + } else { + dragWindow.setVisible(true); + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + labelMouseReleasedCount++; + if (dragWindow != null) { + dragWindow.setVisible(false); + } + } + + public void mouseDragged(MouseEvent e) { + if (dragWindow != null) { + dragWindow.dragTo(getAbsoluteLocation(e)); + } + } + } + + static class DragWindowMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + dragWindowMouseEnteredCount++; + } + + @Override + public void mouseReleased(MouseEvent e) { + dragWindowMouseReleasedCount++; + } + } + + static class ButtonMouseListener extends MouseAdapter { + + @Override + public void mouseEntered(MouseEvent e) { + buttonMouseEnteredCount++; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithOverlay.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithOverlay.java + * @run main/othervm GetMousePositionWithOverlay + */ + +public class GetMousePositionWithOverlay { + + static Frame backFrame; + static Frame frontFrame; + + public static void main(String[] args) throws Throwable { + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + Util.waitForIdle(null); + + Robot r = new Robot(); + Util.pointOnComp(frontFrame, r); + Util.waitForIdle(null); + + Point pos = getMousePosition(backFrame); + if (pos != null) { + throw new RuntimeException("Test failed. Mouse position should be null but was" + pos); + } + + pos = getMousePosition(frontFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + + r.mouseMove(189, 189); + Util.waitForIdle(null); + + pos = getMousePosition(backFrame); + if (pos == null) { + throw new RuntimeException("Test failed. Mouse position should not be null"); + } + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + backFrame.dispose(); + frontFrame.dispose(); + } + }); + } + } + + private static Point getMousePosition(final Component component) throws Exception { + final AtomicReference<Point> pos = new AtomicReference<Point>(); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + pos.set(component.getMousePosition()); + } + }); + return pos.get(); + } + + private static void constructTestUI() { + backFrame = new Frame(); + backFrame.setBounds(100, 100, 100, 100); + backFrame.setVisible(true); + + frontFrame = new Frame(); + frontFrame.setBounds(120, 120, 60, 60); + frontFrame.setVisible(true); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/GetMousePositionTest/GetMousePositionWithPopup.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; + +/** + * @test + * @bug 8012026 + * @summary Component.getMousePosition() does not work in an applet on MacOS + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile GetMousePositionWithPopup.java + * @run main/othervm GetMousePositionWithPopup + */ + +public class GetMousePositionWithPopup { + + private static Frame frame1; + private static Frame frame2; + + public static void main(String[] args) throws Exception { + try { + Robot r = Util.createRobot(); + r.mouseMove(0, 0); + Util.waitForIdle(null); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + + Util.waitForIdle(null); + r.mouseMove(149, 149); + Util.waitForIdle(null); + r.mouseMove(150, 150); + Util.waitForIdle(null); + + } finally { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + frame1.dispose(); + frame2.dispose(); + } + }); + } + } + + private static void constructTestUI() { + frame1 = new Frame(); + frame1.setBounds(100, 100, 100, 100); + frame1.addMouseMotionListener(new MouseMotionAdapter() { + + private boolean shown = false; + + @Override + public void mouseMoved(MouseEvent e) { + if (shown) { + return; + } + + shown = true; + + frame2 = new Frame(); + frame2.setBounds(120, 120, 120, 120); + frame2.setVisible(true); + + Point positionInFrame2 = frame2.getMousePosition(); + if (positionInFrame2.x != 30 || positionInFrame2.y != 30) { + throw new RuntimeException("Wrong position reported. Should be [30, 30] but was [" + + positionInFrame2.x + ", " + positionInFrame2.y + "]"); + } + + Point positionInFrame1 = frame1.getMousePosition(); + if (positionInFrame1 != null) { + throw new RuntimeException("Wrong position reported. Should be null"); + } + + } + }); + frame1.setVisible(true); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,138 @@ +/* + * 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 8032872 + * @summary Tests JComboBox selection via the mouse + * @author Dmitry Markov + */ +import sun.awt.SunToolkit; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicComboPopup; +import javax.swing.plaf.basic.ComboPopup; +import javax.swing.plaf.metal.MetalComboBoxUI; +import javax.swing.plaf.metal.MetalLookAndFeel; +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class MouseComboBoxTest { + private static final String[] items = {"One", "Two", "Three", "Four", "Five"}; + + private static SunToolkit toolkit = null; + private static Robot robot = null; + private static JFrame frame = null; + private static JComboBox comboBox = null; + private static MyComboBoxUI comboBoxUI = null; + + public static void main(String[] args) throws Exception { + toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); + robot = new Robot(); + robot.setAutoDelay(50); + + UIManager.setLookAndFeel(new MetalLookAndFeel()); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + createAndShowGUI(); + } + }); + toolkit.realSync(); + + for (int i = 0; i < items.length; i++) { + // Open popup + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + toolkit.realSync(); + + Point point = getItemPointToClick(i); + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + toolkit.realSync(); + + if (i != getSelectedIndex()) { + throw new RuntimeException("Test Failed! Incorrect value of selected index = " + getSelectedIndex() + + ", expected value = " + i); + } + } + } + + private static Point getItemPointToClick(final int item) throws Exception { + final Point[] result = new Point[1]; + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + BasicComboPopup popup = (BasicComboPopup)comboBoxUI.getComboPopup(); + Point point = popup.getLocationOnScreen(); + Dimension size = popup.getSize(); + + int step = size.height / items.length; + point.x += size.width / 2; + point.y += step / 2 + step * item; + result[0] = point; + } + }); + return result[0]; + } + + private static int getSelectedIndex() throws Exception { + final int[] result = new int[1]; + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + result[0] = comboBox.getSelectedIndex(); + } + }); + return result[0]; + } + + private static void createAndShowGUI() { + frame = new JFrame("MouseComboBoxTest"); + + comboBox = new JComboBox(items); + comboBox.setEditable(true); + comboBoxUI = new MyComboBoxUI(); + comboBox.setUI(comboBoxUI); + + frame.pack(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + + JWindow window = new JWindow(frame); + window.add(comboBox); + window.pack(); + window.setVisible(true); + } + + private static class MyComboBoxUI extends MetalComboBoxUI { + public ComboPopup getComboPopup() { + return popup; + } + } +} +
--- a/test/java/awt/Window/Grab/GrabTest.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/awt/Window/Grab/GrabTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -40,7 +40,10 @@ public class GrabTest { private static Frame f; private static Frame f1; + private static Frame frame; private static Window w; + private static Window window1; + private static Window window2; private static Button b; private static Robot robot; @@ -98,6 +101,15 @@ f.setVisible(true); w.setVisible(true); + frame = new Frame(); + window1 = new Window(frame); + window1.setBounds(0, 0, 100, 100); + window1.setBackground(Color.blue); + + window2 = new Window(window1); + window2.setBounds(0, 0, 50, 50); + window2.setBackground(Color.green); + tk = (sun.awt.SunToolkit)Toolkit.getDefaultToolkit(); try { @@ -175,7 +187,7 @@ // 6. Check that press on the outside area causes ungrab Point loc = f.getLocationOnScreen(); - robot.mouseMove(loc.x + 100, loc.y + f.getSize().height + 1); + robot.mouseMove(loc.x + 100, loc.y + f.getSize().height + 10); Util.waitForIdle(robot); robot.mousePress(InputEvent.BUTTON1_MASK); robot.delay(50); @@ -196,6 +208,24 @@ passed = false; System.err.println("Failure: [7] Window disposal didn't cause ungrab"); } + ungrabbed = false; + + + // 8. Check that mouse click on subwindow does not cause ungrab + frame.setVisible(true); + window1.setVisible(true); + window2.setVisible(true); + Util.waitForIdle(robot); + + tk.grab(window1); + + Util.clickOnComp(window2, robot); + Util.waitForIdle(robot); + + if (ungrabbed) { + passed = false; + System.err.println("Failure: [8] Press on the subwindow caused ungrab"); + } if (passed) { System.out.println("Test passed.");
--- a/test/java/lang/ClassLoader/Assert.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/lang/ClassLoader/Assert.sh Thu Apr 03 00:39:02 2014 +0100 @@ -23,6 +23,21 @@ # +OS=`uname -s` +case "$OS" in + SunOS | Linux | Darwin ) + FS="/" + CHMOD="${FS}bin${FS}chmod" + ;; + Windows* | CYGWIN* ) + CHMOD="chmod" + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + if [ "${TESTSRC}" = "" ] then echo "TESTSRC not set. Test cannot execute. Failed." @@ -46,6 +61,7 @@ cp ${TESTSRC}/Assert.java . cp -R ${TESTSRC}/package1 . cp -R ${TESTSRC}/package2 . +${CHMOD} -R u+w * ${TESTJAVA}/bin/javac Assert.java
--- a/test/java/lang/ProcessBuilder/Basic.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/lang/ProcessBuilder/Basic.java Thu Apr 03 00:39:02 2014 +0100 @@ -559,9 +559,10 @@ System.getProperty("java.class.path"); private static final List<String> javaChildArgs = - Arrays.asList(new String[] - { javaExe, "-classpath", absolutifyPath(classpath), - "Basic$JavaChild"}); + Arrays.asList(javaExe, + "-XX:+DisplayVMOutputToStderr", + "-classpath", absolutifyPath(classpath), + "Basic$JavaChild"); private static void testEncoding(String encoding, String tested) { try { @@ -1597,8 +1598,8 @@ javaExe)); list.add("ArrayOOME"); ProcessResults r = run(new ProcessBuilder(list)); - check(r.out().contains("java.lang.OutOfMemoryError:")); - check(r.out().contains(javaExe)); + check(r.err().contains("java.lang.OutOfMemoryError:")); + check(r.err().contains(javaExe)); check(r.err().contains(System.getProperty("java.version"))); equal(r.exitValue(), 1); } catch (Throwable t) { unexpected(t); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacEncoding/ExpectedEncoding.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Check that the value of file.encoding and sun.jnu.encoding match the expected + * values passed in on the command-line. + */ +public class ExpectedEncoding { + public static void main(String[] args) { + boolean failed = false; + if (args.length != 2) { + System.out.println("Usage:"); + System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>"); + System.out.println("$ use \"skip\" to skip checking property's value"); + System.exit(1); + } + String expectFileEnc = args[0]; + String expectSunJnuEnc = args[1]; + + String fileEnc = System.getProperty("file.encoding"); + String jnuEnc = System.getProperty("sun.jnu.encoding"); + + if ("skip".equals(expectFileEnc)) { + System.err.println("Expected file.encoding is \"skip\", ignoring"); + } else { + System.err.println("Expected file.encoding: " + expectFileEnc); + System.err.println("Actual file.encoding: " + fileEnc); + if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { + failed = true; + } + } + if ("skip".equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding is \"skip\", ignoring"); + } else { + if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { + System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); + System.err.println("Actual sun.jnu.encoding: " + jnuEnc); + failed = true; + } + } + + if (failed) { + throw new RuntimeException("Test Failed"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacEncoding/MacJNUEncoding.sh Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please 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 8003228 +# @summary Test the value of sun.jnu.encoding on Mac +# @author Brent Christian +# +# @run shell MacJNUEncoding.sh + +# Only run test on Mac +OS=`uname -s` +case "$OS" in + Darwin ) ;; + * ) + exit 0 + ;; +esac + +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${TESTSRC}" = "" ] +then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASSES not set. Test cannot execute. Failed." + exit 1 +fi + +JAVAC="${TESTJAVA}"/bin/javac +JAVA="${TESTJAVA}"/bin/java + +echo "Building test classes..." +"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java + +echo "" +echo "Running test for C locale" +export LANG=C +export LC_ALL=C +"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8 +result1=$? + +echo "" +echo "Running test for en_US.UTF-8 locale" +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 +"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8 +result2=$? + +echo "" +echo "Cleanup" +rm ${TESTCLASSES}/ExpectedEncoding.class + +if [ ${result1} -ne 0 ] ; then + echo "Test failed for C locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" + exit ${result1} +fi +if [ ${result2} -ne 0 ] ; then + echo "Test failed for en_US.UTF-8 locale" + echo " LANG=\"${LANG}\"" + echo " LC_ALL=\"${LC_ALL}\"" + exit ${result2} +fi +exit 0 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/System/MacEncoding/TestFileEncoding.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.*; + +/* + * @test + * @bug 8011194 + * @summary Test value of file.encoding for corresponding value of LANG, etc + * @library ../../../../tools/launcher/ ../ + * @build TestHelper TestFileEncoding ExpectedEncoding + * @run main TestFileEncoding UTF-8 + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding + * @run main TestFileEncoding UTF-8 en_US.UTF-8 + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding en_US.UTF-8 + * @run main TestFileEncoding US-ASCII C + * @run main/othervm -Dfile.encoding=MyEncoding -DuserEncoding=MyEncoding TestFileEncoding MyEncoding C + * @author Brent Christian + */ + +/** + * Setup the environment and run a sub-test to check the expected value of + * file.encoding, based on the value(s) of encoding-related environment vars + * (LANG, LC_ALL, LC_CTYPE). + * + * The first argument (required) is the expected value of the + * file.encoding System property. + * The second argument (optional) is the value to set to the LANG/etc env vars. + */ +public class TestFileEncoding { + private static final String TEST_NAME = "ExpectedEncoding"; + + private String expectedEncoding; // Expected value for file.encoding + private String langVar = null; // Value to set for LANG, etc + + private static Set<String> envToRm = new HashSet<>(3); + static { + // Take these vars out of the test's run environment, possibly adding + // our own value back in. + envToRm.add("LANG"); + envToRm.add("LC_ALL"); + envToRm.add("LC_CTYPE"); + } + + public TestFileEncoding(String expectedEncoding) { + this.expectedEncoding = expectedEncoding; + } + + public TestFileEncoding(String expectedEncoding, String langVar) { + this.expectedEncoding = expectedEncoding; + this.langVar = langVar; + } + + /* + * Launch ExpectedEncoding with the given parameters, check for the + * expected file.encoding. + */ + private void run() { + String testClasses = System.getProperty("test.classes"); + + // Pick up VM opts + String vmOptsStr = System.getProperty("test.vm.opts"); + System.out.println("test.vm.opts: " + vmOptsStr); + String[] vmOpts = new String[0]; + if (vmOptsStr != null && !"".equals(vmOptsStr)) { + vmOpts = vmOptsStr.split(" "); + System.out.println("found vm options:"); + for (String opt : vmOpts) { + System.out.println(" <" + opt + ">"); + } + } + + // Build java cmd + LinkedList<String> cmdList = new LinkedList<>(); + cmdList.add(TestHelper.javaCmd); + for (String vmOpt : vmOpts) { + if (vmOpt != null && !vmOpt.equals("")) { + cmdList.add(vmOpt); + } + } + + // See if the user specified a file.encoding that we should pass through + String userEncoding = System.getProperty("userEncoding"); + if (userEncoding != null) { + cmdList.add("-Dfile.encoding="+userEncoding); + } + + cmdList.add("-cp"); + cmdList.add(testClasses); + cmdList.add(TEST_NAME); + cmdList.add(expectedEncoding); + cmdList.add("skip"); // ignore sun.jnu.encoding for this test + + String cmdArray[] = new String[cmdList.size()]; + cmdList.toArray(cmdArray); + + // Run the test(s) + if (langVar == null) { + System.out.println("TestFileEncoding: Running with no envvars set"); + TestHelper.TestResult tr = TestHelper.doExec(null, envToRm, + cmdArray); + checkResult(tr); + } else { + runWithEnvVar("LANG", cmdArray); + runWithEnvVar("LC_ALL", cmdArray); + runWithEnvVar("LC_CTYPE", cmdArray); + } + } + + /* + * Run the test, setting the environment named by envVarName to the value + * in langVar. + */ + private void runWithEnvVar(String envVarName, String[] cmdArray) { + Map<String, String> envToAdd = new HashMap<>(1); + TestHelper.TestResult tr = null; + + System.out.println("TestFileEncoding: Running with " + envVarName + "=" + langVar); + envToAdd.put(envVarName, langVar); + tr = TestHelper.doExec(envToAdd, envToRm, cmdArray); + checkResult(tr); + } + + private void checkResult(TestHelper.TestResult tr) { + System.out.println(tr); + if (!tr.isOK()) { + throw new RuntimeException("TEST FAILED: !tr.isOK()"); + } + } + + public static void main(String[] args) { + TestFileEncoding cfe = null; + if (!TestHelper.isMacOSX) { + System.out.println("Test is currently only for Mac OS X - pass."); + return; + } + if (args.length == 1) { + cfe = new TestFileEncoding(args[0]); + } else if (args.length == 2) { + cfe = new TestFileEncoding(args[0], args[1]); + } else { + System.out.println("Usage: TestFileEncoding <expected file.encoding>"); + System.out.println(" TestFileEncoding <expected file.encoding> <value for LANG/etc env var>"); + return; + } + cfe.run(); + } +}
--- a/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * Check that the value of file.encoding and sun.jnu.encoding match the expected - * values passed in on the command-line. - */ -public class ExpectedEncoding { - public static void main(String[] args) { - boolean failed = false; - if (args.length != 2) { - System.out.println("Usage:"); - System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>"); - System.exit(1); - } - String expectFileEnc = args[0]; - String expectSunJnuEnc = args[1]; - - String fileEnc = System.getProperty("file.encoding"); - String jnuEnc = System.getProperty("sun.jnu.encoding"); - - if (fileEnc == null || !fileEnc.equals(expectFileEnc)) { - System.err.println("Expected file.encoding: " + expectFileEnc); - System.err.println("Actual file.encoding: " + fileEnc); - failed = true; - } - if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) { - System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc); - System.err.println("Actual sun.jnu.encoding: " + jnuEnc); - failed = true; - } - if (failed) { - throw new RuntimeException("Test Failed"); - } - } -}
--- a/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -#!/bin/sh - -# -# Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please 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 8003228 -# @summary Test the value of sun.jnu.encoding on Mac -# @author Brent Christian -# -# @run shell MacJNUEncoding.sh - -# Only run test on Mac -OS=`uname -s` -case "$OS" in - Darwin ) ;; - * ) - exit 0 - ;; -esac - -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi - -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -JAVAC="${TESTJAVA}"/bin/javac -JAVA="${TESTJAVA}"/bin/java - -echo "Building test classes..." -"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java - -echo "" -echo "Running test for C locale" -export LANG=C -export LC_ALL=C -"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8 -result1=$? - -echo "" -echo "Running test for en_US.UTF-8 locale" -export LANG=en_US.UTF-8 -export LC_ALL=en_US.UTF-8 -"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8 -result2=$? - -echo "" -echo "Cleanup" -rm ${TESTCLASSES}/ExpectedEncoding.class - -if [ ${result1} -ne 0 ] ; then - echo "Test failed for C locale" - echo " LANG=\"${LANG}\"" - echo " LC_ALL=\"${LC_ALL}\"" - exit ${result1} -fi -if [ ${result2} -ne 0 ] ; then - echo "Test failed for en_US.UTF-8 locale" - echo " LANG=\"${LANG}\"" - echo " LC_ALL=\"${LC_ALL}\"" - exit ${result2} -fi -exit 0 -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/annotation/AnnotationType/AnnotationTypeDeadlockTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 7122142 + * @summary Test deadlock situation when recursive annotations are parsed + */ + +import java.lang.annotation.Retention; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +public class AnnotationTypeDeadlockTest { + + @Retention(RUNTIME) + @AnnB + public @interface AnnA { + } + + @Retention(RUNTIME) + @AnnA + public @interface AnnB { + } + + static class Task extends Thread { + final CountDownLatch prepareLatch; + final AtomicInteger goLatch; + final Class<?> clazz; + + Task(CountDownLatch prepareLatch, AtomicInteger goLatch, Class<?> clazz) { + super(clazz.getSimpleName()); + setDaemon(true); // in case it deadlocks + this.prepareLatch = prepareLatch; + this.goLatch = goLatch; + this.clazz = clazz; + } + + @Override + public void run() { + prepareLatch.countDown(); // notify we are prepared + while (goLatch.get() > 0); // spin-wait before go + clazz.getDeclaredAnnotations(); + } + } + + public static void main(String[] args) throws Exception { + CountDownLatch prepareLatch = new CountDownLatch(2); + AtomicInteger goLatch = new AtomicInteger(1); + Task taskA = new Task(prepareLatch, goLatch, AnnA.class); + Task taskB = new Task(prepareLatch, goLatch, AnnB.class); + taskA.start(); + taskB.start(); + // wait until both threads start-up + prepareLatch.await(); + // let them go + goLatch.set(0); + // obtain ThreadMXBean + ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); + // wait for threads to finish or dead-lock + while (taskA.isAlive() || taskB.isAlive()) { + // attempt to join threads + taskA.join(500L); + taskB.join(500L); + // detect dead-lock + long[] deadlockedIds = threadBean.findMonitorDeadlockedThreads(); + if (deadlockedIds != null && deadlockedIds.length > 0) { + StringBuilder sb = new StringBuilder("deadlock detected:\n\n"); + for (ThreadInfo ti : threadBean.getThreadInfo(deadlockedIds, Integer.MAX_VALUE)) { + sb.append(ti); + } + throw new IllegalStateException(sb.toString()); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/annotation/AnnotationType/AnnotationTypeRuntimeAssumptionTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,187 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 7122142 + * @summary Test consistent parsing of ex-RUNTIME annotations that + * were changed and separately compiled to have CLASS retention + */ + +import sun.misc.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import static java.lang.annotation.RetentionPolicy.CLASS; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * This test simulates a situation where there are two mutually recursive + * {@link RetentionPolicy#RUNTIME RUNTIME} annotations {@link AnnA_v1 AnnA_v1} + * and {@link AnnB AnnB} and then the first is changed to have + * {@link RetentionPolicy#CLASS CLASS} retention and separately compiled. + * When {@link AnnA_v1 AnnA_v1} annotation is looked-up on {@link AnnB AnnB} + * it still appears to have {@link RetentionPolicy#RUNTIME RUNTIME} retention. + */ +public class AnnotationTypeRuntimeAssumptionTest { + + @Retention(RUNTIME) + @AnnB + public @interface AnnA_v1 { + } + + // An alternative version of AnnA_v1 with CLASS retention instead. + // Used to simulate separate compilation (see AltClassLoader below). + @Retention(CLASS) + @AnnB + public @interface AnnA_v2 { + } + + @Retention(RUNTIME) + @AnnA_v1 + public @interface AnnB { + } + + @AnnA_v1 + public static class TestTask implements Runnable { + @Override + public void run() { + AnnA_v1 ann1 = getDeclaredAnnotation(TestTask.class, AnnA_v1.class); + if (ann1 != null) { + throw new IllegalStateException( + "@" + ann1.annotationType().getSimpleName() + + " found on: " + TestTask.class.getName() + + " should not be visible at runtime"); + } + AnnA_v1 ann2 = getDeclaredAnnotation(AnnB.class, AnnA_v1.class); + if (ann2 != null) { + throw new IllegalStateException( + "@" + ann2.annotationType().getSimpleName() + + " found on: " + AnnB.class.getName() + + " should not be visible at runtime"); + } + } + + private static <A extends Annotation> A getDeclaredAnnotation(Class<?> clazz, Class<A> annotationClass) { + for (Annotation ann : clazz.getDeclaredAnnotations()) { + if (ann.annotationType() == annotationClass) { + return annotationClass.cast(ann); + } + } + return null; + } + } + + public static void main(String[] args) throws Exception { + ClassLoader altLoader = new AltClassLoader( + AnnotationTypeRuntimeAssumptionTest.class.getClassLoader()); + + Runnable altTask = (Runnable) Class.forName( + TestTask.class.getName(), + true, + altLoader).newInstance(); + + altTask.run(); + } + + /** + * A ClassLoader implementation that loads alternative implementations of + * classes. If class name ends with "_v1" it locates instead a class with + * name ending with "_v2" and loads that class instead. + */ + static class AltClassLoader extends ClassLoader { + AltClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + protected Class<?> loadClass(String name, boolean resolve) + throws ClassNotFoundException { + if (name.indexOf('.') < 0) { // root package is our class + synchronized (getClassLoadingLock(name)) { + // First, check if the class has already been loaded + Class<?> c = findLoadedClass(name); + if (c == null) { + c = findClass(name); + } + if (resolve) { + resolveClass(c); + } + return c; + } + } + else { // not our class + return super.loadClass(name, resolve); + } + } + + @Override + protected Class<?> findClass(String name) + throws ClassNotFoundException { + // special class name -> replace it with alternative name + if (name.endsWith("_v1")) { + String altName = name.substring(0, name.length() - 3) + "_v2"; + String altPath = altName.replace('.', '/').concat(".class"); + try (InputStream is = getResourceAsStream(altPath)) { + if (is != null) { + byte[] bytes = IOUtils.readFully(is, -1, true); + // patch class bytes to contain original name + for (int i = 0; i < bytes.length - 2; i++) { + if (bytes[i] == '_' && + bytes[i + 1] == 'v' && + bytes[i + 2] == '2') { + bytes[i + 2] = '1'; + } + } + return defineClass(name, bytes, 0, bytes.length); + } + else { + throw new ClassNotFoundException(name); + } + } + catch (IOException e) { + throw new ClassNotFoundException(name, e); + } + } + else { // not special class name -> just load the class + String path = name.replace('.', '/').concat(".class"); + try (InputStream is = getResourceAsStream(path)) { + if (is != null) { + byte[] bytes = IOUtils.readFully(is, -1, true); + return defineClass(name, bytes, 0, bytes.length); + } + else { + throw new ClassNotFoundException(name); + } + } + catch (IOException e) { + throw new ClassNotFoundException(name, e); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/8009222/Test8009222.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8009222 + * @summary java.lang.IllegalArgumentException: not invocable, no method type + * when attempting to get getter method handle for a static field + * + * @run main/othervm Test8009222 + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +interface Intf { + static int i = 0; +} + +public class Test8009222 { + public static void main(String[] args) throws Exception { + MethodHandles.lookup() + .findStaticGetter(Intf.class, "i", int.class) + .getClass(); // null check + + System.out.println("TEST PASSED"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/TestCatchExceptionWithVarargs.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8019184 + * @summary MethodHandles.catchException() fails when methods have 8 args + varargs + */ + +import java.util.*; +import java.lang.invoke.*; + +public class TestCatchExceptionWithVarargs { + + private static final Class<?> CLASS = TestCatchExceptionWithVarargs.class; + private static final int MAX_MH_ARITY = 254; + + public static MethodHandle target; + public static MethodHandle handler; + + private static Object firstArg; + + static class MyException extends Exception { + } + + public static Object target(Object... a) throws Exception { + if (a[0] != firstArg) { + throw new AssertionError("first argument different than expected: " + a[0] + " != " + firstArg); + } + throw new MyException(); + } + + public static Object handler(Object... a) { + if (a[0] != firstArg) { + throw new AssertionError("first argument different than expected: " + a[0] + " != " + firstArg); + } + return a[0]; + } + + static { + try { + MethodType mtype = MethodType.methodType(Object.class, Object[].class); + target = MethodHandles.lookup().findStatic(CLASS, "target", mtype); + handler = MethodHandles.lookup().findStatic(CLASS, "handler", mtype); + } catch (Exception e) { + throw new AssertionError(e); + } + } + + public static void main(String[] args) throws Throwable { + List<Class<?>> ptypes = new LinkedList<>(); + ptypes.add(Object[].class); + + // We use MAX_MH_ARITY - 1 here to account for the Object[] argument. + for (int i = 1; i < MAX_MH_ARITY - 1; i++) { + ptypes.add(0, Object.class); + + MethodHandle targetWithArgs = target.asType(MethodType.methodType(Object.class, ptypes)); + MethodHandle handlerWithArgs = handler.asType(MethodType.methodType(Object.class, ptypes)); + handlerWithArgs = MethodHandles.dropArguments(handlerWithArgs, 0, MyException.class); + + MethodHandle gwc1 = MethodHandles.catchException(targetWithArgs, MyException.class, handlerWithArgs); + + // The next line throws an IllegalArgumentException if there is a bug. + MethodHandle gwc2 = MethodHandles.catchException(gwc1, MyException.class, handlerWithArgs); + + // This is only to verify that the method handles can actually be invoked and do the right thing. + firstArg = new Object(); + Object o = gwc2.asSpreader(Object[].class, ptypes.size() - 1).invoke(firstArg, new Object[i]); + if (o != firstArg) { + throw new AssertionError("return value different than expected: " + o + " != " + firstArg); + } + } + } +}
--- a/test/java/net/Authenticator/B4769350.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/net/Authenticator/B4769350.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, 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 @@ -23,9 +23,7 @@ /** * @test - * @bug 4769350 - * @library ../../../sun/net/www/httptest/ - * @build HttpCallback HttpServer ClosedChannelList HttpTransaction AbstractCallback + * @bug 4769350 8017779 * @run main/othervm B4769350 server * @run main/othervm B4769350 proxy * @summary proxy authentication username and password caching only works in serial case @@ -34,8 +32,17 @@ * tests may already have invoked the HTTP handler. */ +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; import java.io.*; import java.net.*; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class B4769350 { @@ -43,13 +50,12 @@ static boolean error = false; static void read (InputStream is) throws IOException { - int c; - while ((c=is.read()) != -1) { + while (is.read() != -1) { //System.out.write (c); } } - static class Client extends Thread { + static class Client extends Thread { String authority, path; boolean allowerror; @@ -64,8 +70,8 @@ try { URI u = new URI ("http", authority, path, null, null); URL url = u.toURL(); - URLConnection urlc = url.openConnection (); - InputStream is = urlc.getInputStream (); + URLConnection urlc = url.openConnection(); + InputStream is = urlc.getInputStream(); read (is); is.close(); } catch (URISyntaxException e) { @@ -73,7 +79,8 @@ error = true; } catch (IOException e) { if (!allowerror) { - System.out.println (Thread.currentThread().getName() + " " + e); + System.out.println (Thread.currentThread().getName() + + " " + e); e.printStackTrace(); error = true; } @@ -81,55 +88,58 @@ } } - static class CallBack extends AbstractCallback { - - void errorReply (HttpTransaction req, String reply) throws IOException { - req.addResponseHeader ("Connection", "close"); - req.addResponseHeader ("WWW-Authenticate", reply); - req.sendResponse (401, "Unauthorized"); - req.orderlyClose(); - } + class Server implements AutoCloseable { + HttpServer server; + Executor executor; + CyclicBarrier t1Cond1; + CyclicBarrier t1Cond2; - void proxyReply (HttpTransaction req, String reply) throws IOException { - req.addResponseHeader ("Proxy-Authenticate", reply); - req.sendResponse (407, "Proxy Authentication Required"); - } - - void okReply (HttpTransaction req) throws IOException { - req.addResponseHeader ("Connection", "close"); - req.setResponseEntityBody ("Hello ."); - req.sendResponse (200, "Ok"); - req.orderlyClose(); + public String getAddress() { + return server.getAddress().getHostName(); } - public void request (HttpTransaction req, int count) { + public void startServer() { + InetSocketAddress addr = new InetSocketAddress(0); + try { - URI uri = req.getRequestURI(); - String path = uri.getPath(); - if (path.endsWith ("/t1a")) { - doT1a (req, count); - } else if (path.endsWith ("/t1b")) { - doT1b (req, count); - } else if (path.endsWith ("/t1c")) { - doT1c (req, count); - } else if (path.endsWith ("/t1d")) { - doT1d (req, count); - } else if (path.endsWith ("/t2a")) { - doT2a (req, count); - } else if (path.endsWith ("/t2b")) { - doT2b (req, count); - } else if (path.endsWith ("/t3a")) { - doT3a (req, count); - } else if (path.endsWith ("/t3b")) { - doT3bc (req, count); - } else if (path.endsWith ("/t3c")) { - doT3bc (req, count); - } else { - System.out.println ("unexpected request URI"); - } - } catch (IOException e) { - e.printStackTrace(); + server = HttpServer.create(addr, 0); + } catch (IOException ioe) { + throw new RuntimeException("Server could not be created"); } + executor = Executors.newFixedThreadPool(10); + server.setExecutor(executor); + server.createContext("/test/realm1/t1a", + new AuthenticationHandlerT1a() ); + server.createContext("/test/realm2/t1b", + new AuthenticationHandlerT1b()); + server.createContext("/test/realm1/t1c", + new AuthenticationHandlerT1c()); + server.createContext("/test/realm2/t1d", + new AuthenticationHandlerT1d()); + server.createContext("/test/realm3/t2a", + new AuthenticationHandlerT2a()); + server.createContext("/test/realm3/t2b", + new AuthenticationHandlerT2b()); + server.createContext("/test/realm4/t3a", + new AuthenticationHandlerT3a()); + server.createContext("/test/realm4/t3b", + new AuthenticationHandlerT3bc()); + server.createContext("/test/realm4/t3c", + new AuthenticationHandlerT3bc()); + t1Cond1 = new CyclicBarrier(2); + t1Cond2 = new CyclicBarrier(2); + server.start(); + } + + public int getPort() { + return server.getAddress().getPort(); + } + + public void close() { + if (executor != null) + ((ExecutorService)executor).shutdownNow(); + if (server != null) + server.stop(0); } /* T1 tests the client by sending 4 requests to 2 different realms @@ -138,90 +148,158 @@ * the second requests should be executed without calling the authenticator. * The test succeeds if the authenticator was only called twice. */ - void doT1a (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - errorReply (req, "Basic realm=\"realm1\""); - HttpServer.rendezvous ("one", 2); - break; - case 1: - HttpServer.waitForCondition ("cond2"); - okReply (req); - break; - default: - System.out.println ("Unexpected request"); + class AuthenticationHandlerT1a implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + try { + switch(count) { + case 0: + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm1\""); + break; + case 1: + t1Cond1.await(); + t1cond2latch.await(); + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } + } catch (InterruptedException | + BrokenBarrierException e) + { + throw new RuntimeException(e); + } + } + } + + class AuthenticationHandlerT1b implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + try { + switch(count) { + case 0: + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm2\""); + break; + case 1: + t1Cond1.await(); + t1cond1latch.countDown(); + t1cond2latch.await(); + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } + } catch (InterruptedException | BrokenBarrierException e) { + throw new RuntimeException(e); + } } } + class AuthenticationHandlerT1c implements HttpHandler + { + volatile int count = -1; - void doT1b (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - errorReply (req, "Basic realm=\"realm2\""); - HttpServer.rendezvous ("one", 2); - HttpServer.setCondition ("cond1"); - break; - case 1: - HttpServer.waitForCondition ("cond2"); - okReply (req); - break; - default: - System.out.println ("Unexpected request"); + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + switch(count) { + case 0: + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm1\""); + try { + t1Cond2.await(); + } catch (InterruptedException | + BrokenBarrierException e) + { + throw new RuntimeException(e); + } + break; + case 1: + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } } } - void doT1c (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - errorReply (req, "Basic realm=\"realm1\""); - HttpServer.rendezvous ("two", 2); - break; - case 1: - okReply (req); - break; - default: - System.out.println ("Unexpected request"); + class AuthenticationHandlerT1d implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + switch(count) { + case 0: + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm2\""); + try { + t1Cond2.await(); + } catch (InterruptedException | + BrokenBarrierException e) + { + throw new RuntimeException(e); + } + t1cond2latch.countDown(); + break; + case 1: + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } } } - void doT1d (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - errorReply (req, "Basic realm=\"realm2\""); - HttpServer.rendezvous ("two", 2); - HttpServer.setCondition ("cond2"); - break; - case 1: - okReply (req); - break; - default: - System.out.println ("Unexpected request"); - } - } - - /* T2 tests to check that if initial authentication fails, the second will * succeed, and the authenticator is called twice */ - void doT2a (HttpTransaction req, int count) throws IOException { - /* This will be called several times */ - if (count == 1) { - HttpServer.setCondition ("T2cond1"); + class AuthenticationHandlerT2a implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + if (count == 1) { + t2condlatch.countDown(); + } + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm3\""); + } - errorReply (req, "Basic realm=\"realm3\""); } - void doT2b (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - errorReply (req, "Basic realm=\"realm3\""); - break; - case 1: - okReply (req); - break; - default: - System.out.println ("Unexpected request"); + class AuthenticationHandlerT2b implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + switch(count) { + case 0: + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm3\""); + break; + case 1: + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } } } @@ -229,36 +307,82 @@ * resource at same time. Authenticator should be called once for server * and once for proxy */ - void doT3a (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - proxyReply (req, "Basic realm=\"proxy\""); - HttpServer.setCondition ("T3cond1"); - break; - case 1: - errorReply (req, "Basic realm=\"realm4\""); - break; - case 2: - okReply (req); - break; - default: - System.out.println ("Unexpected request"); + + class AuthenticationHandlerT3a implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + switch(count) { + case 0: + AuthenticationHandler.proxyReply(exchange, + "Basic realm=\"proxy\""); + break; + case 1: + t3cond1.countDown(); + AuthenticationHandler.errorReply(exchange, + "Basic realm=\"realm4\""); + break; + case 2: + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } } } - void doT3bc (HttpTransaction req, int count) throws IOException { - switch (count) { - case 0: - proxyReply (req, "Basic realm=\"proxy\""); - break; - case 1: - okReply (req); - break; - default: - System.out.println ("Unexpected request"); + class AuthenticationHandlerT3bc implements HttpHandler + { + volatile int count = -1; + + @Override + public void handle(HttpExchange exchange) throws IOException { + count++; + switch(count) { + case 0: + AuthenticationHandler.proxyReply(exchange, + "Basic realm=\"proxy\""); + break; + case 1: + AuthenticationHandler.okReply(exchange); + break; + default: + System.out.println ("Unexpected request"); + } } } - }; + } + + static class AuthenticationHandler { + static void errorReply(HttpExchange exchange, String reply) + throws IOException + { + exchange.getResponseHeaders().add("Connection", "close"); + exchange.getResponseHeaders().add("WWW-Authenticate", reply); + exchange.sendResponseHeaders(401, 0); + exchange.close(); + } + + static void proxyReply (HttpExchange exchange, String reply) + throws IOException + { + exchange.getResponseHeaders().add("Proxy-Authenticate", reply); + exchange.sendResponseHeaders(407, 0); + } + + static void okReply (HttpExchange exchange) throws IOException { + exchange.getResponseHeaders().add("Connection", "close"); + String response = "Hello ."; + exchange.sendResponseHeaders(200, response.getBytes().length); + OutputStream os = exchange.getResponseBody(); + os.write(response.getBytes()); + os.close(); + exchange.close(); + } + } static HttpServer server; static MyAuthenticator auth = new MyAuthenticator (); @@ -267,7 +391,14 @@ static Client c1,c2,c3,c4,c5,c6,c7,c8,c9; - static void doServerTests (String authority) throws Exception { + static CountDownLatch t1cond1latch; + static CountDownLatch t1cond2latch; + static CountDownLatch t2condlatch; + static CountDownLatch t3cond1; + + static void doServerTests (String authority, Server server) throws Exception + { + System.out.println ("Doing Server tests"); System.out.println ("T1"); c1 = new Client (authority, "/test/realm1/t1a", false); @@ -275,17 +406,20 @@ c3 = new Client (authority, "/test/realm1/t1c", false); c4 = new Client (authority, "/test/realm2/t1d", false); + t1cond1latch = new CountDownLatch(1); + t1cond2latch = new CountDownLatch(1); c1.start(); c2.start(); - HttpServer.waitForCondition ("cond1"); + t1cond1latch.await(); c3.start(); c4.start(); c1.join(); c2.join(); c3.join(); c4.join(); int f = auth.getCount(); if (f != 2) { - except ("Authenticator was called "+f+" times. Should be 2"); + except ("Authenticator was called "+f+" times. Should be 2", + server); } if (error) { - except ("error occurred"); + except ("error occurred", server); } auth.resetCount(); @@ -293,73 +427,71 @@ c5 = new Client (authority, "/test/realm3/t2a", true); c6 = new Client (authority, "/test/realm3/t2b", false); + t2condlatch = new CountDownLatch(1); c5.start (); - HttpServer.waitForCondition ("T2cond1"); + t2condlatch.await(); c6.start (); c5.join(); c6.join(); f = auth.getCount(); if (f != redirects+1) { - except ("Authenticator was called "+f+" times. Should be: " + redirects+1); + except ("Authenticator was called "+f+" times. Should be: " + + redirects+1, server); } if (error) { - except ("error occurred"); + except ("error occurred", server); } } - static void doProxyTests (String authority) throws Exception { + static void doProxyTests (String authority, Server server) throws Exception + { System.out.println ("Doing Proxy tests"); c7 = new Client (authority, "/test/realm4/t3a", false); c8 = new Client (authority, "/test/realm4/t3b", false); c9 = new Client (authority, "/test/realm4/t3c", false); + t3cond1 = new CountDownLatch(1); c7.start (); - HttpServer.waitForCondition ("T3cond1"); + t3cond1.await(); c8.start (); c9.start (); c7.join(); c8.join(); c9.join(); int f = auth.getCount(); if (f != 2) { - except ("Authenticator was called "+f+" times. Should be: " + 2); + except ("Authenticator was called "+f+" times. Should be: " + 2, + server); } if (error) { - except ("error occurred"); + except ("error occurred", server); } } public static void main (String[] args) throws Exception { + new B4769350().runTest(args[0].equals ("proxy")); + } + + public void runTest(boolean proxy) throws Exception { System.setProperty ("http.maxRedirects", Integer.toString (redirects)); System.setProperty ("http.auth.serializeRequests", "true"); Authenticator.setDefault (auth); - boolean proxy = args[0].equals ("proxy"); - try { - server = new HttpServer (new CallBack(), 10, 1, 0); - System.out.println ("Server: listening on port: " + server.getLocalPort()); + try (Server server = new Server()) { + server.startServer(); + System.out.println ("Server: listening on port: " + + server.getPort()); if (proxy) { System.setProperty ("http.proxyHost", "localhost"); - System.setProperty ("http.proxyPort",Integer.toString(server.getLocalPort())); - doProxyTests ("www.foo.com"); + System.setProperty ("http.proxyPort", + Integer.toString(server.getPort())); + doProxyTests ("www.foo.com", server); } else { - doServerTests ("localhost:"+server.getLocalPort()); + doServerTests ("localhost:"+server.getPort(), server); } - server.terminate(); + } - } catch (Exception e) { - if (server != null) { - server.terminate(); - } - throw e; - } } - static void pause (int millis) { - try { - Thread.sleep (millis); - } catch (InterruptedException e) {} - } - - public static void except (String s) { - server.terminate(); + public static void except (String s, Server server) { + server.close(); throw new RuntimeException (s); } @@ -368,13 +500,10 @@ super (); } - int count = 0; + volatile int count = 0; + @Override public PasswordAuthentication getPasswordAuthentication () { - //System.out.println ("Authenticator called: " + getRequestingPrompt()); - //try { - //Thread.sleep (1000); - //} catch (InterruptedException e) {} PasswordAuthentication pw; pw = new PasswordAuthentication ("user", "pass1".toCharArray()); count ++; @@ -386,7 +515,7 @@ } public int getCount () { - return (count); + return count; } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/CookieHandler/LocalHostCookie.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.net.httpserver.*; +import java.io.IOException; +import java.io.OutputStream; +import java.net.*; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; + +/* + * @test + * @bug 7169142 + * @summary CookieHandler does not work with localhost + * @run main/othervm LocalHostCookie + */ +public class LocalHostCookie { + + public static void main(String[] args) throws Exception { + new LocalHostCookie().runTest(); + } + + public void runTest() throws Exception { + Server s = null; + try { + s = new Server(); + s.startServer(); + URL url = new URL("http","localhost", s.getPort(), "/"); + HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection(); + urlConnection.setRequestMethod("GET"); + urlConnection.setDoOutput(true); + urlConnection.connect(); + urlConnection.getInputStream(); + + CookieHandler cookieHandler = CookieHandler.getDefault(); + if (cookieHandler == null) { + cookieHandler = new java.net.CookieManager(); + CookieHandler.setDefault(cookieHandler); + } + cookieHandler.put(urlConnection.getURL().toURI(), + urlConnection.getHeaderFields()); + Map<String, List<String>> map = + cookieHandler.get(urlConnection.getURL().toURI(), + urlConnection.getHeaderFields()); + if (map.containsKey("Cookie")) { + List<String> list = map.get("Cookie"); + // name-value list will be empty if ".local" is not appended + if (list == null || list.size() == 0) { + throw new RuntimeException("Test failed!"); + } + } + } finally { + s.stopServer(); + } + } + + class Server { + HttpServer server; + + public void startServer() { + InetSocketAddress addr = new InetSocketAddress(0); + try { + server = HttpServer.create(addr, 0); + } catch (IOException ioe) { + throw new RuntimeException("Server could not be created"); + } + + server.createContext("/", new MyCookieHandler()); + server.start(); + } + + public int getPort() { + return server.getAddress().getPort(); + } + + public void stopServer() { + server.stop(0); + } + } + + class MyCookieHandler implements HttpHandler { + + @Override + public void handle(HttpExchange exchange) throws IOException { + String requestMethod = exchange.getRequestMethod(); + if (requestMethod.equalsIgnoreCase("GET")){ + Headers responseHeaders = exchange.getResponseHeaders(); + responseHeaders.set("Content-Type", "text/plain"); + responseHeaders.set("Date", "June 13th 2012"); + // No domain value set + responseHeaders.set("Set-Cookie2", "name=value"); + exchange.sendResponseHeaders(200, 0); + OutputStream os = exchange.getResponseBody(); + String str = "This is what the server sent!"; + os.write(str.getBytes()); + os.flush(); + os.close(); + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/IDN/UseSTD3ASCIIRules.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8023881 + * @summary IDN.USE_STD3_ASCII_RULES option is too strict to use Unicode + * in IDN.toASCII + */ + +import java.net.*; + +public class UseSTD3ASCIIRules { + + public static void main(String[] args) throws Exception { + // Per Section 4.1, RFC 3490, if the UseSTD3ASCIIRules flag is set, + // then perform these checks: + // + // (a) Verify the absence of non-LDH ASCII code points; that is, the + // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F. + // + // (b) Verify the absence of leading and trailing hyphen-minus; that + // is, the absence of U+002D at the beginning and end of the + // sequence. + String[] illegalNames = { + "www.example.com-", + "-www.example.com", + "-www.example.com-", + "www.ex\u002Cmple.com", + "www.ex\u007Bmple.com", + "www.ex\u007Fmple.com" + }; + + String[] legalNames = { + "www.ex-ample.com", + "www.ex\u002Dmple.com", // www.ex-mple.com + "www.ex\u007Ample.com", // www.exzmple.com + "www.ex\u3042mple.com", // www.xn--exmple-j43e.com + "www.\u3042\u3044\u3046.com", // www.xn--l8jeg.com + "www.\u793A\u4F8B.com" // www.xn--fsq092h.com + }; + + for (String name : illegalNames) { + try { + System.out.println("Convering illegal IDN: " + name); + IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES); + throw new Exception( + "Expected to get IllegalArgumentException for " + name); + } catch (IllegalArgumentException iae) { + // That's the right behavior. + } + } + + for (String name : legalNames) { + System.out.println("Convering legal IDN: " + name); + System.out.println("\tThe ACE form is: " + + IDN.toASCII(name, IDN.USE_STD3_ASCII_RULES)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/NetworkInterface/UniqueMacAddressesTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; + + +/* + * @test + * @bug 8021372 + * @summary Tests that the MAC addresses returned by NetworkInterface.getNetworkInterfaces are unique for each adapter. + * + */ +public class UniqueMacAddressesTest { + + public static void main(String[] args) throws Exception { + new UniqueMacAddressesTest().execute(); + System.out.println("UniqueMacAddressesTest: OK"); + } + + public UniqueMacAddressesTest() { + System.out.println("UniqueMacAddressesTest: start "); + } + + public void execute() throws Exception { + Enumeration<NetworkInterface> networkInterfaces; + boolean areMacAddressesUnique = false; + List<NetworkInterface> networkInterfaceList = new ArrayList<NetworkInterface>(); + networkInterfaces = NetworkInterface.getNetworkInterfaces(); + + // build a list of NetworkInterface objects to test MAC address + // uniqueness + createNetworkInterfaceList(networkInterfaces, networkInterfaceList); + areMacAddressesUnique = checkMacAddressesAreUnique(networkInterfaceList); + if (!areMacAddressesUnique) { + throw new RuntimeException("mac address uniqueness test failed"); + } + } + + private boolean checkMacAddressesAreUnique ( + List<NetworkInterface> networkInterfaces) throws Exception { + boolean uniqueMacAddresses = true; + for (NetworkInterface networkInterface : networkInterfaces) { + for (NetworkInterface comparisonNetIf : networkInterfaces) { + System.out.println("Comparing netif " + + networkInterface.getName() + " and netif " + + comparisonNetIf.getName()); + if (testMacAddressesEqual(networkInterface, comparisonNetIf)) { + uniqueMacAddresses = false; + break; + } + } + if (uniqueMacAddresses != true) + break; + } + return uniqueMacAddresses; + } + + private boolean testMacAddressesEqual(NetworkInterface netIf1, + NetworkInterface netIf2) throws Exception { + + byte[] rawMacAddress1 = null; + byte[] rawMacAddress2 = null; + boolean macAddressesEqual = false; + if (!netIf1.getName().equals(netIf2.getName())) { + System.out.println("compare hardware addresses " + + createMacAddressString(netIf1) + " and " + createMacAddressString(netIf2)); + rawMacAddress1 = netIf1.getHardwareAddress(); + rawMacAddress2 = netIf2.getHardwareAddress(); + macAddressesEqual = Arrays.equals(rawMacAddress1, rawMacAddress2); + } else { + // same interface + macAddressesEqual = false; + } + return macAddressesEqual; + } + + private String createMacAddressString (NetworkInterface netIf) throws Exception { + byte[] macAddr = netIf.getHardwareAddress(); + StringBuilder sb = new StringBuilder(); + if (macAddr != null) { + for (int i = 0; i < macAddr.length; i++) { + sb.append(String.format("%02X%s", macAddr[i], + (i < macAddr.length - 1) ? "-" : "")); + } + } + return sb.toString(); + } + + private void createNetworkInterfaceList(Enumeration<NetworkInterface> nis, + List<NetworkInterface> networkInterfaceList) throws Exception { + byte[] macAddr = null; + NetworkInterface netIf = null; + while (nis.hasMoreElements()) { + netIf = (NetworkInterface) nis.nextElement(); + if (netIf.isUp()) { + macAddr = netIf.getHardwareAddress(); + if (macAddr != null) { + System.out.println("Adding NetworkInterface " + + netIf.getName() + " with mac address " + + createMacAddressString(netIf)); + networkInterfaceList.add(netIf); + } + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/net/ServerSocket/AnotherSelectFdsLimit.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,78 @@ +/* + * 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 8035897 + * @summary FD_SETSIZE should be set on macosx + * @run main/othervm AnotherSelectFdsLimit 1023 + * @run main/othervm AnotherSelectFdsLimit 1024 + * @run main/othervm AnotherSelectFdsLimit 1025 + * @run main/othervm AnotherSelectFdsLimit 1600 + */ + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.List; + +public class AnotherSelectFdsLimit { + static final int DEFAULT_FDS_TO_USE = 1600; + + public static void main(String [] args) throws Exception { + if (!System.getProperty("os.name").contains("OS X")) { + System.out.println("Test only run on MAC. Exiting."); + return; + } + + int fdsToUse = DEFAULT_FDS_TO_USE; + if (args.length == 1) + fdsToUse = Integer.parseInt(args[0]); + + System.out.println("Using " + fdsToUse + " fds."); + + List<Thread> threads = new ArrayList<>(); + for (int i=0; i<fdsToUse; i++) + threads.add(new WorkerThread()); + + for (Thread t : threads) + t.start(); + + for (Thread t : threads) + t.join(); + } + + static class WorkerThread extends Thread { + public void run() { + try (ServerSocket ss = new ServerSocket(0)) { + ss.setSoTimeout(2000); + ss.accept(); + } catch (SocketTimeoutException x) { + // expected + } catch (IOException x) { + throw new RuntimeException(x); + } + } + } +}
--- a/test/java/net/Socket/asyncClose/Race.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/net/Socket/asyncClose/Race.java Thu Apr 03 00:39:02 2014 +0100 @@ -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,8 +23,8 @@ /* * @test - * @bug 8006395 - * @summary Race in async socket close on Linux + * @bug 8006395 8012244 + * @summary Tests racing code that reads and closes a Socket */ import java.io.InputStream; @@ -58,7 +58,7 @@ Thread.sleep(50); } catch (Exception x) { if (!(x instanceof SocketException - && x.getMessage().equals("Socket closed"))) + && x.getMessage().equalsIgnoreCase("socket closed"))) x.printStackTrace(); // ok, expect Socket closed }
--- a/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java Thu Apr 03 00:39:02 2014 +0100 @@ -36,44 +36,31 @@ // number of concurrent completion handlers static final int CONCURRENCY_COUNT = 256; + // set to true if an I/O operation fails + static volatile boolean failed; + + // set to true when the test is done + static volatile boolean finished; + public static void main(String[] args) throws Exception { - // all accepted connections are added to a queue - final ArrayBlockingQueue<AsynchronousSocketChannel> queue = - new ArrayBlockingQueue<AsynchronousSocketChannel>(CONCURRENCY_COUNT); - // create listener to accept connections - final AsynchronousServerSocketChannel listener = + AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open() .bind(new InetSocketAddress(0)); - listener.accept((Void)null, new CompletionHandler<AsynchronousSocketChannel,Void>() { - public void completed(AsynchronousSocketChannel ch, Void att) { - queue.add(ch); - listener.accept((Void)null, this); - } - public void failed(Throwable exc, Void att) { - } - }); - System.out.println("Listener created."); + + // establish connections - // establish lots of connections + AsynchronousSocketChannel[] clients = new AsynchronousSocketChannel[CONCURRENCY_COUNT]; + AsynchronousSocketChannel[] peers = new AsynchronousSocketChannel[CONCURRENCY_COUNT]; + int port = ((InetSocketAddress)(listener.getLocalAddress())).getPort(); SocketAddress sa = new InetSocketAddress(InetAddress.getLocalHost(), port); - AsynchronousSocketChannel[] channels = - new AsynchronousSocketChannel[CONCURRENCY_COUNT]; + for (int i=0; i<CONCURRENCY_COUNT; i++) { - int attempts = 0; - for (;;) { - try { - channels[i] = AsynchronousSocketChannel.open(); - channels[i].connect(sa).get(); - break; - } catch (IOException x) { - // probably resource issue so back off and retry - if (++attempts >= 3) - throw x; - Thread.sleep(50); - } - } + clients[i] = AsynchronousSocketChannel.open(); + Future<Void> result = clients[i].connect(sa); + peers[i] = listener.accept().get(); + result.get(); } System.out.println("All connection established."); @@ -81,9 +68,9 @@ final CyclicBarrier barrier = new CyclicBarrier(CONCURRENCY_COUNT+1); // initiate a read operation on each channel. - for (int i=0; i<CONCURRENCY_COUNT; i++) { + for (AsynchronousSocketChannel client: clients) { ByteBuffer buf = ByteBuffer.allocateDirect(100); - channels[i].read( buf, channels[i], + client.read(buf, client, new CompletionHandler<Integer,AsynchronousSocketChannel>() { public void completed(Integer bytesRead, AsynchronousSocketChannel ch) { try { @@ -94,23 +81,29 @@ } } public void failed(Throwable exc, AsynchronousSocketChannel ch) { + failed = true; + System.err.println("read failed: " + exc); + completed(0, ch); } }); } System.out.println("All read operations outstanding."); // write data to each of the accepted connections - int remaining = CONCURRENCY_COUNT; - while (remaining > 0) { - AsynchronousSocketChannel ch = queue.take(); - ch.write(ByteBuffer.wrap("welcome".getBytes())).get(); - ch.close(); - remaining--; + for (AsynchronousSocketChannel peer: peers) { + peer.write(ByteBuffer.wrap("welcome".getBytes())).get(); + peer.shutdownOutput(); + peer.close(); } // wait for all threads to reach the barrier System.out.println("Waiting for all threads to reach barrier"); barrier.await(); + + // finish up + finished = true; listener.close(); + if (failed) + throw new RuntimeException("I/O operation failed, see log for details"); } }
--- a/test/java/nio/channels/Selector/ByteServer.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/channels/Selector/ByteServer.java Thu Apr 03 00:39:02 2014 +0100 @@ -22,52 +22,54 @@ */ /** - * - * Utility class for tests. A simple server, which waits for a connection, - * writes out n bytes and waits. + * Utility class for tests. A simple "in-thread" server to accept connections + * and write bytes. * @author kladko */ import java.net.Socket; import java.net.ServerSocket; - -public class ByteServer { +import java.net.SocketAddress; +import java.net.InetSocketAddress; +import java.io.IOException; +import java.io.Closeable; - public static final String LOCALHOST = "localhost"; - private int bytecount; - private Socket socket; - private ServerSocket serversocket; - private Thread serverthread; - volatile Exception savedException; +public class ByteServer implements Closeable { - public ByteServer(int bytecount) throws Exception{ - this.bytecount = bytecount; - serversocket = new ServerSocket(0); + private final ServerSocket ss; + private Socket s; + + ByteServer() throws IOException { + this.ss = new ServerSocket(0); } - public int port() { - return serversocket.getLocalPort(); + SocketAddress address() { + return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort()); } - public void start() { - serverthread = new Thread() { - public void run() { - try { - socket = serversocket.accept(); - socket.getOutputStream().write(new byte[bytecount]); - socket.getOutputStream().flush(); - } catch (Exception e) { - System.err.println("Exception in ByteServer: " + e); - System.exit(1); - } - } - }; - serverthread.start(); + void acceptConnection() throws IOException { + if (s != null) + throw new IllegalStateException("already connected"); + this.s = ss.accept(); } - public void exit() throws Exception { - serverthread.join(); - socket.close(); - serversocket.close(); + void closeConnection() throws IOException { + Socket s = this.s; + if (s != null) { + this.s = null; + s.close(); + } + } + + void write(int count) throws IOException { + if (s == null) + throw new IllegalStateException("no connection"); + s.getOutputStream().write(new byte[count]); + } + + public void close() throws IOException { + if (s != null) + s.close(); + ss.close(); } }
--- a/test/java/nio/channels/Selector/ReadAfterConnect.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/channels/Selector/ReadAfterConnect.java Thu Apr 03 00:39:02 2014 +0100 @@ -27,27 +27,25 @@ * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class ReadAfterConnect { + public static void main(String[] argv) throws Exception { + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { - public static void main(String[] argv) throws Exception { - ByteServer server = new ByteServer(0); // server: accept connection and do nothing - server.start(); - InetSocketAddress isa = new InetSocketAddress( - InetAddress.getByName(ByteServer.LOCALHOST), server.port()); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(isa); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_READ); - // Previously channel would get selected here, although there is nothing to read - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - server.exit(); + server.acceptConnection(); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + // Previously channel would get selected here, although there is nothing to read + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } } }
--- a/test/java/nio/channels/Selector/SelectAfterRead.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/channels/Selector/SelectAfterRead.java Thu Apr 03 00:39:02 2014 +0100 @@ -28,60 +28,62 @@ * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.nio.ByteBuffer; +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class SelectAfterRead { - final static int TIMEOUT = 1000; + private static final int TIMEOUT = 1000; public static void main(String[] argv) throws Exception { - InetAddress lh = InetAddress.getByName(ByteServer.LOCALHOST); // server: accept connection and write one byte - ByteServer server = new ByteServer(1); - server.start(); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(new InetSocketAddress(lh, server.port())); - sc.read(ByteBuffer.allocate(1)); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_READ); - // previously on Windows select would select channel here, although there was - // nothing to read - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - sel.close(); - server.exit(); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + server.write(1); + + try (Selector sel = Selector.open()) { + sc.read(ByteBuffer.allocate(1)); + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + // previously on Windows select would select channel here, although there was + // nothing to read + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } // Now we will test a two reads combination // server: accept connection and write two bytes - server = new ByteServer(2); - server.start(); - sc = SocketChannel.open(); - sc.connect(new InetSocketAddress(lh, server.port())); - sc.configureBlocking(false); - sel = Selector.open(); - sc.register(sel, SelectionKey.OP_READ); - if (sel.select(TIMEOUT) != 1) - throw new Exception("One selected key expected"); - sel.selectedKeys().clear(); - // previously on Windows a channel would get selected only once - if (sel.selectNow() != 1) - throw new Exception("One selected key expected"); - // Previously on Windows two consequent reads would cause select() - // to select a channel, although there was nothing remaining to - // read in the channel - if (sc.read(ByteBuffer.allocate(1)) != 1) - throw new Exception("One byte expected"); - if (sc.read(ByteBuffer.allocate(1)) != 1) - throw new Exception("One byte expected"); - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - sel.close(); - server.exit(); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + server.write(2); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + if (sel.select(TIMEOUT) != 1) + throw new Exception("One selected key expected"); + sel.selectedKeys().clear(); + // previously on Windows a channel would get selected only once + if (sel.selectNow() != 1) + throw new Exception("One selected key expected"); + // Previously on Windows two consequent reads would cause select() + // to select a channel, although there was nothing remaining to + // read in the channel + if (sc.read(ByteBuffer.allocate(1)) != 1) + throw new Exception("One byte expected"); + if (sc.read(ByteBuffer.allocate(1)) != 1) + throw new Exception("One byte expected"); + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } } }
--- a/test/java/nio/channels/Selector/SelectWrite.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/channels/Selector/SelectWrite.java Thu Apr 03 00:39:02 2014 +0100 @@ -22,36 +22,33 @@ */ /* @test - @bug 4645302 - @summary Socket with OP_WRITE would get selected only once - @author kladko + * @bug 4645302 + * @summary Socket with OP_WRITE would get selected only once + * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; - +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class SelectWrite { public static void main(String[] argv) throws Exception { - ByteServer server = new ByteServer(0); - // server: accept connection and do nothing - server.start(); - InetSocketAddress isa = new InetSocketAddress( - InetAddress.getByName(ByteServer.LOCALHOST), server.port()); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(isa); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_WRITE); - sel.select(); - sel.selectedKeys().clear(); - if (sel.select() == 0) { - throw new Exception("Select returned zero"); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_WRITE); + sel.select(); + sel.selectedKeys().clear(); + if (sel.select() == 0) { + throw new Exception("Select returned zero"); + } + } } - sc.close(); - sel.close(); } }
--- a/test/java/nio/channels/SocketChannel/ShortWrite.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/channels/SocketChannel/ShortWrite.java Thu Apr 03 00:39:02 2014 +0100 @@ -22,7 +22,7 @@ */ /* @test - * @bug 7176630 + * @bug 7176630 7074436 * @summary Check for short writes on SocketChannels configured in blocking mode */ @@ -40,9 +40,10 @@ /** * Returns a checksum on the remaining bytes in the given buffer. */ - static long computeChecksum(ByteBuffer bb) { + static long computeChecksum(ByteBuffer... bufs) { CRC32 crc32 = new CRC32(); - crc32.update(bb.array()); + for (int i=0; i<bufs.length; i++) + crc32.update(bufs[i].array()); return crc32.getValue(); } @@ -71,15 +72,15 @@ } /** - * Run test with a write of the given number of bytes. + * Exercise write(ByteBuffer) with given number of bytes. */ - static void test(ExecutorService pool, - SocketChannel source, - SocketChannel sink, - int size) + static void test1(ExecutorService pool, + SocketChannel source, + SocketChannel sink, + int size) throws Exception { - System.out.println(size); + System.out.println("write(ByteBuffer), size=" + size); // random bytes in the buffer ByteBuffer buf = ByteBuffer.allocate(size); @@ -101,6 +102,47 @@ throw new RuntimeException("Checksum did not match"); } + /** + * Exercise write(ByteBuffer[]) with buffers of the given sizes. + */ + static void testN(ExecutorService pool, + SocketChannel source, + SocketChannel sink, + int... sizes) + throws Exception + { + System.out.print("write(ByteBuffer[]), sizes="); + for (int size: sizes) + System.out.print(size + " "); + System.out.println(); + + int total = 0; + int len = sizes.length; + ByteBuffer[] bufs = new ByteBuffer[len]; + for (int i=0; i<len; i++) { + int size = sizes[i]; + ByteBuffer buf = ByteBuffer.allocate(size); + rand.nextBytes(buf.array()); + bufs[i] = buf; + total += size; + } + + // submit task to read the bytes + Future<Long> result = pool.submit(new Reader(sink, total)); + + // write the bytes + long n = source.write(bufs); + if (n != total) + throw new RuntimeException("Short write detected"); + + // check the bytes that were received match + for (int i=0; i<len; i++) + bufs[i].rewind(); + long expected = computeChecksum(bufs); + long actual = result.get(); + if (actual != expected) + throw new RuntimeException("Checksum did not match"); + } public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newSingleThreadExecutor(); @@ -114,17 +156,47 @@ try (SocketChannel source = SocketChannel.open(sa); SocketChannel sink = ssc.accept()) { - // run tests on sizes around 128k as that is the problem - // area on Windows. + // Exercise write(BufferBuffer) on sizes around 128k int BOUNDARY = 128 * 1024; for (int size=(BOUNDARY-2); size<=(BOUNDARY+2); size++) { - test(pool, source, sink, size); + test1(pool, source, sink, size); + } + + // Exercise write(BufferBuffer) on random sizes + for (int i=0; i<20; i++) { + int size = rand.nextInt(1024*1024); + test1(pool, source, sink, size); } - // run tests on random sizes + // Exercise write(BufferBuffer[]) on sizes around 128k + for (int i=BOUNDARY-2; i<=BOUNDARY+2; i++) { + testN(pool, source, sink, i); + testN(pool, source, sink, 0, i); + testN(pool, source, sink, i, 0); + for (int j=BOUNDARY-2; j<=BOUNDARY+2; j++) { + testN(pool, source, sink, i, j); + testN(pool, source, sink, 0, i, j); + testN(pool, source, sink, i, 0, j); + testN(pool, source, sink, i, j, 0); + for (int k=BOUNDARY-2; k<=BOUNDARY+2; k++) { + testN(pool, source, sink, i, j, k); + testN(pool, source, sink, 0, i, j, k); + testN(pool, source, sink, i, 0, j, k); + testN(pool, source, sink, i, j, 0, k); + testN(pool, source, sink, i, j, k, 0); + } + } + } + + // Exercise write(BufferBuffer[]) on random sizes + // (assumes IOV_MAX >= 8) for (int i=0; i<20; i++) { - int size = rand.nextInt(1024*1024); - test(pool, source, sink, size); + int n = rand.nextInt(9); + int[] sizes = new int[n]; + for (int j=0; j<n; j++) { + sizes[j] = rand.nextInt(1024*1024); + } + testN(pool, source, sink, sizes); } } }
--- a/test/java/nio/file/Files/BytesAndLines.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/nio/file/Files/BytesAndLines.java Thu Apr 03 00:39:02 2014 +0100 @@ -22,7 +22,9 @@ */ /* @test - * @bug 7006126 8020669 + * @bug 7006126 8020669 8024788 + * @build BytesAndLines PassThroughFileSystem + * @run main BytesAndLines * @summary Unit test for methods for Files readAllBytes, readAllLines and * and write methods. */ @@ -92,6 +94,16 @@ byte[] data = Files.readAllBytes(pathStat); assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read"); } + + // test readAllBytes on custom file system + Path myfile = PassThroughFileSystem.create().getPath(file.toString()); + for (int size=0; size<=1024; size+=512) { + byte[] b1 = new byte[size]; + rand.nextBytes(b1); + Files.write(myfile, b1); + byte[] b2 = Files.readAllBytes(myfile); + assertTrue(Arrays.equals(b1, b2), "bytes not equal"); + } }
--- a/test/java/rmi/registry/readTest/readTest.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/rmi/registry/readTest/readTest.sh Thu Apr 03 00:39:02 2014 +0100 @@ -37,11 +37,13 @@ SunOS | Linux | Darwin | AIX ) PS=":" FS="/" + CHMOD="${FS}bin${FS}chmod" FILEURL="file:" ;; Windows* ) PS=";" FS="\\" + CHMOD="chmod" FILEURL="file:/" if [ "$VER" -eq "5" ]; then ARGS="-Djdk.net.ephemeralPortRange.low=1024 -Djdk.net.ephemeralPortRange.high=65000" @@ -51,6 +53,7 @@ CYGWIN* ) PS=";" FS="/" + CHMOD="chmod" FILEURL="file:/" if [ "${VER}" -eq "5" ]; then ARGS="-Djdk.net.ephemeralPortRange.low=1024 -Djdk.net.ephemeralPortRange.high=65000" @@ -65,6 +68,7 @@ TEST_CLASSPATH=.$PS${TESTCLASSPATH:-$TESTCLASSES} cp -r ${TESTSRC}${FS}* . +${CHMOD} -R u+w * ${TESTJAVA}${FS}bin${FS}javac testPkg${FS}*java ${TESTJAVA}${FS}bin${FS}javac -cp $TEST_CLASSPATH readTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/Arrays/TimSortStackSize.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,123 @@ +/* + * 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 8011944 + * @summary Test TimSort stack size + */ +import java.util.Arrays; +import java.util.ArrayDeque; +import java.util.Comparator; + +public class TimSortStackSize { + + public static void main(String[] args) { + testComparableTimSort(); + testTimSort(); + } + + static void testComparableTimSort() { + System.out.printf("testComparableTimSort()%n"); + Arrays.sort(genData()); + } + + static void testTimSort() { + System.out.printf("testTimSort()%n"); + //Arrays.sort(genData(), Integer::compare); + Arrays.sort(genData(), + new java.util.Comparator<Integer>() { + public int compare(Integer a1, Integer a2){ + return Integer.compare(a1.intValue(), a2.intValue()); + } + }); + } + + private static final int MIN = 16; + + private static final int BOUND1 = 2 * MIN + 1; + private static final int BOUND2 = BOUND1 + MIN + 2; + private static final int BOUND3 = BOUND1 + 1 + BOUND2; + private static final int BOUND4 = BOUND2 + 1 + BOUND3; + private static final int BOUND5 = BOUND3 + 1 + BOUND4; + + static int build(int size, int B, ArrayDeque<Integer> chunks) { + chunks.addFirst(B); + if (size < BOUND1) { + chunks.addFirst(size); + return size; + } + + int asize = (size + 2) / 2; + if (size >= BOUND2 && asize < BOUND1) { + asize = BOUND1; + } else if (size >= BOUND3 && asize < BOUND2) { + asize = BOUND2; + } else if (size >= BOUND4 && asize < BOUND3) { + asize = BOUND3; + } else if (size >= BOUND5 && asize < BOUND4) { + asize = BOUND4; + } + if (size - asize >= B) { + throw new AssertionError(" " + size + " , " + asize + " , " + B); + } + return build(asize, size - asize, chunks); + } + + static Integer[] genData() { + ArrayDeque<Integer> chunks = new ArrayDeque<Integer>(); + chunks.addFirst(MIN); + + int B = MIN + 4; + int A = B + MIN + 1; + + for (int i = 0; i < 8; i++) { + int eps = build(A, B, chunks); + B = B + A + 1; + A = B + eps + 1; + } + chunks.addFirst(B); + chunks.addFirst(A); + int total = 0; + for (Integer len : chunks) { + total += len; + } + int pow = MIN; + while (pow < total) { + pow += pow; + } + chunks.addLast(pow - total); + System.out.println(" Total: " + total); + Integer[] array = new Integer[pow]; + int off = 0; + int pos = 0; + for (Integer len : chunks) { + for (int i = 0; i < len; i++) { + array[pos++] = Integer.valueOf(i == 0 ? 0 : 1); + } + off++; + } + return array; + } + +}
--- a/test/java/util/TimeZone/TimeZoneDatePermissionCheck.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/util/TimeZone/TimeZoneDatePermissionCheck.sh Thu Apr 03 00:39:02 2014 +0100 @@ -36,6 +36,7 @@ ${TESTJAVA}/bin/keytool -genkeypair -alias testcert \ -keystore ${TESTCLASSES}/timezonedatetest.store \ -storepass testpass -validity 360 \ + -keyalg rsa \ -dname "cn=Mark Wildebeest, ou=FreeSoft, o=Red Hat, c=NL" \ -keypass testpass
--- a/test/java/util/jar/JarInputStream/ExtraFileInMetaInf.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/util/jar/JarInputStream/ExtraFileInMetaInf.java Thu Apr 03 00:39:02 2014 +0100 @@ -49,7 +49,7 @@ new File("ks").delete(); sun.security.tools.KeyTool.main( ("-keystore ks -storepass changeit -keypass changeit " + - "-alias a -dname CN=A -genkeypair").split(" ")); + "-keyalg rsa -alias a -dname CN=A -genkeypair").split(" ")); sun.security.tools.JarSigner.main( "-keystore ks -storepass changeit x.jar a".split(" "));
--- a/test/java/util/logging/TestAppletLoggerContext.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/util/logging/TestAppletLoggerContext.java Thu Apr 03 00:39:02 2014 +0100 @@ -110,28 +110,19 @@ } TestExc exc; - TestExc global = new TestExc(); @Override - public Object getContext() { return active ? global : null; } - @Override - public Object getExecutionContext() { return active ? exc : null; } + public Object getAppletContext() { return active ? exc : null; } @Override - public Object get(Object o, Object o1) { return TestExc.exc(o).get(o1); } - @Override - public void put(Object o, Object o1, Object o2) { TestExc.exc(o).put(o1, o2); } + public Object get(Object o) { return exc.get(o); } @Override - public void remove(Object o, Object o1) { TestExc.exc(o).remove(o1); } - @Override - public Object get(Object o) { return global.get(o); } + public void put(Object o, Object o1) { exc.put(o, o1); } @Override - public void put(Object o, Object o1) { global.put(o, o1); } - @Override - public void remove(Object o) { global.remove(o); } + public void remove(Object o) { exc.remove(o); } @Override public boolean isDisposed() { return false; } @Override - public boolean isMainAppContext() { return exc == null; } + public boolean isMainAppContext() { return !active || exc == null; } } final static JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestLogConfigurationDeadLock.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.LogManager; +import java.util.logging.Logger; + + +/** + * @test + * @bug 8029281 8027670 + * @summary Synchronization issues in Logger and LogManager. This test + * focusses more particularly on potential deadlock in + * drainLoggerRefQueueBounded / readConfiguration + * @run main/othervm TestLogConfigurationDeadLock + * @author danielfuchs + */ +// This test is a best effort to try & detect issues. The test itself will run +// for 8secs. This is usually unsufficient to detect issues. +// To get a greater confidence it is recommended to run this test in a loop: +// e.g. use something like: +// $ while jtreg -jdk:$JDK -verbose:all \ +// test/java/util/logging/TestLogConfigurationDeadLock.java ; \ +// do echo Running test again ; done +// and let it run for a few hours... +// +public class TestLogConfigurationDeadLock { + + static volatile Exception thrown = null; + static volatile boolean goOn = true; + + static final int READERS = 2; + static final int LOGGERS = 2; + static final long TIME = 4 * 1000; // 4 sec. + static final long STEP = 1 * 1000; // message every 1 sec. + static final int LCOUNT = 50; // 50 loggers created in a row... + static final AtomicLong nextLogger = new AtomicLong(0); + static final AtomicLong readCount = new AtomicLong(0); + static final AtomicLong checkCount = new AtomicLong(0); + + /** + * This test will run both with and without a security manager. + * + * The test starts a number of threads that will call + * LogManager.readConfiguration() concurrently (ReadConf), then starts + * a number of threads that will create new loggers concurrently + * (AddLogger), and then two additional threads: one (Stopper) that + * will stop the test after 4secs (TIME ms), and one DeadlockDetector + * that will attempt to detect deadlocks. + * If after 4secs no deadlock was detected and no exception was thrown + * then the test is considered a success and passes. + * + * This procedure is done twice: once without a security manager and once + * again with a security manager - which means the test takes ~8secs to + * run. + * + * Note that 8sec may not be enough to detect issues if there are some. + * This is a best effort test. + * + * @param args the command line arguments + */ + public static void main(String[] args) throws Exception { + + // test without security + System.out.println("No security"); + test(); + + // test with security + System.out.println("\nWith security"); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + if (super.implies(domain, permission)) return true; + // System.out.println("Granting " + permission); + return true; // all permissions + } + }); + System.setSecurityManager(new SecurityManager()); + test(); + } + + /** + * Starts all threads, wait 4secs, then stops all threads. + * @throws Exception if a deadlock was detected or an error occurred. + */ + public static void test() throws Exception { + goOn = true; + thrown = null; + long sNextLogger = nextLogger.get(); + long sReadCount = readCount.get(); + long sCheckCount = checkCount.get(); + List<Thread> threads = new ArrayList<>(); + for (int i = 0; i<READERS; i++) { + threads.add(new ReadConf()); + } + for (int i = 0; i<LOGGERS; i++) { + threads.add(new AddLogger()); + } + threads.add(new DeadlockDetector()); + threads.add(0, new Stopper(TIME)); + for (Thread t : threads) { + t.start(); + } + for (Thread t : threads) { + try { + t.join(); + } catch (Exception x) { + fail(x); + } + } + if (thrown != null) { + throw thrown; + } + System.out.println("Passed: " + (nextLogger.get() - sNextLogger) + + " loggers created by " + LOGGERS + " Thread(s),"); + System.out.println("\t LogManager.readConfiguration() called " + + (readCount.get() - sReadCount) + " times by " + READERS + + " Thread(s)."); + System.out.println("\t ThreadMXBean.findDeadlockedThreads called " + + (checkCount.get() -sCheckCount) + " times by 1 Thread."); + + } + + + final static class ReadConf extends Thread { + @Override + public void run() { + while (goOn) { + try { + LogManager.getLogManager().readConfiguration(); + readCount.incrementAndGet(); + Thread.sleep(1); + } catch (Exception x) { + fail(x); + } + } + } + } + + final static class AddLogger extends Thread { + @Override + public void run() { + try { + while (goOn) { + Logger l; + Logger foo = Logger.getLogger("foo"); + Logger bar = Logger.getLogger("foo.bar"); + for (int i=0; i < LCOUNT ; i++) { + l = Logger.getLogger("foo.bar.l"+nextLogger.incrementAndGet()); + l.fine("I'm fine"); + if (!goOn) break; + Thread.sleep(1); + } + } + } catch (InterruptedException | RuntimeException x ) { + fail(x); + } + } + } + + final static class DeadlockDetector extends Thread { + + @Override + public void run() { + while(goOn) { + try { + long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); + checkCount.incrementAndGet(); + ids = ids == null ? new long[0] : ids; + if (ids.length == 1) { + throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]); + } else if (ids.length > 0) { + ThreadInfo[] infos = ManagementFactory.getThreadMXBean() + .getThreadInfo(ids, Integer.MAX_VALUE); + System.err.println("Found "+ids.length+" deadlocked threads: "); + for (ThreadInfo inf : infos) { + System.err.println(inf.toString()); + } + throw new RuntimeException("Found "+ids.length+" deadlocked threads"); + } + Thread.sleep(100); + } catch(InterruptedException | RuntimeException x) { + fail(x); + } + } + } + + } + + static final class Stopper extends Thread { + long start; + long time; + + Stopper(long time) { + start = System.currentTimeMillis(); + this.time = time; + } + + @Override + public void run() { + try { + long rest, previous; + previous = time; + while (goOn && (rest = start - System.currentTimeMillis() + time) > 0) { + if (previous == time || previous - rest >= STEP) { + Logger.getLogger("remaining").info(String.valueOf(rest)+"ms remaining..."); + previous = rest == time ? rest -1 : rest; + System.gc(); + } + if (goOn == false) break; + Thread.sleep(Math.min(rest, 100)); + } + System.out.println(System.currentTimeMillis() - start + + " ms elapsed ("+time+ " requested)"); + goOn = false; + } catch(InterruptedException | RuntimeException x) { + fail(x); + } + } + + } + + static void fail(Exception x) { + x.printStackTrace(); + if (thrown == null) { + thrown = x; + } + goOn = false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestLogConfigurationDeadLockWithConf.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.File; +import java.io.PrintStream; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + + +/** + * @test + * @bug 8027670 8029281 + * @summary Deadlock in drainLoggerRefQueueBounded / readConfiguration + * caused by synchronization issues in Logger and LogManager. + * @run main/othervm TestLogConfigurationDeadLockWithConf + * @author danielfuchs + */ +// This test is a best effort to try & detect issues. The test itself will run +// for 8secs. This is usually sufficient to detect issues. +// However to get a greater confidence it is recommended to run this test in a loop: +// e.g. use something like: +// $ while jtreg -jdk:$JDK -verbose:all \ +// test/java/util/logging/TestLogConfigurationDeadLockWithConf.java ; \ +// do echo Running test again ; done +// and let it run for a few hours... +// +public class TestLogConfigurationDeadLockWithConf { + + static volatile Exception thrown = null; + static volatile boolean goOn = true; + + static final int READERS = 2; + static final int LOGGERS = 2; + static final long TIME = 4 * 1000; // 4 sec. + static final long STEP = 1 * 1000; // message every 1 sec. + static final int LCOUNT = 50; // 50 loggers created in a row... + static final AtomicLong nextLogger = new AtomicLong(0); + static final AtomicLong readCount = new AtomicLong(0); + static final AtomicLong checkCount = new AtomicLong(0); + + /** + * This test will run both with and without a security manager. + * + * The test starts a number of threads that will call + * LogManager.readConfiguration() concurrently (ReadConf), then starts + * a number of threads that will create new loggers concurrently + * (AddLogger), and then two additional threads: one (Stopper) that + * will stop the test after 4secs (TIME ms), and one DeadlockDetector + * that will attempt to detect deadlocks. + * If after 4secs no deadlock was detected and no exception was thrown + * then the test is considered a success and passes. + * + * This procedure is done twice: once without a security manager and once + * again with a security manager - which means the test takes ~8secs to + * run. + * + * Note that 8sec may not be enough to detect issues if there are some. + * This is a best effort test. + * + * @param args the command line arguments + * @throws java.lang.Exception if the test fails. + */ + public static void main(String[] args) throws Exception { + File config = new File(System.getProperty("test.src", "."), + "deadlockconf.properties"); + if (!config.canRead()) { + System.err.println("Can't read config file: test cannot execute."); + System.err.println("Please check your test environment: "); + System.err.println("\t -Dtest.src=" + System.getProperty("test.src", ".")); + System.err.println("\t config file is: " + config.getAbsolutePath()); + throw new RuntimeException("Can't read config file: " + + config.getAbsolutePath()); + } + + System.setProperty("java.util.logging.config.file", + config.getAbsolutePath()); + + // test without security + System.out.println("No security"); + test(); + + // test with security + System.out.println("\nWith security"); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + if (super.implies(domain, permission)) return true; + // System.out.println("Granting " + permission); + return true; // all permissions + } + }); + System.setSecurityManager(new SecurityManager()); + test(); + } + + static Random rand = new Random(System.currentTimeMillis()); + private static int getBarCount() { + return rand.nextInt(10); + } + + /** + * Starts all threads, wait 4secs, then stops all threads. + * @throws Exception if a deadlock was detected or an error occurred. + */ + public static void test() throws Exception { + goOn = true; + thrown = null; + long sNextLogger = nextLogger.get(); + long sReadCount = readCount.get(); + long sCheckCount = checkCount.get(); + List<Thread> threads = new ArrayList<>(); + for (int i = 0; i<READERS; i++) { + threads.add(new ReadConf()); + } + for (int i = 0; i<LOGGERS; i++) { + threads.add(new AddLogger()); + } + DeadlockDetector detector = new DeadlockDetector(); + threads.add(detector); + threads.add(0, new Stopper(TIME)); + for (Thread t : threads) { + t.start(); + } + + // wait for the detector to finish. + detector.join(); + + final PrintStream out = thrown == null ? System.out : System.err; + + // Try to wait for all threads to finish. + // This is a best effort: if some threads are in deadlock we can't + // obviously wait for them, and other threads may have joined in + // the deadlock since we last checked. + // However, all threads which are succeptible of deadlocking + // extend DeamonThread. + for (Thread t : threads) { + if (t == detector) { + continue; + } + if (detector.deadlocked.contains(t.getId())) { + out.println("Skipping deadlocked thread " + + t.getClass().getSimpleName() + ": " + t); + continue; // don't wait for deadlocked thread: they won't terminate + } + try { + if (detector.deadlocked.isEmpty()) { + t.join(); + } else { + if (t instanceof DaemonThread) { + // Some other threads may have join the deadlock. + // don't wait forever. + t.join(100); + } else { + // Those threads that don't extend DaemonThread + // should be safe from deadlock. + out.println("Waiting for " + + t.getClass().getSimpleName() + ": " + t); + t.join(); + } + } + } catch (Exception x) { + fail(x); + } + } + out.println("All threads joined."); + + final String status = thrown == null ? "Passed" : "FAILED"; + + out.println(status + ": " + (nextLogger.get() - sNextLogger) + + " loggers created by " + LOGGERS + " Thread(s),"); + out.println("\t LogManager.readConfiguration() called " + + (readCount.get() - sReadCount) + " times by " + READERS + + " Thread(s)."); + out.println("\t ThreadMXBean.findDeadlockedThreads called " + + (checkCount.get() -sCheckCount) + " times by 1 Thread."); + + if (thrown != null) { + out.println("\t Error is: "+thrown.getMessage()); + throw thrown; + } + } + + static class DaemonThread extends Thread { + public DaemonThread() { + this.setDaemon(true); + } + } + + final static class ReadConf extends DaemonThread { + @Override + public void run() { + while (goOn) { + try { + LogManager.getLogManager().readConfiguration(); + readCount.incrementAndGet(); + Thread.sleep(1); + } catch (Exception x) { + fail(x); + } + } + } + } + + final static class AddLogger extends DaemonThread { + @Override + public void run() { + try { + while (goOn) { + Logger l; + int barcount = getBarCount(); + for (int i=0; i < LCOUNT ; i++) { + l = Logger.getLogger("foo.bar"+barcount+".l"+nextLogger.incrementAndGet()); + l.fine("I'm fine"); + if (!goOn) break; + Thread.sleep(1); + } + } + } catch (InterruptedException | RuntimeException x ) { + fail(x); + } + } + } + + final static class DeadlockDetector extends Thread { + + final Set<Long> deadlocked = Collections.synchronizedSet(new HashSet<Long>()); + + static List<Long> asList(long... ids) { + final List<Long> list = new ArrayList<>(ids.length); + for (long id : ids) { + list.add(id); + } + return list; + } + + @Override + public void run() { + while(goOn) { + try { + long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); + checkCount.incrementAndGet(); + ids = ids == null ? new long[0] : ids; + if (ids.length > 0) { + deadlocked.addAll(asList(ids)); + } + if (ids.length == 1) { + throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]); + } else if (ids.length > 0) { + ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(ids, Integer.MAX_VALUE); + System.err.println("Found "+ids.length+" deadlocked threads: "); + for (ThreadInfo inf : infos) { + System.err.println(inf.toString()); + } + throw new RuntimeException("Found "+ids.length+" deadlocked threads"); + } + Thread.sleep(100); + } catch(InterruptedException | RuntimeException x) { + fail(x); + } + } + } + + } + + static final class Stopper extends Thread { + long start; + long time; + + static final Logger logger = Logger.getLogger("remaining"); + + Stopper(long time) { + start = System.currentTimeMillis(); + this.time = time; + } + + @Override + public void run() { + try { + long rest, previous; + previous = time; + while (goOn && (rest = start - System.currentTimeMillis() + time) > 0) { + if (previous == time || previous - rest >= STEP) { + logger.log(Level.INFO, + "{0}ms remaining...", String.valueOf(rest)); + previous = rest == time ? rest -1 : rest; + System.gc(); + } + if (goOn == false) break; + Thread.sleep(Math.min(rest, 100)); + } + System.out.println(System.currentTimeMillis() - start + + " ms elapsed ("+time+ " requested)"); + goOn = false; + } catch(InterruptedException | RuntimeException x) { + fail(x); + } + } + + } + + static void fail(Exception x) { + x.printStackTrace(); + if (thrown == null) { + thrown = x; + } + goOn = false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestLoggerBundleSync.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.List; +import java.util.ListResourceBundle; +import java.util.Objects; +import java.util.ResourceBundle; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * @test + * @bug 8029281 8028763 + * @summary Attempts to detect synchronization issues with getResourceBundle() + * and getResourceBundleName(). It might also detect issues in the way + * that the logger tree is cleaned up after a logger has been garbage + * collected. This test helped find the root cause of 8029092, so if + * this test fails one might also expect failures in + * java/util/logging/Logger/logrb/TestLogrbResourceBundle.java and + * java/util/logging/Logger/setResourceBundle/TestSetResourceBundle.java. + * Note that this is a best effort test. Running it in a loop to + * reproduce intermittent issues can be a good idea. + * @run main/othervm TestLoggerBundleSync + * @author danielfuchs + */ +public class TestLoggerBundleSync { + + static volatile Exception thrown = null; + static volatile boolean goOn = true; + + static final int READERS = 3; + static final long TIME = 4 * 1000; // 4 sec. + static final long STEP = 1 * 1000; // message every 1 sec. + static final int LCOUNT = 50; // change bundle 50 times... + static final AtomicLong setRBcount = new AtomicLong(0); + static final AtomicLong setRBNameCount = new AtomicLong(0); + static final AtomicLong getRBcount = new AtomicLong(0); + static final AtomicLong checkCount = new AtomicLong(0); + static final AtomicLong nextLong = new AtomicLong(0); + + public static class MyBundle extends ListResourceBundle { + @Override + protected Object[][] getContents() { + return new Object[][] { + {"dummy", "foo"} + }; + } + } + + public static final class MyBundle1 extends MyBundle { }; + public static final class MyBundle2 extends MyBundle { }; + public static final class MyBundle3 extends MyBundle { }; + + + public static final class LoggerRB { + public final String resourceBundleName; + public final ResourceBundle userBundle; + public LoggerRB(String name, ResourceBundle bundle) { + resourceBundleName = name; + userBundle = bundle; + } + } + + static final List<Class<? extends ResourceBundle>> classes = new ArrayList<>(); + static { + classes.add(MyBundle1.class); + classes.add(MyBundle2.class); + classes.add(MyBundle3.class); + } + + + /** + * This test will run both with and without a security manager. + * + * The test starts a number of threads that will attempt to concurrently + * set resource bundles on Logger, and verifies the consistency of the + * obtained results. + * + * This is a best effort test. + * + * @param args the command line arguments + */ + public static void main(String[] args) throws Exception { + + try { + // test without security + System.out.println("No security"); + test(); + + // test with security + System.out.println("\nWith security"); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + if (super.implies(domain, permission)) return true; + // System.out.println("Granting " + permission); + return true; // all permissions + } + }); + System.setSecurityManager(new SecurityManager()); + test(); + } finally { + SetRB.executor.shutdownNow(); + SetRBName.executor.shutdownNow(); + } + } + + /** + * Starts all threads, wait 15secs, then stops all threads. + * @throws Exception if a deadlock was detected or an error occurred. + */ + public static void test() throws Exception { + goOn = true; + thrown = null; + long sGetRBCount = getRBcount.get(); + long sSetRBCount = setRBcount.get(); + long sSetRBNameCount = setRBNameCount.get(); + long sCheckCount = checkCount.get(); + long sNextLong = nextLong.get(); + List<Thread> threads = new ArrayList<>(); + for (Class<? extends ResourceBundle> type : classes) { + threads.add(new SetRB(type)); + threads.add(new SetRBName(type)); + } + for (int i =0 ; i < READERS ; i++) { + threads.add(new GetRB()); + } + threads.add(new DeadlockDetector()); + threads.add(0, new Stopper(TIME)); + for (Thread t : threads) { + t.start(); + } + for (Thread t : threads) { + try { + t.join(); + } catch (Exception x) { + fail(x); + } + } + if (thrown != null) { + throw thrown; + } + System.out.println("Passed: " + (nextLong.longValue() - sNextLong) + + " unique loggers created"); + System.out.println("\t " +(getRBcount.get() - sGetRBCount) + + " loggers tested by " + READERS + " Thread(s),"); + System.out.println("\t " + (setRBcount.get() - sSetRBCount) + + " resource bundles set by " + classes.size() + " Thread(s),"); + System.out.println("\t " + (setRBNameCount.get() - sSetRBNameCount) + + " resource bundle names set by " + classes.size() + " Thread(s),"); + System.out.println("\t ThreadMXBean.findDeadlockedThreads called " + + (checkCount.get() -sCheckCount) + " times by 1 Thread."); + + } + + final static class GetRB extends Thread { + final static class MyHandler extends Handler { + volatile ResourceBundle rb; + volatile String rbName; + @Override + public synchronized void publish(LogRecord record) { + rb = record.getResourceBundle(); + rbName = record.getResourceBundleName(); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + }; + final MyHandler handler = new MyHandler(); + @Override + public void run() { + try { + handler.setLevel(Level.FINEST); + while (goOn) { + Logger l; + Logger foo = Logger.getLogger("foo"); + Logger bar = Logger.getLogger("foo.bar"); + for (long i=0; i < nextLong.longValue() + 100 ; i++) { + if (!goOn) break; + l = Logger.getLogger("foo.bar.l"+i); + final ResourceBundle b = l.getResourceBundle(); + final String name = l.getResourceBundleName(); + if (b != null) { + if (!name.equals(b.getClass().getName())) { + throw new RuntimeException("Unexpected bundle name: " + +b.getClass().getName()); + } + } + Logger ll = Logger.getLogger(l.getName()+".bie.bye"); + ResourceBundle hrb; + String hrbName; + ll.setLevel(Level.FINEST); + ll.addHandler(handler); + ll.fine("dummy"); + ll.removeHandler(handler); + hrb = handler.rb; + hrbName = handler.rbName; + if (name != null) { + if (!name.equals(hrbName)) { + throw new RuntimeException("Unexpected bundle name: " + +hrb.getClass().getName()); + } + if (!name.equals(hrb.getClass().getName())) { + throw new RuntimeException("Unexpected bundle name: " + +hrb.getClass().getName()); + } + } + + getRBcount.incrementAndGet(); + if (!goOn) break; + Thread.sleep(1); + } + } + } catch (Exception x) { + fail(x); + } + } + } + + final static class SetRB extends Thread { + final Class<? extends ResourceBundle> type; + final static ExecutorService executor = Executors.newSingleThreadExecutor(); + final static class CheckRBTask implements Callable<Exception> { + final Logger logger; + volatile String rbName; + volatile ResourceBundle rb; + + public CheckRBTask(Logger logger) { + this.logger = logger; + } + + @Override + public Exception call() throws Exception { + try { + final String name = logger.getResourceBundleName(); + if (!Objects.equals(name, rbName)) { + throw new RuntimeException("Unexpected rbname for " + + logger.getName() + ": " + name); + } + final ResourceBundle b = logger.getResourceBundle(); + if (b != rb) { + throw new RuntimeException("Unexpected rb for " + + logger.getName() + ": " + b); + } + } catch(Exception x) { + return x; + } + return null; + } + + public void check() throws Exception { + final FutureTask<Exception> futureTask = new FutureTask<>(this); + executor.submit(futureTask); + Exception x = futureTask.get(); + if ( x != null) { + throw new RuntimeException("Check failed: "+x,x); + } + } + } + SetRB(Class<? extends ResourceBundle> type) { + super("SetRB["+type.getSimpleName()+"]"); + this.type = type; + } + @Override + public void run() { + try { + while (goOn) { + Logger l; + Logger foo = Logger.getLogger("foo"); + Logger bar = Logger.getLogger("foo.bar"); + l = Logger.getLogger("foo.bar.l"+nextLong.incrementAndGet()); + final CheckRBTask checkTask = new CheckRBTask(l); + checkTask.check(); + Logger l1 = l; + + for (int i=0; i < LCOUNT ; i++) { + if (!goOn) break; + + ResourceBundle b = ResourceBundle.getBundle(type.getName()); + try { + l = Logger.getLogger(l1.getName(), type.getName()); + checkTask.rb = b; + checkTask.rbName = type.getName(); + checkTask.check(); + if (!goOn) break; + + String name = l.getResourceBundleName(); + ResourceBundle bb = l.getResourceBundle(); + if (!type.getName().equals(name)) { + throw new RuntimeException(this.getName() + + ": Unexpected name: "+name); + } + if (!b.getClass().getName().equals(name)) { + throw new RuntimeException(this.getName() + + ": Unexpected base name: " + + b.getClass().getName()); + } + if (b != bb) { + throw new RuntimeException(this.getName() + + ": Unexpected bundle: "+bb); + } + setRBcount.incrementAndGet(); + } catch (IllegalArgumentException x) { + final String name = l.getResourceBundleName(); + if (!name.startsWith(MyBundle.class.getName())) { + throw new RuntimeException(this.getName() + + ": Unexpected name: "+name, x); + } else if (type.getName().equals(name)) { + throw new RuntimeException(this.getName() + + ": Unexpected exception for "+name, x); + } + throw x; + } + l.fine("I'm fine"); + if (!goOn) break; + Thread.sleep(1); + } + } + } catch (Exception x) { + fail(x); + } + } + } + + final static class SetRBName extends Thread { + int nexti = 0; + final Class<? extends ResourceBundle> type; + final static ExecutorService executor = Executors.newSingleThreadExecutor(); + final static class CheckRBNameTask implements Callable<Exception> { + final Logger logger; + volatile String rbName; + + public CheckRBNameTask(Logger logger) { + this.logger = logger; + } + + @Override + public Exception call() throws Exception { + try { + final String name = logger.getResourceBundleName(); + if (!Objects.equals(name, rbName)) { + throw new RuntimeException("Unexpected rbname for " + + logger.getName() + ": " + name); + } + final ResourceBundle b = logger.getResourceBundle(); + if (!Objects.equals(b == null ? null : b.getClass().getName(), rbName)) { + throw new RuntimeException("Unexpected base name for " + + logger.getName() + ": " + b.getClass().getName()); + } + } catch(Exception x) { + return x; + } + return null; + } + + public void check() throws Exception { + final FutureTask<Exception> futureTask = new FutureTask<>(this); + executor.submit(futureTask); + Exception x = futureTask.get(); + if ( x != null) { + throw new RuntimeException("Check failed: "+x,x); + } + } + + } + SetRBName(Class<? extends ResourceBundle> type) { + super("SetRB["+type.getSimpleName()+"]"); + this.type = type; + } + @Override + public void run() { + try { + while (goOn) { + Logger foo = Logger.getLogger("foo"); + Logger bar = Logger.getLogger("foo.bar"); + Logger l = Logger.getLogger("foo.bar.l"+nextLong.incrementAndGet()); + final CheckRBNameTask checkTask = new CheckRBNameTask(l); + checkTask.check(); + + for (int i=0; i < LCOUNT ; i++) { + if (!goOn) break; + + try { + Logger l2 = Logger.getLogger(l.getName(), type.getName()); + if (l2 != l) { + System.err.println("**** ERROR WITH "+l.getName()); + throw new RuntimeException("l2 != l [" + + l2 + "(" + l2.getName() + ") != " + + l + "(" + l.getName() + ")]"); + } + checkTask.rbName = type.getName(); + checkTask.check(); + if (!goOn) break; + + String name = l.getResourceBundleName(); + ResourceBundle bb = l.getResourceBundle(); + if (!type.getName().equals(name)) { + throw new RuntimeException(this.getName() + + ": Unexpected name: "+name); + } + if (!bb.getClass().getName().equals(name)) { + throw new RuntimeException(this.getName() + + ": Unexpected base name: " + + bb.getClass().getName()); + } + setRBNameCount.incrementAndGet(); + } catch (IllegalArgumentException x) { + final String name = l.getResourceBundleName(); + if (!name.startsWith(MyBundle.class.getName())) { + throw new RuntimeException(this.getName() + + ": Unexpected name: "+name, x); + } else if (type.getName().equals(name)) { + throw new RuntimeException(this.getName() + + ": Unexpected exception for "+name, x); + } + throw x; + } + l.fine("I'm fine"); + if (!goOn) break; + Thread.sleep(1); + } + } + } catch (Exception x) { + fail(x); + } + } + } + + final static class DeadlockDetector extends Thread { + + @Override + public void run() { + while(goOn) { + try { + long[] ids = ManagementFactory.getThreadMXBean().findDeadlockedThreads(); + checkCount.incrementAndGet(); + ids = ids == null ? new long[0] : ids; + if (ids.length == 1) { + throw new RuntimeException("Found 1 deadlocked thread: "+ids[0]); + } else if (ids.length > 0) { + ThreadInfo[] infos = ManagementFactory.getThreadMXBean().getThreadInfo(ids); + System.err.println("Found "+ids.length+" deadlocked threads: "); + for (ThreadInfo inf : infos) { + System.err.println(inf.toString()); + } + throw new RuntimeException("Found "+ids.length+" deadlocked threads"); + } + Thread.sleep(100); + } catch(InterruptedException | RuntimeException x) { + fail(x); + } + } + } + + } + + static final class Stopper extends Thread { + long start; + long time; + + Stopper(long time) { + start = System.currentTimeMillis(); + this.time = time; + } + + @Override + public void run() { + try { + long rest, previous; + previous = time; + while (goOn && (rest = start - System.currentTimeMillis() + time) > 0) { + if (previous == time || previous - rest >= STEP) { + Logger.getLogger("remaining").info(String.valueOf(rest)+"ms remaining..."); + previous = rest == time ? rest -1 : rest; + System.gc(); + } + if (goOn == false) break; + Thread.sleep(Math.min(rest, 100)); + } + System.out.println(System.currentTimeMillis() - start + + " ms elapsed ("+time+ " requested)"); + goOn = false; + } catch(InterruptedException | RuntimeException x) { + fail(x); + } + } + + } + + static void fail(Exception x) { + x.printStackTrace(); + if (thrown == null) { + thrown = x; + } + goOn = false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestLoggingWithMainAppContext.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.logging.Logger; +import javax.imageio.ImageIO; + +/** + * @test + * @bug 8019853 8023258 + * @summary Test that the default user context is used when in the main + * application context. This test must not be run in same VM or agent + * VM mode: it would not test the intended behavior. + * @run main/othervm TestLoggingWithMainAppContext + */ +public class TestLoggingWithMainAppContext { + + public static void main(String[] args) throws IOException { + System.out.println("Creating loggers."); + + // These loggers will be created in the default user context. + final Logger foo1 = Logger.getLogger( "foo" ); + final Logger bar1 = Logger.getLogger( "foo.bar" ); + if (bar1.getParent() != foo1) { + throw new RuntimeException("Parent logger of bar1 "+bar1+" is not "+foo1); + } + System.out.println("bar1.getParent() is the same as foo1"); + + // Set a security manager + System.setSecurityManager(new SecurityManager()); + System.out.println("Now running with security manager"); + + // Triggers the creation of the main AppContext + ByteArrayInputStream is = new ByteArrayInputStream(new byte[] { 0, 1 }); + ImageIO.read(is); // triggers calls to system loggers & creation of main AppContext + + // verify that we're still using the default user context + final Logger bar2 = Logger.getLogger( "foo.bar" ); + if (bar1 != bar2) { + throw new RuntimeException("bar2 "+bar2+" is not the same as bar1 "+bar1); + } + System.out.println("bar2 is the same as bar1"); + if (bar2.getParent() != foo1) { + throw new RuntimeException("Parent logger of bar2 "+bar2+" is not foo1 "+foo1); + } + System.out.println("bar2.getParent() is the same as foo1"); + final Logger foo2 = Logger.getLogger("foo"); + if (foo1 != foo2) { + throw new RuntimeException("foo2 "+foo2+" is not the same as foo1 "+foo1); + } + System.out.println("foo2 is the same as foo1"); + + System.out.println("Test passed."); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestMainAppContext.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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.logging.Logger; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + + +/** + * @test + * @bug 8026404 + * @summary checks that calling getLogger() from a Thread whose ThreadGroup is + * a child of the main root group doesn't throw an exception. + * @build TestMainAppContext + * @run main/othervm TestMainAppContext + * @author danielfuchs + */ +public class TestMainAppContext { + + static volatile Throwable thrown = null; + + public static void main(String... args) throws Exception { + ThreadGroup rootTG = Thread.currentThread().getThreadGroup(); + while (rootTG.getParent() != null) { + rootTG = rootTG.getParent(); + } + + ThreadGroup tg = new ThreadGroup(rootTG, "FakeApplet"); + final Thread t1 = new Thread(tg, "createNewAppContext") { + @Override + public void run() { + try { + AppContext context = SunToolkit.createNewAppContext(); + } catch(Throwable t) { + thrown = t; + } + } + }; + t1.start(); + t1.join(); + if (thrown != null) { + throw new RuntimeException("Unexpected exception: " + thrown, thrown); + } + Thread t2 = new Thread(tg, "BugDetector") { + + @Override + public void run() { + try { + Logger.getLogger("foo").info("Done"); + } catch (Throwable x) { + thrown = x; + } + } + + }; + + System.setSecurityManager(new SecurityManager()); + t2.start(); + t2.join(); + if (thrown != null) { + throw new RuntimeException("Test failed: " + thrown, thrown); + } + + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/deadlockconf.properties Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,22 @@ +# This file is used by TestLogConfigurationDeadLockWithConf +handlers= java.util.logging.ConsoleHandler +.level= INFO +java.util.logging.ConsoleHandler.level = INFO +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + + +foo.bar0.level = INFO +foo.bar1.level = INFO +foo.bar2.level = INFO +foo.bar3.level = INFO +foo.bar4.level = INFO + +# We leave foo.bar5 out so that we have at least +# one logger whose parent won't be in the configuration +# file +#foo.bar5.level = INFO + +foo.bar6.level = INFO +foo.bar7.level = INFO +foo.bar8.level = INFO +foo.bar9.level = INFO
--- a/test/java/util/zip/ZipFile/ReadZip.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/java/util/zip/ZipFile/ReadZip.java Thu Apr 03 00:39:02 2014 +0100 @@ -63,6 +63,8 @@ Files.copy(Paths.get(System.getProperty("test.src", ""), "input.zip"), newZip.toPath(), StandardCopyOption.REPLACE_EXISTING); + newZip.setWritable(true); + // pad some bytes try (OutputStream os = Files.newOutputStream(newZip.toPath(), StandardOpenOption.APPEND)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/text/html/parser/Parser/8028616/bug8028616.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,77 @@ +/* + * 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 8028616 + * @summary Tests correct parsing of the text with leading slash (/) + * @author Dmitry Markov + */ + +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; +import java.io.StringReader; + +public class bug8028616 { + private static final String text = "/ at start is bad"; + private static Object lock = new Object(); + private static boolean isCallbackInvoked = false; + private static Exception exception = null; + + public static void main(String[] args) throws Exception { + ParserCB cb = new ParserCB(); + HTMLEditorKit htmlKit = new HTMLEditorKit(); + HTMLDocument htmlDoc = (HTMLDocument) htmlKit.createDefaultDocument(); + + htmlDoc.getParser().parse(new StringReader(text), cb, true); + + synchronized (lock) { + if (!isCallbackInvoked) { + lock.wait(5000); + } + } + + if (!isCallbackInvoked) { + throw new RuntimeException("Test Failed: ParserCallback.handleText() is not invoked for text - " + text); + } + + if (exception != null) { + throw exception; + } + } + + private static class ParserCB extends HTMLEditorKit.ParserCallback { + @Override + public void handleText(char[] data, int pos) { + synchronized (lock) { + if (!text.equals(new String(data)) || pos != 0) { + exception = new RuntimeException( + "Test Failed: the data passed to ParserCallback.handleText() does not meet the expectation"); + } + isCallbackInvoked = true; + lock.notifyAll(); + } + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/transform/8004476/SecureProcessingTest.xml Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<helloWorld/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/transform/8004476/TestBase.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ +import java.security.Policy; + +/** + * + * + * @author huizhe.wang@oracle.com + */ +public class TestBase { + public static boolean isWindows = false; + static { + if (System.getProperty("os.name").indexOf("Windows")>-1) { + isWindows = true; + } + }; + + String filepath; + boolean hasSM; + String curDir; + Policy origPolicy; + String testName; + static String errMessage; + + int passed = 0, failed = 0; + + /** + * Creates a new instance of StreamReader + */ + public TestBase(String name) { + testName = name; + } + + //junit @Override + protected void setUp() { + if (System.getSecurityManager() != null) { + hasSM = true; + System.setSecurityManager(null); + } + + filepath = System.getProperty("test.src"); + if (filepath == null) { + //current directory + filepath = System.getProperty("user.dir"); + } + origPolicy = Policy.getPolicy(); + + } + + //junit @Override + public void tearDown() { + // turn off security manager and restore policy + System.setSecurityManager(null); + Policy.setPolicy(origPolicy); + if (hasSM) { + System.setSecurityManager(new SecurityManager()); + } + System.out.println("\nNumber of tests passed: " + passed); + System.out.println("Number of tests failed: " + failed + "\n"); + + if (errMessage != null ) { + throw new RuntimeException(errMessage); + } + } + + void fail(String errMsg) { + if (errMessage == null) { + errMessage = errMsg; + } else { + errMessage = errMessage + "\n" + errMsg; + } + failed++; + } + + void success(String msg) { + passed++; + System.out.println(msg); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/transform/8004476/XPathExFuncTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8004476 + * @summary test XPath extension functions + * @run main/othervm XPathExFuncTest + */ +import java.io.FileInputStream; +import java.io.InputStream; +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.Iterator; +import java.util.List; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathFactoryConfigurationException; +import javax.xml.xpath.XPathFunction; +import javax.xml.xpath.XPathFunctionException; +import javax.xml.xpath.XPathFunctionResolver; +import org.w3c.dom.Document; + +/** + * test XPath extension functions + * + * @author huizhe.wang@oracle.com + */ +public class XPathExFuncTest extends TestBase { + + final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions"; + final static String CLASSNAME = "DocumentBuilderFactoryImpl"; + final String XPATH_EXPRESSION = "ext:helloWorld()"; + + /** + * Creates a new instance of StreamReader + */ + public XPathExFuncTest(String name) { + super(name); + } + boolean hasSM; + String xslFile, xslFileId; + String xmlFile, xmlFileId; + + protected void setUp() { + super.setUp(); + xmlFile = filepath + "/SecureProcessingTest.xml"; + + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + XPathExFuncTest test = new XPathExFuncTest("OneTest"); + test.setUp(); + + test.testExtFunc(); + test.testExtFuncNotAllowed(); + test.testEnableExtFunc(); + test.tearDown(); + + } + + /** + * by default, extension function is enabled + */ + public void testExtFunc() { + + try { + evaluate(false); + System.out.println("testExtFunc: OK"); + } catch (XPathFactoryConfigurationException e) { + fail(e.getMessage()); + } catch (XPathExpressionException e) { + fail(e.getMessage()); + } + } + + /** + * Security is enabled, extension function not allowed + */ + public void testExtFuncNotAllowed() { + Policy p = new SimplePolicy(new AllPermission()); + Policy.setPolicy(p); + System.setSecurityManager(new SecurityManager()); + + try { + evaluate(false); + } catch (XPathFactoryConfigurationException e) { + fail(e.getMessage()); + } catch (XPathExpressionException ex) { + //expected since extension function is disallowed + System.out.println("testExtFuncNotAllowed: OK"); + } finally { + System.setSecurityManager(null); + } + } + + /** + * Security is enabled, use new feature: enableExtensionFunctions + */ + public void testEnableExtFunc() { + Policy p = new SimplePolicy(new AllPermission()); + Policy.setPolicy(p); + System.setSecurityManager(new SecurityManager()); + + + try { + evaluate(true); + System.out.println("testEnableExt: OK"); + } catch (XPathFactoryConfigurationException e) { + fail(e.getMessage()); + } catch (XPathExpressionException e) { + fail(e.getMessage()); + } finally { + System.setSecurityManager(null); + } + } + + Document getDocument() { + // the xml source + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = null; + Document document = null; + + try { + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + InputStream xmlStream = new FileInputStream(xmlFile); + document = documentBuilder.parse(xmlStream); + } catch (Exception e) { + fail(e.toString()); + } + return document; + } + + void evaluate(boolean enableExt) throws XPathFactoryConfigurationException, XPathExpressionException { + Document document = getDocument(); + + XPathFactory xPathFactory = XPathFactory.newInstance(); + /** + * Use of the extension function 'http://exslt.org/strings:tokenize' is + * not allowed when the secure processing feature is set to true. + * Attempt to use the new property to enable extension function + */ + if (enableExt) { + boolean isExtensionSupported = enableExtensionFunction(xPathFactory); + } + + xPathFactory.setXPathFunctionResolver(new MyXPathFunctionResolver()); + if (System.getSecurityManager() == null) { + xPathFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); + } + + XPath xPath = xPathFactory.newXPath(); + xPath.setNamespaceContext(new MyNamespaceContext()); + + String xPathResult = xPath.evaluate(XPATH_EXPRESSION, document); + System.out.println( + "XPath result (enableExtensionFunction == " + enableExt + ") = \"" + + xPathResult + + "\""); + } + + public class MyXPathFunctionResolver + implements XPathFunctionResolver { + + public XPathFunction resolveFunction(QName functionName, int arity) { + + // not a real ewsolver, always return a default XPathFunction + return new MyXPathFunction(); + } + } + + public class MyXPathFunction + implements XPathFunction { + + public Object evaluate(List list) throws XPathFunctionException { + + return "Hello World"; + } + } + + public class MyNamespaceContext implements NamespaceContext { + + public String getNamespaceURI(String prefix) { + if (prefix == null) { + throw new IllegalArgumentException("The prefix cannot be null."); + } + + if (prefix.equals("ext")) { + return "http://ext.com"; + } else { + return null; + } + } + + public String getPrefix(String namespace) { + + if (namespace == null) { + throw new IllegalArgumentException("The namespace uri cannot be null."); + } + + if (namespace.equals("http://ext.com")) { + return "ext"; + } else { + return null; + } + } + + public Iterator getPrefixes(String namespace) { + return null; + } + } + + boolean enableExtensionFunction(XPathFactory factory) { + boolean isSupported = true; + try { + factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true); + } catch (XPathFactoryConfigurationException ex) { + isSupported = false; + } + return isSupported; + } + + class SimplePolicy extends Policy { + + private final Permissions perms; + + public SimplePolicy(Permission... permissions) { + perms = new Permissions(); + for (Permission permission : permissions) { + perms.add(permission); + } + } + + @Override + public PermissionCollection getPermissions(CodeSource cs) { + return perms; + } + + @Override + public PermissionCollection getPermissions(ProtectionDomain pd) { + return perms; + } + + @Override + public boolean implies(ProtectionDomain pd, Permission p) { + return perms.implies(p); + } + + //for older jdk + @Override + public void refresh() { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/transform/8004476/XSLTExFuncTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 8004476 + * @summary test XSLT extension functions + * @run main/othervm XSLTExFuncTest + */ + +import java.io.StringWriter; +import java.security.AllPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import javax.xml.transform.*; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamResult; +import org.xml.sax.InputSource; + +/** + * test XSLT extension functions + * + * @author huizhe.wang@oracle.com + */ +public class XSLTExFuncTest extends TestBase { + + final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions"; + final static String CLASSNAME = "DocumentBuilderFactoryImpl"; + + /** + * Creates a new instance of StreamReader + */ + public XSLTExFuncTest(String name) { + super(name); + } + boolean hasSM; + String xslFile, xslFileId; + String xmlFile, xmlFileId; + + protected void setUp() { + super.setUp(); + xmlFile = filepath + "/tokenize.xml"; + xslFile = filepath + "/tokenize.xsl"; + + /** + * On Windows platform it needs triple '/' for valid URL while double '/' is enough on Linux or Solaris. + * Here use file:/// directly to make it work on Windows and it will not impact other platforms. + */ + xslFileId = "file:///" + xslFile; + } + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + XSLTExFuncTest test = new XSLTExFuncTest("OneTest"); + test.setUp(); + + test.testExtFunc(); + test.testExtFuncNotAllowed(); + test.testEnableExtFunc(); + test.testTemplatesEnableExtFunc(); + test.tearDown(); + + } + + /** + * by default, extension function is enabled + */ + public void testExtFunc() { + TransformerFactory factory = TransformerFactory.newInstance(); + + try { + transform(factory); + System.out.println("testExtFunc: OK"); + } catch (TransformerConfigurationException e) { + fail(e.getMessage()); + } catch (TransformerException ex) { + fail(ex.getMessage()); + } + } + + /** + * Security is enabled, extension function not allowed + */ + public void testExtFuncNotAllowed() { + Policy p = new SimplePolicy(new AllPermission()); + Policy.setPolicy(p); + System.setSecurityManager(new SecurityManager()); + TransformerFactory factory = TransformerFactory.newInstance(); + + try { + transform(factory); + } catch (TransformerConfigurationException e) { + fail(e.getMessage()); + } catch (TransformerException ex) { + //expected since extension function is disallowed + System.out.println("testExtFuncNotAllowed: OK"); + } finally { + System.setSecurityManager(null); + } + } + + /** + * Security is enabled, use new feature: enableExtensionFunctions + */ + public void testEnableExtFunc() { + Policy p = new SimplePolicy(new AllPermission()); + Policy.setPolicy(p); + System.setSecurityManager(new SecurityManager()); + TransformerFactory factory = TransformerFactory.newInstance(); + + /** + * Use of the extension function 'http://exslt.org/strings:tokenize' is + * not allowed when the secure processing feature is set to true. + * Attempt to use the new property to enable extension function + */ + boolean isExtensionSupported = enableExtensionFunction(factory); + + try { + transform(factory); + System.out.println("testEnableExt: OK"); + } catch (TransformerConfigurationException e) { + fail(e.getMessage()); + } catch (TransformerException e) { + fail(e.getMessage()); + } finally { + System.setSecurityManager(null); + } + } + + /** + * use Templates template = factory.newTemplates(new StreamSource( new + * FileInputStream(xslFilename))); // Use the template to create a + * transformer Transformer xformer = template.newTransformer(); + * + * @param factory + * @return + */ + /** + * Security is enabled, use new feature: enableExtensionFunctions Use the + * template to create a transformer + */ + public void testTemplatesEnableExtFunc() { + Policy p = new SimplePolicy(new AllPermission()); + Policy.setPolicy(p); + System.setSecurityManager(new SecurityManager()); + TransformerFactory factory = TransformerFactory.newInstance(); + + /** + * Use of the extension function 'http://exslt.org/strings:tokenize' is + * not allowed when the secure processing feature is set to true. + * Attempt to use the new property to enable extension function + */ + boolean isExtensionSupported = enableExtensionFunction(factory); + + try { + SAXSource xslSource = new SAXSource(new InputSource(xslFile)); + xslSource.setSystemId(xslFileId); + Templates template = factory.newTemplates(xslSource); + Transformer transformer = template.newTransformer(); + StringWriter stringResult = new StringWriter(); + Result result = new StreamResult(stringResult); + transformer.transform(new SAXSource(new InputSource(xmlFile)), result); + System.out.println("testTemplatesEnableExtFunc: OK"); + } catch (TransformerConfigurationException e) { + fail(e.getMessage()); + } catch (TransformerException e) { + fail(e.getMessage()); + } finally { + System.setSecurityManager(null); + } + } + + boolean enableExtensionFunction(TransformerFactory factory) { + boolean isSupported = true; + try { + factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true); + } catch (TransformerConfigurationException ex) { + isSupported = false; + } + return isSupported; + } + + void transform(TransformerFactory factory) throws TransformerConfigurationException, TransformerException { + SAXSource xslSource = new SAXSource(new InputSource(xslFile)); + xslSource.setSystemId(xslFileId); + Transformer transformer = factory.newTransformer(xslSource); + StringWriter stringResult = new StringWriter(); + Result result = new StreamResult(stringResult); + transformer.transform(new SAXSource(new InputSource(xmlFile)), result); + } + + class SimplePolicy extends Policy { + + private final Permissions perms; + + public SimplePolicy(Permission... permissions) { + perms = new Permissions(); + for (Permission permission : permissions) { + perms.add(permission); + } + } + + @Override + public PermissionCollection getPermissions(CodeSource cs) { + return perms; + } + + @Override + public PermissionCollection getPermissions(ProtectionDomain pd) { + return perms; + } + + @Override + public boolean implies(ProtectionDomain pd, Permission p) { + return perms.implies(p); + } + + //for older jdk + @Override + public void refresh() { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/transform/8004476/tokenize.xml Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<html> +<a> + <b>Is this EXSLT? No. no</b> + <c>Is this EXSLT? No. no</c> +</a> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/xml/jaxp/transform/8004476/tokenize.xsl Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:str="http://exslt.org/strings" + xmlns:xalan="http://xml.apache.org/xalan" + version="1.0"> +<xsl:template match="a"> + <xsl:apply-templates /> +</xsl:template> +<xsl:template match="//a/c"> + <xsl:value-of select="." /> + - + <xsl:value-of select="str:tokenize(string(.), ' ')" /> + <xsl:value-of select="str:tokenize(string(.), '')" /> + <xsl:for-each select="str:tokenize(string(.), ' ')"> + <xsl:value-of select="." /> + </xsl:for-each> + <xsl:apply-templates select="*" /> +</xsl:template> +<xsl:template match="//a/b"> + <xsl:value-of select="." /> + - + <xsl:value-of select="xalan:tokenize(string(.), ' ')" /> + <xsl:value-of select="xalan:tokenize(string(.), '')" /> + <xsl:for-each select="xalan:tokenize(string(.), ' ')"> + <xsl:value-of select="." /> + </xsl:for-each> + <xsl:apply-templates select="*" /> +</xsl:template> + +</xsl:stylesheet>
--- a/test/javax/xml/jaxp/transform/jdk8004476/SecureProcessingTest.xml Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -<?xml version="1.0"?> -<helloWorld/>
--- a/test/javax/xml/jaxp/transform/jdk8004476/TestBase.java Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - */ -import java.security.Policy; - -/** - * - * - * @author huizhe.wang@oracle.com - */ -public class TestBase { - public static boolean isWindows = false; - static { - if (System.getProperty("os.name").indexOf("Windows")>-1) { - isWindows = true; - } - }; - - String filepath; - boolean hasSM; - String curDir; - Policy origPolicy; - String testName; - static String errMessage; - - int passed = 0, failed = 0; - - /** - * Creates a new instance of StreamReader - */ - public TestBase(String name) { - testName = name; - } - - //junit @Override - protected void setUp() { - if (System.getSecurityManager() != null) { - hasSM = true; - System.setSecurityManager(null); - } - - filepath = System.getProperty("test.src"); - if (filepath == null) { - //current directory - filepath = System.getProperty("user.dir"); - } - origPolicy = Policy.getPolicy(); - - } - - //junit @Override - public void tearDown() { - // turn off security manager and restore policy - System.setSecurityManager(null); - Policy.setPolicy(origPolicy); - if (hasSM) { - System.setSecurityManager(new SecurityManager()); - } - System.out.println("\nNumber of tests passed: " + passed); - System.out.println("Number of tests failed: " + failed + "\n"); - - if (errMessage != null ) { - throw new RuntimeException(errMessage); - } - } - - void fail(String errMsg) { - if (errMessage == null) { - errMessage = errMsg; - } else { - errMessage = errMessage + "\n" + errMsg; - } - failed++; - } - - void success(String msg) { - passed++; - System.out.println(msg); - } - -}
--- a/test/javax/xml/jaxp/transform/jdk8004476/XPathExFuncTest.java Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8004476 - * @summary test XPath extension functions - * @run main/othervm XPathExFuncTest - */ -import java.io.FileInputStream; -import java.io.InputStream; -import java.security.AllPermission; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.util.Iterator; -import java.util.List; -import javax.xml.XMLConstants; -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import javax.xml.xpath.XPathFactoryConfigurationException; -import javax.xml.xpath.XPathFunction; -import javax.xml.xpath.XPathFunctionException; -import javax.xml.xpath.XPathFunctionResolver; -import org.w3c.dom.Document; - -/** - * test XPath extension functions - * - * @author huizhe.wang@oracle.com - */ -public class XPathExFuncTest extends TestBase { - - final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions"; - final static String CLASSNAME = "DocumentBuilderFactoryImpl"; - final String XPATH_EXPRESSION = "ext:helloWorld()"; - - /** - * Creates a new instance of StreamReader - */ - public XPathExFuncTest(String name) { - super(name); - } - boolean hasSM; - String xslFile, xslFileId; - String xmlFile, xmlFileId; - - protected void setUp() { - super.setUp(); - xmlFile = filepath + "/SecureProcessingTest.xml"; - - } - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - XPathExFuncTest test = new XPathExFuncTest("OneTest"); - test.setUp(); - - test.testExtFunc(); - test.testExtFuncNotAllowed(); - test.testEnableExtFunc(); - test.tearDown(); - - } - - /** - * by default, extension function is enabled - */ - public void testExtFunc() { - - try { - evaluate(false); - System.out.println("testExtFunc: OK"); - } catch (XPathFactoryConfigurationException e) { - fail(e.getMessage()); - } catch (XPathExpressionException e) { - fail(e.getMessage()); - } - } - - /** - * Security is enabled, extension function not allowed - */ - public void testExtFuncNotAllowed() { - Policy p = new SimplePolicy(new AllPermission()); - Policy.setPolicy(p); - System.setSecurityManager(new SecurityManager()); - - try { - evaluate(false); - } catch (XPathFactoryConfigurationException e) { - fail(e.getMessage()); - } catch (XPathExpressionException ex) { - //expected since extension function is disallowed - System.out.println("testExtFuncNotAllowed: OK"); - } finally { - System.setSecurityManager(null); - } - } - - /** - * Security is enabled, use new feature: enableExtensionFunctions - */ - public void testEnableExtFunc() { - Policy p = new SimplePolicy(new AllPermission()); - Policy.setPolicy(p); - System.setSecurityManager(new SecurityManager()); - - - try { - evaluate(true); - System.out.println("testEnableExt: OK"); - } catch (XPathFactoryConfigurationException e) { - fail(e.getMessage()); - } catch (XPathExpressionException e) { - fail(e.getMessage()); - } finally { - System.setSecurityManager(null); - } - } - - Document getDocument() { - // the xml source - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = null; - Document document = null; - - try { - documentBuilder = documentBuilderFactory.newDocumentBuilder(); - InputStream xmlStream = new FileInputStream(xmlFile); - document = documentBuilder.parse(xmlStream); - } catch (Exception e) { - fail(e.toString()); - } - return document; - } - - void evaluate(boolean enableExt) throws XPathFactoryConfigurationException, XPathExpressionException { - Document document = getDocument(); - - XPathFactory xPathFactory = XPathFactory.newInstance(); - /** - * Use of the extension function 'http://exslt.org/strings:tokenize' is - * not allowed when the secure processing feature is set to true. - * Attempt to use the new property to enable extension function - */ - if (enableExt) { - boolean isExtensionSupported = enableExtensionFunction(xPathFactory); - } - - xPathFactory.setXPathFunctionResolver(new MyXPathFunctionResolver()); - if (System.getSecurityManager() == null) { - xPathFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - } - - XPath xPath = xPathFactory.newXPath(); - xPath.setNamespaceContext(new MyNamespaceContext()); - - String xPathResult = xPath.evaluate(XPATH_EXPRESSION, document); - System.out.println( - "XPath result (enableExtensionFunction == " + enableExt + ") = \"" - + xPathResult - + "\""); - } - - public class MyXPathFunctionResolver - implements XPathFunctionResolver { - - public XPathFunction resolveFunction(QName functionName, int arity) { - - // not a real ewsolver, always return a default XPathFunction - return new MyXPathFunction(); - } - } - - public class MyXPathFunction - implements XPathFunction { - - public Object evaluate(List list) throws XPathFunctionException { - - return "Hello World"; - } - } - - public class MyNamespaceContext implements NamespaceContext { - - public String getNamespaceURI(String prefix) { - if (prefix == null) { - throw new IllegalArgumentException("The prefix cannot be null."); - } - - if (prefix.equals("ext")) { - return "http://ext.com"; - } else { - return null; - } - } - - public String getPrefix(String namespace) { - - if (namespace == null) { - throw new IllegalArgumentException("The namespace uri cannot be null."); - } - - if (namespace.equals("http://ext.com")) { - return "ext"; - } else { - return null; - } - } - - public Iterator getPrefixes(String namespace) { - return null; - } - } - - boolean enableExtensionFunction(XPathFactory factory) { - boolean isSupported = true; - try { - factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true); - } catch (XPathFactoryConfigurationException ex) { - isSupported = false; - } - return isSupported; - } - - class SimplePolicy extends Policy { - - private final Permissions perms; - - public SimplePolicy(Permission... permissions) { - perms = new Permissions(); - for (Permission permission : permissions) { - perms.add(permission); - } - } - - @Override - public PermissionCollection getPermissions(CodeSource cs) { - return perms; - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain pd) { - return perms; - } - - @Override - public boolean implies(ProtectionDomain pd, Permission p) { - return perms.implies(p); - } - - //for older jdk - @Override - public void refresh() { - } - } -}
--- a/test/javax/xml/jaxp/transform/jdk8004476/XSLTExFuncTest.java Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 8004476 - * @summary test XSLT extension functions - * @run main/othervm XSLTExFuncTest - */ - -import java.io.StringWriter; -import java.security.AllPermission; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import javax.xml.transform.*; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.stream.StreamResult; -import org.xml.sax.InputSource; - -/** - * test XSLT extension functions - * - * @author huizhe.wang@oracle.com - */ -public class XSLTExFuncTest extends TestBase { - - final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions"; - final static String CLASSNAME = "DocumentBuilderFactoryImpl"; - - /** - * Creates a new instance of StreamReader - */ - public XSLTExFuncTest(String name) { - super(name); - } - boolean hasSM; - String xslFile, xslFileId; - String xmlFile, xmlFileId; - - protected void setUp() { - super.setUp(); - xmlFile = filepath + "/tokenize.xml"; - xslFile = filepath + "/tokenize.xsl"; - - /** - * if (isWindows) { xslFile = "/" + xslFile; } - * - */ - xslFileId = "file://" + xslFile; - } - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - XSLTExFuncTest test = new XSLTExFuncTest("OneTest"); - test.setUp(); - - test.testExtFunc(); - test.testExtFuncNotAllowed(); - test.testEnableExtFunc(); - test.testTemplatesEnableExtFunc(); - test.tearDown(); - - } - - /** - * by default, extension function is enabled - */ - public void testExtFunc() { - TransformerFactory factory = TransformerFactory.newInstance(); - - try { - transform(factory); - System.out.println("testExtFunc: OK"); - } catch (TransformerConfigurationException e) { - fail(e.getMessage()); - } catch (TransformerException ex) { - fail(ex.getMessage()); - } - } - - /** - * Security is enabled, extension function not allowed - */ - public void testExtFuncNotAllowed() { - Policy p = new SimplePolicy(new AllPermission()); - Policy.setPolicy(p); - System.setSecurityManager(new SecurityManager()); - TransformerFactory factory = TransformerFactory.newInstance(); - - try { - transform(factory); - } catch (TransformerConfigurationException e) { - fail(e.getMessage()); - } catch (TransformerException ex) { - //expected since extension function is disallowed - System.out.println("testExtFuncNotAllowed: OK"); - } finally { - System.setSecurityManager(null); - } - } - - /** - * Security is enabled, use new feature: enableExtensionFunctions - */ - public void testEnableExtFunc() { - Policy p = new SimplePolicy(new AllPermission()); - Policy.setPolicy(p); - System.setSecurityManager(new SecurityManager()); - TransformerFactory factory = TransformerFactory.newInstance(); - - /** - * Use of the extension function 'http://exslt.org/strings:tokenize' is - * not allowed when the secure processing feature is set to true. - * Attempt to use the new property to enable extension function - */ - boolean isExtensionSupported = enableExtensionFunction(factory); - - try { - transform(factory); - System.out.println("testEnableExt: OK"); - } catch (TransformerConfigurationException e) { - fail(e.getMessage()); - } catch (TransformerException e) { - fail(e.getMessage()); - } finally { - System.setSecurityManager(null); - } - } - - /** - * use Templates template = factory.newTemplates(new StreamSource( new - * FileInputStream(xslFilename))); // Use the template to create a - * transformer Transformer xformer = template.newTransformer(); - * - * @param factory - * @return - */ - /** - * Security is enabled, use new feature: enableExtensionFunctions Use the - * template to create a transformer - */ - public void testTemplatesEnableExtFunc() { - Policy p = new SimplePolicy(new AllPermission()); - Policy.setPolicy(p); - System.setSecurityManager(new SecurityManager()); - TransformerFactory factory = TransformerFactory.newInstance(); - - /** - * Use of the extension function 'http://exslt.org/strings:tokenize' is - * not allowed when the secure processing feature is set to true. - * Attempt to use the new property to enable extension function - */ - boolean isExtensionSupported = enableExtensionFunction(factory); - - try { - SAXSource xslSource = new SAXSource(new InputSource(xslFile)); - xslSource.setSystemId(xslFileId); - Templates template = factory.newTemplates(xslSource); - Transformer transformer = template.newTransformer(); - StringWriter stringResult = new StringWriter(); - Result result = new StreamResult(stringResult); - transformer.transform(new SAXSource(new InputSource(xmlFile)), result); - System.out.println("testTemplatesEnableExtFunc: OK"); - } catch (TransformerConfigurationException e) { - fail(e.getMessage()); - } catch (TransformerException e) { - fail(e.getMessage()); - } finally { - System.setSecurityManager(null); - } - } - - boolean enableExtensionFunction(TransformerFactory factory) { - boolean isSupported = true; - try { - factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true); - } catch (TransformerConfigurationException ex) { - isSupported = false; - } - return isSupported; - } - - void transform(TransformerFactory factory) throws TransformerConfigurationException, TransformerException { - SAXSource xslSource = new SAXSource(new InputSource(xslFile)); - xslSource.setSystemId(xslFileId); - Transformer transformer = factory.newTransformer(xslSource); - StringWriter stringResult = new StringWriter(); - Result result = new StreamResult(stringResult); - transformer.transform(new SAXSource(new InputSource(xmlFile)), result); - } - - class SimplePolicy extends Policy { - - private final Permissions perms; - - public SimplePolicy(Permission... permissions) { - perms = new Permissions(); - for (Permission permission : permissions) { - perms.add(permission); - } - } - - @Override - public PermissionCollection getPermissions(CodeSource cs) { - return perms; - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain pd) { - return perms; - } - - @Override - public boolean implies(ProtectionDomain pd, Permission p) { - return perms.implies(p); - } - - //for older jdk - @Override - public void refresh() { - } - } -}
--- a/test/javax/xml/jaxp/transform/jdk8004476/tokenize.xml Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<html> -<a> - <b>Is this EXSLT? No. no</b> - <c>Is this EXSLT? No. no</c> -</a> -</html>
--- a/test/javax/xml/jaxp/transform/jdk8004476/tokenize.xsl Fri Mar 21 17:54:04 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:str="http://exslt.org/strings" - xmlns:xalan="http://xml.apache.org/xalan" - version="1.0"> -<xsl:template match="a"> - <xsl:apply-templates /> -</xsl:template> -<xsl:template match="//a/c"> - <xsl:value-of select="." /> - - - <xsl:value-of select="str:tokenize(string(.), ' ')" /> - <xsl:value-of select="str:tokenize(string(.), '')" /> - <xsl:for-each select="str:tokenize(string(.), ' ')"> - <xsl:value-of select="." /> - </xsl:for-each> - <xsl:apply-templates select="*" /> -</xsl:template> -<xsl:template match="//a/b"> - <xsl:value-of select="." /> - - - <xsl:value-of select="xalan:tokenize(string(.), ' ')" /> - <xsl:value-of select="xalan:tokenize(string(.), '')" /> - <xsl:for-each select="xalan:tokenize(string(.), ' ')"> - <xsl:value-of select="." /> - </xsl:for-each> - <xsl:apply-templates select="*" /> -</xsl:template> - -</xsl:stylesheet>
--- a/test/sun/net/www/protocol/jar/jarbug/run.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/net/www/protocol/jar/jarbug/run.sh Thu Apr 03 00:39:02 2014 +0100 @@ -34,14 +34,17 @@ SunOS | Linux | Darwin | AIX ) PS=":" FS="/" + CHMOD="${FS}bin${FS}chmod" ;; Windows* ) PS=";" FS="\\" + CHMOD="chmod" ;; CYGWIN* ) PS=";" FS="/" + CHMOD="chmod" # # javac does not like /cygdrive produced by `pwd`. # @@ -59,6 +62,7 @@ mkdir -p ${DEST}${FS}jar1 cd ${TESTSRC}${FS}etc${FS}jar1 cp -r . ${DEST}${FS}jar1 +${CHMOD} -R u+w ${DEST}${FS}jar1 ${TESTJAVA}${FS}bin${FS}javac -d ${DEST}${FS}jar1 \ ${TESTSRC}${FS}src${FS}jar1${FS}LoadResourceBundle.java ${TESTJAVA}${FS}bin${FS}javac -d ${DEST}${FS}jar1 \
--- a/test/sun/security/krb5/auto/TcpTimeout.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/krb5/auto/TcpTimeout.java Thu Apr 03 00:39:02 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ /* * @test * @bug 6952519 - * @run main/timeout=40/othervm TcpTimeout + * @compile -XDignore.symbol.file TcpTimeout.java + * @run main/othervm TcpTimeout * @summary kdc_timeout is not being honoured when using TCP */ @@ -36,103 +37,71 @@ public static void main(String[] args) throws Exception { + // Set debug to grab debug output like ">>> KDCCommunication" System.setProperty("sun.security.krb5.debug", "true"); - final int p1 = 10000 + new java.util.Random().nextInt(10000); - final int p2 = 20000 + new java.util.Random().nextInt(10000); - final int p3 = 30000 + new java.util.Random().nextInt(10000); - KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p3, true); + // Called before new ServerSocket on p1 and p2 to make sure + // customized nameservice is used + KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, 0, true); + int p3 = k.getPort(); k.addPrincipal(OneKDC.USER, OneKDC.PASS); k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM); // Start two listener that does not communicate, simulate timeout - new Thread() { - public void run() { - try { - new ServerSocket(p1).accept(); - } catch (Exception e) { - }} - }.start(); - new Thread() { - public void run() { - try { - new ServerSocket(p2).accept(); - } catch (Exception e) { - }} - }.start(); + ServerSocket ss1 = null; + ServerSocket ss2 = null; + + try { + ss1 = new ServerSocket(0); + ss2 = new ServerSocket(0); + int p1 = ss1.getLocalPort(); + int p2 = ss2.getLocalPort(); + + FileWriter fw = new FileWriter("alternative-krb5.conf"); - FileWriter fw = new FileWriter("alternative-krb5.conf"); + fw.write("[libdefaults]\n" + + "udp_preference_limit = 1\n" + + "max_retries = 2\n" + + "default_realm = " + OneKDC.REALM + "\n" + + "kdc_timeout = 5000\n"); + fw.write("[realms]\n" + OneKDC.REALM + " = {\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" + + "}\n"); - fw.write("[libdefaults]\n" + - "udp_preference_limit = 1\n" + - "max_retries = 2\n" + - "default_realm = " + OneKDC.REALM + "\n" + - "kdc_timeout = 5000\n"); - fw.write("[realms]\n" + OneKDC.REALM + " = {\n" + - "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" + - "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" + - "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" + - "}\n"); + fw.close(); + System.setProperty("java.security.krb5.conf", + "alternative-krb5.conf"); + Config.refresh(); - fw.close(); - System.setProperty("java.security.krb5.conf", "alternative-krb5.conf"); - Config.refresh(); + System.out.println("Ports opened on " + p1 + ", " + p2 + ", " + p3); - // The correct behavior should be: - // 5 sec on p1, 5 sec on p1, fail - // 5 sec on p2, 5 sec on p2, fail - // p3 ok, p3 ok again for preauth. - // The total time should be 20sec + 2x. x is processing time for AS-REQ. - int count = 6; - long start = System.nanoTime(); + // The correct behavior should be: + // 5 sec on p1, 5 sec on p1, fail + // 5 sec on p2, 5 sec on p2, fail + // p3 ok, p3 ok again for preauth. + int count = 6; + + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + PrintStream oldout = System.out; + System.setOut(new PrintStream(bo)); + Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + System.setOut(oldout); - ByteArrayOutputStream bo = new ByteArrayOutputStream(); - PrintStream oldout = System.out; - System.setOut(new PrintStream(bo)); - Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); - System.setOut(oldout); - - String[] lines = new String(bo.toByteArray()).split("\n"); - for (String line: lines) { - if (line.startsWith(">>> KDCCommunication")) { - System.out.println(line); - count--; + String[] lines = new String(bo.toByteArray()).split("\n"); + for (String line: lines) { + if (line.startsWith(">>> KDCCommunication")) { + System.out.println(line); + count--; + } } - } - if (count != 0) { - throw new Exception("Retry count is " + count + " less"); - } - - long end = System.nanoTime(); - if ((end - start)/1000000000L < 20) { - throw new Exception("Too fast? " + (end - start)/1000000000L); + if (count != 0) { + throw new Exception("Retry count is " + count + " less"); + } + } finally { + if (ss1 != null) ss1.close(); + if (ss2 != null) ss2.close(); } } - - private static KDC on(int p) throws Exception { - KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true); - k.addPrincipal(OneKDC.USER, OneKDC.PASS); - k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM); - return k; - } - - private static void addFakeKDCs() - throws Exception { - BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF)); - FileWriter fw = new FileWriter("alternative-krb5.conf"); - while (true) { - String s = fr.readLine(); - if (s == null) { - break; - } - if (s.trim().startsWith("kdc = ")) { - fw.write(" kdc = localhost:33333\n"); - fw.write(" kdc = localhost:22222\n"); - } - fw.write(s + "\n"); - } - fr.close(); - fw.close(); - sun.security.krb5.Config.refresh(); - } }
--- a/test/sun/security/pkcs12/PKCS12SameKeyId.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/pkcs12/PKCS12SameKeyId.java Thu Apr 03 00:39:02 2014 +0100 @@ -59,7 +59,7 @@ for (int i=0; i<SIZE; i++) { System.err.print("."); String cmd = "-keystore " + JKSFILE - + " -storepass changeit -keypass changeit " + + " -storepass changeit -keypass changeit -keyalg rsa " + "-genkeypair -alias p" + i + " -dname CN=" + i; KeyTool.main(cmd.split(" ")); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/tools/jarsigner/EntriesOrder.java Thu Apr 03 00:39:02 2014 +0100 @@ -0,0 +1,204 @@ +/* + * 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 8031572 + * @summary jarsigner -verify exits with 0 when a jar file is not properly signed + */ + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.cert.Certificate; +import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +public class EntriesOrder { + + public static void main(String[] args) throws Exception { + + String[] entries = { + "META-INF/", + "META-INF/MANIFEST.MF", + "META-INF/A.RSA", + "META-INF/A.SF", + "META-INF/inf", + "a"}; + + Map<String,byte[]> content = new HashMap<>(); + + // We will create a jar containing entries above. Try all permutations + // and confirm 1) When opened as a JarFile, we can always get 3 signed + // ones (MANIFEST, inf, a), and 2) When opened as a JarInputStream, + // when the order is correct (MANIFEST at beginning, followed by RSA/SF, + // directory ignored), we can get 2 signed ones (inf, a). + + // Prepares raw files + Files.write(Paths.get("a"), "a".getBytes()); + Files.createDirectory(Paths.get("META-INF/")); + Files.write(Paths.get("META-INF/inf"), "inf".getBytes()); + + // Pack, sign, and extract to get all files + sun.tools.jar.Main m = + new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!m.run("cvf a.jar a META-INF/inf".split(" "))) { + throw new Exception("jar creation failed"); + } + sun.security.tools.KeyTool.main( + ("-keystore jks -storepass changeit -keypass changeit -dname" + + " CN=A -alias a -genkeypair -keyalg rsa").split(" ")); + sun.security.tools.JarSigner.main( + "-keystore jks -storepass changeit a.jar a".split(" ")); + m = new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!m.run("xvf a.jar".split(" "))) { + throw new Exception("jar extraction failed"); + } + + // Data + for (String s: entries) { + if (!s.endsWith("/")) { + content.put(s, Files.readAllBytes(Paths.get(s))); + } + } + + // Test + for (List<String> perm: Permute(entries)) { + + // Recreate a jar + try (ZipOutputStream zos + = new ZipOutputStream(new FileOutputStream("x.jar"))) { + for (String e: perm) { + zos.putNextEntry(new ZipEntry(e)); + if (Paths.get(e).toFile().isDirectory()) continue; + zos.write(content.get(e)); + } + } + + // Open with JarFile, number of signed entries should be 3. + int cc = 0; + try (JarFile jf = new JarFile("x.jar")) { + Enumeration<JarEntry> jes = jf.entries(); + while (jes.hasMoreElements()) { + JarEntry je = jes.nextElement(); + sun.misc.IOUtils.readFully(jf.getInputStream(je), -1, true); + Certificate[] certs = je.getCertificates(); + if (certs != null && certs.length > 0) { + cc++; + } + } + } + + if (cc != 3) { + System.out.println(perm + " - jf - " + cc); + throw new Exception(); + } + + // Open with JarInputStream + int signed; + + perm.remove("META-INF/"); + if (perm.get(0).equals("META-INF/MANIFEST.MF") && + perm.get(1).contains("/A.") && + perm.get(2).contains("/A.")) { + signed = 2; // Good order + } else { + signed = 0; // Bad order. In this case, the number of signed + // entries is not documented. Just test impl. + } + + cc = 0; + try (JarInputStream jis + = new JarInputStream(new FileInputStream("x.jar"))) { + while (true) { + JarEntry je = jis.getNextJarEntry(); + if (je == null) break; + sun.misc.IOUtils.readFully(jis, -1, true); + Certificate[] certs = je.getCertificates(); + if (certs != null && certs.length > 0) { + cc++; + } + } + } + + if (cc != signed) { + System.out.println(perm + " - jis - " + cc + " " + signed); + throw new Exception(); + } + } + } + + // Helper method to return all permutations of an array. Each output can + // be altered without damaging the iteration process. + static Iterable<List<String>> Permute(final String[] entries) { + return new Iterable<List<String>>() { + + int s = entries.length; + long c = factorial(s) - 1; // number of permutations + + private long factorial(int n) { + return (n == 1) ? 1: (n * factorial(n-1)); + } + + @Override + public Iterator<List<String>> iterator() { + return new Iterator<List<String>>() { + @Override + public boolean hasNext() { + return c >= 0; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove"); + } + + @Override + public List<String> next() { + if (c < 0) return null; + List<String> result = new ArrayList<>(s); + LinkedList<String> source = new LinkedList<>( + Arrays.asList(entries)); + // Treat c as a integer with different radixes at + // different digits, i.e. at digit 0, radix is s; + // at digit 1, radix is s-1. Thus a s-digit number + // is able to represent s! different values. + long n = c; + for (int i=s; i>=1; i--) { + int x = (int)(n % i); + result.add(source.remove(x)); + n = n / i; + } + c--; + return result; + } + }; + } + }; + } +}
--- a/test/sun/security/tools/jarsigner/TimestampCheck.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/TimestampCheck.java Thu Apr 03 00:39:02 2014 +0100 @@ -188,7 +188,7 @@ DerOutputStream tstInfo2 = new DerOutputStream(); tstInfo2.putOctetString(tstInfo.toByteArray()); - Signature sig = Signature.getInstance("SHA1withDSA"); + Signature sig = Signature.getInstance("SHA1withRSA"); sig.initSign((PrivateKey)(ks.getKey( alias, "changeit".toCharArray()))); sig.update(tstInfo.toByteArray()); @@ -205,7 +205,7 @@ SignerInfo signerInfo = new SignerInfo( new X500Name(signer.getIssuerX500Principal().getName()), signer.getSerialNumber(), - aid, AlgorithmId.get("DSA"), sig.sign()); + aid, AlgorithmId.get("RSA"), sig.sign()); SignerInfo[] signerInfos = {signerInfo}; PKCS7 p7 =
--- a/test/sun/security/tools/jarsigner/checkusage.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/checkusage.sh Thu Apr 03 00:39:02 2014 +0100 @@ -45,7 +45,7 @@ ;; esac -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit" +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keyalg rsa" JAR=$TESTJAVA${FS}bin${FS}jar JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner"
--- a/test/sun/security/tools/jarsigner/crl.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/crl.sh Thu Apr 03 00:39:02 2014 +0100 @@ -45,7 +45,7 @@ KS=crl.jks -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" rm $KS 2> /dev/null
--- a/test/sun/security/tools/jarsigner/jvindex.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/jvindex.sh Thu Apr 03 00:39:02 2014 +0100 @@ -47,7 +47,7 @@ JFILE=jvindex.jar KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ - -keystore $KS" + -keystore $KS -keyalg rsa" JAR=$TESTJAVA${FS}bin${FS}jar JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner -keystore $KS -storepass changeit"
--- a/test/sun/security/tools/jarsigner/newsize7.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/newsize7.sh Thu Apr 03 00:39:02 2014 +0100 @@ -51,7 +51,7 @@ KSFILE=ns7.jks -KT="${TESTJAVA}${FS}bin${FS}keytool -keystore ns7.jks -storepass changeit -keypass changeit" +KT="${TESTJAVA}${FS}bin${FS}keytool -keystore ns7.jks -storepass changeit -keypass changeit -keyalg rsa" JAR="${TESTJAVA}${FS}bin${FS}jar" JS="${TESTJAVA}${FS}bin${FS}jarsigner -keystore ns7.jks -storepass changeit"
--- a/test/sun/security/tools/jarsigner/onlymanifest.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/onlymanifest.sh Thu Apr 03 00:39:02 2014 +0100 @@ -46,7 +46,7 @@ JFILE=onlymanifest.jar KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit \ - -keystore $KS" + -keystore $KS -keyalg rsa" JAR=$TESTJAVA${FS}bin${FS}jar JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
--- a/test/sun/security/tools/jarsigner/passtype.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/passtype.sh Thu Apr 03 00:39:02 2014 +0100 @@ -45,7 +45,7 @@ KS=pt.jks JFILE=pt.jar -KT="$TESTJAVA${FS}bin${FS}keytool -keystore $KS -validity 300" +KT="$TESTJAVA${FS}bin${FS}keytool -keystore $KS -validity 300 -keyalg rsa" JAR=$TESTJAVA${FS}bin${FS}jar JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
--- a/test/sun/security/tools/jarsigner/samename.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/samename.sh Thu Apr 03 00:39:02 2014 +0100 @@ -47,7 +47,7 @@ KS=samename.jks JFILE=em.jar -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" JAR=$TESTJAVA${FS}bin${FS}jar JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
--- a/test/sun/security/tools/jarsigner/ts.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/jarsigner/ts.sh Thu Apr 03 00:39:02 2014 +0100 @@ -53,7 +53,7 @@ JAR="${TESTJAVA}${FS}bin${FS}jar" JAVA="${TESTJAVA}${FS}bin${FS}java" JAVAC="${TESTJAVA}${FS}bin${FS}javac" -KT="${TESTJAVA}${FS}bin${FS}keytool -keystore tsks -storepass changeit -keypass changeit -validity 200" +KT="${TESTJAVA}${FS}bin${FS}keytool -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200" rm tsks echo Nothing > A
--- a/test/sun/security/tools/keytool/CloseFile.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/CloseFile.java Thu Apr 03 00:39:02 2014 +0100 @@ -58,7 +58,7 @@ } static void run(String s) throws Exception { - KeyTool.main((s+" -debug").split(" ")); + KeyTool.main((s+" -debug -keyalg rsa").split(" ")); } static void remove(String filename, boolean check) { new File(filename).delete();
--- a/test/sun/security/tools/keytool/ListKeychainStore.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/ListKeychainStore.sh Thu Apr 03 00:39:02 2014 +0100 @@ -71,6 +71,7 @@ -storetype PKCS12 \ -keystore $TEMPORARY_P12 \ -storepass $PWD \ + -keyalg rsa \ -dname "CN=$i,OU=$i,O=$i,ST=$i,C=US" \ -alias 7133495-$i
--- a/test/sun/security/tools/keytool/StartDateTest.java Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/StartDateTest.java Thu Apr 03 00:39:02 2014 +0100 @@ -48,7 +48,7 @@ new File("jks").delete(); run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " + - "-genkeypair -dname CN=Haha -startdate +1y"); + "-keyalg rsa -genkeypair -dname CN=Haha -startdate +1y"); cal.setTime(getIssueDate()); System.out.println(cal); if (cal.get(Calendar.YEAR) != year + 1) {
--- a/test/sun/security/tools/keytool/emptysubject.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/emptysubject.sh Thu Apr 03 00:39:02 2014 +0100 @@ -45,7 +45,7 @@ esac KS=emptysubject.jks -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" rm $KS
--- a/test/sun/security/tools/keytool/importreadall.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/importreadall.sh Thu Apr 03 00:39:02 2014 +0100 @@ -49,7 +49,7 @@ ;; esac -KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool -keystore importreadall.jks -storepass changeit -keypass changeit" +KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool -keystore importreadall.jks -storepass changeit -keypass changeit -keyalg rsa" # In case the test is run twice in the same directory
--- a/test/sun/security/tools/keytool/readjar.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/readjar.sh Thu Apr 03 00:39:02 2014 +0100 @@ -45,7 +45,7 @@ KS=readjar.jks rm $KS $TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS \ - -alias x -dname CN=X -genkeypair + -keyalg rsa -alias x -dname CN=X -genkeypair $TESTJAVA${FS}bin${FS}jar cvf readjar.jar $KS $TESTJAVA${FS}bin${FS}jarsigner -storepass changeit -keystore $KS readjar.jar x
--- a/test/sun/security/tools/keytool/selfissued.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/selfissued.sh Thu Apr 03 00:39:02 2014 +0100 @@ -45,7 +45,7 @@ esac KS=selfsigned.jks -KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS -keyalg rsa" rm $KS
--- a/test/sun/security/tools/keytool/trystore.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/tools/keytool/trystore.sh Thu Apr 03 00:39:02 2014 +0100 @@ -43,7 +43,7 @@ rm trystore.jks 2> /dev/null -KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool -storetype jks -keystore trystore.jks" +KEYTOOL="${TESTJAVA}${FS}bin${FS}keytool -storetype jks -keystore trystore.jks -keyalg rsa" $KEYTOOL -genkeypair -alias a -dname CN=A -storepass changeit -keypass changeit $KEYTOOL -genkeypair -alias b -dname CN=B -storepass changeit -keypass changeit
--- a/test/sun/security/validator/samedn.sh Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/security/validator/samedn.sh Thu Apr 03 00:39:02 2014 +0100 @@ -47,7 +47,7 @@ esac KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit \ - -keypass changeit -keystore samedn.jks" + -keypass changeit -keystore samedn.jks -keyalg rsa" JAVAC=$TESTJAVA${FS}bin${FS}javac JAVA=$TESTJAVA${FS}bin${FS}java
--- a/test/sun/tools/jcmd/help_help.out Fri Mar 21 17:54:04 2014 +0000 +++ b/test/sun/tools/jcmd/help_help.out Thu Apr 03 00:39:02 2014 +0100 @@ -1,7 +1,7 @@ help For more information about a specific command use 'help <command>'. With no argument this will show a list of available commands. 'help all' will show help for all commands. -Impact: Low: +Impact: Low Syntax : help [options] [<command name>]