Merge
diff --git a/.hgtags b/.hgtags
index 6622885..fbd3f71 100644
--- a/.hgtags
+++ b/.hgtags
@@ -199,3 +199,6 @@
4a67fdb752b7d6329d9be9c28d3f9d6cf7eb9a3c jdk8-b75
3a263052866137b645ab86498a43693ff5c19e69 jdk8-b76
b2fc8e31cecc35b76188e821d4c5dc0e0b74ac24 jdk8-b77
+00b7535d743f83eda763c10b3c9ea19ba4b67f55 jdk8-b78
+c933505d75c2a0a671f06d6dac5d2237a9228d2d jdk8-b79
+dfb40f066c6ce129822f0f5dc2ac89173808781a jdk8-b80
diff --git a/make/common/Defs-macosx.gmk b/make/common/Defs-macosx.gmk
index 951a18d..1b7aaa8 100644
--- a/make/common/Defs-macosx.gmk
+++ b/make/common/Defs-macosx.gmk
@@ -406,10 +406,16 @@
LIB_LOCATION ?= $(LIBDIR)
-# Adding these macros will make it an error to link to mac APIs newer than OS version 10.7
-ifeq ($(MACOSX_REQUIRED_VERSION),)
- MACOSX_REQUIRED_VERSION:=1070
+# Setting these parameters makes it an error to link to macosx APIs that are
+# newer than the given OS version and makes the linked binaries compatible even
+# if built on a newer version of the OS.
+# The expected format is X.Y.Z
+ifeq ($(MACOSX_VERSION_MIN),)
+ MACOSX_VERSION_MIN=10.7.0
endif
-MACOSX_OS_VERSION_CFLAGS := -DMAC_OS_X_VERSION_MAX_ALLOWED=$(MACOSX_REQUIRED_VERSION) -DMAC_OS_X_VERSION_MIN_REQUIRED=$(MACOSX_REQUIRED_VERSION)
+# The macro takes the version with no dots, ex: 1070
+MACOSX_OS_VERSION_CFLAGS := -DMAC_OS_X_VERSION_MAX_ALLOWED=$(subst .,,$(MACOSX_VERSION_MIN)) \
+ -mmacosx-version-min=$(MACOSX_VERSION_MIN)
OTHER_CFLAGS += $(MACOSX_OS_VERSION_CFLAGS)
OTHER_CXXFLAGS += $(MACOSX_OS_VERSION_CFLAGS)
+OTHER_LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
diff --git a/make/common/Release.gmk b/make/common/Release.gmk
index 70033e4..5371d04 100644
--- a/make/common/Release.gmk
+++ b/make/common/Release.gmk
@@ -348,7 +348,6 @@
sun/tools/serialver \
sun/tools/tree \
sun/tools/util \
- sun/security/tools/jarsigner/JarBASE64Encoder.class \
sun/security/tools/jarsigner/Main.class \
sun/security/tools/jarsigner/JarSignerParameters.class \
sun/security/tools/jarsigner/Resources.class \
@@ -576,7 +575,6 @@
$(ECHO) "sun/tools/serialver/" >> $@
$(ECHO) "sun/tools/tree/" >> $@
$(ECHO) "sun/tools/util/" >> $@
- $(ECHO) "sun/security/tools/jarsigner/JarBASE64Encoder.class" >> $@
$(ECHO) "sun/security/tools/jarsigner/Main.class" >> $@
$(ECHO) "sun/security/tools/jarsigner/JarSignerParameters.class" >> $@
$(ECHO) "sun/security/tools/jarsigner/Resources.class" >> $@
diff --git a/make/common/shared/Compiler-msvc.gmk b/make/common/shared/Compiler-msvc.gmk
index c50706c..af7dd10 100644
--- a/make/common/shared/Compiler-msvc.gmk
+++ b/make/common/shared/Compiler-msvc.gmk
@@ -28,6 +28,7 @@
#
ifeq ($(PLATFORM), windows)
+ifndef CONFIGURE_BUILD
CC = $(COMPILER_PATH)cl
CPP = $(COMPILER_PATH)cl
CXX = $(COMPILER_PATH)cl
@@ -36,7 +37,7 @@
LINK = $(COMPILER_PATH)link
LINK32 = $(LINK)
DUMPBIN = $(COMPILER_PATH)dumpbin.exe
-
+
# Fill in unknown values
COMPILER_NAME=Unknown MSVC Compiler
COMPILER_VERSION=
@@ -87,6 +88,6 @@
SHARED_LIBRARY_FLAG = -LD
# RSC is always same as RC (Not sure who uses this RSC variable)
RSC = $(RC)
-
+endif
endif
diff --git a/make/common/shared/Defs-utils.gmk b/make/common/shared/Defs-utils.gmk
index 2d3104d..a210de0 100644
--- a/make/common/shared/Defs-utils.gmk
+++ b/make/common/shared/Defs-utils.gmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -82,7 +82,9 @@
MCS = $(COMPILER_PATH)mcs
NM = $(COMPILER_PATH)nm
STRIP = $(COMPILER_PATH)strip
-else
+endif
+
+ifeq ($(PLATFORM),solaris)
AR = $(UTILS_CCS_BIN_PATH)ar
AS = $(UTILS_CCS_BIN_PATH)as
LD = $(UTILS_CCS_BIN_PATH)ld
diff --git a/make/java/java/FILES_java.gmk b/make/java/java/FILES_java.gmk
index 8c2f80c..189b9fc 100644
--- a/make/java/java/FILES_java.gmk
+++ b/make/java/java/FILES_java.gmk
@@ -257,6 +257,7 @@
sun/util/calendar/ZoneInfoFile.java \
java/util/TooManyListenersException.java \
java/util/Comparator.java \
+ java/util/Comparators.java \
java/util/Collections.java \
java/util/Iterator.java \
java/util/ListIterator.java \
diff --git a/make/java/zip/Makefile b/make/java/zip/Makefile
index 67a8557..99afd60 100644
--- a/make/java/zip/Makefile
+++ b/make/java/zip/Makefile
@@ -68,6 +68,16 @@
FILES_reorder += reorder-$(ARCH)
endif
endif
+
+#
+# Use mapfile unconditionally (even with fastdebug).
+# JDK's internal zlib is incompatible with stock zlib, because the
+# size of struct z_stream has been changed, so internal zlib
+# implementation must not be allowed to leak outside of libzip.so,
+# else you get hard to debug failures with fastdebug jdk when user
+# native code includes stock zlib.
+#
+FILES_m = mapfile-vers
include $(BUILDDIR)/common/Mapfile-vers.gmk
include $(BUILDDIR)/common/Library.gmk
diff --git a/make/sun/cmm/lcms/Makefile b/make/sun/cmm/lcms/Makefile
index 24fde37..85b02e4 100644
--- a/make/sun/cmm/lcms/Makefile
+++ b/make/sun/cmm/lcms/Makefile
@@ -28,6 +28,9 @@
LIBRARY = lcms
PRODUCT = sun
+# Use highest level of optimization on this library
+OPTIMIZATION_LEVEL = HIGHEST
+
include $(BUILDDIR)/common/Defs.gmk
#
diff --git a/make/sun/cmm/lcms/mapfile-vers b/make/sun/cmm/lcms/mapfile-vers
index ac4e745..3d9074f 100644
--- a/make/sun/cmm/lcms/mapfile-vers
+++ b/make/sun/cmm/lcms/mapfile-vers
@@ -27,13 +27,12 @@
SUNWprivate_1.1 {
global:
- Java_sun_java2d_cmm_lcms_LCMS_loadProfile;
- Java_sun_java2d_cmm_lcms_LCMS_freeProfile;
+ Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
+ Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
- Java_sun_java2d_cmm_lcms_LCMS_getTagSize;
- Java_sun_java2d_cmm_lcms_LCMS_getTagData;
- Java_sun_java2d_cmm_lcms_LCMS_setTagData;
+ Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
+ Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
Java_sun_java2d_cmm_lcms_LCMS_getProfileID;
Java_sun_java2d_cmm_lcms_LCMS_initLCMS;
diff --git a/make/sun/lwawt/FILES_export_macosx.gmk b/make/sun/lwawt/FILES_export_macosx.gmk
index 2101fd8..6a2e2f9 100644
--- a/make/sun/lwawt/FILES_export_macosx.gmk
+++ b/make/sun/lwawt/FILES_export_macosx.gmk
@@ -122,7 +122,6 @@
sun/lwawt/macosx/CTextPipe.java \
sun/lwawt/macosx/CDesktopPeer.java \
sun/java2d/CRenderer.java \
- sun/lwawt/macosx/EventDispatchAccess.java \
sun/lwawt/macosx/NSPrintInfo.java \
sun/lwawt/macosx/CAccessibility.java \
sun/lwawt/macosx/CAccessible.java \
diff --git a/makefiles/CompileNativeLibraries.gmk b/makefiles/CompileNativeLibraries.gmk
index 01dbc2b..46f1778 100644
--- a/makefiles/CompileNativeLibraries.gmk
+++ b/makefiles/CompileNativeLibraries.gmk
@@ -1218,7 +1218,7 @@
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms,\
LANG:=C,\
- OPTIMIZATION:=LOW, \
+ OPTIMIZATION:=HIGHEST, \
CFLAGS:=$(filter-out -xc99=%none,$(CFLAGS_JDKLIB)) \
$(SHARED_LIBRARY_FLAGS) \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d \
diff --git a/makefiles/Images.gmk b/makefiles/Images.gmk
index 029a488..2d25473 100644
--- a/makefiles/Images.gmk
+++ b/makefiles/Images.gmk
@@ -59,7 +59,7 @@
$(ECHO) $(LOG_INFO) Processing $(patsubst $(OUTPUT_ROOT)/%,%,$@)
$(MKDIR) -p $(@D)
$(RM) $@
- $(SED) 's/$$//g' $< > $@
+ LC_ALL=C $(SED) 's/$$//g' $< > $@
$(CHMOD) 444 $@
endef
diff --git a/makefiles/mapfiles/liblcms/mapfile-vers b/makefiles/mapfiles/liblcms/mapfile-vers
index 04703df..0245114 100644
--- a/makefiles/mapfiles/liblcms/mapfile-vers
+++ b/makefiles/mapfiles/liblcms/mapfile-vers
@@ -27,13 +27,12 @@
SUNWprivate_1.1 {
global:
- Java_sun_java2d_cmm_lcms_LCMS_loadProfile;
- Java_sun_java2d_cmm_lcms_LCMS_freeProfile;
+ Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
+ Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
- Java_sun_java2d_cmm_lcms_LCMS_getTagSize;
- Java_sun_java2d_cmm_lcms_LCMS_getTagData;
- Java_sun_java2d_cmm_lcms_LCMS_setTagData;
+ Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
+ Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
Java_sun_java2d_cmm_lcms_LCMS_getProfileID;
Java_sun_java2d_cmm_lcms_LCMS_initLCMS;
diff --git a/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java b/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java
index a4831d2..8e8527f 100644
--- a/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java
+++ b/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,6 @@
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
-import com.apple.laf.ClientPropertyApplicator;
import com.apple.laf.ClientPropertyApplicator.Property;
import apple.laf.JRSUIConstants.Size;
@@ -142,35 +141,46 @@
return new AquaComboBoxEditor();
}
- class AquaComboBoxEditor extends BasicComboBoxEditor implements UIResource, DocumentListener {
- protected AquaComboBoxEditor() {
+ final class AquaComboBoxEditor extends BasicComboBoxEditor
+ implements UIResource, DocumentListener {
+
+ AquaComboBoxEditor() {
super();
editor = new AquaCustomComboTextField();
editor.addFocusListener(this);
editor.getDocument().addDocumentListener(this);
}
+ @Override
public void focusGained(final FocusEvent e) {
- arrowButton.repaint();
+ if (arrowButton != null) {
+ arrowButton.repaint();
+ }
}
+ @Override
public void focusLost(final FocusEvent e) {
- arrowButton.repaint();
+ if (arrowButton != null) {
+ arrowButton.repaint();
+ }
}
+ @Override
public void changedUpdate(final DocumentEvent e) {
editorTextChanged();
}
+ @Override
public void insertUpdate(final DocumentEvent e) {
editorTextChanged();
}
+ @Override
public void removeUpdate(final DocumentEvent e) {
editorTextChanged();
}
- protected void editorTextChanged() {
+ private void editorTextChanged() {
if (!popup.isVisible()) return;
final Object text = editor.getText();
diff --git a/src/macosx/classes/sun/awt/CGraphicsConfig.java b/src/macosx/classes/sun/awt/CGraphicsConfig.java
index fb37d01..055af2e 100644
--- a/src/macosx/classes/sun/awt/CGraphicsConfig.java
+++ b/src/macosx/classes/sun/awt/CGraphicsConfig.java
@@ -53,7 +53,7 @@
@Override
public Rectangle getBounds() {
- final Rectangle2D nativeBounds = nativeGetBounds(device.getCoreGraphicsScreen());
+ final Rectangle2D nativeBounds = nativeGetBounds(device.getCGDisplayID());
return nativeBounds.getBounds(); // does integer rounding
}
diff --git a/src/macosx/classes/sun/awt/CGraphicsDevice.java b/src/macosx/classes/sun/awt/CGraphicsDevice.java
index bcb24ea..1a5e22a 100644
--- a/src/macosx/classes/sun/awt/CGraphicsDevice.java
+++ b/src/macosx/classes/sun/awt/CGraphicsDevice.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -25,11 +25,12 @@
package sun.awt;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.Window;
import java.awt.AWTPermission;
import java.awt.DisplayMode;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Insets;
+import java.awt.Window;
import java.util.Objects;
import sun.java2d.opengl.CGLGraphicsConfig;
@@ -58,9 +59,12 @@
}
/**
+ * Returns CGDirectDisplayID, which is the same id as @"NSScreenNumber" in
+ * NSScreen.
+ *
* @return CoreGraphics display id.
*/
- public int getCoreGraphicsScreen() {
+ public int getCGDisplayID() {
return displayID;
}
@@ -107,8 +111,9 @@
return nativeGetYResolution(displayID);
}
- private static native double nativeGetXResolution(int displayID);
- private static native double nativeGetYResolution(int displayID);
+ public Insets getScreenInsets() {
+ return nativeGetScreenInsets(displayID);
+ }
/**
* Enters full-screen mode, or returns to windowed mode.
@@ -214,9 +219,15 @@
return nativeGetDisplayModes(displayID);
}
- private native void nativeSetDisplayMode(int displayID, int w, int h, int bpp, int refrate);
+ private static native void nativeSetDisplayMode(int displayID, int w, int h, int bpp, int refrate);
- private native DisplayMode nativeGetDisplayMode(int displayID);
+ private static native DisplayMode nativeGetDisplayMode(int displayID);
- private native DisplayMode[] nativeGetDisplayModes(int displayID);
+ private static native DisplayMode[] nativeGetDisplayModes(int displayID);
+
+ private static native double nativeGetXResolution(int displayID);
+
+ private static native double nativeGetYResolution(int displayID);
+
+ private static native Insets nativeGetScreenInsets(int displayID);
}
diff --git a/src/macosx/classes/sun/font/CStrike.java b/src/macosx/classes/sun/font/CStrike.java
index 61fe234..9635b85 100644
--- a/src/macosx/classes/sun/font/CStrike.java
+++ b/src/macosx/classes/sun/font/CStrike.java
@@ -500,7 +500,10 @@
final Iterator<Long> i = generalCache.values().iterator();
while (i.hasNext()) {
final long longValue = i.next().longValue();
- if (longValue != -1 && longValue != 0) StrikeCache.freeLongPointer(longValue);
+ if (longValue != -1 && longValue != 0) {
+ removeGlyphInfoFromCache(longValue);
+ StrikeCache.freeLongPointer(longValue);
+ }
}
}
@@ -512,7 +515,10 @@
private static void disposeLongArray(final long[] longArray) {
for (int i = 0; i < longArray.length; i++) {
final long ptr = longArray[i];
- if (ptr != 0 && ptr != -1) StrikeCache.freeLongPointer(ptr); // free's the native struct pointer
+ if (ptr != 0 && ptr != -1) {
+ removeGlyphInfoFromCache(ptr);
+ StrikeCache.freeLongPointer(ptr); // free's the native struct pointer
+ }
}
}
diff --git a/src/macosx/classes/sun/font/CStrikeDisposer.java b/src/macosx/classes/sun/font/CStrikeDisposer.java
index 7357ea6..661bd6a 100644
--- a/src/macosx/classes/sun/font/CStrikeDisposer.java
+++ b/src/macosx/classes/sun/font/CStrikeDisposer.java
@@ -85,4 +85,6 @@
}
private native void freeNativeScalerContext(long pContext);
+
+ protected static native void removeGlyphInfoFromCache(long glyphInfo);
}
diff --git a/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java b/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
index 230f705..c8539a8 100644
--- a/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
+++ b/src/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java
@@ -80,10 +80,8 @@
private ContextCapabilities oglCaps;
private OGLContext context;
private final Object disposerReferent = new Object();
-
- public static native int getDefaultPixFmt(int screennum);
private static native boolean initCGL();
- private static native long getCGLConfigInfo(int screennum, int visualnum,
+ private static native long getCGLConfigInfo(int displayID, int visualnum,
int swapInterval);
private static native int getOGLCapabilities(long configInfo);
@@ -137,15 +135,16 @@
// Java-level context and flush the queue...
OGLContext.invalidateCurrentContext();
- cfginfo = getCGLConfigInfo(device.getCoreGraphicsScreen(), pixfmt,
+ cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt,
kOpenGLSwapInterval);
-
- OGLContext.setScratchSurface(cfginfo);
- rq.flushAndInvokeNow(new Runnable() {
- public void run() {
- ids[0] = OGLContext.getOGLIdString();
- }
- });
+ if (cfginfo != 0L) {
+ OGLContext.setScratchSurface(cfginfo);
+ rq.flushAndInvokeNow(new Runnable() {
+ public void run() {
+ ids[0] = OGLContext.getOGLIdString();
+ }
+ });
+ }
} finally {
rq.unlock();
}
@@ -253,8 +252,8 @@
@Override
public String toString() {
- int screen = getDevice().getCoreGraphicsScreen();
- return ("CGLGraphicsConfig[dev="+screen+",pixfmt="+pixfmt+"]");
+ int displayID = getDevice().getCGDisplayID();
+ return ("CGLGraphicsConfig[dev="+displayID+",pixfmt="+pixfmt+"]");
}
@Override
@@ -413,8 +412,8 @@
@Override
public void addDeviceEventListener(AccelDeviceEventListener l) {
- int screen = getDevice().getCoreGraphicsScreen();
- AccelDeviceEventNotifier.addListener(l, screen);
+ int displayID = getDevice().getCGDisplayID();
+ AccelDeviceEventNotifier.addListener(l, displayID);
}
@Override
diff --git a/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/src/macosx/classes/sun/lwawt/LWComponentPeer.java
index aa9b798..052b917 100644
--- a/src/macosx/classes/sun/lwawt/LWComponentPeer.java
+++ b/src/macosx/classes/sun/lwawt/LWComponentPeer.java
@@ -439,7 +439,7 @@
}
@Override
- public final Graphics getGraphics() {
+ public Graphics getGraphics() {
final Graphics g = getOnscreenGraphics();
if (g != null) {
synchronized (getPeerTreeLock()){
@@ -1227,10 +1227,10 @@
}
protected void sendEventToDelegate(final AWTEvent e) {
+ if (getDelegate() == null || !isShowing() || !isEnabled()) {
+ return;
+ }
synchronized (getDelegateLock()) {
- if (getDelegate() == null || !isShowing() || !isEnabled()) {
- return;
- }
AWTEvent delegateEvent = createDelegateEvent(e);
if (delegateEvent != null) {
AWTAccessor.getComponentAccessor()
@@ -1244,7 +1244,12 @@
}
}
- protected AWTEvent createDelegateEvent(AWTEvent e) {
+ /**
+ * Changes the target of the AWTEvent from awt component to appropriate
+ * swing delegate.
+ */
+ private AWTEvent createDelegateEvent(final AWTEvent e) {
+ // TODO modifiers should be changed to getModifiers()|getModifiersEx()?
AWTEvent delegateEvent = null;
if (e instanceof MouseWheelEvent) {
MouseWheelEvent me = (MouseWheelEvent) e;
diff --git a/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java b/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java
new file mode 100644
index 0000000..90e2e88
--- /dev/null
+++ b/src/macosx/classes/sun/lwawt/LWLightweightFramePeer.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+package sun.lwawt;
+
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Window;
+import java.awt.dnd.DropTarget;
+
+import sun.awt.CausedFocusEvent;
+import sun.awt.LightweightFrame;
+
+public class LWLightweightFramePeer extends LWWindowPeer {
+
+ public LWLightweightFramePeer(LightweightFrame target,
+ PlatformComponent platformComponent,
+ PlatformWindow platformWindow)
+ {
+ super(target, platformComponent, platformWindow, LWWindowPeer.PeerType.LW_FRAME);
+ }
+
+ private LightweightFrame getLwTarget() {
+ return (LightweightFrame)getTarget();
+ }
+
+ @Override
+ public Graphics getGraphics() {
+ return getLwTarget().getGraphics();
+ }
+
+ @Override
+ protected void setVisibleImpl(final boolean visible) {
+ }
+
+ @Override
+ public boolean requestWindowFocus(CausedFocusEvent.Cause cause) {
+ if (!focusAllowedFor()) {
+ return false;
+ }
+ if (getPlatformWindow().rejectFocusRequest(cause)) {
+ return false;
+ }
+
+ Window opposite = LWKeyboardFocusManagerPeer.getInstance().
+ getCurrentFocusedWindow();
+
+ changeFocusedWindow(true, opposite);
+
+ return true;
+ }
+
+ @Override
+ public Point getLocationOnScreen() {
+ Rectangle bounds = getBounds();
+ return new Point(bounds.x, bounds.y); // todo
+ }
+
+ @Override
+ public Insets getInsets() {
+ return new Insets(0, 0, 0, 0);
+ }
+
+ @Override
+ public void setBounds(int x, int y, int w, int h, int op) {
+ setBounds(x, y, w, h, op, true, false);
+ }
+
+ @Override
+ public void updateCursorImmediately() {
+ // TODO: tries to switch to the awt/fx toolkit thread and causes a deadlock on macosx
+ }
+
+ @Override
+ public void addDropTarget(DropTarget dt) {
+ }
+
+ @Override
+ public void removeDropTarget(DropTarget dt) {
+ }
+
+ @Override
+ public void grab() {
+ getLwTarget().grabFocus();
+ }
+
+ @Override
+ public void ungrab() {
+ getLwTarget().ungrabFocus();
+ }
+}
diff --git a/src/macosx/classes/sun/lwawt/LWToolkit.java b/src/macosx/classes/sun/lwawt/LWToolkit.java
index 89f39fc..cad6e43 100644
--- a/src/macosx/classes/sun/lwawt/LWToolkit.java
+++ b/src/macosx/classes/sun/lwawt/LWToolkit.java
@@ -218,6 +218,23 @@
return peer;
}
+ private LWLightweightFramePeer createDelegatedLwPeer(LightweightFrame target,
+ PlatformComponent platformComponent,
+ PlatformWindow platformWindow)
+ {
+ LWLightweightFramePeer peer = new LWLightweightFramePeer(target, platformComponent, platformWindow);
+ targetCreatedPeer(target, peer);
+ peer.initialize();
+ return peer;
+ }
+
+ @Override
+ public FramePeer createLightweightFrame(LightweightFrame target) {
+ PlatformComponent platformComponent = createLwPlatformComponent();
+ PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.LW_FRAME);
+ return createDelegatedLwPeer(target, platformComponent, platformWindow);
+ }
+
@Override
public WindowPeer createWindow(Window target) {
PlatformComponent platformComponent = createPlatformComponent();
@@ -502,6 +519,8 @@
protected abstract PlatformComponent createPlatformComponent();
+ protected abstract PlatformComponent createLwPlatformComponent();
+
protected abstract FileDialogPeer createFileDialogPeer(FileDialog target);
// ---- UTILITY METHODS ---- //
diff --git a/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/src/macosx/classes/sun/lwawt/LWWindowPeer.java
index 5b19788..d50335f 100644
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java
+++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java
@@ -48,7 +48,8 @@
FRAME,
DIALOG,
EMBEDDED_FRAME,
- VIEW_EMBEDDED_FRAME
+ VIEW_EMBEDDED_FRAME,
+ LW_FRAME
}
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
@@ -1090,7 +1091,7 @@
return platformWindow.requestWindowFocus();
}
- private boolean focusAllowedFor() {
+ protected boolean focusAllowedFor() {
Window window = getTarget();
// TODO: check if modal blocked
return window.isVisible() && window.isEnabled() && isFocusableWindow();
@@ -1113,10 +1114,15 @@
return !(window instanceof Dialog || window instanceof Frame);
}
+ @Override
+ public void emulateActivation(boolean activate) {
+ changeFocusedWindow(activate, null);
+ }
+
/*
* Changes focused window on java level.
*/
- private void changeFocusedWindow(boolean becomesFocused, Window opposite) {
+ protected void changeFocusedWindow(boolean becomesFocused, Window opposite) {
if (focusLog.isLoggable(PlatformLogger.FINE)) {
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java b/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java
index 181d084..0f32d31 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java
@@ -128,6 +128,15 @@
}
}
+ @Override
+ protected int postDropTargetEvent(Component component, int x, int y, int dropAction,
+ int actions, long[] formats, long nativeCtxt, int eventID,
+ boolean dispatchType) {
+ // On MacOS X all the DnD events should be synchronous
+ return super.postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt,
+ eventID, SunDropTargetContextPeer.DISPATCH_SYNC);
+ }
+
// Signal drop complete:
protected void doDropDone(boolean success, int dropAction, boolean isLocal) {
long nativeDropTarget = this.getNativeDragContext();
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java
index 370b930..978f65c 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java
@@ -35,7 +35,7 @@
* On OSX {@code CPlatformComponent} stores pointer to the native CAlayer which
* can be used from JAWT.
*/
-final class CPlatformComponent extends CFRetainedResource
+class CPlatformComponent extends CFRetainedResource
implements PlatformComponent {
private volatile PlatformWindow platformWindow;
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWComponent.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWComponent.java
new file mode 100644
index 0000000..fd76cf5
--- /dev/null
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWComponent.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+
+package sun.lwawt.macosx;
+
+import sun.lwawt.PlatformWindow;
+
+class CPlatformLWComponent extends CPlatformComponent {
+
+ CPlatformLWComponent() {
+ super();
+ }
+
+ @Override
+ public long getPointer() {
+ return 0;
+ }
+
+ @Override
+ public void initialize(final PlatformWindow platformWindow) {
+ }
+
+ @Override
+ public void setBounds(final int x, final int y, final int w, final int h) {
+ }
+
+ @Override
+ public void dispose() {
+ }
+}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWView.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWView.java
new file mode 100644
index 0000000..e5d9967
--- /dev/null
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWView.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package sun.lwawt.macosx;
+
+import sun.lwawt.LWWindowPeer;
+import sun.java2d.SurfaceData;
+
+public class CPlatformLWView extends CPlatformView {
+
+ public CPlatformLWView() {
+ super();
+ }
+
+ @Override
+ public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
+ initializeBase(peer, responder);
+ }
+
+ @Override
+ public long getAWTView() {
+ return 0;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return true;
+ }
+
+ @Override
+ public void setBounds(int x, int y, int width, int height) {
+ }
+
+ @Override
+ public void enterFullScreenMode() {
+ }
+
+ @Override
+ public void exitFullScreenMode() {
+ }
+
+ @Override
+ public SurfaceData replaceSurfaceData() {
+ return null;
+ }
+
+ @Override
+ public SurfaceData getSurfaceData() {
+ return null;
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public long getWindowLayerPtr() {
+ return 0;
+ }
+}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java
new file mode 100644
index 0000000..d7a9126
--- /dev/null
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformLWWindow.java
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+package sun.lwawt.macosx;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsDevice;
+import java.awt.Insets;
+import java.awt.MenuBar;
+import java.awt.Point;
+import java.awt.Window;
+import sun.awt.CausedFocusEvent;
+import sun.java2d.SurfaceData;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.PlatformWindow;
+
+public class CPlatformLWWindow extends CPlatformWindow {
+
+ @Override
+ public void initialize(Window target, LWWindowPeer peer, PlatformWindow owner) {
+ initializeBase(target, peer, owner, new CPlatformLWView());
+ }
+
+ @Override
+ public void toggleFullScreen() {
+ }
+
+ @Override
+ public void setMenuBar(MenuBar mb) {
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public FontMetrics getFontMetrics(Font f) {
+ return null;
+ }
+
+ @Override
+ public Insets getInsets() {
+ return new Insets(0, 0, 0, 0);
+ }
+
+ @Override
+ public Point getLocationOnScreen() {
+ return null;
+ }
+
+ @Override
+ public GraphicsDevice getGraphicsDevice() {
+ return null;
+ }
+
+ @Override
+ public SurfaceData getScreenSurface() {
+ return null;
+ }
+
+ @Override
+ public SurfaceData replaceSurfaceData() {
+ return null;
+ }
+
+ @Override
+ public void setBounds(int x, int y, int w, int h) {
+ if (getPeer() != null) {
+ getPeer().notifyReshape(x, y, w, h);
+ }
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ }
+
+ @Override
+ public void setTitle(String title) {
+ }
+
+ @Override
+ public void updateIconImages() {
+ }
+
+ @Override
+ public long getNSWindowPtr() {
+ return 0;
+ }
+
+ @Override
+ public SurfaceData getSurfaceData() {
+ return null;
+ }
+
+ @Override
+ public void toBack() {
+ }
+
+ @Override
+ public void toFront() {
+ }
+
+ @Override
+ public void setResizable(final boolean resizable) {
+ }
+
+ @Override
+ public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {
+ }
+
+ @Override
+ public boolean rejectFocusRequest(CausedFocusEvent.Cause cause) {
+ return false;
+ }
+
+ @Override
+ public boolean requestWindowFocus() {
+ return true;
+ }
+
+ @Override
+ public boolean isActive() {
+ return true;
+ }
+
+ @Override
+ public void updateFocusableWindowState() {
+ }
+
+ @Override
+ public Graphics transformGraphics(Graphics g) {
+ return null;
+ }
+
+ @Override
+ public void setAlwaysOnTop(boolean isAlwaysOnTop) {
+ }
+
+ @Override
+ public PlatformWindow getTopmostPlatformWindowUnderMouse(){
+ return null;
+ }
+
+ @Override
+ public void setOpacity(float opacity) {
+ }
+
+ @Override
+ public void setOpaque(boolean isOpaque) {
+ }
+
+ @Override
+ public void enterFullScreenMode() {
+ }
+
+ @Override
+ public void exitFullScreenMode() {
+ }
+
+ @Override
+ public void setWindowState(int windowState) {
+ }
+
+ @Override
+ public LWWindowPeer getPeer() {
+ return super.getPeer();
+ }
+
+ @Override
+ public CPlatformView getContentView() {
+ return super.getContentView();
+ }
+
+ @Override
+ public long getLayerPtr() {
+ return 0;
+ }
+}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java
index 4956579..3a0bec4 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java
@@ -54,8 +54,7 @@
}
public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
- this.peer = peer;
- this.responder = responder;
+ initializeBase(peer, responder);
if (!LWCToolkit.getSunAwtDisableCALayers()) {
this.windowLayer = new CGLLayer(peer);
@@ -63,6 +62,11 @@
setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr()));
}
+ protected void initializeBase(LWWindowPeer peer, CPlatformResponder responder) {
+ this.peer = peer;
+ this.responder = responder;
+ }
+
public long getAWTView() {
return ptr;
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index 8f83702..3fb585b 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -30,6 +30,7 @@
import java.awt.event.*;
import java.awt.peer.WindowPeer;
import java.beans.*;
+import java.lang.reflect.InvocationTargetException;
import java.util.List;
import javax.swing.*;
@@ -44,7 +45,7 @@
import com.apple.laf.ClientPropertyApplicator.Property;
import com.sun.awt.AWTUtilities;
-public final class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
+public class CPlatformWindow extends CFRetainedResource implements PlatformWindow {
private native long nativeCreateNSWindow(long nsViewPtr, long styleBits, double x, double y, double w, double h);
private static native void nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr);
@@ -218,11 +219,7 @@
*/
@Override // PlatformWindow
public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
- this.peer = _peer;
- this.target = _target;
- if (_owner instanceof CPlatformWindow) {
- this.owner = (CPlatformWindow)_owner;
- }
+ initializeBase(_target, _peer, _owner, new CPlatformView());
final int styleBits = getInitialStyleBits();
@@ -231,7 +228,6 @@
String warningString = target.getWarningString();
responder = new CPlatformResponder(peer, false);
- contentView = new CPlatformView();
contentView.initialize(peer, responder);
final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(), styleBits, 0, 0, 0, 0);
@@ -253,6 +249,15 @@
validateSurface();
}
+ protected void initializeBase(Window target, LWWindowPeer peer, PlatformWindow owner, CPlatformView view) {
+ this.peer = peer;
+ this.target = target;
+ if (owner instanceof CPlatformWindow) {
+ this.owner = (CPlatformWindow)owner;
+ }
+ this.contentView = view;
+ }
+
private int getInitialStyleBits() {
// defaults style bits
int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE;
@@ -857,7 +862,16 @@
private void flushBuffers() {
if (isVisible() && !nativeBounds.isEmpty()) {
- LWCToolkit.getLWCToolkit().flushPendingEventsOnAppkit(target);
+ try {
+ LWCToolkit.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ //Posting an empty to flush the EventQueue without blocking the main thread
+ }
+ }, target);
+ } catch (InterruptedException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CRobot.java b/src/macosx/classes/sun/lwawt/macosx/CRobot.java
index e04a45f..c74a589 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CRobot.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CRobot.java
@@ -65,7 +65,7 @@
mouseLastX = x;
mouseLastY = y;
- mouseEvent(fDevice.getCoreGraphicsScreen(), mouseLastX, mouseLastY,
+ mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY,
mouseButtonsState, true, true);
}
@@ -79,7 +79,7 @@
public void mousePress(int buttons) {
mouseButtonsState |= buttons;
- mouseEvent(fDevice.getCoreGraphicsScreen(), mouseLastX, mouseLastY,
+ mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY,
buttons, true, false);
}
@@ -93,7 +93,7 @@
public void mouseRelease(int buttons) {
mouseButtonsState &= ~buttons;
- mouseEvent(fDevice.getCoreGraphicsScreen(), mouseLastX, mouseLastY,
+ mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY,
buttons, false, false);
}
@@ -163,7 +163,7 @@
}
private native void initRobot();
- private native void mouseEvent(int screen, int lastX, int lastY,
+ private native void mouseEvent(int displayID, int lastX, int lastY,
int buttonsState,
boolean isButtonsDownState,
boolean isMouseMove);
diff --git a/src/macosx/classes/sun/lwawt/macosx/CToolkitThreadBlockedHandler.java b/src/macosx/classes/sun/lwawt/macosx/CToolkitThreadBlockedHandler.java
index 94a74e5..6bc6cc7 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CToolkitThreadBlockedHandler.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CToolkitThreadBlockedHandler.java
@@ -25,27 +25,33 @@
package sun.lwawt.macosx;
+import sun.awt.Mutex;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
-final class CToolkitThreadBlockedHandler implements ToolkitThreadBlockedHandler {
- private final LWCToolkit toolkit = (LWCToolkit)java.awt.Toolkit.getDefaultToolkit();
+final class CToolkitThreadBlockedHandler extends Mutex implements ToolkitThreadBlockedHandler {
+ private long awtRunLoopMediator = 0;
+ private final boolean processEvents;
- public void lock() {
- }
-
- public void unlock() {
- }
-
- protected boolean isOwned() {
- return false;
+ CToolkitThreadBlockedHandler() {
+ super();
+ this.processEvents = true;
}
public void enter() {
- // Execute the next AppKit event while we are waiting for system to
- // finish our request - this will save us from biting our own tail
- toolkit.executeNextAppKitEvent();
+ if (!isOwned()) {
+ throw new IllegalMonitorStateException();
+ }
+ awtRunLoopMediator = LWCToolkit.createAWTRunLoopMediator();
+ unlock();
+ LWCToolkit.doAWTRunLoop(awtRunLoopMediator, processEvents);
+ lock();
}
public void exit() {
+ if (!isOwned()) {
+ throw new IllegalMonitorStateException();
+ }
+ LWCToolkit.stopAWTRunLoop(awtRunLoopMediator);
+ awtRunLoopMediator = 0;
}
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
index ae6a4f7..a15eb46 100644
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
+++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,8 +63,6 @@
private static native void initIDs();
- static native void executeNextAppKitEvent();
-
private static CInputMethodDescriptor sInputMethodDescriptor;
static {
@@ -160,6 +158,8 @@
return new CPlatformEmbeddedFrame();
} else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) {
return new CViewPlatformEmbeddedFrame();
+ } else if (peerType == PeerType.LW_FRAME) {
+ return new CPlatformLWWindow();
} else {
assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
return new CPlatformWindow();
@@ -172,6 +172,11 @@
}
@Override
+ protected PlatformComponent createLwPlatformComponent() {
+ return new CPlatformLWComponent();
+ }
+
+ @Override
protected FileDialogPeer createFileDialogPeer(FileDialog target) {
return new CFileDialog(target);
}
@@ -346,22 +351,7 @@
@Override
public Insets getScreenInsets(final GraphicsConfiguration gc) {
- final CGraphicsConfig cgc = (CGraphicsConfig) gc;
- final int displayId = cgc.getDevice().getCoreGraphicsScreen();
- Rectangle fullScreen, workArea;
- final long screen = CWrapper.NSScreen.screenByDisplayId(displayId);
- try {
- fullScreen = CWrapper.NSScreen.frame(screen).getBounds();
- workArea = CWrapper.NSScreen.visibleFrame(screen).getBounds();
- } finally {
- CWrapper.NSObject.release(screen);
- }
- // Convert between Cocoa's coordinate system and Java.
- int bottom = workArea.y - fullScreen.y;
- int top = fullScreen.height - workArea.height - bottom;
- int left = workArea.x - fullScreen.x;
- int right = fullScreen.width - workArea.width - left;
- return new Insets(top, left, bottom, right);
+ return ((CGraphicsConfig) gc).getDevice().getScreenInsets();
}
@Override
@@ -495,30 +485,6 @@
synchronized(ret) { return ret[0]; }
}
- /**
- * Just a wrapper for LWCToolkit.invokeAndWait. Posts an empty event to the
- * appropriate event queue and waits for it to finish.
- */
- public static void flushPendingEventsOnAppkit(final Component component) {
- try {
- invokeAndWait(new Runnable() {
- @Override
- public void run() {
- }
- }, component);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- // Kicks an event over to the appropriate eventqueue and waits for it to finish
- // To avoid deadlocking, we manually run the NSRunLoop while waiting
- // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop
- // The CInvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop
- public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException {
- invokeAndWait(event, component, true);
- }
-
public static <T> T invokeAndWait(final Callable<T> callable, Component component) throws Exception {
final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable);
invokeAndWait(wrapper, component);
@@ -548,10 +514,27 @@
}
}
- public static void invokeAndWait(Runnable event, Component component, boolean detectDeadlocks) throws InterruptedException, InvocationTargetException {
- long mediator = createAWTRunLoopMediator();
+ // Kicks an event over to the appropriate eventqueue and waits for it to finish
+ // To avoid deadlocking, we manually run the NSRunLoop while waiting
+ // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop
+ // The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop
+ // Does not dispatch native events while in the loop
+ public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException {
+ final long mediator = createAWTRunLoopMediator();
- InvocationEvent invocationEvent = new CPeerEvent(event, mediator);
+ InvocationEvent invocationEvent =
+ new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event) {
+ @Override
+ public void dispatch() {
+ try {
+ super.dispatch();
+ } finally {
+ if (mediator != 0) {
+ stopAWTRunLoop(mediator);
+ }
+ }
+ }
+ };
if (component != null) {
AppContext appContext = SunToolkit.targetToAppContext(component);
@@ -564,7 +547,7 @@
((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent);
}
- doAWTRunLoop(mediator, true, detectDeadlocks);
+ doAWTRunLoop(mediator, false);
Throwable eventException = invocationEvent.getException();
if (eventException != null) {
@@ -576,7 +559,8 @@
}
public static void invokeLater(Runnable event, Component component) throws InvocationTargetException {
- final InvocationEvent invocationEvent = new CPeerEvent(event, 0);
+ final InvocationEvent invocationEvent =
+ new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event);
if (component != null) {
final AppContext appContext = SunToolkit.targetToAppContext(component);
@@ -681,31 +665,6 @@
return false;
}
- // Extends PeerEvent because we want to pass long an ObjC mediator object and because we want these events to be posted early
- // Typically, rather than relying on the notifier to call notifyAll(), we use the mediator to stop the runloop
- public static class CPeerEvent extends PeerEvent {
- private long _mediator = 0;
-
- public CPeerEvent(Runnable runnable, long mediator) {
- super(Toolkit.getDefaultToolkit(), runnable, null, true, 0);
- _mediator = mediator;
- }
-
- public void dispatch() {
- try {
- super.dispatch();
- } finally {
- if (_mediator != 0) {
- LWCToolkit.stopAWTRunLoop(_mediator);
- }
- }
- }
- }
-
- // Call through to native methods
- public static void doAWTRunLoop(long mediator, boolean awtMode) { doAWTRunLoop(mediator, awtMode, true); }
- public static void doAWTRunLoop(long mediator) { doAWTRunLoop(mediator, true); }
-
private static Boolean sunAwtDisableCALayers = null;
/**
@@ -730,12 +689,20 @@
* Native methods section
************************/
- // These are public because they are accessed from WebKitPluginObject in JavaDeploy
- // Basic usage:
- // createAWTRunLoopMediator. Start client code on another thread. doAWTRunLoop. When client code is finished, stopAWTRunLoop.
- public static native long createAWTRunLoopMediator();
- public static native void doAWTRunLoop(long mediator, boolean awtMode, boolean detectDeadlocks);
- public static native void stopAWTRunLoop(long mediator);
+ static native long createAWTRunLoopMediator();
+ /**
+ * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent
+ * by [JNFRunLoop performOnMainThreadWaiting] are processed.
+ * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator
+ * @param processEvents if true - dispatches event while in the nested loop. Used in DnD.
+ * Additional attention is needed when using this feature as we short-circuit normal event
+ * processing which could break Appkit.
+ * (One known example is when the window is resized with the mouse)
+ *
+ * if false - all events come after exit form the nested loop
+ */
+ static native void doAWTRunLoop(long mediator, boolean processEvents);
+ static native void stopAWTRunLoop(long mediator);
private native boolean nativeSyncQueue(long timeout);
diff --git a/src/macosx/native/sun/awt/AWTView.m b/src/macosx/native/sun/awt/AWTView.m
index cc16a20..7e1f248 100644
--- a/src/macosx/native/sun/awt/AWTView.m
+++ b/src/macosx/native/sun/awt/AWTView.m
@@ -227,7 +227,7 @@
- (void) mouseMoved: (NSEvent *)event {
// TODO: better way to redirect move events to the "under" view
-
+
NSPoint eventLocation = [event locationInWindow];
NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
@@ -668,7 +668,7 @@
- (void) setDropTarget:(CDropTarget *)target {
self._dropTarget = target;
- [ThreadUtilities performOnMainThread:@selector(controlModelControlValid) onObject:self._dropTarget withObject:nil waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(controlModelControlValid) on:self._dropTarget withObject:nil waitUntilDone:YES];
}
/******************************** BEGIN NSDraggingSource Interface ********************************/
@@ -1215,7 +1215,7 @@
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
#endif // IM_DEBUG
- [ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) onObject:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
[self unmarkText];
}
diff --git a/src/macosx/native/sun/awt/ApplicationDelegate.m b/src/macosx/native/sun/awt/ApplicationDelegate.m
index 9a5aee9..6b584b2 100644
--- a/src/macosx/native/sun/awt/ApplicationDelegate.m
+++ b/src/macosx/native/sun/awt/ApplicationDelegate.m
@@ -567,10 +567,9 @@
{
JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(_registerForNotification:)
- onObject:[ApplicationDelegate class]
+ on:[ApplicationDelegate class]
withObject:[NSNumber numberWithInt:notificationType]
- waitUntilDone:NO
- awtMode:NO]; // AWT_THREADING Safe (non-blocking)
+ waitUntilDone:NO]; // AWT_THREADING Safe (non-blocking)
JNF_COCOA_EXIT(env);
}
diff --git a/src/macosx/native/sun/awt/CClipboard.m b/src/macosx/native/sun/awt/CClipboard.m
index fb300f7..bfba06b 100644
--- a/src/macosx/native/sun/awt/CClipboard.m
+++ b/src/macosx/native/sun/awt/CClipboard.m
@@ -120,7 +120,7 @@
fClipboardOwner = JNFNewGlobalRef(inEnv, inClipboard);
}
}
- [ThreadUtilities performOnMainThread:@selector(_nativeDeclareTypes:) onObject:self withObject:inTypes waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_nativeDeclareTypes:) on:self withObject:inTypes waitUntilDone:YES];
}
- (void) _nativeDeclareTypes:(NSArray *)inTypes {
@@ -135,7 +135,7 @@
- (NSArray *) javaGetTypes {
NSMutableArray *args = [NSMutableArray arrayWithCapacity:1];
- [ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) onObject:self withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_nativeGetTypes:) on:self withObject:args waitUntilDone:YES];
//NSLog(@"CClipboard getTypes returns %@", [args lastObject]);
return [args lastObject];
@@ -152,7 +152,7 @@
- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat {
CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat:inFormat];
- [ThreadUtilities performOnMainThread:@selector(_nativeSetData:) onObject:self withObject:newUpdate waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_nativeSetData:) on:self withObject:newUpdate waitUntilDone:YES];
[newUpdate release];
//NSLog(@"CClipboard javaSetData forType %@", inFormat);
@@ -170,7 +170,7 @@
- (NSData *) javaGetDataForType:(NSString *) inFormat {
NSMutableArray *args = [NSMutableArray arrayWithObject:inFormat];
- [ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) onObject:self withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_nativeGetDataForType:) on:self withObject:args waitUntilDone:YES];
//NSLog(@"CClipboard javaGetDataForType %@ returns an NSData", inFormat);
return [args lastObject];
diff --git a/src/macosx/native/sun/awt/CDropTarget.m b/src/macosx/native/sun/awt/CDropTarget.m
index 60cd781..9dda8ae 100644
--- a/src/macosx/native/sun/awt/CDropTarget.m
+++ b/src/macosx/native/sun/awt/CDropTarget.m
@@ -390,8 +390,7 @@
// Release dragging data if any when Java's AWT event thread is all finished.
// Make sure dragging data is released on the native event thread.
- [ThreadUtilities performOnMainThread:@selector(safeReleaseDraggingData:) onObject:self
- withObject:draggingSequenceNumberID waitUntilDone:NO awtMode:NO];
+ [ThreadUtilities performOnMainThread:@selector(safeReleaseDraggingData:) on:self withObject:draggingSequenceNumberID waitUntilDone:NO];
}
- (jint)currentJavaActions {
diff --git a/src/macosx/native/sun/awt/CGraphicsDevice.m b/src/macosx/native/sun/awt/CGraphicsDevice.m
index 9bc5393..1e2df28 100644
--- a/src/macosx/native/sun/awt/CGraphicsDevice.m
+++ b/src/macosx/native/sun/awt/CGraphicsDevice.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,7 +23,8 @@
* questions.
*/
-#include "LWCToolkit.h"
+#import "LWCToolkit.h"
+#import "ThreadUtilities.h"
/*
* Convert the mode string to the more convinient bits per pixel value
@@ -148,6 +149,47 @@
/*
* Class: sun_awt_CGraphicsDevice
+ * Method: nativeGetScreenInsets
+ * Signature: (I)D
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_awt_CGraphicsDevice_nativeGetScreenInsets
+ (JNIEnv *env, jclass class, jint displayID)
+{
+ jobject ret = NULL;
+ __block NSRect frame = NSZeroRect;
+ __block NSRect visibleFrame = NSZeroRect;
+JNF_COCOA_ENTER(env);
+
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ NSArray *screens = [NSScreen screens];
+ for (NSScreen *screen in screens) {
+ NSDictionary *screenInfo = [screen deviceDescription];
+ NSNumber *screenID = [screenInfo objectForKey:@"NSScreenNumber"];
+ if ([screenID pointerValue] == displayID){
+ frame = [screen frame];
+ visibleFrame = [screen visibleFrame];
+ break;
+ }
+ }
+ }];
+ // Convert between Cocoa's coordinate system and Java.
+ jint bottom = visibleFrame.origin.y - frame.origin.y;
+ jint top = frame.size.height - visibleFrame.size.height - bottom;
+ jint left = visibleFrame.origin.x - frame.origin.x;
+ jint right = frame.size.width - visibleFrame.size.width - left;
+
+ static JNF_CLASS_CACHE(jc_Insets, "java/awt/Insets");
+ static JNF_CTOR_CACHE(jc_Insets_ctor, jc_Insets, "(IIII)V");
+ ret = JNFNewObject(env, jc_Insets_ctor, top, left, bottom, right);
+
+JNF_COCOA_EXIT(env);
+
+ return ret;
+}
+
+/*
+ * Class: sun_awt_CGraphicsDevice
* Method: nativeSetDisplayMode
* Signature: (IIIII)V
*/
diff --git a/src/macosx/native/sun/awt/CMenu.m b/src/macosx/native/sun/awt/CMenu.m
index e6325c2..8b643b3 100644
--- a/src/macosx/native/sun/awt/CMenu.m
+++ b/src/macosx/native/sun/awt/CMenu.m
@@ -55,11 +55,11 @@
//- (void)finalize { [super finalize]; }
- (void)addJavaSubmenu:(CMenu *)submenu {
- [ThreadUtilities performOnMainThread:@selector(addNativeItem_OnAppKitThread:) onObject:self withObject:submenu waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(addNativeItem_OnAppKitThread:) on:self withObject:submenu waitUntilDone:YES];
}
- (void)addJavaMenuItem:(CMenuItem *)theMenuItem {
- [ThreadUtilities performOnMainThread:@selector(addNativeItem_OnAppKitThread:) onObject:self withObject:theMenuItem waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(addNativeItem_OnAppKitThread:) on:self withObject:theMenuItem waitUntilDone:YES];
}
- (void)addNativeItem_OnAppKitThread:(CMenuItem *)itemModified {
@@ -70,7 +70,7 @@
- (void)setJavaMenuTitle:(NSString *)title {
if (title) {
- [ThreadUtilities performOnMainThread:@selector(setNativeMenuTitle_OnAppKitThread:) onObject:self withObject:title waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(setNativeMenuTitle_OnAppKitThread:) on:self withObject:title waitUntilDone:YES];
}
}
@@ -93,7 +93,7 @@
- (void)deleteJavaItem:(jint)index {
- [ThreadUtilities performOnMainThread:@selector(deleteNativeJavaItem_OnAppKitThread:) onObject:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(deleteNativeJavaItem_OnAppKitThread:) on:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES];
}
- (void)deleteNativeJavaItem_OnAppKitThread:(NSNumber *)number {
@@ -139,7 +139,7 @@
// We use an array here only to be able to get a return value
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil];
- [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) onObject:[CMenu alloc] withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenu alloc] withObject:args waitUntilDone:YES];
aCMenu = (CMenu *)[args objectAtIndex: 0];
diff --git a/src/macosx/native/sun/awt/CMenuBar.m b/src/macosx/native/sun/awt/CMenuBar.m
index 23c7949..b0d67f7 100644
--- a/src/macosx/native/sun/awt/CMenuBar.m
+++ b/src/macosx/native/sun/awt/CMenuBar.m
@@ -197,7 +197,7 @@
if (self == sActiveMenuBar) {
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:-1], nil];
- [ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) onObject:self withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) on:self withObject:args waitUntilDone:YES];
[args release];
}
}
@@ -216,7 +216,7 @@
if (self == sActiveMenuBar) {
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:index], nil];
- [ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) onObject:self withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(nativeAddMenuAtIndex_OnAppKitThread:) on:self withObject:args waitUntilDone:YES];
[args release];
}
}
@@ -286,7 +286,7 @@
- (void) javaDeleteMenu: (jint)index {
if (self == sActiveMenuBar) {
- [ThreadUtilities performOnMainThread:@selector(nativeDeleteMenu_OnAppKitThread:) onObject:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(nativeDeleteMenu_OnAppKitThread:) on:self withObject:[NSNumber numberWithInt:index] waitUntilDone:YES];
}
@synchronized(self) {
@@ -388,7 +388,7 @@
// We use an array here only to be able to get a return value
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil];
- [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) onObject:[CMenuBar alloc] withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenuBar alloc] withObject:args waitUntilDone:YES];
aCMenuBar = (CMenuBar *)[args objectAtIndex: 0];
diff --git a/src/macosx/native/sun/awt/CMenuItem.m b/src/macosx/native/sun/awt/CMenuItem.m
index 2281d8b..b67c706 100644
--- a/src/macosx/native/sun/awt/CMenuItem.m
+++ b/src/macosx/native/sun/awt/CMenuItem.m
@@ -386,7 +386,7 @@
args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO], nil];
}
- [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) onObject:[CMenuItem alloc] withObject:args waitUntilDone:YES awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];
aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
diff --git a/src/macosx/native/sun/awt/CRobot.m b/src/macosx/native/sun/awt/CRobot.m
index c04d568..056fd19 100644
--- a/src/macosx/native/sun/awt/CRobot.m
+++ b/src/macosx/native/sun/awt/CRobot.m
@@ -135,7 +135,7 @@
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_mouseEvent
(JNIEnv *env, jobject peer,
- jint screenIndex, jint mouseLastX, jint mouseLastY, jint buttonsState,
+ jint displayID, jint mouseLastX, jint mouseLastY, jint buttonsState,
jboolean isButtonsDownState, jboolean isMouseMove)
{
JNF_COCOA_ENTER(env);
@@ -149,8 +149,6 @@
CGError err = kCGErrorSuccess;
- CGDirectDisplayID displayID =
- FindCGDirectDisplayIDForScreenIndex(screenIndex);
CGRect globalDeviceBounds = CGDisplayBounds(displayID);
// Set unknown mouse location, if needed.
diff --git a/src/macosx/native/sun/awt/JavaComponentAccessibility.m b/src/macosx/native/sun/awt/JavaComponentAccessibility.m
index f886c4a..a01bd78 100644
--- a/src/macosx/native/sun/awt/JavaComponentAccessibility.m
+++ b/src/macosx/native/sun/awt/JavaComponentAccessibility.m
@@ -1113,18 +1113,10 @@
JNIEnv *env = [ThreadUtilities getJNIEnv];
id value = nil;
- // This code frequently gets called indirectly by Java when VoiceOver is active.
- // Basically, we just have to know when we going to be a bad state, and do something "special".
- // Note that while NSApplication isn't technically correct, we post a focus changed notification
- // (which will call this method, but with the correct codepath) shortly afterwards. See +postFocusChanged.
- if (sInPerformFromJava) {
- return [NSApplication sharedApplication];
- } else {
- jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
- if (focused != NULL) {
- if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
- value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
- }
+ jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
+ if (focused != NULL) {
+ if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
+ value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
}
}
@@ -1149,7 +1141,7 @@
{
JNF_COCOA_ENTER(env);
- [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) onObject:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO awtMode:NO];
+ [ThreadUtilities performOnMainThread:@selector(postFocusChanged:) on:[JavaComponentAccessibility class] withObject:nil waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@@ -1164,7 +1156,7 @@
(JNIEnv *env, jclass jklass, jlong element)
{
JNF_COCOA_ENTER(env);
- [ThreadUtilities performOnMainThread:@selector(postValueChanged) onObject:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO awtMode:NO];
+ [ThreadUtilities performOnMainThread:@selector(postValueChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@@ -1177,7 +1169,7 @@
(JNIEnv *env, jclass jklass, jlong element)
{
JNF_COCOA_ENTER(env);
- [ThreadUtilities performOnMainThread:@selector(postSelectionChanged) onObject:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO awtMode:NO];
+ [ThreadUtilities performOnMainThread:@selector(postSelectionChanged) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
@@ -1191,7 +1183,7 @@
(JNIEnv *env, jclass jklass, jlong element)
{
JNF_COCOA_ENTER(env);
- [ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) onObject:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO awtMode:NO];
+ [ThreadUtilities performOnMainThread:@selector(unregisterFromCocoaAXSystem) on:(JavaComponentAccessibility *)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
JNF_COCOA_EXIT(env);
}
diff --git a/src/macosx/native/sun/awt/LWCToolkit.h b/src/macosx/native/sun/awt/LWCToolkit.h
index c318421..8df2c55 100644
--- a/src/macosx/native/sun/awt/LWCToolkit.h
+++ b/src/macosx/native/sun/awt/LWCToolkit.h
@@ -44,8 +44,6 @@
+ (void) eventCountPlusPlus;
@end
-CGDirectDisplayID FindCGDirectDisplayIDForScreenIndex(jint screenIndex);
-
/*
* Utility Macros
*/
diff --git a/src/macosx/native/sun/awt/LWCToolkit.m b/src/macosx/native/sun/awt/LWCToolkit.m
index 45c5461..47c72ab 100644
--- a/src/macosx/native/sun/awt/LWCToolkit.m
+++ b/src/macosx/native/sun/awt/LWCToolkit.m
@@ -177,39 +177,6 @@
NSBeep(); // produces both sound and visual flash, if configured in System Preferences
}
-CGDirectDisplayID
-FindCGDirectDisplayIDForScreenIndex(jint screenIndex)
-{
- // most common case - just one monitor
- CGDirectDisplayID screenID = CGMainDisplayID();
-
- CGDisplayCount displayCount = 0;
- CGGetOnlineDisplayList(0, NULL, &displayCount);
-
- if ((displayCount > 1) &&
- (screenIndex >= 0) &&
- (screenIndex < (jint)displayCount))
- {
- if (displayCount < 10) {
- // stack allocated optimization for less than 10 monitors
- CGDirectDisplayID onlineDisplays[displayCount];
- CGGetOnlineDisplayList(displayCount, onlineDisplays, &displayCount);
- screenID = (CGDirectDisplayID)onlineDisplays[screenIndex];
- } else {
- CGDirectDisplayID *onlineDisplays =
- malloc(displayCount*sizeof(CGDirectDisplayID));
- if (onlineDisplays != NULL) {
- CGGetOnlineDisplayList(displayCount, onlineDisplays,
- &displayCount);
- screenID = (CGDirectDisplayID)onlineDisplays[screenIndex];
- free(onlineDisplays);
- }
- }
- }
-
- return screenID;
-}
-
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: initIDs
@@ -332,7 +299,7 @@
* Signature: (JZZ)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop
-(JNIEnv *env, jclass clz, jlong mediator, jboolean awtMode, jboolean detectDeadlocks)
+(JNIEnv *env, jclass clz, jlong mediator, jboolean processEvents)
{
AWT_ASSERT_APPKIT_THREAD;
JNF_COCOA_ENTER(env);
@@ -341,26 +308,25 @@
if (mediatorObject == nil) return;
- if (!sInPerformFromJava || !detectDeadlocks) {
+ // Don't use acceptInputForMode because that doesn't setup autorelease pools properly
+ BOOL isRunning = true;
+ while (![mediatorObject shouldEndRunLoop] && isRunning) {
+ isRunning = [[NSRunLoop currentRunLoop] runMode:[JNFRunLoop javaRunLoopMode]
+ beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.010]];
+ if (processEvents) {
+ //We do not spin a runloop here as date is nil, so does not matter which mode to use
+ NSEvent *event;
+ if ((event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES]) != nil) {
+ [NSApp sendEvent:event];
+ }
- NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
- NSDate *distantFuture = [NSDate distantFuture];
- NSString *mode = (awtMode) ? [JNFRunLoop javaRunLoopMode] : NSDefaultRunLoopMode;
-
- BOOL isRunning = YES;
- while (isRunning && ![mediatorObject shouldEndRunLoop]) {
- // Don't use acceptInputForMode because that doesn't setup autorelease pools properly
- isRunning = [currentRunLoop runMode:mode beforeDate:distantFuture];
}
-
}
-#ifndef PRODUCT_BUILD
- if (sInPerformFromJava) {
- NSLog(@"Apple AWT: Short-circuiting CToolkit.invokeAndWait trampoline deadlock!!!!!");
- NSLog(@"\tPlease file a bug report with this message and a reproducible test case.");
- }
-#endif
+
CFRelease(mediatorObject);
JNF_COCOA_EXIT(env);
@@ -379,7 +345,7 @@
AWTRunLoopObject* mediatorObject = (AWTRunLoopObject*)jlong_to_ptr(mediator);
- [ThreadUtilities performOnMainThread:@selector(endRunLoop) onObject:mediatorObject withObject:nil waitUntilDone:NO awtMode:YES];
+ [ThreadUtilities performOnMainThread:@selector(endRunLoop) on:mediatorObject withObject:nil waitUntilDone:NO];
CFRelease(mediatorObject);
@@ -463,20 +429,3 @@
}
-/*
- * Class: sun_lwawt_macosx_LWCToolkit
- * Method: executeNextAppKitEvent
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_executeNextAppKitEvent
-(JNIEnv *env, jclass cls)
-{
- // Simply get the next event in native loop and pass it to execution
- // We'll be called repeatedly so there's no need to block here
- NSRunLoop *theRL = [NSRunLoop currentRunLoop];
- NSApplication * app = [NSApplication sharedApplication];
- NSEvent * event = [app nextEventMatchingMask: 0xFFFFFFFF untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
- if (event != nil) {
- [app sendEvent: event];
- }
-}
diff --git a/src/macosx/native/sun/font/AWTStrike.m b/src/macosx/native/sun/font/AWTStrike.m
index 261bd34..7f04b53 100644
--- a/src/macosx/native/sun/font/AWTStrike.m
+++ b/src/macosx/native/sun/font/AWTStrike.m
@@ -27,11 +27,13 @@
#import "java_awt_geom_PathIterator.h"
#import "sun_awt_SunHints.h"
#import "sun_font_CStrike.h"
+#import "sun_font_CStrikeDisposer.h"
#import "CGGlyphImages.h"
#import "CGGlyphOutlines.h"
#import "AWTStrike.h"
#import "CoreTextSupport.h"
//#import "jni_util.h"
+#include "fontscalerdefs.h"
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
@@ -423,3 +425,19 @@
return metrics;
}
+
+extern void AccelGlyphCache_RemoveAllInfos(GlyphInfo* glyph);
+/*
+ * Class: sun_font_CStrikeDisposer
+ * Method: removeGlyphInfoFromCache
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_font_CStrikeDisposer_removeGlyphInfoFromCache
+(JNIEnv *env, jclass cls, jlong glyphInfo)
+{
+ JNF_COCOA_ENTER(env);
+
+ AccelGlyphCache_RemoveAllCellInfos((GlyphInfo*)jlong_to_ptr(glyphInfo));
+
+ JNF_COCOA_EXIT(env);
+}
diff --git a/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m b/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
index 0bc58ec..a9de285 100644
--- a/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
+++ b/src/macosx/native/sun/java2d/opengl/CGLGraphicsConfig.m
@@ -192,12 +192,12 @@
JNIEXPORT jlong JNICALL
Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
(JNIEnv *env, jclass cglgc,
- jint screennum, jint pixfmt, jint swapInterval)
+ jint displayID, jint pixfmt, jint swapInterval)
{
jlong ret = 0L;
JNF_COCOA_ENTER(env);
NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3];
- [retArray addObject: [NSNumber numberWithInt: (int)screennum]];
+ [retArray addObject: [NSNumber numberWithInt: (int)displayID]];
[retArray addObject: [NSNumber numberWithInt: (int)pixfmt]];
[retArray addObject: [NSNumber numberWithInt: (int)swapInterval]];
if ([NSThread isMainThread]) {
@@ -217,7 +217,7 @@
+ (void) _getCGLConfigInfo: (NSMutableArray *)argValue {
AWT_ASSERT_APPKIT_THREAD;
- jint screennum = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
+ jint displayID = (jint)[(NSNumber *)[argValue objectAtIndex: 0] intValue];
jint pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue];
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
@@ -230,16 +230,11 @@
CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
if (sharedContext == NULL) {
if (glMask == 0) {
- CGDirectDisplayID id =
- FindCGDirectDisplayIDForScreenIndex(screennum);
- glMask = CGDisplayIDToOpenGLDisplayMask(id);
+ glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
}
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAClosestPolicy,
- NSOpenGLPFANoRecovery,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAFullScreen,
NSOpenGLPFAWindow,
NSOpenGLPFAPixelBuffer,
NSOpenGLPFADoubleBuffer,
@@ -412,7 +407,7 @@
return;
}
memset(cglinfo, 0, sizeof(CGLGraphicsConfigInfo));
- cglinfo->screen = screennum;
+ cglinfo->screen = displayID;
cglinfo->pixfmt = sharedPixelFormat;
cglinfo->context = oglc;
@@ -422,17 +417,6 @@
}
@end //GraphicsConfigUtil
-
-JNIEXPORT jint JNICALL
-Java_sun_java2d_opengl_CGLGraphicsConfig_getDefaultPixFmt
- (JNIEnv *env, jclass cglgc, jint screennum)
-{
- J2dTraceLn(J2D_TRACE_INFO, "CGLGraphicsConfig_getDefaultPixFmt");
-
- CGDirectDisplayID id = FindCGDirectDisplayIDForScreenIndex(screennum);
- return (jint)CGDisplayIDToOpenGLDisplayMask(id);
-}
-
JNIEXPORT jint JNICALL
Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities
(JNIEnv *env, jclass cglgc, jlong configInfo)
diff --git a/src/macosx/native/sun/osxapp/ThreadUtilities.h b/src/macosx/native/sun/osxapp/ThreadUtilities.h
index c0d2054..2ee65e9 100644
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.h
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.h
@@ -122,19 +122,12 @@
#endif /* AWT_THREAD_ASSERTS */
// --------------------------------------------------------------------------
-// This tracks if we are current inside of a performOnMainThread that is both waiting and in the AWTRunLoopMode
-extern BOOL sInPerformFromJava;
-
-// This is an empty Obj-C object just so that -performSelectorOnMainThread
-// can be used, and to use the Obj-C +initialize feature.
__attribute__((visibility("default")))
-@interface ThreadUtilities : NSObject { }
+@interface ThreadUtilities { }
+ (JNIEnv*)getJNIEnv;
+ (JNIEnv*)getJNIEnvUncached;
-+ (void)performOnMainThread:(SEL)aSelector onObject:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait awtMode:(BOOL)inAWT;
-
//Wrappers for the corresponding JNFRunLoop methods with a check for main thread
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
+ (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait;
diff --git a/src/macosx/native/sun/osxapp/ThreadUtilities.m b/src/macosx/native/sun/osxapp/ThreadUtilities.m
index 0b42f1b..d431386 100644
--- a/src/macosx/native/sun/osxapp/ThreadUtilities.m
+++ b/src/macosx/native/sun/osxapp/ThreadUtilities.m
@@ -34,85 +34,6 @@
JavaVM *jvm = NULL;
static JNIEnv *appKitEnv = NULL;
-static NSArray *sPerformModes = nil;
-static NSArray *sAWTPerformModes = nil;
-
-static BOOL sLoggingEnabled = YES;
-
-#ifdef AWT_THREAD_ASSERTS_ENV_ASSERT
-int sAWTThreadAsserts = 0;
-#endif /* AWT_THREAD_ASSERTS_ENV_ASSERT */
-
-BOOL sInPerformFromJava = NO;
-
-// This class is used so that performSelectorOnMainThread can be
-// controlled a little more easily by us. It has 2 roles.
-// The first is to set/unset a flag (sInPerformFromJava) that code can
-// check to see if we are in a synchronous perform initiated by a java thread.
-// The second is to implement the CocoaComponent backward compatibility mode.
-@interface CPerformer : NSObject {
- id fTarget;
- SEL fSelector;
- id fArg;
- BOOL fWait;
-}
-
-- (id) initWithTarget:(id)target selector:(SEL)selector arg:(id)arg wait:(BOOL)wait;
-- (void) perform;
-@end
-
-
-@implementation CPerformer
-
-- (id) initWithTarget:(id)target selector:(SEL)selector arg:(id)arg {
- return [self initWithTarget:target selector:selector arg:arg wait:YES];
-}
-
-- (id) initWithTarget:(id)target selector:(SEL)selector arg:(id)arg wait:(BOOL)wait {
- self = [super init];
- if (self != nil) {
- fTarget = [target retain];
- fSelector = selector;
- fArg = [arg retain];
- // Only set sInPerformFromJava if this is a synchronous perform
- fWait = wait;
- }
- return self;
-}
-
-- (void) dealloc {
- [fTarget release];
- [fArg release];
- [super dealloc];
-}
-//- (void)finalize { [super finalize]; }
-
-- (void) perform {
- AWT_ASSERT_APPKIT_THREAD;
-
- // If this is the first time we're going from java thread -> appkit thread,
- // set sInPerformFromJava for the duration of the invocation
- BOOL nestedPerform = sInPerformFromJava;
- if (fWait) {
- sInPerformFromJava = YES;
- }
-
- // Actually do the work (cheat to avoid a method call)
- @try {
- objc_msgSend(fTarget, fSelector, fArg);
- //[fTarget performSelector:fSelector withObject:fArg];
- } @catch (NSException *e) {
- NSLog(@"*** CPerformer: ignoring exception '%@' raised during perform of selector '%@' on target '%@' with args '%@'", e, NSStringFromSelector(fSelector), fTarget, fArg);
- } @finally {
- // If we actually set sInPerformFromJava, unset it now
- if (!nestedPerform && fWait) {
- sInPerformFromJava = NO;
- }
- }
-}
-@end
-
-
@implementation ThreadUtilities
+ (JNIEnv*)getJNIEnv {
@@ -129,36 +50,6 @@
return env;
}
-+ (void)initialize {
- // Headless: BOTH
- // Embedded: BOTH
- // Multiple Calls: NO
- // Caller: Obj-C class initialization
- // Thread: ?
-
- if (sPerformModes == nil) {
- // Create list of Run Loop modes to perform on
- // The default performSelector, with no mode argument, runs in Default,
- // ModalPanel, and EventTracking modes
- sPerformModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, NSModalPanelRunLoopMode, nil];
- sAWTPerformModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, NSModalPanelRunLoopMode, NSEventTrackingRunLoopMode, [JNFRunLoop javaRunLoopMode], nil];
-
-#ifdef AWT_THREAD_ASSERTS_ENV_ASSERT
- sAWTThreadAsserts = (getenv("COCOA_AWT_DISABLE_THREAD_ASSERTS") == NULL);
-#endif /* AWT_THREAD_ASSERTS_ENV_ASSERT */
- }
-}
-
-// These methods can behave slightly differently than the normal
-// performSelector... In particular, we define a special runloop mode
-// (AWTRunLoopMode) so that we can "block" the main thread against the
-// java event thread without deadlocking. See CToolkit.invokeAndWait.
-+ (void)performOnMainThread:(SEL)aSelector onObject:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait awtMode:(BOOL)inAWT {
- CPerformer *performer = [[CPerformer alloc] initWithTarget:target selector:aSelector arg:arg wait:wait];
- [performer performSelectorOnMainThread:@selector(perform) withObject:nil waitUntilDone:wait modes:((inAWT) ? sAWTPerformModes : sPerformModes)]; // AWT_THREADING Safe (cover method)
- [performer release];
-}
-
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
if ([NSThread isMainThread] && wait == YES) {
block();
diff --git a/src/share/back/transport.c b/src/share/back/transport.c
index 40608b3..1d7335d 100644
--- a/src/share/back/transport.c
+++ b/src/share/back/transport.c
@@ -117,6 +117,9 @@
/* Construct library name (simple name or full path) */
dbgsysBuildLibName(libname, sizeof(libname), plibdir, name);
+ if (strlen(libname) == 0) {
+ return NULL;
+ }
/* dlopen (unix) / LoadLibrary (windows) the transport library */
handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
diff --git a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
index 3df8706..3da159f 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java
@@ -564,7 +564,7 @@
code.bytes = new byte[readInt()];
in.readFully(code.bytes);
Entry[] cpMap = cls.getCPMap();
- Instruction.opcodeChecker(code.bytes, cpMap);
+ Instruction.opcodeChecker(code.bytes, cpMap, this.cls.version);
int nh = readUnsignedShort();
code.setHandlerCount(nh);
for (int i = 0; i < nh; i++) {
diff --git a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
index dfa6a12..1ede291 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
@@ -207,6 +207,10 @@
return tag;
}
+ public final boolean tagEquals(int tag) {
+ return getTag() == tag;
+ }
+
public Entry getRef(int i) {
return null;
}
diff --git a/src/share/classes/com/sun/java/util/jar/pack/Constants.java b/src/share/classes/com/sun/java/util/jar/pack/Constants.java
index 1588262..5059bc0 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/Constants.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/Constants.java
@@ -479,4 +479,10 @@
public final static int _qldc = _xldc_op+7;
public final static int _qldc_w = _xldc_op+8;
public final static int _xldc_limit = _xldc_op+9;
+
+ // handling of InterfaceMethodRef
+ public final static int _invoke_int_op = _xldc_limit;
+ public final static int _invokespecial_int = _invoke_int_op+0;
+ public final static int _invokestatic_int = _invoke_int_op+1;
+ public final static int _invoke_int_limit = _invoke_int_op+2;
}
diff --git a/src/share/classes/com/sun/java/util/jar/pack/Instruction.java b/src/share/classes/com/sun/java/util/jar/pack/Instruction.java
index 31ee22b..93175fe 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/Instruction.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/Instruction.java
@@ -446,12 +446,14 @@
public static boolean isCPRefOp(int bc) {
if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return true;
if (bc >= _xldc_op && bc < _xldc_limit) return true;
+ if (bc == _invokespecial_int || bc == _invokestatic_int) return true;
return false;
}
public static byte getCPRefOpTag(int bc) {
if (bc < BC_INDEX[0].length && BC_INDEX[0][bc] > 0) return BC_TAG[0][bc];
if (bc >= _xldc_op && bc < _xldc_limit) return CONSTANT_LoadableValue;
+ if (bc == _invokestatic_int || bc == _invokespecial_int) return CONSTANT_InterfaceMethodref;
return CONSTANT_None;
}
@@ -647,7 +649,8 @@
}
}
- public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap) throws FormatException {
+ public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap,
+ Package.Version clsVersion) throws FormatException {
Instruction i = at(code, 0);
while (i != null) {
int opcode = i.getBC();
@@ -658,10 +661,17 @@
ConstantPool.Entry e = i.getCPRef(cpMap);
if (e != null) {
byte tag = i.getCPTag();
- if (!e.tagMatches(tag)) {
- String message = "illegal reference, expected type=" +
- ConstantPool.tagName(tag) + ": " +
- i.toString(cpMap);
+ boolean match = e.tagMatches(tag);
+ if (!match &&
+ (i.bc == _invokespecial || i.bc == _invokestatic) &&
+ e.tagMatches(CONSTANT_InterfaceMethodref) &&
+ clsVersion.greaterThan(Constants.JAVA7_MAX_CLASS_VERSION)) {
+ match = true;
+ }
+ if (!match) {
+ String message = "illegal reference, expected type="
+ + ConstantPool.tagName(tag) + ": "
+ + i.toString(cpMap);
throw new FormatException(message);
}
}
diff --git a/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java b/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
index df4687b..b42dda3 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/PackageReader.java
@@ -2256,6 +2256,12 @@
int origBC = bc;
int size = 2;
switch (bc) {
+ case _invokestatic_int:
+ origBC = _invokestatic;
+ break;
+ case _invokespecial_int:
+ origBC = _invokespecial;
+ break;
case _ildc:
case _cldc:
case _fldc:
diff --git a/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java b/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
index 4795929..a78c9ae 100644
--- a/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
+++ b/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java
@@ -1409,6 +1409,10 @@
int bc = i.getBC();
if (!(bc >= _first_linker_op && bc <= _last_linker_op)) return -1;
MemberEntry ref = (MemberEntry) i.getCPRef(curCPMap);
+ // do not optimize this case, simply fall back to regular coding
+ if ((bc == _invokespecial || bc == _invokestatic) &&
+ ref.tagEquals(CONSTANT_InterfaceMethodref))
+ return -1;
ClassEntry refClass = ref.classRef;
int self_bc = _self_linker_op + (bc - _first_linker_op);
if (refClass == curClass.thisClass)
@@ -1609,7 +1613,16 @@
case CONSTANT_Fieldref:
bc_which = bc_fieldref; break;
case CONSTANT_Methodref:
- bc_which = bc_methodref; break;
+ if (ref.tagEquals(CONSTANT_InterfaceMethodref)) {
+ if (bc == _invokespecial)
+ vbc = _invokespecial_int;
+ if (bc == _invokestatic)
+ vbc = _invokestatic_int;
+ bc_which = bc_imethodref;
+ } else {
+ bc_which = bc_methodref;
+ }
+ break;
case CONSTANT_InterfaceMethodref:
bc_which = bc_imethodref; break;
case CONSTANT_InvokeDynamic:
diff --git a/src/share/classes/java/awt/CheckboxMenuItem.java b/src/share/classes/java/awt/CheckboxMenuItem.java
index 635e9b5..ad12d4c 100644
--- a/src/share/classes/java/awt/CheckboxMenuItem.java
+++ b/src/share/classes/java/awt/CheckboxMenuItem.java
@@ -277,7 +277,7 @@
* @since 1.4
*/
public synchronized ItemListener[] getItemListeners() {
- return (ItemListener[])(getListeners(ItemListener.class));
+ return getListeners(ItemListener.class);
}
/**
diff --git a/src/share/classes/java/awt/Cursor.java b/src/share/classes/java/awt/Cursor.java
index c340532..d022a64 100644
--- a/src/share/classes/java/awt/Cursor.java
+++ b/src/share/classes/java/awt/Cursor.java
@@ -163,11 +163,11 @@
* hashtable, filesystem dir prefix, filename, and properties for custom cursors support
*/
- private static final Hashtable systemCustomCursors = new Hashtable(1);
+ private static final Hashtable<String,Cursor> systemCustomCursors = new Hashtable<>(1);
private static final String systemCustomCursorDirPrefix = initCursorDir();
private static String initCursorDir() {
- String jhome = (String) java.security.AccessController.doPrivileged(
+ String jhome = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.home"));
return jhome +
File.separator + "lib" + File.separator + "images" +
@@ -298,7 +298,7 @@
static public Cursor getSystemCustomCursor(final String name)
throws AWTException, HeadlessException {
GraphicsEnvironment.checkHeadless();
- Cursor cursor = (Cursor)systemCustomCursors.get(name);
+ Cursor cursor = systemCustomCursors.get(name);
if (cursor == null) {
synchronized(systemCustomCursors) {
@@ -319,11 +319,11 @@
final String fileName =
systemCustomCursorProperties.getProperty(key);
- String localized = (String)systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
+ String localized = systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
if (localized == null) localized = name;
- String hotspot = (String)systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
+ String hotspot = systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
if (hotspot == null)
throw new AWTException("no hotspot property defined for cursor: " + name);
@@ -348,9 +348,9 @@
final int fy = y;
final String flocalized = localized;
- cursor = (Cursor) java.security.AccessController.doPrivileged(
- new java.security.PrivilegedExceptionAction() {
- public Object run() throws Exception {
+ cursor = java.security.AccessController.<Cursor>doPrivileged(
+ new java.security.PrivilegedExceptionAction<Cursor>() {
+ public Cursor run() throws Exception {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage(
systemCustomCursorDirPrefix + fileName);
@@ -447,8 +447,8 @@
systemCustomCursorProperties = new Properties();
try {
- AccessController.doPrivileged(
- new java.security.PrivilegedExceptionAction() {
+ AccessController.<Object>doPrivileged(
+ new java.security.PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
FileInputStream fis = null;
try {
diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java
index 57a2ccf..5795c37 100644
--- a/src/share/classes/java/awt/EventQueue.java
+++ b/src/share/classes/java/awt/EventQueue.java
@@ -171,7 +171,7 @@
* The modifiers field of the current event, if the current event is an
* InputEvent or ActionEvent.
*/
- private WeakReference currentEvent;
+ private WeakReference<AWTEvent> currentEvent;
/*
* Non-zero if a thread is waiting in getNextEvent(int) for an event of
@@ -815,7 +815,7 @@
pushPopLock.lock();
try {
return (Thread.currentThread() == dispatchThread)
- ? ((AWTEvent)currentEvent.get())
+ ? currentEvent.get()
: null;
} finally {
pushPopLock.unlock();
@@ -1173,7 +1173,7 @@
return;
}
- currentEvent = new WeakReference(e);
+ currentEvent = new WeakReference<>(e);
// This series of 'instanceof' checks should be replaced with a
// polymorphic type (for example, an interface which declares a
diff --git a/src/share/classes/java/awt/Menu.java b/src/share/classes/java/awt/Menu.java
index e702a9c..ae5d2fa 100644
--- a/src/share/classes/java/awt/Menu.java
+++ b/src/share/classes/java/awt/Menu.java
@@ -66,7 +66,7 @@
AWTAccessor.setMenuAccessor(
new AWTAccessor.MenuAccessor() {
- public Vector getItems(Menu menu) {
+ public Vector<MenuComponent> getItems(Menu menu) {
return menu.items;
}
});
@@ -78,7 +78,7 @@
* @serial
* @see #countItems()
*/
- Vector items = new Vector();
+ Vector<MenuComponent> items = new Vector<>();
/**
* This field indicates whether the menu has the
@@ -313,7 +313,7 @@
}
int nitems = getItemCount();
- Vector tempItems = new Vector();
+ Vector<MenuItem> tempItems = new Vector<>();
/* Remove the item at index, nitems-index times
storing them in a temporary vector in the
@@ -330,7 +330,7 @@
already in the correct order in the temp vector.
*/
for (int i = 0; i < tempItems.size() ; i++) {
- add((MenuItem)tempItems.elementAt(i));
+ add(tempItems.elementAt(i));
}
}
}
@@ -379,7 +379,7 @@
}
int nitems = getItemCount();
- Vector tempItems = new Vector();
+ Vector<MenuItem> tempItems = new Vector<>();
/* Remove the item at index, nitems-index times
storing them in a temporary vector in the
@@ -396,7 +396,7 @@
already in the correct order in the temp vector.
*/
for (int i = 0; i < tempItems.size() ; i++) {
- add((MenuItem)tempItems.elementAt(i));
+ add(tempItems.elementAt(i));
}
}
}
@@ -475,13 +475,13 @@
return null;
}
- synchronized Enumeration shortcuts() {
- Vector shortcuts = new Vector();
+ synchronized Enumeration<MenuShortcut> shortcuts() {
+ Vector<MenuShortcut> shortcuts = new Vector<>();
int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i);
if (mi instanceof Menu) {
- Enumeration e = ((Menu)mi).shortcuts();
+ Enumeration<MenuShortcut> e = ((Menu)mi).shortcuts();
while (e.hasMoreElements()) {
shortcuts.addElement(e.nextElement());
}
diff --git a/src/share/classes/java/awt/MenuBar.java b/src/share/classes/java/awt/MenuBar.java
index 1fd442e..bd0a7d8 100644
--- a/src/share/classes/java/awt/MenuBar.java
+++ b/src/share/classes/java/awt/MenuBar.java
@@ -81,7 +81,7 @@
return menuBar.helpMenu;
}
- public Vector getMenus(MenuBar menuBar) {
+ public Vector<Menu> getMenus(MenuBar menuBar) {
return menuBar.menus;
}
});
@@ -94,7 +94,7 @@
* @serial
* @see #countMenus()
*/
- Vector menus = new Vector();
+ Vector<Menu> menus = new Vector<>();
/**
* This menu is a special menu dedicated to
@@ -309,7 +309,7 @@
* be called on the toolkit thread.
*/
final Menu getMenuImpl(int i) {
- return (Menu)menus.elementAt(i);
+ return menus.elementAt(i);
}
/**
@@ -321,10 +321,10 @@
* @since JDK1.1
*/
public synchronized Enumeration<MenuShortcut> shortcuts() {
- Vector shortcuts = new Vector();
+ Vector<MenuShortcut> shortcuts = new Vector<>();
int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) {
- Enumeration e = getMenu(i).shortcuts();
+ Enumeration<MenuShortcut> e = getMenu(i).shortcuts();
while (e.hasMoreElements()) {
shortcuts.addElement(e.nextElement());
}
@@ -438,7 +438,7 @@
// HeadlessException will be thrown from MenuComponent's readObject
s.defaultReadObject();
for (int i = 0; i < menus.size(); i++) {
- Menu m = (Menu)menus.elementAt(i);
+ Menu m = menus.elementAt(i);
m.parent = this;
}
}
diff --git a/src/share/classes/java/awt/MenuComponent.java b/src/share/classes/java/awt/MenuComponent.java
index ebd9c05..4895fdc 100644
--- a/src/share/classes/java/awt/MenuComponent.java
+++ b/src/share/classes/java/awt/MenuComponent.java
@@ -290,7 +290,7 @@
public void setFont(Font f) {
font = f;
//Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font)
- MenuComponentPeer peer = (MenuComponentPeer)this.peer;
+ MenuComponentPeer peer = this.peer;
if (peer != null) {
peer.setFont(f);
}
@@ -303,7 +303,7 @@
*/
public void removeNotify() {
synchronized (getTreeLock()) {
- MenuComponentPeer p = (MenuComponentPeer)this.peer;
+ MenuComponentPeer p = this.peer;
if (p != null) {
Toolkit.getEventQueue().removeSourceEvents(this, true);
this.peer = null;
diff --git a/src/share/classes/java/awt/MenuItem.java b/src/share/classes/java/awt/MenuItem.java
index 3b8b2cf..4838d18 100644
--- a/src/share/classes/java/awt/MenuItem.java
+++ b/src/share/classes/java/awt/MenuItem.java
@@ -564,7 +564,7 @@
* @since 1.4
*/
public synchronized ActionListener[] getActionListeners() {
- return (ActionListener[])(getListeners(ActionListener.class));
+ return getListeners(ActionListener.class);
}
/**
diff --git a/src/share/classes/java/awt/RenderingHints.java b/src/share/classes/java/awt/RenderingHints.java
index 5b8daa9..48cf9e1 100644
--- a/src/share/classes/java/awt/RenderingHints.java
+++ b/src/share/classes/java/awt/RenderingHints.java
@@ -92,7 +92,7 @@
* {@code equals()} method.
*/
public abstract static class Key {
- private static HashMap identitymap = new HashMap(17);
+ private static HashMap<Object,Object> identitymap = new HashMap<>(17);
private String getIdentity() {
// Note that the identity string is dependent on 3 variables:
@@ -138,7 +138,7 @@
}
// Note: Use a weak reference to avoid holding on to extra
// objects and classes after they should be unloaded.
- identitymap.put(identity, new WeakReference(k));
+ identitymap.put(identity, new WeakReference<Key>(k));
}
private int privatekey;
@@ -195,7 +195,7 @@
}
}
- HashMap hintmap = new HashMap(7);
+ HashMap<Object,Object> hintmap = new HashMap<>(7);
/**
* Antialiasing hint key.
@@ -1267,12 +1267,13 @@
* object.
* @return a clone of this instance.
*/
+ @SuppressWarnings("unchecked")
public Object clone() {
RenderingHints rh;
try {
rh = (RenderingHints) super.clone();
if (hintmap != null) {
- rh.hintmap = (HashMap) hintmap.clone();
+ rh.hintmap = (HashMap<Object,Object>) hintmap.clone();
}
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
diff --git a/src/share/classes/java/awt/datatransfer/Clipboard.java b/src/share/classes/java/awt/datatransfer/Clipboard.java
index d58bd92..cce9c74 100644
--- a/src/share/classes/java/awt/datatransfer/Clipboard.java
+++ b/src/share/classes/java/awt/datatransfer/Clipboard.java
@@ -71,7 +71,7 @@
*
* @since 1.5
*/
- private Set currentDataFlavors;
+ private Set<DataFlavor> currentDataFlavors;
/**
* Creates a clipboard object.
@@ -313,7 +313,7 @@
if (flavorListeners == null) {
return;
}
- Set prevDataFlavors = currentDataFlavors;
+ Set<DataFlavor> prevDataFlavors = currentDataFlavors;
currentDataFlavors = getAvailableDataFlavorSet();
if (prevDataFlavors.equals(currentDataFlavors)) {
return;
@@ -339,8 +339,8 @@
*
* @since 1.5
*/
- private Set getAvailableDataFlavorSet() {
- Set set = new HashSet();
+ private Set<DataFlavor> getAvailableDataFlavorSet() {
+ Set<DataFlavor> set = new HashSet<>();
Transferable contents = getContents(null);
if (contents != null) {
DataFlavor[] flavors = contents.getTransferDataFlavors();
diff --git a/src/share/classes/java/awt/dnd/DragGestureEvent.java b/src/share/classes/java/awt/dnd/DragGestureEvent.java
index 298436f..3b72ed9 100644
--- a/src/share/classes/java/awt/dnd/DragGestureEvent.java
+++ b/src/share/classes/java/awt/dnd/DragGestureEvent.java
@@ -165,7 +165,7 @@
* <P>
* @return an Iterator for the events comprising the gesture
*/
-
+ @SuppressWarnings("unchecked")
public Iterator<InputEvent> iterator() { return events.iterator(); }
/**
@@ -184,7 +184,7 @@
* <P>
* @return an array of the events comprising the gesture
*/
-
+ @SuppressWarnings("unchecked")
public Object[] toArray(Object[] array) { return events.toArray(array); }
/**
@@ -333,7 +333,6 @@
component = (Component)f.get("component", null);
origin = (Point)f.get("origin", null);
action = f.get("action", 0);
-
// Pre-1.4 support. 'events' was previously non-transient
try {
events = (List)f.get("events", null);
@@ -351,7 +350,7 @@
/*
* fields
*/
-
+ @SuppressWarnings("rawtypes")
private transient List events;
/**
diff --git a/src/share/classes/java/awt/dnd/DragGestureRecognizer.java b/src/share/classes/java/awt/dnd/DragGestureRecognizer.java
index 4b43326..1f1b9a3 100644
--- a/src/share/classes/java/awt/dnd/DragGestureRecognizer.java
+++ b/src/share/classes/java/awt/dnd/DragGestureRecognizer.java
@@ -297,7 +297,7 @@
* @return the initial event that triggered the drag gesture
*/
- public InputEvent getTriggerEvent() { return events.isEmpty() ? null : (InputEvent)events.get(0); }
+ public InputEvent getTriggerEvent() { return events.isEmpty() ? null : events.get(0); }
/**
* Reset the Recognizer, if its currently recognizing a gesture, ignore
diff --git a/src/share/classes/java/awt/dnd/DragSource.java b/src/share/classes/java/awt/dnd/DragSource.java
index 2311ccc..bceedda 100644
--- a/src/share/classes/java/awt/dnd/DragSource.java
+++ b/src/share/classes/java/awt/dnd/DragSource.java
@@ -600,7 +600,7 @@
* @since 1.4
*/
public DragSourceListener[] getDragSourceListeners() {
- return (DragSourceListener[])getListeners(DragSourceListener.class);
+ return getListeners(DragSourceListener.class);
}
/**
@@ -660,8 +660,7 @@
* @since 1.4
*/
public DragSourceMotionListener[] getDragSourceMotionListeners() {
- return (DragSourceMotionListener[])
- getListeners(DragSourceMotionListener.class);
+ return getListeners(DragSourceMotionListener.class);
}
/**
@@ -896,8 +895,8 @@
* @since 1.5
*/
public static int getDragThreshold() {
- int ts = ((Integer)AccessController.doPrivileged(
- new GetIntegerAction("awt.dnd.drag.threshold", 0))).intValue();
+ int ts = AccessController.doPrivileged(
+ new GetIntegerAction("awt.dnd.drag.threshold", 0)).intValue();
if (ts > 0) {
return ts;
} else {
diff --git a/src/share/classes/java/awt/dnd/InvalidDnDOperationException.java b/src/share/classes/java/awt/dnd/InvalidDnDOperationException.java
index 4ea863c..ed94cee 100644
--- a/src/share/classes/java/awt/dnd/InvalidDnDOperationException.java
+++ b/src/share/classes/java/awt/dnd/InvalidDnDOperationException.java
@@ -36,6 +36,8 @@
public class InvalidDnDOperationException extends IllegalStateException {
+ private static final long serialVersionUID = 5156676500247816278L;
+
static private String dft_msg = "The operation requested cannot be performed by the DnD system since it is not in the appropriate state";
/**
diff --git a/src/share/classes/java/awt/geom/AffineTransform.java b/src/share/classes/java/awt/geom/AffineTransform.java
index 2fa1dc2..751deac 100644
--- a/src/share/classes/java/awt/geom/AffineTransform.java
+++ b/src/share/classes/java/awt/geom/AffineTransform.java
@@ -876,6 +876,7 @@
* they have not been cached.
* @see #getType
*/
+ @SuppressWarnings("fallthrough")
private void calculateType() {
int ret = TYPE_IDENTITY;
boolean sgn0, sgn1;
@@ -1038,6 +1039,7 @@
* @see #TYPE_UNIFORM_SCALE
* @since 1.2
*/
+ @SuppressWarnings("fallthrough")
public double getDeterminant() {
switch (state) {
default:
@@ -1250,6 +1252,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
m02 = tx * m00 + ty * m01 + m02;
m12 = tx * m10 + ty * m11 + m12;
@@ -1631,6 +1634,7 @@
* Y axis direction
* @since 1.2
*/
+ @SuppressWarnings("fallthrough")
public void scale(double sx, double sy) {
int state = this.state;
switch (state) {
@@ -1705,6 +1709,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
case (APPLY_SHEAR | APPLY_SCALE):
double M0, M1;
@@ -2224,6 +2229,7 @@
* @see #preConcatenate
* @since 1.2
*/
+ @SuppressWarnings("fallthrough")
public void concatenate(AffineTransform Tx) {
double M0, M1;
double T00, T01, T10, T11;
@@ -2432,6 +2438,7 @@
* @see #concatenate
* @since 1.2
*/
+ @SuppressWarnings("fallthrough")
public void preConcatenate(AffineTransform Tx) {
double M0, M1;
double T00, T01, T10, T11;
@@ -2655,6 +2662,7 @@
default:
stateError();
/* NOTREACHED */
+ return null;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
det = m00 * m11 - m01 * m10;
if (Math.abs(det) <= Double.MIN_VALUE) {
@@ -2751,6 +2759,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12;
@@ -2885,6 +2894,7 @@
default:
stateError();
/* NOTREACHED */
+ return null;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
ptDst.setLocation(x * m00 + y * m01 + m02,
x * m10 + y * m11 + m12);
@@ -2968,6 +2978,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
dst.setLocation(x * m00 + y * m01 + m02,
x * m10 + y * m11 + m12);
@@ -3043,6 +3054,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12;
@@ -3157,6 +3169,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12;
@@ -3252,6 +3265,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12;
@@ -3347,6 +3361,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12;
@@ -3436,6 +3451,7 @@
* inverted.
* @since 1.2
*/
+ @SuppressWarnings("fallthrough")
public Point2D inverseTransform(Point2D ptSrc, Point2D ptDst)
throws NoninvertibleTransformException
{
@@ -3547,6 +3563,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12;
@@ -3679,6 +3696,7 @@
default:
stateError();
/* NOTREACHED */
+ return null;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
case (APPLY_SHEAR | APPLY_SCALE):
ptDst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
@@ -3754,6 +3772,7 @@
default:
stateError();
/* NOTREACHED */
+ return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
case (APPLY_SHEAR | APPLY_SCALE):
M00 = m00; M01 = m01;
diff --git a/src/share/classes/java/awt/peer/FramePeer.java b/src/share/classes/java/awt/peer/FramePeer.java
index 8bb3b07..e9d2b00 100644
--- a/src/share/classes/java/awt/peer/FramePeer.java
+++ b/src/share/classes/java/awt/peer/FramePeer.java
@@ -125,4 +125,10 @@
// into an EmbeddedFramePeer which would extend FramePeer
Rectangle getBoundsPrivate();
+ /**
+ * Requests the peer to emulate window activation.
+ *
+ * @param activate activate or deactivate the window
+ */
+ void emulateActivation(boolean activate);
}
diff --git a/src/share/classes/java/awt/peer/WindowPeer.java b/src/share/classes/java/awt/peer/WindowPeer.java
index f2e8993..fca78b7 100644
--- a/src/share/classes/java/awt/peer/WindowPeer.java
+++ b/src/share/classes/java/awt/peer/WindowPeer.java
@@ -27,8 +27,6 @@
import java.awt.*;
-import java.awt.image.BufferedImage;
-
/**
* The peer interface for {@link Window}.
*
diff --git a/src/share/classes/java/beans/PropertyDescriptor.java b/src/share/classes/java/beans/PropertyDescriptor.java
index c03149c..0abdcad 100644
--- a/src/share/classes/java/beans/PropertyDescriptor.java
+++ b/src/share/classes/java/beans/PropertyDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -109,10 +109,6 @@
if (writeMethodName != null && getWriteMethod() == null) {
throw new IntrospectionException("Method not found: " + writeMethodName);
}
- boundInitialization(beanClass);
- }
-
- private void boundInitialization(Class<?> beanClass) {
// If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method.
@@ -163,7 +159,6 @@
setReadMethod(read);
setWriteMethod(write);
this.baseName = base;
- boundInitialization(bean);
}
/**
diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java
index 0c8b732..f0ab8b2 100644
--- a/src/share/classes/java/lang/Class.java
+++ b/src/share/classes/java/lang/Class.java
@@ -25,6 +25,7 @@
package java.lang;
+import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Member;
@@ -3094,6 +3095,16 @@
}
/**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
diff --git a/src/share/classes/java/lang/ClassLoader.java b/src/share/classes/java/lang/ClassLoader.java
index e62c69a..a1e18ff 100644
--- a/src/share/classes/java/lang/ClassLoader.java
+++ b/src/share/classes/java/lang/ClassLoader.java
@@ -51,7 +51,6 @@
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
-import sun.misc.ClassFileTransformer;
import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
import sun.misc.URLClassPath;
@@ -669,41 +668,6 @@
return source;
}
- private Class<?> defineTransformedClass(String name, byte[] b, int off, int len,
- ProtectionDomain pd,
- ClassFormatError cfe, String source)
- throws ClassFormatError
- {
- // Class format error - try to transform the bytecode and
- // define the class again
- //
- ClassFileTransformer[] transformers =
- ClassFileTransformer.getTransformers();
- Class<?> c = null;
-
- if (transformers != null) {
- for (ClassFileTransformer transformer : transformers) {
- try {
- // Transform byte code using transformer
- byte[] tb = transformer.transform(b, off, len);
- c = defineClass1(name, tb, 0, tb.length,
- pd, source);
- break;
- } catch (ClassFormatError cfe2) {
- // If ClassFormatError occurs, try next transformer
- }
- }
- }
-
- // Rethrow original ClassFormatError if unable to transform
- // bytecode to well-formed
- //
- if (c == null)
- throw cfe;
-
- return c;
- }
-
private void postDefineClass(Class<?> c, ProtectionDomain pd)
{
if (pd.getCodeSource() != null) {
@@ -783,17 +747,8 @@
throws ClassFormatError
{
protectionDomain = preDefineClass(name, protectionDomain);
-
- Class<?> c = null;
String source = defineClassSourceLocation(protectionDomain);
-
- try {
- c = defineClass1(name, b, off, len, protectionDomain, source);
- } catch (ClassFormatError cfe) {
- c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
- source);
- }
-
+ Class<?> c = defineClass1(name, b, off, len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
@@ -881,20 +836,8 @@
}
protectionDomain = preDefineClass(name, protectionDomain);
-
- Class<?> c = null;
String source = defineClassSourceLocation(protectionDomain);
-
- try {
- c = defineClass2(name, b, b.position(), len, protectionDomain,
- source);
- } catch (ClassFormatError cfe) {
- byte[] tb = new byte[len];
- b.get(tb); // get bytes out of byte buffer.
- c = defineTransformedClass(name, tb, 0, len, protectionDomain, cfe,
- source);
- }
-
+ Class<?> c = defineClass2(name, b, b.position(), len, protectionDomain, source);
postDefineClass(c, protectionDomain);
return c;
}
diff --git a/src/share/classes/java/lang/Package.java b/src/share/classes/java/lang/Package.java
index b9776f4..7d1d38d 100644
--- a/src/share/classes/java/lang/Package.java
+++ b/src/share/classes/java/lang/Package.java
@@ -25,6 +25,7 @@
package java.lang;
+import java.lang.reflect.AnnotatedElement;
import java.io.InputStream;
import java.util.Enumeration;
@@ -386,6 +387,16 @@
}
/**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
diff --git a/src/share/classes/java/lang/reflect/AccessibleObject.java b/src/share/classes/java/lang/reflect/AccessibleObject.java
index d198d93..f98aed5 100644
--- a/src/share/classes/java/lang/reflect/AccessibleObject.java
+++ b/src/share/classes/java/lang/reflect/AccessibleObject.java
@@ -181,6 +181,16 @@
}
/**
+ * {@inheritDoc}
+ * @throws NullPointerException {@inheritDoc}
+ * @since 1.5
+ */
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+ return AnnotatedElement.super.isAnnotationPresent(annotationClass);
+ }
+
+ /**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
diff --git a/src/share/classes/java/lang/reflect/Constructor.java b/src/share/classes/java/lang/reflect/Constructor.java
index bbfd1d5..bdbd7c3 100644
--- a/src/share/classes/java/lang/reflect/Constructor.java
+++ b/src/share/classes/java/lang/reflect/Constructor.java
@@ -532,6 +532,7 @@
* {@inheritDoc}
* @since 1.8
*/
+ @Override
public AnnotatedType getAnnotatedReturnType() {
return getAnnotatedReturnType0(getDeclaringClass());
}
diff --git a/src/share/classes/java/lang/reflect/Executable.java b/src/share/classes/java/lang/reflect/Executable.java
index 83b5e9c..1a89968 100644
--- a/src/share/classes/java/lang/reflect/Executable.java
+++ b/src/share/classes/java/lang/reflect/Executable.java
@@ -476,6 +476,20 @@
return declaredAnnotations;
}
+ /**
+ * Returns an AnnotatedType object that represents the potentially
+ * annotated return type of the method/constructor represented by this
+ * Executable.
+ *
+ * If this Executable represents a constructor, the AnnotatedType object
+ * represents the type of the constructed object.
+ *
+ * If this Executable represents a method, the AnnotatedType object
+ * represents the use of a type to specify the return type of the method.
+ *
+ * @since 1.8
+ */
+ public abstract AnnotatedType getAnnotatedReturnType();
/* Helper for subclasses of Executable.
*
diff --git a/src/share/classes/java/lang/reflect/Method.java b/src/share/classes/java/lang/reflect/Method.java
index 1507c77..30e7646 100644
--- a/src/share/classes/java/lang/reflect/Method.java
+++ b/src/share/classes/java/lang/reflect/Method.java
@@ -629,6 +629,7 @@
* {@inheritDoc}
* @since 1.8
*/
+ @Override
public AnnotatedType getAnnotatedReturnType() {
return getAnnotatedReturnType0(getGenericReturnType());
}
diff --git a/src/share/classes/java/net/HttpConnectSocketImpl.java b/src/share/classes/java/net/HttpConnectSocketImpl.java
new file mode 100644
index 0000000..b6e70ca
--- /dev/null
+++ b/src/share/classes/java/net/HttpConnectSocketImpl.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Basic SocketImpl that relies on the internal HTTP protocol handler
+ * implementation to perform the HTTP tunneling and authentication. The
+ * sockets impl is swapped out and replaced with the socket from the HTTP
+ * handler after the tunnel is successfully setup.
+ *
+ * @since 1.8
+ */
+
+/*package*/ class HttpConnectSocketImpl extends PlainSocketImpl {
+
+ private static final String httpURLClazzStr =
+ "sun.net.www.protocol.http.HttpURLConnection";
+ private static final String netClientClazzStr = "sun.net.NetworkClient";
+ private static final String doTunnelingStr = "doTunneling";
+ private static final Field httpField;
+ private static final Field serverSocketField;
+ private static final Method doTunneling;
+
+ private final String server;
+ private InetSocketAddress external_address;
+ private HashMap<Integer, Object> optionsMap = new HashMap<>();
+
+ static {
+ try {
+ Class<?> httpClazz = Class.forName(httpURLClazzStr, true, null);
+ httpField = httpClazz.getDeclaredField("http");
+ doTunneling = httpClazz.getDeclaredMethod(doTunnelingStr);
+ Class<?> netClientClazz = Class.forName(netClientClazzStr, true, null);
+ serverSocketField = netClientClazz.getDeclaredField("serverSocket");
+
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ httpField.setAccessible(true);
+ serverSocketField.setAccessible(true);
+ return null;
+ }
+ });
+ } catch (ReflectiveOperationException x) {
+ throw new InternalError("Should not reach here", x);
+ }
+ }
+
+ HttpConnectSocketImpl(String server, int port) {
+ this.server = server;
+ this.port = port;
+ }
+
+ HttpConnectSocketImpl(Proxy proxy) {
+ SocketAddress a = proxy.address();
+ if ( !(a instanceof InetSocketAddress) )
+ throw new IllegalArgumentException("Unsupported address type");
+
+ InetSocketAddress ad = (InetSocketAddress) a;
+ server = ad.getHostString();
+ port = ad.getPort();
+ }
+
+ @Override
+ protected void connect(SocketAddress endpoint, int timeout)
+ throws IOException
+ {
+ if (endpoint == null || !(endpoint instanceof InetSocketAddress))
+ throw new IllegalArgumentException("Unsupported address type");
+ final InetSocketAddress epoint = (InetSocketAddress)endpoint;
+ final String destHost = epoint.isUnresolved() ? epoint.getHostName()
+ : epoint.getAddress().getHostAddress();
+ final int destPort = epoint.getPort();
+
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkConnect(destHost, destPort);
+
+ // Connect to the HTTP proxy server
+ String urlString = "http://" + destHost + ":" + destPort;
+ Socket httpSocket = privilegedDoTunnel(urlString, timeout);
+
+ // Success!
+ external_address = epoint;
+
+ // close the original socket impl and release its descriptor
+ close();
+
+ // update the Sockets impl to the impl from the http Socket
+ AbstractPlainSocketImpl psi = (AbstractPlainSocketImpl) httpSocket.impl;
+ this.getSocket().impl = psi;
+
+ // best effort is made to try and reset options previously set
+ Set<Map.Entry<Integer,Object>> options = optionsMap.entrySet();
+ try {
+ for(Map.Entry<Integer,Object> entry : options) {
+ psi.setOption(entry.getKey(), entry.getValue());
+ }
+ } catch (IOException x) { /* gulp! */ }
+ }
+
+ @Override
+ public void setOption(int opt, Object val) throws SocketException {
+ super.setOption(opt, val);
+
+ if (external_address != null)
+ return; // we're connected, just return
+
+ // store options so that they can be re-applied to the impl after connect
+ optionsMap.put(opt, val);
+ }
+
+ private Socket privilegedDoTunnel(final String urlString,
+ final int timeout)
+ throws IOException
+ {
+ try {
+ return java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedExceptionAction<Socket>() {
+ public Socket run() throws IOException {
+ return doTunnel(urlString, timeout);
+ }
+ });
+ } catch (java.security.PrivilegedActionException pae) {
+ throw (IOException) pae.getException();
+ }
+ }
+
+ private Socket doTunnel(String urlString, int connectTimeout)
+ throws IOException
+ {
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(server, port));
+ URL destURL = new URL(urlString);
+ HttpURLConnection conn = (HttpURLConnection) destURL.openConnection(proxy);
+ conn.setConnectTimeout(connectTimeout);
+ conn.setReadTimeout(this.timeout);
+ conn.connect();
+ doTunneling(conn);
+ try {
+ Object httpClient = httpField.get(conn);
+ return (Socket) serverSocketField.get(httpClient);
+ } catch (IllegalAccessException x) {
+ throw new InternalError("Should not reach here", x);
+ }
+ }
+
+ private void doTunneling(HttpURLConnection conn) {
+ try {
+ doTunneling.invoke(conn);
+ } catch (ReflectiveOperationException x) {
+ throw new InternalError("Should not reach here", x);
+ }
+ }
+
+ @Override
+ protected InetAddress getInetAddress() {
+ if (external_address != null)
+ return external_address.getAddress();
+ else
+ return super.getInetAddress();
+ }
+
+ @Override
+ protected int getPort() {
+ if (external_address != null)
+ return external_address.getPort();
+ else
+ return super.getPort();
+ }
+
+ @Override
+ protected int getLocalPort() {
+ if (socket != null)
+ return super.getLocalPort();
+ if (external_address != null)
+ return external_address.getPort();
+ else
+ return super.getLocalPort();
+ }
+}
diff --git a/src/share/classes/java/net/Socket.java b/src/share/classes/java/net/Socket.java
index 22d4d6a..d4f28e9 100644
--- a/src/share/classes/java/net/Socket.java
+++ b/src/share/classes/java/net/Socket.java
@@ -117,8 +117,10 @@
if (proxy == null) {
throw new IllegalArgumentException("Invalid Proxy");
}
- Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy);
- if (p.type() == Proxy.Type.SOCKS) {
+ Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY
+ : sun.net.ApplicationProxy.create(proxy);
+ Proxy.Type type = p.type();
+ if (type == Proxy.Type.SOCKS || type == Proxy.Type.HTTP) {
SecurityManager security = System.getSecurityManager();
InetSocketAddress epoint = (InetSocketAddress) p.address();
if (epoint.getAddress() != null) {
@@ -133,7 +135,8 @@
security.checkConnect(epoint.getAddress().getHostAddress(),
epoint.getPort());
}
- impl = new SocksSocketImpl(p);
+ impl = type == Proxy.Type.SOCKS ? new SocksSocketImpl(p)
+ : new HttpConnectSocketImpl(p);
impl.setSocket(this);
} else {
if (p == Proxy.NO_PROXY) {
diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java
index 6227103..caa1d59 100644
--- a/src/share/classes/java/net/URL.java
+++ b/src/share/classes/java/net/URL.java
@@ -661,8 +661,8 @@
* @param file the file on the host
* @param ref the internal reference in the URL
*/
- protected void set(String protocol, String host,
- int port, String file, String ref) {
+ void set(String protocol, String host, int port,
+ String file, String ref) {
synchronized (this) {
this.protocol = protocol;
this.host = host;
@@ -698,9 +698,9 @@
* @param query the query part of this URL
* @since 1.3
*/
- protected void set(String protocol, String host, int port,
- String authority, String userInfo, String path,
- String query, String ref) {
+ void set(String protocol, String host, int port,
+ String authority, String userInfo, String path,
+ String query, String ref) {
synchronized (this) {
this.protocol = protocol;
this.host = host;
diff --git a/src/share/classes/java/net/URLStreamHandler.java b/src/share/classes/java/net/URLStreamHandler.java
index 6af130b..0561527 100644
--- a/src/share/classes/java/net/URLStreamHandler.java
+++ b/src/share/classes/java/net/URLStreamHandler.java
@@ -509,8 +509,8 @@
/**
* Sets the fields of the <code>URL</code> argument to the indicated values.
- * Only classes derived from URLStreamHandler are supposed to be able
- * to call the set method on a URL.
+ * Only classes derived from URLStreamHandler are able
+ * to use this method to set the values of the URL fields.
*
* @param u the URL to modify.
* @param protocol the protocol name.
@@ -539,8 +539,8 @@
/**
* Sets the fields of the <code>URL</code> argument to the indicated values.
- * Only classes derived from URLStreamHandler are supposed to be able
- * to call the set method on a URL.
+ * Only classes derived from URLStreamHandler are able
+ * to use this method to set the values of the URL fields.
*
* @param u the URL to modify.
* @param protocol the protocol name. This value is ignored since 1.2.
diff --git a/src/share/classes/java/nio/file/Files.java b/src/share/classes/java/nio/file/Files.java
index c1c85b5..2db7ba2 100644
--- a/src/share/classes/java/nio/file/Files.java
+++ b/src/share/classes/java/nio/file/Files.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -1152,7 +1152,7 @@
* and file system dependent and therefore unspecified. Minimally, the
* {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
* copied to the target file if supported by both the source and target
- * file store. Copying of file timestamps may result in precision
+ * file stores. Copying of file timestamps may result in precision
* loss. </td>
* </tr>
* <tr>
@@ -1169,12 +1169,12 @@
* implementation specific options.
*
* <p> Copying a file is not an atomic operation. If an {@link IOException}
- * is thrown then it possible that the target file is incomplete or some of
- * its file attributes have not been copied from the source file. When the
- * {@code REPLACE_EXISTING} option is specified and the target file exists,
- * then the target file is replaced. The check for the existence of the file
- * and the creation of the new file may not be atomic with respect to other
- * file system activities.
+ * is thrown, then it is possible that the target file is incomplete or some
+ * of its file attributes have not been copied from the source file. When
+ * the {@code REPLACE_EXISTING} option is specified and the target file
+ * exists, then the target file is replaced. The check for the existence of
+ * the file and the creation of the new file may not be atomic with respect
+ * to other file system activities.
*
* <p> <b>Usage Example:</b>
* Suppose we want to copy a file into a directory, giving it the same file
@@ -1279,15 +1279,16 @@
* <p> An implementation of this interface may support additional
* implementation specific options.
*
- * <p> Where the move requires that the file be copied then the {@link
- * BasicFileAttributes#lastModifiedTime last-modified-time} is copied to the
- * new file. An implementation may also attempt to copy other file
- * attributes but is not required to fail if the file attributes cannot be
- * copied. When the move is performed as a non-atomic operation, and a {@code
- * IOException} is thrown, then the state of the files is not defined. The
- * original file and the target file may both exist, the target file may be
- * incomplete or some of its file attributes may not been copied from the
- * original file.
+ * <p> Moving a file will copy the {@link
+ * BasicFileAttributes#lastModifiedTime last-modified-time} to the target
+ * file if supported by both source and target file stores. Copying of file
+ * timestamps may result in precision loss. An implementation may also
+ * attempt to copy other file attributes but is not required to fail if the
+ * file attributes cannot be copied. When the move is performed as
+ * a non-atomic operation, and an {@code IOException} is thrown, then the
+ * state of the files is not defined. The original file and the target file
+ * may both exist, the target file may be incomplete or some of its file
+ * attributes may not been copied from the original file.
*
* <p> <b>Usage Examples:</b>
* Suppose we want to rename a file to "newname", keeping the file in the
diff --git a/src/share/classes/java/util/Collections.java b/src/share/classes/java/util/Collections.java
index 58eae6f..b6bac48 100644
--- a/src/share/classes/java/util/Collections.java
+++ b/src/share/classes/java/util/Collections.java
@@ -3759,7 +3759,7 @@
return c2.compareTo(c1);
}
- private Object readResolve() { return reverseOrder(); }
+ private Object readResolve() { return Collections.reverseOrder(); }
}
/**
diff --git a/src/share/classes/java/util/Comparator.java b/src/share/classes/java/util/Comparator.java
index 35ead37..017c2e7 100644
--- a/src/share/classes/java/util/Comparator.java
+++ b/src/share/classes/java/util/Comparator.java
@@ -25,6 +25,11 @@
package java.util;
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.ToDoubleFunction;
+
/**
* A comparison function, which imposes a <i>total ordering</i> on some
* collection of objects. Comparators can be passed to a sort method (such
@@ -165,4 +170,93 @@
* @see Object#hashCode()
*/
boolean equals(Object obj);
+
+ /**
+ * Returns a comparator that imposes the reverse ordering of this
+ * comparator.
+ *
+ * @return A comparator that imposes the reverse ordering of this
+ * comparator.
+ * @since 1.8
+ */
+ default Comparator<T> reverseOrder() {
+ return Collections.reverseOrder(this);
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with another comparator.
+ * For example, a {@code Comparator<Person> byLastName} can be composed
+ * with another {@code Comparator<Person> byFirstName}, then {@code
+ * byLastName.thenComparing(byFirstName)} creates a {@code
+ * Comparator<Person>} which sorts by last name, and for equal last names
+ * sorts by first name.
+ *
+ * @param other the other comparator used when equals on this.
+ * @throws NullPointerException if the argument is null.
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(Comparator<? super T> other) {
+ return Comparators.compose(this, other);
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code Comparable} key. This default implementation calls
+ * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param <U> the {@link Comparable} type for comparison
+ * @param keyExtractor the function used to extract the {@link Comparable} sort key
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(Function)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code int} value. This default implementation calls {@code
+ * thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param keyExtractor the function used to extract the integer value
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(ToIntFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code long} value. This default implementation calls
+ * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param keyExtractor the function used to extract the long value
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(ToLongFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
+
+ /**
+ * Constructs a lexicographic order comparator with a function that
+ * extracts a {@code double} value. This default implementation calls
+ * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+ *
+ * @param keyExtractor the function used to extract the double value
+ * @throws NullPointerException if the argument is null.
+ * @see Comparators#comparing(ToDoubleFunction)
+ * @see #thenComparing(Comparator)
+ * @since 1.8
+ */
+ default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
+ return thenComparing(Comparators.comparing(keyExtractor));
+ }
}
diff --git a/src/share/classes/java/util/Comparators.java b/src/share/classes/java/util/Comparators.java
new file mode 100644
index 0000000..7582133
--- /dev/null
+++ b/src/share/classes/java/util/Comparators.java
@@ -0,0 +1,279 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.util;
+
+import java.io.Serializable;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+/**
+ * This class consists of {@code static} utility methods for comparators. Mostly
+ * factory method that returns a {@link Comparator}.
+ *
+ * <p> Unless otherwise noted, passing a {@code null} argument to a method in
+ * this class will cause a {@link NullPointerException} to be thrown.
+ *
+ * @see Comparator
+ * @since 1.8
+ */
+public class Comparators {
+ private Comparators() {
+ throw new AssertionError("no instances");
+ }
+
+ /**
+ * Compares {@link Comparable} objects in natural order.
+ *
+ * @see Comparable
+ */
+ private enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
+ INSTANCE;
+
+ @Override
+ public int compare(Comparable<Object> c1, Comparable<Object> c2) {
+ return c1.compareTo(c2);
+ }
+ }
+
+ /**
+ * Returns a comparator that imposes the reverse of the <em>natural
+ * ordering</em>.
+ *
+ * <p>The returned comparator is serializable.
+ *
+ * @param <T> {@link Comparable} type
+ *
+ * @return A comparator that imposes the reverse of the <i>natural
+ * ordering</i> on a collection of objects that implement
+ * the {@link Comparable} interface.
+ * @see Comparable
+ */
+ public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
+ return Collections.reverseOrder();
+ }
+
+ /**
+ * Returns a comparator that imposes the reverse ordering of the specified
+ * {@link Comparator}.
+ *
+ * <p>The returned comparator is serializable (assuming the specified
+ * comparator is also serializable).
+ *
+ * @param <T> the element type to be compared
+ * @param cmp a comparator whose ordering is to be reversed by the returned
+ * comparator
+ * @return A comparator that imposes the reverse ordering of the
+ * specified comparator.
+ */
+ public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
+ Objects.requireNonNull(cmp);
+ return Collections.reverseOrder(cmp);
+ }
+
+ /**
+ * Gets a comparator compares {@link Comparable} type in natural order.
+ *
+ * @param <T> {@link Comparable} type
+ */
+ public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
+ return (Comparator<T>) NaturalOrderComparator.INSTANCE;
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} in natural order on key.
+ *
+ * @param <K> {@link Comparable} key type
+ * @param <V> value type
+ */
+ public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> naturalOrderKeys() {
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> c1.getKey().compareTo(c2.getKey());
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} in natural order on value.
+ *
+ * @param <K> key type
+ * @param <V> {@link Comparable} value type
+ */
+ public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> naturalOrderValues() {
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> c1.getValue().compareTo(c2.getValue());
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} by key using the given
+ * {@link Comparator}.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * comparators are also serializable.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @param cmp the key {@link Comparator}
+ */
+ public static <K, V> Comparator<Map.Entry<K, V>> byKey(Comparator<? super K> cmp) {
+ Objects.requireNonNull(cmp);
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
+ }
+
+ /**
+ * Gets a comparator compares {@link Map.Entry} by value using the given
+ * {@link Comparator}.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @param cmp the value {@link Comparator}
+ */
+ public static <K, V> Comparator<Map.Entry<K, V>> byValue(Comparator<? super V> cmp) {
+ Objects.requireNonNull(cmp);
+ return (Comparator<Map.Entry<K, V>> & Serializable)
+ (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
+ }
+
+ /**
+ * Accepts a function that extracts a {@link java.lang.Comparable
+ * Comparable} sort key from a type {@code T}, and returns a {@code
+ * Comparator<T>} that compares by that sort key. For example, if a class
+ * {@code Person} has a {@code String}-valued getter {@code getLastName},
+ * then {@code comparing(Person::getLastName)} would return a {@code
+ * Comparator<Person>} that compares {@code Person} objects by their last
+ * name.
+ *
+ * @param <T> the original element type
+ * @param <U> the {@link Comparable} type for comparison
+ * @param keyExtractor the function used to extract the {@link Comparable} sort key
+ */
+ public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
+ }
+
+ /**
+ * Accepts a function that extracts an {@code int} value from a type {@code
+ * T}, and returns a {@code Comparator<T>} that compares by that value.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * function is also serializable.
+ *
+ * @see #comparing(Function)
+ * @param <T> the original element type
+ * @param keyExtractor the function used to extract the integer value
+ */
+ public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@code long} value from a type {@code
+ * T}, and returns a {@code Comparator<T>} that compares by that value.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * function is also serializable.
+ *
+ * @see #comparing(Function)
+ * @param <T> the original element type
+ * @param keyExtractor the function used to extract the long value
+ */
+ public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
+ }
+
+ /**
+ * Accepts a function that extracts a {@code double} value from a type
+ * {@code T}, and returns a {@code Comparator<T>} that compares by that
+ * value.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * function is also serializable.
+ *
+ * @see #comparing(Function)
+ * @param <T> the original element type
+ * @param keyExtractor the function used to extract the double value
+ */
+ public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
+ Objects.requireNonNull(keyExtractor);
+ return (Comparator<T> & Serializable)
+ (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
+ }
+
+ /**
+ * Constructs a lexicographic order from two {@link Comparator}s. For
+ * example, if you have comparators {@code byLastName} and {@code
+ * byFirstName}, each of type {@code Comparator<Person>}, then {@code
+ * compose(byLastName, byFirstName)} creates a {@code Comparator<Person>}
+ * which sorts by last name, and for equal last names sorts by first name.
+ *
+ * <p>The returned comparator is serializable assuming the specified
+ * comparators are also serializable.
+ *
+ * @param <T> the element type to be compared
+ * @param first the first comparator
+ * @param second the secondary comparator used when equals on the first
+ */
+ public static<T> Comparator<T> compose(Comparator<? super T> first, Comparator<? super T> second) {
+ Objects.requireNonNull(first);
+ Objects.requireNonNull(second);
+ return (Comparator<T> & Serializable) (c1, c2) -> {
+ int res = first.compare(c1, c2);
+ return (res != 0) ? res : second.compare(c1, c2);
+ };
+ }
+
+ /**
+ * Constructs a {@link BinaryOperator} which returns the lesser of two elements
+ * according to the specified {@code Comparator}
+ *
+ * @param comparator A {@code Comparator} for comparing the two values
+ * @param <T> the type of the elements to be compared
+ * @return a {@code BinaryOperator} which returns the lesser of its operands,
+ * according to the supplied {@code Comparator}
+ */
+ public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
+ return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
+ }
+
+ /**
+ * Constructs a {@link BinaryOperator} which returns the greater of two elements
+ * according to the specified {@code Comparator}
+ *
+ * @param comparator A {@code Comparator} for comparing the two values
+ * @param <T> the type of the elements to be compared
+ * @return a {@code BinaryOperator} which returns the greater of its operands,
+ * according to the supplied {@code Comparator}
+ */
+ public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
+ return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
+ }
+}
diff --git a/src/share/classes/java/util/IdentityHashMap.java b/src/share/classes/java/util/IdentityHashMap.java
index f05bd14..49bb994 100644
--- a/src/share/classes/java/util/IdentityHashMap.java
+++ b/src/share/classes/java/util/IdentityHashMap.java
@@ -1106,12 +1106,12 @@
Object[] tab = table;
int ti = 0;
for (int si = 0; si < tab.length; si += 2) {
- if (tab[si++] != null) { // key present ?
+ if (tab[si] != null) { // key present ?
// more elements than expected -> concurrent modification from other thread
if (ti >= size) {
throw new ConcurrentModificationException();
}
- a[ti++] = (T) tab[si]; // copy value
+ a[ti++] = (T) tab[si+1]; // copy value
}
}
// fewer elements than expected or concurrent modification from other thread detected
diff --git a/src/share/classes/java/util/concurrent/ForkJoinPool.java b/src/share/classes/java/util/concurrent/ForkJoinPool.java
index 86bb3b5..0bb2758 100644
--- a/src/share/classes/java/util/concurrent/ForkJoinPool.java
+++ b/src/share/classes/java/util/concurrent/ForkJoinPool.java
@@ -35,6 +35,7 @@
package java.util.concurrent;
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -104,38 +105,45 @@
* there is little difference among choice of methods.
*
* <table BORDER CELLPADDING=3 CELLSPACING=1>
+ * <caption>Summary of task execution methods</caption>
* <tr>
* <td></td>
* <td ALIGN=CENTER> <b>Call from non-fork/join clients</b></td>
* <td ALIGN=CENTER> <b>Call from within fork/join computations</b></td>
* </tr>
* <tr>
- * <td> <b>Arrange async execution</td>
+ * <td> <b>Arrange async execution</b></td>
* <td> {@link #execute(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#fork}</td>
* </tr>
* <tr>
- * <td> <b>Await and obtain result</td>
+ * <td> <b>Await and obtain result</b></td>
* <td> {@link #invoke(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#invoke}</td>
* </tr>
* <tr>
- * <td> <b>Arrange exec and obtain Future</td>
+ * <td> <b>Arrange exec and obtain Future</b></td>
* <td> {@link #submit(ForkJoinTask)}</td>
* <td> {@link ForkJoinTask#fork} (ForkJoinTasks <em>are</em> Futures)</td>
* </tr>
* </table>
*
* <p>The common pool is by default constructed with default
- * parameters, but these may be controlled by setting three {@link
- * System#getProperty system properties} with prefix {@code
- * java.util.concurrent.ForkJoinPool.common}: {@code parallelism} --
- * an integer greater than zero, {@code threadFactory} -- the class
- * name of a {@link ForkJoinWorkerThreadFactory}, and {@code
- * exceptionHandler} -- the class name of a {@link
- * java.lang.Thread.UncaughtExceptionHandler
- * Thread.UncaughtExceptionHandler}. Upon any error in establishing
- * these settings, default parameters are used.
+ * parameters, but these may be controlled by setting three
+ * {@linkplain System#getProperty system properties}:
+ * <ul>
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
+ * - the parallelism level, a non-negative integer
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.threadFactory}
+ * - the class name of a {@link ForkJoinWorkerThreadFactory}
+ * <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
+ * - the class name of a {@link UncaughtExceptionHandler}
+ * </ul>
+ * The system class loader is used to load these classes.
+ * Upon any error in establishing these settings, default parameters
+ * are used. It is possible to disable or limit the use of threads in
+ * the common pool by setting the parallelism property to zero, and/or
+ * using a factory that may return {@code null}.
*
* <p><b>Implementation notes</b>: This implementation restricts the
* maximum number of running threads to 32767. Attempts to create
@@ -225,18 +233,18 @@
* for work-stealing (this would contaminate lifo/fifo
* processing). Instead, we randomly associate submission queues
* with submitting threads, using a form of hashing. The
- * ThreadLocal Submitter class contains a value initially used as
- * a hash code for choosing existing queues, but may be randomly
- * repositioned upon contention with other submitters. In
- * essence, submitters act like workers except that they are
- * restricted to executing local tasks that they submitted (or in
- * the case of CountedCompleters, others with the same root task).
- * However, because most shared/external queue operations are more
- * expensive than internal, and because, at steady state, external
- * submitters will compete for CPU with workers, ForkJoinTask.join
- * and related methods disable them from repeatedly helping to
- * process tasks if all workers are active. Insertion of tasks in
- * shared mode requires a lock (mainly to protect in the case of
+ * ThreadLocalRandom probe value serves as a hash code for
+ * choosing existing queues, and may be randomly repositioned upon
+ * contention with other submitters. In essence, submitters act
+ * like workers except that they are restricted to executing local
+ * tasks that they submitted (or in the case of CountedCompleters,
+ * others with the same root task). However, because most
+ * shared/external queue operations are more expensive than
+ * internal, and because, at steady state, external submitters
+ * will compete for CPU with workers, ForkJoinTask.join and
+ * related methods disable them from repeatedly helping to process
+ * tasks if all workers are active. Insertion of tasks in shared
+ * mode requires a lock (mainly to protect in the case of
* resizing) but we use only a simple spinlock (using bits in
* field qlock), because submitters encountering a busy queue move
* on to try or create other queues -- they block only when
@@ -469,7 +477,7 @@
* Common Pool
* ===========
*
- * The static commonPool always exists after static
+ * The static common Pool always exists after static
* initialization. Since it (or any other created pool) need
* never be used, we minimize initial construction overhead and
* footprint to the setup of about a dozen fields, with no nested
@@ -548,6 +556,7 @@
*
* @param pool the pool this thread works in
* @throws NullPointerException if the pool is null
+ * @return the new worker thread
*/
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
}
@@ -564,26 +573,6 @@
}
/**
- * Per-thread records for threads that submit to pools. Currently
- * holds only pseudo-random seed / index that is used to choose
- * submission queues in method externalPush. In the future, this may
- * also incorporate a means to implement different task rejection
- * and resubmission policies.
- *
- * Seeds for submitters and workers/workQueues work in basically
- * the same way but are initialized and updated using slightly
- * different mechanics. Both are initialized using the same
- * approach as in class ThreadLocal, where successive values are
- * unlikely to collide with previous values. Seeds are then
- * randomly modified upon collisions using xorshifts, which
- * requires a non-zero seed.
- */
- static final class Submitter {
- int seed;
- Submitter(int s) { seed = s; }
- }
-
- /**
* Class for artificial tasks that are used to replace the target
* of local joins if they are removed from an interior queue slot
* in WorkQueue.tryRemoveAndExec. We don't need the proxy to
@@ -737,7 +726,7 @@
* shared-queue version is embedded in method externalPush.)
*
* @param task the task. Caller must ensure non-null.
- * @throw RejectedExecutionException if array cannot be resized
+ * @throws RejectedExecutionException if array cannot be resized
*/
final void push(ForkJoinTask<?> task) {
ForkJoinTask<?>[] a; ForkJoinPool p;
@@ -936,7 +925,7 @@
* or any other cancelled task. Returns (true) on any CAS
* or consistency check failure so caller can retry.
*
- * @return false if no progress can be made, else true;
+ * @return false if no progress can be made, else true
*/
final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
boolean stat = true, removed = false, empty = true;
@@ -981,7 +970,7 @@
/**
* Polls for and executes the given task or any other task in
- * its CountedCompleter computation
+ * its CountedCompleter computation.
*/
final boolean pollAndExecCC(ForkJoinTask<?> root) {
ForkJoinTask<?>[] a; int b; Object o;
@@ -1055,7 +1044,6 @@
private static final int ABASE;
private static final int ASHIFT;
static {
- int s;
try {
U = sun.misc.Unsafe.getUnsafe();
Class<?> k = WorkQueue.class;
@@ -1063,13 +1051,13 @@
QLOCK = U.objectFieldOffset
(k.getDeclaredField("qlock"));
ABASE = U.arrayBaseOffset(ak);
- s = U.arrayIndexScale(ak);
+ int scale = U.arrayIndexScale(ak);
+ if ((scale & (scale - 1)) != 0)
+ throw new Error("data type scale not a power of two");
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
- if ((s & (s-1)) != 0)
- throw new Error("data type scale not a power of two");
- ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
}
}
@@ -1083,15 +1071,6 @@
defaultForkJoinWorkerThreadFactory;
/**
- * Per-thread submission bookkeeping. Shared across all pools
- * to reduce ThreadLocal pollution and because random motion
- * to avoid contention in one pool is likely to hold for others.
- * Lazily initialized on first submission (but null-checked
- * in other contexts to avoid unnecessary initialization).
- */
- static final ThreadLocal<Submitter> submitters;
-
- /**
* Permission required for callers of methods that may start or
* kill threads.
*/
@@ -1103,12 +1082,15 @@
* to paranoically avoid potential initialization circularities
* as well as to simplify generated code.
*/
- static final ForkJoinPool commonPool;
+ static final ForkJoinPool common;
/**
- * Common pool parallelism. Must equal commonPool.parallelism.
+ * Common pool parallelism. To allow simpler use and management
+ * when common pool threads are disabled, we allow the underlying
+ * common.config field to be zero, but in that case still report
+ * parallelism as 1 to reflect resulting caller-runs mechanics.
*/
- static final int commonPoolParallelism;
+ static final int commonParallelism;
/**
* Sequence number for creating workerNamePrefix.
@@ -1116,8 +1098,8 @@
private static int poolNumberSequence;
/**
- * Return the next sequence number. We don't expect this to
- * ever contend so use simple builtin sync.
+ * Returns the next sequence number. We don't expect this to
+ * ever contend, so use simple builtin sync.
*/
private static final synchronized int nextPoolId() {
return ++poolNumberSequence;
@@ -1161,7 +1143,7 @@
*/
private static final int SEED_INCREMENT = 0x61c88647;
- /**
+ /*
* Bits and masks for control variables
*
* Field ctl is a long packed with:
@@ -1268,39 +1250,28 @@
final int config; // mode and parallelism level
WorkQueue[] workQueues; // main registry
final ForkJoinWorkerThreadFactory factory;
- final Thread.UncaughtExceptionHandler ueh; // per-worker UEH
+ final UncaughtExceptionHandler ueh; // per-worker UEH
final String workerNamePrefix; // to create worker name string
volatile Object pad10, pad11, pad12, pad13, pad14, pad15, pad16, pad17;
volatile Object pad18, pad19, pad1a, pad1b;
- /*
+ /**
* Acquires the plock lock to protect worker array and related
* updates. This method is called only if an initial CAS on plock
- * fails. This acts as a spinLock for normal cases, but falls back
+ * fails. This acts as a spinlock for normal cases, but falls back
* to builtin monitor to block when (rarely) needed. This would be
* a terrible idea for a highly contended lock, but works fine as
* a more conservative alternative to a pure spinlock.
*/
private int acquirePlock() {
- int spins = PL_SPINS, r = 0, ps, nps;
+ int spins = PL_SPINS, ps, nps;
for (;;) {
if (((ps = plock) & PL_LOCK) == 0 &&
U.compareAndSwapInt(this, PLOCK, ps, nps = ps + PL_LOCK))
return nps;
- else if (r == 0) { // randomize spins if possible
- Thread t = Thread.currentThread(); WorkQueue w; Submitter z;
- if ((t instanceof ForkJoinWorkerThread) &&
- (w = ((ForkJoinWorkerThread)t).workQueue) != null)
- r = w.seed;
- else if ((z = submitters.get()) != null)
- r = z.seed;
- else
- r = 1;
- }
else if (spins >= 0) {
- r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift
- if (r >= 0)
+ if (ThreadLocalRandom.nextSecondarySeed() >= 0)
--spins;
}
else if (U.compareAndSwapInt(this, PLOCK, ps, ps | PL_SIGNAL)) {
@@ -1332,39 +1303,6 @@
}
/**
- * Performs secondary initialization, called when plock is zero.
- * Creates workQueue array and sets plock to a valid value. The
- * lock body must be exception-free (so no try/finally) so we
- * optimistically allocate new array outside the lock and throw
- * away if (very rarely) not needed. (A similar tactic is used in
- * fullExternalPush.) Because the plock seq value can eventually
- * wrap around zero, this method harmlessly fails to reinitialize
- * if workQueues exists, while still advancing plock.
- *
- * Additionally tries to create the first worker.
- */
- private void initWorkers() {
- WorkQueue[] ws, nws; int ps;
- int p = config & SMASK; // find power of two table size
- int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
- n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16;
- n = (n + 1) << 1;
- if ((ws = workQueues) == null || ws.length == 0)
- nws = new WorkQueue[n];
- else
- nws = null;
- if (((ps = plock) & PL_LOCK) != 0 ||
- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
- ps = acquirePlock();
- if (((ws = workQueues) == null || ws.length == 0) && nws != null)
- workQueues = nws;
- int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
- if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
- releasePlock(nps);
- tryAddWorker();
- }
-
- /**
* Tries to create and start one worker if fewer than target
* parallelism level exist. Adjusts counts etc on failure.
*/
@@ -1406,7 +1344,7 @@
* @return the worker's queue
*/
final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
- Thread.UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
+ UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
wt.setDaemon(true);
if ((handler = ueh) != null)
wt.setUncaughtExceptionHandler(handler);
@@ -1450,7 +1388,7 @@
* array, and adjusts counts. If pool is shutting down, tries to
* complete termination.
*
- * @param wt the worker thread or null if construction failed
+ * @param wt the worker thread, or null if construction failed
* @param ex the exception causing failure, or null if none
*/
final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) {
@@ -1489,7 +1427,7 @@
if (e > 0) { // activate or create replacement
if ((ws = workQueues) == null ||
(i = e & SMASK) >= ws.length ||
- (v = ws[i]) != null)
+ (v = ws[i]) == null)
break;
long nc = (((long)(v.nextWait & E_MASK)) |
((long)(u + UAC_UNIT) << 32));
@@ -1526,10 +1464,10 @@
* @param task the task. Caller must ensure non-null.
*/
final void externalPush(ForkJoinTask<?> task) {
- WorkQueue[] ws; WorkQueue q; Submitter z; int m; ForkJoinTask<?>[] a;
- if ((z = submitters.get()) != null && plock > 0 &&
+ WorkQueue[] ws; WorkQueue q; int z, m; ForkJoinTask<?>[] a;
+ if ((z = ThreadLocalRandom.getProbe()) != 0 && plock > 0 &&
(ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ (q = ws[m & z & SQMASK]) != null &&
U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock
int b = q.base, s = q.top, n, an;
if ((a = q.array) != null && (an = a.length) > (n = s + 1 - b)) {
@@ -1549,34 +1487,48 @@
/**
* Full version of externalPush. This method is called, among
* other times, upon the first submission of the first task to the
- * pool, so must perform secondary initialization (via
- * initWorkers). It also detects first submission by an external
- * thread by looking up its ThreadLocal, and creates a new shared
- * queue if the one at index if empty or contended. The plock lock
- * body must be exception-free (so no try/finally) so we
- * optimistically allocate new queues outside the lock and throw
- * them away if (very rarely) not needed.
+ * pool, so must perform secondary initialization. It also
+ * detects first submission by an external thread by looking up
+ * its ThreadLocal, and creates a new shared queue if the one at
+ * index if empty or contended. The plock lock body must be
+ * exception-free (so no try/finally) so we optimistically
+ * allocate new queues outside the lock and throw them away if
+ * (very rarely) not needed.
+ *
+ * Secondary initialization occurs when plock is zero, to create
+ * workQueue array and set plock to a valid value. This lock body
+ * must also be exception-free. Because the plock seq value can
+ * eventually wrap around zero, this method harmlessly fails to
+ * reinitialize if workQueues exists, while still advancing plock.
*/
private void fullExternalPush(ForkJoinTask<?> task) {
- int r = 0; // random index seed
- for (Submitter z = submitters.get();;) {
+ int r;
+ if ((r = ThreadLocalRandom.getProbe()) == 0) {
+ ThreadLocalRandom.localInit();
+ r = ThreadLocalRandom.getProbe();
+ }
+ for (;;) {
WorkQueue[] ws; WorkQueue q; int ps, m, k;
- if (z == null) {
- if (U.compareAndSwapInt(this, INDEXSEED, r = indexSeed,
- r += SEED_INCREMENT) && r != 0)
- submitters.set(z = new Submitter(r));
- }
- else if (r == 0) { // move to a different index
- r = z.seed;
- r ^= r << 13; // same xorshift as WorkQueues
- r ^= r >>> 17;
- z.seed = r ^ (r << 5);
- }
- else if ((ps = plock) < 0)
+ boolean move = false;
+ if ((ps = plock) < 0)
throw new RejectedExecutionException();
else if (ps == 0 || (ws = workQueues) == null ||
- (m = ws.length - 1) < 0)
- initWorkers();
+ (m = ws.length - 1) < 0) { // initialize workQueues
+ int p = config & SMASK; // find power of two table size
+ int n = (p > 1) ? p - 1 : 1; // ensure at least 2 slots
+ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4;
+ n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
+ WorkQueue[] nws = ((ws = workQueues) == null || ws.length == 0 ?
+ new WorkQueue[n] : null);
+ if (((ps = plock) & PL_LOCK) != 0 ||
+ !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+ ps = acquirePlock();
+ if (((ws = workQueues) == null || ws.length == 0) && nws != null)
+ workQueues = nws;
+ int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+ if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+ releasePlock(nps);
+ }
else if ((q = ws[k = r & m & SQMASK]) != null) {
if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
ForkJoinTask<?>[] a = q.array;
@@ -1598,7 +1550,7 @@
return;
}
}
- r = 0; // move on failure
+ move = true; // move on failure
}
else if (((ps = plock) & PL_LOCK) == 0) { // create new queue
q = new WorkQueue(this, null, SHARED_QUEUE, r);
@@ -1612,7 +1564,9 @@
releasePlock(nps);
}
else
- r = 0; // try elsewhere while lock held
+ move = true; // move if busy
+ if (move)
+ r = ThreadLocalRandom.advanceProbe(r);
}
}
@@ -1703,7 +1657,7 @@
* park awaiting signal, else lingering to help scan and signal.
*
* * If a non-empty queue discovered or left as a hint,
- * help wake up other workers before return
+ * help wake up other workers before return.
*
* @param w the worker (via its WorkQueue)
* @return a task or null if none found
@@ -1758,14 +1712,13 @@
else if ((int)(c >> AC_SHIFT) == 1 - (config & SMASK))
idleAwaitWork(w, nc, c);
}
- else if (w.eventCount < 0 && !tryTerminate(false, false) &&
- ctl == c) { // block
+ else if (w.eventCount < 0 && ctl == c) {
Thread wt = Thread.currentThread();
Thread.interrupted(); // clear status
U.putObject(wt, PARKBLOCKER, this);
w.parker = wt; // emulate LockSupport.park
if (w.eventCount < 0) // recheck
- U.park(false, 0L);
+ U.park(false, 0L); // block
w.parker = null;
U.putObject(wt, PARKBLOCKER, null);
}
@@ -1774,7 +1727,7 @@
(ws = workQueues) != null && h < ws.length &&
(q = ws[h]) != null) { // signal others before retry
WorkQueue v; Thread p; int u, i, s;
- for (int n = (config & SMASK) >>> 1;;) {
+ for (int n = (config & SMASK) - 1;;) {
int idleCount = (w.eventCount < 0) ? 0 : -1;
if (((s = idleCount - q.base + q.top) <= n &&
(n = s) <= 0) ||
@@ -1814,7 +1767,8 @@
*/
private void idleAwaitWork(WorkQueue w, long currentCtl, long prevCtl) {
if (w != null && w.eventCount < 0 &&
- !tryTerminate(false, false) && (int)prevCtl != 0) {
+ !tryTerminate(false, false) && (int)prevCtl != 0 &&
+ ctl == currentCtl) {
int dc = -(short)(currentCtl >>> TC_SHIFT);
long parkTime = dc < 0 ? FAST_IDLE_TIMEOUT: (dc + 1) * IDLE_TIMEOUT;
long deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
@@ -1832,6 +1786,7 @@
if (deadline - System.nanoTime() <= 0L &&
U.compareAndSwapLong(this, CTL, currentCtl, prevCtl)) {
w.eventCount = (w.eventCount + E_SEQ) | E_MASK;
+ w.hint = -1;
w.qlock = -1; // shrink
break;
}
@@ -1973,7 +1928,6 @@
* @param task the task to join
* @param mode if shared, exit upon completing any task
* if all workers are active
- *
*/
private int helpComplete(ForkJoinTask<?> task, int mode) {
WorkQueue[] ws; WorkQueue q; int m, n, s, u;
@@ -2125,29 +2079,22 @@
/**
* Returns a (probably) non-empty steal queue, if one is found
- * during a random, then cyclic scan, else null. This method must
- * be retried by caller if, by the time it tries to use the queue,
- * it is empty.
+ * during a scan, else null. This method must be retried by
+ * caller if, by the time it tries to use the queue, it is empty.
* @param r a (random) seed for scanning
*/
private WorkQueue findNonEmptyStealQueue(int r) {
- for (WorkQueue[] ws;;) {
- int ps = plock, m, n;
- if ((ws = workQueues) == null || (m = ws.length - 1) < 1)
- return null;
- for (int j = (m + 1) << 2; ;) {
- WorkQueue q = ws[(((r + j) << 1) | 1) & m];
- if (q != null && (n = q.base - q.top) < 0) {
- if (n < -1)
- signalWork(q);
- return q;
- }
- else if (--j < 0) {
- if (plock == ps)
- return null;
- break;
+ for (;;) {
+ int ps = plock, m; WorkQueue[] ws; WorkQueue q;
+ if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+ if ((q = ws[(((r + j) << 1) | 1) & m]) != null &&
+ q.base - q.top < 0)
+ return q;
}
}
+ if (plock == ps)
+ return null;
}
}
@@ -2159,37 +2106,34 @@
*/
final void helpQuiescePool(WorkQueue w) {
for (boolean active = true;;) {
- ForkJoinTask<?> localTask; // exhaust local queue
- while ((localTask = w.nextLocalTask()) != null)
- localTask.doExec();
- // Similar to loop in scan(), but ignoring submissions
- WorkQueue q = findNonEmptyStealQueue(w.nextSeed());
- if (q != null) {
- ForkJoinTask<?> t; int b;
+ long c; WorkQueue q; ForkJoinTask<?> t; int b;
+ while ((t = w.nextLocalTask()) != null) {
+ if (w.base - w.top < 0)
+ signalWork(w);
+ t.doExec();
+ }
+ if ((q = findNonEmptyStealQueue(w.nextSeed())) != null) {
if (!active) { // re-establish active count
- long c;
active = true;
do {} while (!U.compareAndSwapLong
(this, CTL, c = ctl, c + AC_UNIT));
}
- if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
+ if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+ if (q.base - q.top < 0)
+ signalWork(q);
w.runSubtask(t);
+ }
}
- else {
- long c;
- if (active) { // decrement active count without queuing
+ else if (active) { // decrement active count without queuing
+ long nc = (c = ctl) - AC_UNIT;
+ if ((int)(nc >> AC_SHIFT) + (config & SMASK) == 0)
+ return; // bypass decrement-then-increment
+ if (U.compareAndSwapLong(this, CTL, c, nc))
active = false;
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c -= AC_UNIT));
- }
- else
- c = ctl; // re-increment on exit
- if ((int)(c >> AC_SHIFT) + (config & SMASK) == 0) {
- do {} while (!U.compareAndSwapLong
- (this, CTL, c = ctl, c + AC_UNIT));
- break;
- }
}
+ else if ((int)((c = ctl) >> AC_SHIFT) + (config & SMASK) == 0 &&
+ U.compareAndSwapLong(this, CTL, c, c + AC_UNIT))
+ return;
}
}
@@ -2205,8 +2149,11 @@
return t;
if ((q = findNonEmptyStealQueue(w.nextSeed())) == null)
return null;
- if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
+ if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+ if (q.base - q.top < 0)
+ signalWork(q);
return t;
+ }
}
}
@@ -2235,7 +2182,7 @@
* producing extra tasks amortizes the uncertainty of progress and
* diffusion assumptions.
*
- * So, users will want to use values larger, but not much larger
+ * So, users will want to use values larger (but not much larger)
* than 1 to both smooth over transient shortages and hedge
* against uneven progress; as traded off against the cost of
* extra task overhead. We leave the user to pick a threshold
@@ -2288,45 +2235,49 @@
* @return true if now terminating or terminated
*/
private boolean tryTerminate(boolean now, boolean enable) {
- if (this == commonPool) // cannot shut down
+ int ps;
+ if (this == common) // cannot shut down
return false;
+ if ((ps = plock) >= 0) { // enable by setting plock
+ if (!enable)
+ return false;
+ if ((ps & PL_LOCK) != 0 ||
+ !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
+ ps = acquirePlock();
+ int nps = ((ps + PL_LOCK) & ~SHUTDOWN) | SHUTDOWN;
+ if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
+ releasePlock(nps);
+ }
for (long c;;) {
- if (((c = ctl) & STOP_BIT) != 0) { // already terminating
+ if (((c = ctl) & STOP_BIT) != 0) { // already terminating
if ((short)(c >>> TC_SHIFT) == -(config & SMASK)) {
synchronized (this) {
- notifyAll(); // signal when 0 workers
+ notifyAll(); // signal when 0 workers
}
}
return true;
}
- if (plock >= 0) { // not yet enabled
- int ps;
- if (!enable)
+ if (!now) { // check if idle & no tasks
+ WorkQueue[] ws; WorkQueue w;
+ if ((int)(c >> AC_SHIFT) != -(config & SMASK))
return false;
- if (((ps = plock) & PL_LOCK) != 0 ||
- !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
- ps = acquirePlock();
- if (!U.compareAndSwapInt(this, PLOCK, ps, SHUTDOWN))
- releasePlock(SHUTDOWN);
- }
- if (!now) { // check if idle & no tasks
- if ((int)(c >> AC_SHIFT) != -(config & SMASK) ||
- hasQueuedSubmissions())
- return false;
- // Check for unqueued inactive workers. One pass suffices.
- WorkQueue[] ws = workQueues; WorkQueue w;
- if (ws != null) {
- for (int i = 1; i < ws.length; i += 2) {
- if ((w = ws[i]) != null && w.eventCount >= 0)
- return false;
+ if ((ws = workQueues) != null) {
+ for (int i = 0; i < ws.length; ++i) {
+ if ((w = ws[i]) != null) {
+ if (!w.isEmpty()) { // signal unprocessed tasks
+ signalWork(w);
+ return false;
+ }
+ if ((i & 1) != 0 && w.eventCount >= 0)
+ return false; // unqueued inactive worker
+ }
}
}
}
if (U.compareAndSwapLong(this, CTL, c, c | STOP_BIT)) {
for (int pass = 0; pass < 3; ++pass) {
- WorkQueue[] ws = workQueues;
- if (ws != null) {
- WorkQueue w; Thread wt;
+ WorkQueue[] ws; WorkQueue w; Thread wt;
+ if ((ws = workQueues) != null) {
int n = ws.length;
for (int i = 0; i < n; ++i) {
if ((w = ws[i]) != null) {
@@ -2337,7 +2288,7 @@
if (!wt.isInterrupted()) {
try {
wt.interrupt();
- } catch (SecurityException ignore) {
+ } catch (Throwable ignore) {
}
}
U.unpark(wt);
@@ -2348,7 +2299,7 @@
// Wake up workers parked on event queue
int i, e; long cc; Thread p;
while ((e = (int)(cc = ctl) & E_MASK) != 0 &&
- (i = e & SMASK) < n &&
+ (i = e & SMASK) < n && i >= 0 &&
(w = ws[i]) != null) {
long nc = ((long)(w.nextWait & E_MASK) |
((cc + AC_UNIT) & AC_MASK) |
@@ -2374,26 +2325,26 @@
* least one task.
*/
static WorkQueue commonSubmitterQueue() {
- ForkJoinPool p; WorkQueue[] ws; int m; Submitter z;
- return ((z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ ForkJoinPool p; WorkQueue[] ws; int m, z;
+ return ((z = ThreadLocalRandom.getProbe()) != 0 &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0) ?
- ws[m & z.seed & SQMASK] : null;
+ ws[m & z & SQMASK] : null;
}
/**
* Tries to pop the given task from submitter's queue in common pool.
*/
static boolean tryExternalUnpush(ForkJoinTask<?> t) {
- ForkJoinPool p; WorkQueue[] ws; WorkQueue q; Submitter z;
- ForkJoinTask<?>[] a; int m, s;
+ ForkJoinPool p; WorkQueue[] ws; WorkQueue q;
+ ForkJoinTask<?>[] a; int m, s, z;
if (t != null &&
- (z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ (z = ThreadLocalRandom.getProbe()) != 0 &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ (q = ws[m & z & SQMASK]) != null &&
(s = q.top) != q.base &&
(a = q.array) != null) {
long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
@@ -2445,9 +2396,10 @@
if (task != null)
task.doExec();
if (root.status < 0 ||
- (u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0)
+ (config != 0 &&
+ ((u = (int)(ctl >>> 32)) >= 0 || (u >> UAC_SHIFT) >= 0)))
break;
- if (task == null) {
+ if (task == null) {
helpSignal(root, q.poolIndex);
if (root.status >= 0)
helpComplete(root, SHARED_QUEUE);
@@ -2463,14 +2415,14 @@
*/
static void externalHelpJoin(ForkJoinTask<?> t) {
// Some hard-to-avoid overlap with tryExternalUnpush
- ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w; Submitter z;
- ForkJoinTask<?>[] a; int m, s, n;
+ ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w;
+ ForkJoinTask<?>[] a; int m, s, n, z;
if (t != null &&
- (z = submitters.get()) != null &&
- (p = commonPool) != null &&
+ (z = ThreadLocalRandom.getProbe()) != 0 &&
+ (p = common) != null &&
(ws = p.workQueues) != null &&
(m = ws.length - 1) >= 0 &&
- (q = ws[m & z.seed & SQMASK]) != null &&
+ (q = ws[m & z & SQMASK]) != null &&
(a = q.array) != null) {
int am = a.length - 1;
if ((s = q.top) != q.base) {
@@ -2496,18 +2448,6 @@
}
}
- /**
- * Restricted version of helpQuiescePool for external callers
- */
- static void externalHelpQuiescePool() {
- ForkJoinPool p; ForkJoinTask<?> t; WorkQueue q; int b;
- if ((p = commonPool) != null &&
- (q = p.findNonEmptyStealQueue(1)) != null &&
- (b = q.base) - q.top < 0 &&
- (t = q.pollAt(b)) != null)
- t.doExec();
- }
-
// Exported methods
// Constructors
@@ -2524,7 +2464,7 @@
* java.lang.RuntimePermission}{@code ("modifyThread")}
*/
public ForkJoinPool() {
- this(Runtime.getRuntime().availableProcessors(),
+ this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),
defaultForkJoinWorkerThreadFactory, null, false);
}
@@ -2572,50 +2512,63 @@
*/
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
- Thread.UncaughtExceptionHandler handler,
+ UncaughtExceptionHandler handler,
boolean asyncMode) {
+ this(checkParallelism(parallelism),
+ checkFactory(factory),
+ handler,
+ asyncMode,
+ "ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
- if (factory == null)
- throw new NullPointerException();
+ }
+
+ private static int checkParallelism(int parallelism) {
if (parallelism <= 0 || parallelism > MAX_CAP)
throw new IllegalArgumentException();
+ return parallelism;
+ }
+
+ private static ForkJoinWorkerThreadFactory checkFactory
+ (ForkJoinWorkerThreadFactory factory) {
+ if (factory == null)
+ throw new NullPointerException();
+ return factory;
+ }
+
+ /**
+ * Creates a {@code ForkJoinPool} with the given parameters, without
+ * any security checks or parameter validation. Invoked directly by
+ * makeCommonPool.
+ */
+ private ForkJoinPool(int parallelism,
+ ForkJoinWorkerThreadFactory factory,
+ UncaughtExceptionHandler handler,
+ boolean asyncMode,
+ String workerNamePrefix) {
+ this.workerNamePrefix = workerNamePrefix;
this.factory = factory;
this.ueh = handler;
this.config = parallelism | (asyncMode ? (FIFO_QUEUE << 16) : 0);
long np = (long)(-parallelism); // offset ctl counts
this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
- int pn = nextPoolId();
- StringBuilder sb = new StringBuilder("ForkJoinPool-");
- sb.append(Integer.toString(pn));
- sb.append("-worker-");
- this.workerNamePrefix = sb.toString();
- }
-
- /**
- * Constructor for common pool, suitable only for static initialization.
- * Basically the same as above, but uses smallest possible initial footprint.
- */
- ForkJoinPool(int parallelism, long ctl,
- ForkJoinWorkerThreadFactory factory,
- Thread.UncaughtExceptionHandler handler) {
- this.config = parallelism;
- this.ctl = ctl;
- this.factory = factory;
- this.ueh = handler;
- this.workerNamePrefix = "ForkJoinPool.commonPool-worker-";
}
/**
* Returns the common pool instance. This pool is statically
- * constructed; its run state is unaffected by attempts to
- * {@link #shutdown} or {@link #shutdownNow}.
+ * constructed; its run state is unaffected by attempts to {@link
+ * #shutdown} or {@link #shutdownNow}. However this pool and any
+ * ongoing processing are automatically terminated upon program
+ * {@link System#exit}. Any program that relies on asynchronous
+ * task processing to complete before program termination should
+ * invoke {@code commonPool().}{@link #awaitQuiescence awaitQuiescence},
+ * before exit.
*
* @return the common pool instance
* @since 1.8
*/
public static ForkJoinPool commonPool() {
- // assert commonPool != null : "static init error";
- return commonPool;
+ // assert common != null : "static init error";
+ return common;
}
// Execution methods
@@ -2671,7 +2624,7 @@
if (task instanceof ForkJoinTask<?>) // avoid re-wrap
job = (ForkJoinTask<?>) task;
else
- job = new ForkJoinTask.AdaptedRunnableAction(task);
+ job = new ForkJoinTask.RunnableExecuteAction(task);
externalPush(job);
}
@@ -2738,27 +2691,23 @@
// In previous versions of this class, this method constructed
// a task to run ForkJoinTask.invokeAll, but now external
// invocation of multiple tasks is at least as efficient.
- List<ForkJoinTask<T>> fs = new ArrayList<ForkJoinTask<T>>(tasks.size());
- // Workaround needed because method wasn't declared with
- // wildcards in return type but should have been.
- @SuppressWarnings({"unchecked", "rawtypes"})
- List<Future<T>> futures = (List<Future<T>>) (List) fs;
+ ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
boolean done = false;
try {
for (Callable<T> t : tasks) {
ForkJoinTask<T> f = new ForkJoinTask.AdaptedCallable<T>(t);
+ futures.add(f);
externalPush(f);
- fs.add(f);
}
- for (ForkJoinTask<T> f : fs)
- f.quietlyJoin();
+ for (int i = 0, size = futures.size(); i < size; i++)
+ ((ForkJoinTask<?>)futures.get(i)).quietlyJoin();
done = true;
return futures;
} finally {
if (!done)
- for (ForkJoinTask<T> f : fs)
- f.cancel(false);
+ for (int i = 0, size = futures.size(); i < size; i++)
+ futures.get(i).cancel(false);
}
}
@@ -2777,7 +2726,7 @@
*
* @return the handler, or {@code null} if none
*/
- public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
+ public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return ueh;
}
@@ -2787,7 +2736,8 @@
* @return the targeted parallelism level of this pool
*/
public int getParallelism() {
- return config & SMASK;
+ int par = (config & SMASK);
+ return (par > 0) ? par : 1;
}
/**
@@ -2797,7 +2747,7 @@
* @since 1.8
*/
public static int getCommonPoolParallelism() {
- return commonPoolParallelism;
+ return commonParallelism;
}
/**
@@ -3055,7 +3005,7 @@
* Possibly initiates an orderly shutdown in which previously
* submitted tasks are executed, but no new tasks will be
* accepted. Invocation has no effect on execution state if this
- * is the {@link #commonPool}, and no additional effect if
+ * is the {@link #commonPool()}, and no additional effect if
* already shut down. Tasks that are in the process of being
* submitted concurrently during the course of this method may or
* may not be rejected.
@@ -3073,7 +3023,7 @@
/**
* Possibly attempts to cancel and/or stop all tasks, and reject
* all subsequently submitted tasks. Invocation has no effect on
- * execution state if this is the {@link #commonPool}, and no
+ * execution state if this is the {@link #commonPool()}, and no
* additional effect if already shut down. Otherwise, tasks that
* are in the process of being submitted or executed concurrently
* during the course of this method may or may not be
@@ -3136,9 +3086,10 @@
/**
* Blocks until all tasks have completed execution after a
* shutdown request, or the timeout occurs, or the current thread
- * is interrupted, whichever happens first. Note that the {@link
- * #commonPool()} never terminates until program shutdown so
- * this method will always time out.
+ * is interrupted, whichever happens first. Because the {@link
+ * #commonPool()} never terminates until program shutdown, when
+ * applied to the common pool, this method is equivalent to {@link
+ * #awaitQuiescence(long, TimeUnit)} but always returns {@code false}.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
@@ -3148,6 +3099,12 @@
*/
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (this == common) {
+ awaitQuiescence(timeout, unit);
+ return false;
+ }
long nanos = unit.toNanos(timeout);
if (isTerminated())
return true;
@@ -3167,6 +3124,62 @@
}
/**
+ * If called by a ForkJoinTask operating in this pool, equivalent
+ * in effect to {@link ForkJoinTask#helpQuiesce}. Otherwise,
+ * waits and/or attempts to assist performing tasks until this
+ * pool {@link #isQuiescent} or the indicated timeout elapses.
+ *
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return {@code true} if quiescent; {@code false} if the
+ * timeout elapsed.
+ */
+ public boolean awaitQuiescence(long timeout, TimeUnit unit) {
+ long nanos = unit.toNanos(timeout);
+ ForkJoinWorkerThread wt;
+ Thread thread = Thread.currentThread();
+ if ((thread instanceof ForkJoinWorkerThread) &&
+ (wt = (ForkJoinWorkerThread)thread).pool == this) {
+ helpQuiescePool(wt.workQueue);
+ return true;
+ }
+ long startTime = System.nanoTime();
+ WorkQueue[] ws;
+ int r = 0, m;
+ boolean found = true;
+ while (!isQuiescent() && (ws = workQueues) != null &&
+ (m = ws.length - 1) >= 0) {
+ if (!found) {
+ if ((System.nanoTime() - startTime) > nanos)
+ return false;
+ Thread.yield(); // cannot block
+ }
+ found = false;
+ for (int j = (m + 1) << 2; j >= 0; --j) {
+ ForkJoinTask<?> t; WorkQueue q; int b;
+ if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) {
+ found = true;
+ if ((t = q.pollAt(b)) != null) {
+ if (q.base - q.top < 0)
+ signalWork(q);
+ t.doExec();
+ }
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Waits and/or attempts to assist performing tasks indefinitely
+ * until the {@link #commonPool()} {@link #isQuiescent}.
+ */
+ static void quiesceCommonPool() {
+ common.awaitQuiescence(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ }
+
+ /**
* Interface for extending managed parallelism for tasks running
* in {@link ForkJoinPool}s.
*
@@ -3175,9 +3188,9 @@
* not necessary. Method {@code block} blocks the current thread
* if necessary (perhaps internally invoking {@code isReleasable}
* before actually blocking). These actions are performed by any
- * thread invoking {@link ForkJoinPool#managedBlock}. The
- * unusual methods in this API accommodate synchronizers that may,
- * but don't usually, block for long periods. Similarly, they
+ * thread invoking {@link ForkJoinPool#managedBlock(ManagedBlocker)}.
+ * The unusual methods in this API accommodate synchronizers that
+ * may, but don't usually, block for long periods. Similarly, they
* allow more efficient internal handling of cases in which
* additional workers may be, but usually are not, needed to
* ensure sufficient parallelism. Toward this end,
@@ -3235,6 +3248,7 @@
/**
* Returns {@code true} if blocking is unnecessary.
+ * @return {@code true} if blocking is unnecessary
*/
boolean isReleasable();
}
@@ -3319,7 +3333,7 @@
private static final long QLOCK;
static {
- int s; // initialize field offsets for CAS etc
+ // initialize field offsets for CAS etc
try {
U = sun.misc.Unsafe.getUnsafe();
Class<?> k = ForkJoinPool.class;
@@ -3339,54 +3353,58 @@
(wk.getDeclaredField("qlock"));
Class<?> ak = ForkJoinTask[].class;
ABASE = U.arrayBaseOffset(ak);
- s = U.arrayIndexScale(ak);
- ASHIFT = 31 - Integer.numberOfLeadingZeros(s);
+ int scale = U.arrayIndexScale(ak);
+ if ((scale & (scale - 1)) != 0)
+ throw new Error("data type scale not a power of two");
+ ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (Exception e) {
throw new Error(e);
}
- if ((s & (s-1)) != 0)
- throw new Error("data type scale not a power of two");
- submitters = new ThreadLocal<Submitter>();
- ForkJoinWorkerThreadFactory fac = defaultForkJoinWorkerThreadFactory =
+ defaultForkJoinWorkerThreadFactory =
new DefaultForkJoinWorkerThreadFactory();
modifyThreadPermission = new RuntimePermission("modifyThread");
- /*
- * Establish common pool parameters. For extra caution,
- * computations to set up common pool state are here; the
- * constructor just assigns these values to fields.
- */
+ common = java.security.AccessController.doPrivileged
+ (new java.security.PrivilegedAction<ForkJoinPool>() {
+ public ForkJoinPool run() { return makeCommonPool(); }});
+ int par = common.config; // report 1 even if threads disabled
+ commonParallelism = par > 0 ? par : 1;
+ }
- int par = 0;
- Thread.UncaughtExceptionHandler handler = null;
- try { // TBD: limit or report ignored exceptions?
+ /**
+ * Creates and returns the common pool, respecting user settings
+ * specified via system properties.
+ */
+ private static ForkJoinPool makeCommonPool() {
+ int parallelism = -1;
+ ForkJoinWorkerThreadFactory factory
+ = defaultForkJoinWorkerThreadFactory;
+ UncaughtExceptionHandler handler = null;
+ try { // ignore exceptions in accesing/parsing properties
String pp = System.getProperty
("java.util.concurrent.ForkJoinPool.common.parallelism");
- String hp = System.getProperty
- ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
String fp = System.getProperty
("java.util.concurrent.ForkJoinPool.common.threadFactory");
- if (fp != null)
- fac = ((ForkJoinWorkerThreadFactory)ClassLoader.
- getSystemClassLoader().loadClass(fp).newInstance());
- if (hp != null)
- handler = ((Thread.UncaughtExceptionHandler)ClassLoader.
- getSystemClassLoader().loadClass(hp).newInstance());
+ String hp = System.getProperty
+ ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
if (pp != null)
- par = Integer.parseInt(pp);
+ parallelism = Integer.parseInt(pp);
+ if (fp != null)
+ factory = ((ForkJoinWorkerThreadFactory)ClassLoader.
+ getSystemClassLoader().loadClass(fp).newInstance());
+ if (hp != null)
+ handler = ((UncaughtExceptionHandler)ClassLoader.
+ getSystemClassLoader().loadClass(hp).newInstance());
} catch (Exception ignore) {
}
- if (par <= 0)
- par = Runtime.getRuntime().availableProcessors();
- if (par > MAX_CAP)
- par = MAX_CAP;
- commonPoolParallelism = par;
- long np = (long)(-par); // precompute initial ctl value
- long ct = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
-
- commonPool = new ForkJoinPool(par, ct, fac, handler);
+ if (parallelism < 0)
+ parallelism = Runtime.getRuntime().availableProcessors();
+ if (parallelism > MAX_CAP)
+ parallelism = MAX_CAP;
+ return new ForkJoinPool(parallelism, factory, handler, false,
+ "ForkJoinPool.commonPool-worker-");
}
}
diff --git a/src/share/classes/java/util/concurrent/ForkJoinTask.java b/src/share/classes/java/util/concurrent/ForkJoinTask.java
index 3b4fbb1..a17cc28 100644
--- a/src/share/classes/java/util/concurrent/ForkJoinTask.java
+++ b/src/share/classes/java/util/concurrent/ForkJoinTask.java
@@ -464,7 +464,7 @@
}
/**
- * Records exception and possibly propagates
+ * Records exception and possibly propagates.
*
* @return status on exit
*/
@@ -497,7 +497,7 @@
}
/**
- * Removes exception node and clears status
+ * Removes exception node and clears status.
*/
private void clearExceptionalCompletion() {
int h = System.identityHashCode(this);
@@ -635,7 +635,7 @@
throw (Error)ex;
if (ex instanceof RuntimeException)
throw (RuntimeException)ex;
- throw uncheckedThrowable(ex, RuntimeException.class);
+ ForkJoinTask.<RuntimeException>uncheckedThrow(ex);
}
}
@@ -645,8 +645,9 @@
* unchecked exceptions
*/
@SuppressWarnings("unchecked") static <T extends Throwable>
- T uncheckedThrowable(final Throwable t, final Class<T> c) {
- return (T)t; // rely on vacuous cast
+ void uncheckedThrow(Throwable t) throws T {
+ if (t != null)
+ throw (T)t; // rely on vacuous cast
}
/**
@@ -681,7 +682,7 @@
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)
((ForkJoinWorkerThread)t).workQueue.push(this);
else
- ForkJoinPool.commonPool.externalPush(this);
+ ForkJoinPool.common.externalPush(this);
return this;
}
@@ -857,7 +858,7 @@
* <p>This method is designed to be invoked by <em>other</em>
* tasks. To terminate the current task, you can just return or
* throw an unchecked exception from its computation method, or
- * invoke {@link #completeExceptionally}.
+ * invoke {@link #completeExceptionally(Throwable)}.
*
* @param mayInterruptIfRunning this value has no effect in the
* default implementation because interrupts are not used to
@@ -1007,8 +1008,9 @@
if (Thread.interrupted())
throw new InterruptedException();
// Messy in part because we measure in nanosecs, but wait in millisecs
- int s; long ns, ms;
- if ((s = status) >= 0 && (ns = unit.toNanos(timeout)) > 0L) {
+ int s; long ms;
+ long ns = unit.toNanos(timeout);
+ if ((s = status) >= 0 && ns > 0L) {
long deadline = System.nanoTime() + ns;
ForkJoinPool p = null;
ForkJoinPool.WorkQueue w = null;
@@ -1104,7 +1106,7 @@
wt.pool.helpQuiescePool(wt.workQueue);
}
else
- ForkJoinPool.externalHelpQuiescePool();
+ ForkJoinPool.quiesceCommonPool();
}
/**
@@ -1391,6 +1393,24 @@
}
/**
+ * Adaptor for Runnables in which failure forces worker exception
+ */
+ static final class RunnableExecuteAction extends ForkJoinTask<Void> {
+ final Runnable runnable;
+ RunnableExecuteAction(Runnable runnable) {
+ if (runnable == null) throw new NullPointerException();
+ this.runnable = runnable;
+ }
+ public final Void getRawResult() { return null; }
+ public final void setRawResult(Void v) { }
+ public final boolean exec() { runnable.run(); return true; }
+ void internalPropagateException(Throwable ex) {
+ rethrow(ex); // rethrow outside exec() catches.
+ }
+ private static final long serialVersionUID = 5232453952276885070L;
+ }
+
+ /**
* Adaptor for Callables
*/
static final class AdaptedCallable<T> extends ForkJoinTask<T>
diff --git a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java
index 08c870f..c19d512 100644
--- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java
+++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java
@@ -83,22 +83,20 @@
* programs.
*
* Because this class is in a different package than class Thread,
- * field access methods must use Unsafe to bypass access control
- * rules. The base functionality of Random methods is
- * conveniently isolated in method next(bits), that just reads and
- * writes the Thread field rather than its own field. However, to
- * conform to the requirements of the Random constructor, during
- * construction, the common static ThreadLocalRandom must maintain
- * initialization and value fields, mainly for the sake of
- * disabling user calls to setSeed while still allowing a call
- * from constructor. For serialization compatibility, these
- * fields are left with the same declarations as used in the
- * previous ThreadLocal-based version of this class, that used
- * them differently. Note that serialization is completely
- * unnecessary because there is only a static singleton. But these
- * mechanics still ensure compatibility across versions.
+ * field access methods use Unsafe to bypass access control rules.
+ * The base functionality of Random methods is conveniently
+ * isolated in method next(bits), that just reads and writes the
+ * Thread field rather than its own field. However, to conform to
+ * the requirements of the Random superclass constructor, the
+ * common static ThreadLocalRandom maintains an "initialized"
+ * field for the sake of rejecting user calls to setSeed while
+ * still allowing a call from constructor. Note that
+ * serialization is completely unnecessary because there is only a
+ * static singleton. But we generate a serial form containing
+ * "rnd" and "initialized" fields to ensure compatibility across
+ * versions.
*
- * Per-instance initialization is similar to that in the no-arg
+ * Per-thread initialization is similar to that in the no-arg
* Random constructor, but we avoid correlation among not only
* initial seeds of those created in different threads, but also
* those created using class Random itself; while at the same time
@@ -132,10 +130,11 @@
private static final ThreadLocal<Double> nextLocalGaussian =
new ThreadLocal<Double>();
- /*
- * Field used only during singleton initialization
+ /**
+ * Field used only during singleton initialization.
+ * True when constructor completes.
*/
- boolean initialized; // true when constructor completes
+ boolean initialized;
/** Constructor used only for static singleton */
private ThreadLocalRandom() {
@@ -184,7 +183,8 @@
* @throws UnsupportedOperationException always
*/
public void setSeed(long seed) {
- if (initialized) // allow call from super() constructor
+ // only allow call from super() constructor
+ if (initialized)
throw new UnsupportedOperationException();
}
@@ -357,39 +357,29 @@
r ^= r >>> 17;
r ^= r << 5;
}
- else if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
- r = 1; // avoid zero
+ else {
+ localInit();
+ if ((r = (int)UNSAFE.getLong(t, SEED)) == 0)
+ r = 1; // avoid zero
+ }
UNSAFE.putInt(t, SECONDARY, r);
return r;
}
- // Serialization support, maintains original persistent form.
+ // Serialization support
private static final long serialVersionUID = -5851777807851030925L;
/**
* @serialField rnd long
+ * seed for random computations
* @serialField initialized boolean
- * @serialField pad0 long
- * @serialField pad1 long
- * @serialField pad2 long
- * @serialField pad3 long
- * @serialField pad4 long
- * @serialField pad5 long
- * @serialField pad6 long
- * @serialField pad7 long
+ * always true
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("rnd", long.class),
- new ObjectStreamField("initialized", boolean.class),
- new ObjectStreamField("pad0", long.class),
- new ObjectStreamField("pad1", long.class),
- new ObjectStreamField("pad2", long.class),
- new ObjectStreamField("pad3", long.class),
- new ObjectStreamField("pad4", long.class),
- new ObjectStreamField("pad5", long.class),
- new ObjectStreamField("pad6", long.class),
- new ObjectStreamField("pad7", long.class) };
+ new ObjectStreamField("initialized", boolean.class)
+ };
/**
* Saves the {@code ThreadLocalRandom} to a stream (that is, serializes it).
@@ -398,16 +388,8 @@
throws java.io.IOException {
java.io.ObjectOutputStream.PutField fields = out.putFields();
- fields.put("rnd", 0L);
+ fields.put("rnd", UNSAFE.getLong(Thread.currentThread(), SEED));
fields.put("initialized", true);
- fields.put("pad0", 0L);
- fields.put("pad1", 0L);
- fields.put("pad2", 0L);
- fields.put("pad3", 0L);
- fields.put("pad4", 0L);
- fields.put("pad5", 0L);
- fields.put("pad6", 0L);
- fields.put("pad7", 0L);
out.writeFields();
}
diff --git a/src/share/classes/javax/swing/JFrame.java b/src/share/classes/javax/swing/JFrame.java
index cccd6f9..aee994e 100644
--- a/src/share/classes/javax/swing/JFrame.java
+++ b/src/share/classes/javax/swing/JFrame.java
@@ -387,13 +387,14 @@
operation != EXIT_ON_CLOSE) {
throw new IllegalArgumentException("defaultCloseOperation must be one of: DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or EXIT_ON_CLOSE");
}
- if (this.defaultCloseOperation != operation) {
- if (operation == EXIT_ON_CLOSE) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkExit(0);
- }
+
+ if (operation == EXIT_ON_CLOSE) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkExit(0);
}
+ }
+ if (this.defaultCloseOperation != operation) {
int oldValue = this.defaultCloseOperation;
this.defaultCloseOperation = operation;
firePropertyChange("defaultCloseOperation", oldValue, operation);
diff --git a/src/share/classes/javax/swing/SwingUtilities.java b/src/share/classes/javax/swing/SwingUtilities.java
index 956bb83..6bb308d 100644
--- a/src/share/classes/javax/swing/SwingUtilities.java
+++ b/src/share/classes/javax/swing/SwingUtilities.java
@@ -356,7 +356,7 @@
sourceEvent.getYOnScreen(),
sourceEvent.getClickCount(),
sourceEvent.isPopupTrigger(),
- MouseEvent.NOBUTTON );
+ sourceEvent.getButton());
}
return newEvent;
}
diff --git a/src/share/classes/javax/swing/text/html/FormView.java b/src/share/classes/javax/swing/text/html/FormView.java
index 2946372..2d25516 100644
--- a/src/share/classes/javax/swing/text/html/FormView.java
+++ b/src/share/classes/javax/swing/text/html/FormView.java
@@ -159,6 +159,10 @@
attr.getAttribute(StyleConstants.NameAttribute);
JComponent c = null;
Object model = attr.getAttribute(StyleConstants.ModelAttribute);
+
+ // Remove listeners previously registered in shared model
+ // when a new UI component is replaced. See bug 7189299.
+ removeStaleListenerForModel(model);
if (t == HTML.Tag.INPUT) {
c = createInputComponent(attr, model);
} else if (t == HTML.Tag.SELECT) {
@@ -310,6 +314,63 @@
return c;
}
+ private void removeStaleListenerForModel(Object model) {
+ if (model instanceof DefaultButtonModel) {
+ // case of JButton whose model is DefaultButtonModel
+ // Need to remove stale ActionListener, ChangeListener and
+ // ItemListener that are instance of AbstractButton$Handler.
+ DefaultButtonModel buttonModel = (DefaultButtonModel) model;
+ String listenerClass = "javax.swing.AbstractButton$Handler";
+ for (ActionListener listener : buttonModel.getActionListeners()) {
+ if (listenerClass.equals(listener.getClass().getName())) {
+ buttonModel.removeActionListener(listener);
+ }
+ }
+ for (ChangeListener listener : buttonModel.getChangeListeners()) {
+ if (listenerClass.equals(listener.getClass().getName())) {
+ buttonModel.removeChangeListener(listener);
+ }
+ }
+ for (ItemListener listener : buttonModel.getItemListeners()) {
+ if (listenerClass.equals(listener.getClass().getName())) {
+ buttonModel.removeItemListener(listener);
+ }
+ }
+ } else if (model instanceof AbstractListModel) {
+ // case of JComboBox and JList
+ // For JList, the stale ListDataListener is instance
+ // BasicListUI$Handler.
+ // For JComboBox, there are 2 stale ListDataListeners, which are
+ // BasicListUI$Handler and BasicComboBoxUI$Handler.
+ AbstractListModel listModel = (AbstractListModel) model;
+ String listenerClass1 =
+ "javax.swing.plaf.basic.BasicListUI$Handler";
+ String listenerClass2 =
+ "javax.swing.plaf.basic.BasicComboBoxUI$Handler";
+ for (ListDataListener listener : listModel.getListDataListeners()) {
+ if (listenerClass1.equals(listener.getClass().getName())
+ || listenerClass2.equals(listener.getClass().getName()))
+ {
+ listModel.removeListDataListener(listener);
+ }
+ }
+ } else if (model instanceof AbstractDocument) {
+ // case of JPasswordField, JTextField and JTextArea
+ // All have 2 stale DocumentListeners.
+ String listenerClass1 =
+ "javax.swing.plaf.basic.BasicTextUI$UpdateHandler";
+ String listenerClass2 =
+ "javax.swing.text.DefaultCaret$Handler";
+ AbstractDocument docModel = (AbstractDocument) model;
+ for (DocumentListener listener : docModel.getDocumentListeners()) {
+ if (listenerClass1.equals(listener.getClass().getName())
+ || listenerClass2.equals(listener.getClass().getName()))
+ {
+ docModel.removeDocumentListener(listener);
+ }
+ }
+ }
+ }
/**
* Determines the maximum span for this view along an
@@ -347,7 +408,7 @@
/**
- * Responsible for processeing the ActionEvent.
+ * Responsible for processing the ActionEvent.
* If the element associated with the FormView,
* has a type of "submit", "reset", "text" or "password"
* then the action is processed. In the case of a "submit"
diff --git a/src/share/classes/sun/awt/EmbeddedFrame.java b/src/share/classes/sun/awt/EmbeddedFrame.java
index d05e30f..0ae1ec7 100644
--- a/src/share/classes/sun/awt/EmbeddedFrame.java
+++ b/src/share/classes/sun/awt/EmbeddedFrame.java
@@ -582,5 +582,8 @@
public void repositionSecurityWarning() {
}
- }
+
+ public void emulateActivation(boolean activate) {
+ }
+ }
} // class EmbeddedFrame
diff --git a/src/share/classes/sun/awt/HToolkit.java b/src/share/classes/sun/awt/HToolkit.java
index 5721767..8671d8b 100644
--- a/src/share/classes/sun/awt/HToolkit.java
+++ b/src/share/classes/sun/awt/HToolkit.java
@@ -64,6 +64,11 @@
throw new HeadlessException();
}
+ public FramePeer createLightweightFrame(LightweightFrame target)
+ throws HeadlessException {
+ throw new HeadlessException();
+ }
+
public FramePeer createFrame(Frame target)
throws HeadlessException {
throw new HeadlessException();
diff --git a/src/share/classes/sun/awt/LightweightFrame.java b/src/share/classes/sun/awt/LightweightFrame.java
new file mode 100644
index 0000000..71e3dd3
--- /dev/null
+++ b/src/share/classes/sun/awt/LightweightFrame.java
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+package sun.awt;
+
+import java.awt.Container;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MenuBar;
+import java.awt.MenuComponent;
+import java.awt.Toolkit;
+import java.awt.peer.FramePeer;
+
+/**
+ * The class provides basic functionality for a lightweight frame
+ * implementation. A subclass is expected to provide painting to an
+ * offscreen image and access to it. Thus it can be used for lightweight
+ * embedding.
+ *
+ * @author Artem Ananiev
+ * @author Anton Tarasov
+ */
+@SuppressWarnings("serial")
+public abstract class LightweightFrame extends Frame {
+
+ /**
+ * Constructs a new, initially invisible {@code LightweightFrame}
+ * instance.
+ */
+ public LightweightFrame() {
+ setUndecorated(true);
+ setResizable(true);
+ setEnabled(true);
+ }
+
+ /**
+ * Blocks introspection of a parent window by this child.
+ *
+ * @return null
+ */
+ @Override public final Container getParent() { return null; }
+
+ @Override public Graphics getGraphics() { return null; }
+
+ @Override public final boolean isResizable() { return true; }
+
+ // Block modification of any frame attributes, since they aren't
+ // applicable for a lightweight frame.
+
+ @Override public final void setTitle(String title) {}
+ @Override public final void setIconImage(Image image) {}
+ @Override public final void setIconImages(java.util.List<? extends Image> icons) {}
+ @Override public final void setMenuBar(MenuBar mb) {}
+ @Override public final void setResizable(boolean resizable) {}
+ @Override public final void remove(MenuComponent m) {}
+ @Override public final void toFront() {}
+ @Override public final void toBack() {}
+
+ @Override public void addNotify() {
+ synchronized (getTreeLock()) {
+ if (getPeer() == null) {
+ SunToolkit stk = (SunToolkit)Toolkit.getDefaultToolkit();
+ try {
+ setPeer(stk.createLightweightFrame(this));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ super.addNotify();
+ }
+ }
+
+ private void setPeer(final FramePeer p) {
+ AWTAccessor.getComponentAccessor().setPeer(this, p);
+ }
+
+ /**
+ * Requests the peer to emulate activation or deactivation of the
+ * frame. Peers should override this method if they are to implement
+ * this functionality.
+ *
+ * @param activate if <code>true</code>, activates the frame;
+ * otherwise, deactivates the frame
+ */
+ public void emulateActivation(boolean activate) {
+ ((FramePeer)getPeer()).emulateActivation(activate);
+ }
+
+ /**
+ * Delegates the focus grab action to the client (embedding) application.
+ * The method is called by the AWT grab machinery.
+ *
+ * @see SunToolkit#grab(java.awt.Window)
+ */
+ public abstract void grabFocus();
+
+ /**
+ * Delegates the focus ungrab action to the client (embedding) application.
+ * The method is called by the AWT grab machinery.
+ *
+ * @see SunToolkit#ungrab(java.awt.Window)
+ */
+ public abstract void ungrabFocus();
+}
diff --git a/src/share/classes/sun/awt/SunToolkit.java b/src/share/classes/sun/awt/SunToolkit.java
index 4ae6a94..8fc5689 100644
--- a/src/share/classes/sun/awt/SunToolkit.java
+++ b/src/share/classes/sun/awt/SunToolkit.java
@@ -131,6 +131,9 @@
public abstract FramePeer createFrame(Frame target)
throws HeadlessException;
+ public abstract FramePeer createLightweightFrame(LightweightFrame target)
+ throws HeadlessException;
+
public abstract DialogPeer createDialog(Dialog target)
throws HeadlessException;
diff --git a/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/share/classes/sun/awt/datatransfer/DataTransferer.java
index f8dd9df..7465d52 100644
--- a/src/share/classes/sun/awt/datatransfer/DataTransferer.java
+++ b/src/share/classes/sun/awt/datatransfer/DataTransferer.java
@@ -1873,7 +1873,7 @@
*/
public class ReencodingInputStream extends InputStream {
protected BufferedReader wrapped;
- protected final char[] in = new char[1];
+ protected final char[] in = new char[2];
protected byte[] out;
protected CharsetEncoder encoder;
@@ -1926,7 +1926,7 @@
try {
encoder = Charset.forName(targetEncoding).newEncoder();
- out = new byte[(int)(encoder.maxBytesPerChar() + 0.5)];
+ out = new byte[(int)(encoder.maxBytesPerChar() * 2 + 0.5)];
inBuf = CharBuffer.wrap(in);
outBuf = ByteBuffer.wrap(out);
} catch (IllegalCharsetNameException e) {
@@ -1950,31 +1950,50 @@
}
}
+ private int readChar() throws IOException {
+ int c = wrapped.read();
+
+ if (c == -1) { // -1 is EOS
+ eos = true;
+ return -1;
+ }
+
+ // "c == 0" is not quite correct, but good enough on Windows.
+ if (numTerminators > 0 && c == 0) {
+ eos = true;
+ return -1;
+ } else if (eoln != null && matchCharArray(eoln, c)) {
+ c = '\n' & 0xFFFF;
+ }
+
+ return c;
+ }
+
public int read() throws IOException {
if (eos) {
return -1;
}
if (index >= limit) {
- int c = wrapped.read();
-
- if (c == -1) { // -1 is EOS
- eos = true;
+ // deal with supplementary characters
+ int c = readChar();
+ if (c == -1) {
return -1;
}
- // "c == 0" is not quite correct, but good enough on Windows.
- if (numTerminators > 0 && c == 0) {
- eos = true;
- return -1;
- } else if (eoln != null && matchCharArray(eoln, c)) {
- c = '\n' & 0xFFFF;
+ in[0] = (char) c;
+ in[1] = 0;
+ inBuf.limit(1);
+ if (Character.isHighSurrogate((char) c)) {
+ c = readChar();
+ if (c != -1) {
+ in[1] = (char) c;
+ inBuf.limit(2);
+ }
}
- in[0] = (char)c;
-
inBuf.rewind();
- outBuf.rewind();
+ outBuf.limit(out.length).rewind();
encoder.encode(inBuf, outBuf, false);
outBuf.flip();
limit = outBuf.limit();
diff --git a/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java b/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java
index 302a6db..360bb9a 100644
--- a/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java
+++ b/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java
@@ -498,7 +498,7 @@
postDropTargetEvent(component, x, y, dropAction, actions,
formats, nativeCtxt,
SunDropTargetEvent.MOUSE_DROPPED,
- SunDropTargetContextPeer.DISPATCH_SYNC);
+ !SunDropTargetContextPeer.DISPATCH_SYNC);
}
/**
diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/src/share/classes/sun/java2d/cmm/lcms/LCMS.java
index 5cfda3c..c6eae65 100644
--- a/src/share/classes/sun/java2d/cmm/lcms/LCMS.java
+++ b/src/share/classes/sun/java2d/cmm/lcms/LCMS.java
@@ -25,29 +25,91 @@
package sun.java2d.cmm.lcms;
-import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
-import java.awt.color.CMMException;
+import java.util.Arrays;
+import java.util.HashMap;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM;
-import sun.java2d.cmm.lcms.LCMS;
-import sun.java2d.cmm.lcms.LCMSTransform;
public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */
- public native long loadProfile(byte[] data);
+ @Override
+ public long loadProfile(byte[] data) {
+ long id = loadProfileNative(data);
- public native void freeProfile(long profileID);
+ if (id != 0L) {
+ if (profiles == null) {
+ profiles = new HashMap<>();
+ }
+ profiles.put(id, new TagCache(id));
+ }
+ return id;
+ }
+
+ private native long loadProfileNative(byte[] data);
+
+ @Override
+ public void freeProfile(long profileID) {
+ TagCache c = profiles.remove(profileID);
+ if (c != null) {
+ c.clear();
+ }
+ if (profiles.isEmpty()) {
+ profiles = null;
+ }
+ freeProfileNative(profileID);
+ }
+
+ private native void freeProfileNative(long profileID);
public native synchronized int getProfileSize(long profileID);
public native synchronized void getProfileData(long profileID, byte[] data);
- public native synchronized int getTagSize(long profileID, int tagSignature);
- public native synchronized void getTagData(long profileID, int tagSignature,
- byte[] data);
- public native synchronized void setTagData(long profileID, int tagSignature,
+ @Override
+ public synchronized int getTagSize(long profileID, int tagSignature) {
+ TagCache cache = profiles.get(profileID);
+
+ if (cache == null) {
+ cache = new TagCache(profileID);
+ profiles.put(profileID, cache);
+ }
+
+ TagData t = cache.getTag(tagSignature);
+ return t == null ? 0 : t.getSize();
+ }
+
+ private static native byte[] getTagNative(long profileID, int signature);
+
+ @Override
+ public synchronized void getTagData(long profileID, int tagSignature,
+ byte[] data)
+ {
+ TagCache cache = profiles.get(profileID);
+
+ if (cache == null) {
+ cache = new TagCache(profileID);
+ profiles.put(profileID, cache);
+ }
+
+ TagData t = cache.getTag(tagSignature);
+ if (t != null) {
+ t.copyDataTo(data);
+ }
+ }
+
+ @Override
+ public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
+ TagCache cache = profiles.get(profileID);
+
+ if (cache != null) {
+ cache.clear();
+ }
+ setTagDataNative(profileID, tagSignature, data);
+ }
+
+ private native synchronized void setTagDataNative(long profileID, int tagSignature,
byte[] data);
public static native long getProfileID(ICC_Profile profile);
@@ -103,4 +165,59 @@
initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class);
}
+
+ private static class TagData {
+ private int signature;
+ private byte[] data;
+
+ TagData(int sig, byte[] data) {
+ this.signature = sig;
+ this.data = data;
+ }
+
+ int getSize() {
+ return data.length;
+ }
+
+ byte[] getData() {
+ return Arrays.copyOf(data, data.length);
+ }
+
+ void copyDataTo(byte[] dst) {
+ System.arraycopy(data, 0, dst, 0, data.length);
+ }
+
+ int getSignature() {
+ return signature;
+ }
+ }
+
+ private static class TagCache {
+ private long profileID;
+ private HashMap<Integer, TagData> tags;
+
+ TagCache(long id) {
+ profileID = id;
+
+ tags = new HashMap<>();
+ }
+
+ TagData getTag(int sig) {
+ TagData t = tags.get(sig);
+ if (t == null) {
+ byte[] tagData = getTagNative(profileID, sig);
+ if (tagData != null) {
+ t = new TagData(sig, tagData);
+ tags.put(sig, t);
+ }
+ }
+ return t;
+ }
+
+ void clear() {
+ tags.clear();
+ }
+ }
+
+ private static HashMap<Long, TagCache> profiles;
}
diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
index 3695a16..b53bd9a 100644
--- a/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
+++ b/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
@@ -22,26 +22,19 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package sun.java2d.cmm.lcms;
-import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
-import java.awt.image.Raster;
-import java.awt.image.WritableRaster;
-import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferUShort;
-import java.awt.image.DataBufferInt;
import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
import sun.awt.image.ByteComponentRaster;
import sun.awt.image.ShortComponentRaster;
import sun.awt.image.IntegerComponentRaster;
-
class LCMSImageLayout {
public static int BYTES_SH(int x) {
@@ -49,47 +42,34 @@
}
public static int EXTRA_SH(int x) {
- return x<<7;
+ return x << 7;
}
public static int CHANNELS_SH(int x) {
- return x<<3;
+ return x << 3;
}
-
- public static final int SWAPFIRST = 1<<14;
-
- public static final int DOSWAP = 1<<10;
-
+ public static final int SWAPFIRST = 1 << 14;
+ public static final int DOSWAP = 1 << 10;
public static final int PT_RGB_8 =
- CHANNELS_SH(3) | BYTES_SH(1);
-
+ CHANNELS_SH(3) | BYTES_SH(1);
public static final int PT_GRAY_8 =
- CHANNELS_SH(1) | BYTES_SH(1);
-
+ CHANNELS_SH(1) | BYTES_SH(1);
public static final int PT_GRAY_16 =
- CHANNELS_SH(1) | BYTES_SH(2);
-
+ CHANNELS_SH(1) | BYTES_SH(2);
public static final int PT_RGBA_8 =
- EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
-
+ EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
public static final int PT_ARGB_8 =
- EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST;
-
+ EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST;
public static final int PT_BGR_8 =
- DOSWAP | CHANNELS_SH(3) | BYTES_SH(1);
-
+ DOSWAP | CHANNELS_SH(3) | BYTES_SH(1);
public static final int PT_ABGR_8 =
- DOSWAP | EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
-
- public static final int PT_BGRA_8 = EXTRA_SH(1) | CHANNELS_SH(3) |
- BYTES_SH(1) | DOSWAP | SWAPFIRST;
-
- public static final int DT_BYTE = 0;
- public static final int DT_SHORT = 1;
- public static final int DT_INT = 2;
- public static final int DT_DOUBLE = 3;
-
-
+ DOSWAP | EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
+ public static final int PT_BGRA_8 = EXTRA_SH(1) | CHANNELS_SH(3)
+ | BYTES_SH(1) | DOSWAP | SWAPFIRST;
+ public static final int DT_BYTE = 0;
+ public static final int DT_SHORT = 1;
+ public static final int DT_INT = 2;
+ public static final int DT_DOUBLE = 3;
boolean isIntPacked = false;
int pixelType;
int dataType;
@@ -98,25 +78,30 @@
int nextRowOffset;
int offset;
+ /* This flag indicates whether the image can be processed
+ * at once by doTransfrom() native call. Otherwise, the
+ * image is processed scan by scan.
+ */
+ private boolean imageAtOnce = false;
Object dataArray;
+
private LCMSImageLayout(int np, int pixelType, int pixelSize) {
this.pixelType = pixelType;
width = np;
height = 1;
- nextRowOffset = np*pixelSize;
+ nextRowOffset = np * pixelSize;
offset = 0;
}
private LCMSImageLayout(int width, int height, int pixelType,
- int pixelSize) {
+ int pixelSize) {
this.pixelType = pixelType;
this.width = width;
this.height = height;
- nextRowOffset = width*pixelSize;
+ nextRowOffset = width * pixelSize;
offset = 0;
}
-
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
this(np, pixelType, pixelSize);
dataType = DT_BYTE;
@@ -135,102 +120,218 @@
dataArray = data;
}
- public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
- {
+ public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) {
this(np, pixelType, pixelSize);
dataType = DT_DOUBLE;
dataArray = data;
}
- public LCMSImageLayout(BufferedImage image) {
- ShortComponentRaster shortRaster;
- IntegerComponentRaster intRaster;
- ByteComponentRaster byteRaster;
+ private LCMSImageLayout() {
+ }
+
+ /* This method creates a layout object for given image.
+ * Returns null if the image is not supported by current implementation.
+ */
+ public static LCMSImageLayout createImageLayout(BufferedImage image) {
+ LCMSImageLayout l = new LCMSImageLayout();
+
switch (image.getType()) {
case BufferedImage.TYPE_INT_RGB:
- pixelType = PT_ARGB_8;
- isIntPacked = true;
+ l.pixelType = PT_ARGB_8;
+ l.isIntPacked = true;
break;
case BufferedImage.TYPE_INT_ARGB:
- pixelType = PT_ARGB_8;
- isIntPacked = true;
+ l.pixelType = PT_ARGB_8;
+ l.isIntPacked = true;
break;
case BufferedImage.TYPE_INT_BGR:
- pixelType = PT_ABGR_8;
- isIntPacked = true;
+ l.pixelType = PT_ABGR_8;
+ l.isIntPacked = true;
break;
case BufferedImage.TYPE_3BYTE_BGR:
- pixelType = PT_BGR_8;
+ l.pixelType = PT_BGR_8;
break;
case BufferedImage.TYPE_4BYTE_ABGR:
- pixelType = PT_ABGR_8;
+ l.pixelType = PT_ABGR_8;
break;
case BufferedImage.TYPE_BYTE_GRAY:
- pixelType = PT_GRAY_8;
+ l.pixelType = PT_GRAY_8;
break;
case BufferedImage.TYPE_USHORT_GRAY:
- pixelType = PT_GRAY_16;
+ l.pixelType = PT_GRAY_16;
break;
default:
- // TODO: Add support for some images having
- // SinglePixelPackedModel and ComponentSampleModel
- throw new IllegalArgumentException(
- "CMMImageLayout - bad image type passed to constructor");
+ /* ColorConvertOp creates component images as
+ * default destination, so this kind of images
+ * has to be supported.
+ */
+ ColorModel cm = image.getColorModel();
+ if (cm instanceof ComponentColorModel) {
+ ComponentColorModel ccm = (ComponentColorModel) cm;
+
+ // verify whether the component size is fine
+ int[] cs = ccm.getComponentSize();
+ for (int s : cs) {
+ if (s != 8) {
+ return null;
+ }
+ }
+
+ return createImageLayout(image.getRaster());
+
+ }
+ return null;
}
- width = image.getWidth();
- height = image.getHeight();
+ l.width = image.getWidth();
+ l.height = image.getHeight();
switch (image.getType()) {
case BufferedImage.TYPE_INT_RGB:
case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_BGR:
- intRaster = (IntegerComponentRaster)image.getRaster();
- nextRowOffset = intRaster.getScanlineStride()*4;
- offset = intRaster.getDataOffset(0)*4;
- dataArray = intRaster.getDataStorage();
- dataType = DT_INT;
+ do {
+ IntegerComponentRaster intRaster = (IntegerComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = intRaster.getScanlineStride() * 4;
+ l.offset = intRaster.getDataOffset(0) * 4;
+ l.dataArray = intRaster.getDataStorage();
+ l.dataType = DT_INT;
+
+ if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
case BufferedImage.TYPE_3BYTE_BGR:
case BufferedImage.TYPE_4BYTE_ABGR:
- byteRaster = (ByteComponentRaster)image.getRaster();
- nextRowOffset = byteRaster.getScanlineStride();
- int firstBand = image.getSampleModel().getNumBands() - 1;
- offset = byteRaster.getDataOffset(firstBand);
- dataArray = byteRaster.getDataStorage();
- dataType = DT_BYTE;
+ do {
+ ByteComponentRaster byteRaster = (ByteComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = byteRaster.getScanlineStride();
+ int firstBand = image.getSampleModel().getNumBands() - 1;
+ l.offset = byteRaster.getDataOffset(firstBand);
+ l.dataArray = byteRaster.getDataStorage();
+ l.dataType = DT_BYTE;
+ if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
case BufferedImage.TYPE_BYTE_GRAY:
- byteRaster = (ByteComponentRaster)image.getRaster();
- nextRowOffset = byteRaster.getScanlineStride();
- offset = byteRaster.getDataOffset(0);
- dataArray = byteRaster.getDataStorage();
- dataType = DT_BYTE;
+ do {
+ ByteComponentRaster byteRaster = (ByteComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = byteRaster.getScanlineStride();
+ l.offset = byteRaster.getDataOffset(0);
+ l.dataArray = byteRaster.getDataStorage();
+ l.dataType = DT_BYTE;
+
+ if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
case BufferedImage.TYPE_USHORT_GRAY:
- shortRaster = (ShortComponentRaster)image.getRaster();
- nextRowOffset = shortRaster.getScanlineStride()*2;
- offset = shortRaster.getDataOffset(0) * 2;
- dataArray = shortRaster.getDataStorage();
- dataType = DT_SHORT;
+ do {
+ ShortComponentRaster shortRaster = (ShortComponentRaster)
+ image.getRaster();
+ l.nextRowOffset = shortRaster.getScanlineStride() * 2;
+ l.offset = shortRaster.getDataOffset(0) * 2;
+ l.dataArray = shortRaster.getDataStorage();
+ l.dataType = DT_SHORT;
+
+ if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ } while (false);
break;
+ default:
+ return null;
+ }
+ return l;
+ }
+
+ private static enum BandOrder {
+ DIRECT,
+ INVERTED,
+ ARBITRARY,
+ UNKNOWN;
+
+ public static BandOrder getBandOrder(int[] bandOffsets) {
+ BandOrder order = UNKNOWN;
+
+ int numBands = bandOffsets.length;
+
+ for (int i = 0; (order != ARBITRARY) && (i < bandOffsets.length); i++) {
+ switch (order) {
+ case UNKNOWN:
+ if (bandOffsets[i] == i) {
+ order = DIRECT;
+ } else if (bandOffsets[i] == (numBands - 1 - i)) {
+ order = INVERTED;
+ } else {
+ order = ARBITRARY;
+ }
+ break;
+ case DIRECT:
+ if (bandOffsets[i] != i) {
+ order = ARBITRARY;
+ }
+ break;
+ case INVERTED:
+ if (bandOffsets[i] != (numBands - 1 - i)) {
+ order = ARBITRARY;
+ }
+ break;
+ }
+ }
+ return order;
}
}
- public static boolean isSupported(BufferedImage image) {
- switch (image.getType()) {
- case BufferedImage.TYPE_INT_RGB:
- case BufferedImage.TYPE_INT_ARGB:
- case BufferedImage.TYPE_INT_BGR:
- case BufferedImage.TYPE_3BYTE_BGR:
- case BufferedImage.TYPE_4BYTE_ABGR:
- case BufferedImage.TYPE_BYTE_GRAY:
- case BufferedImage.TYPE_USHORT_GRAY:
- return true;
+ public static LCMSImageLayout createImageLayout(Raster r) {
+ LCMSImageLayout l = new LCMSImageLayout();
+ if (r instanceof ByteComponentRaster) {
+ ByteComponentRaster br = (ByteComponentRaster)r;
+
+ ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel();
+
+ l.pixelType = CHANNELS_SH(br.getNumBands()) | BYTES_SH(1);
+
+ int[] bandOffsets = csm.getBandOffsets();
+ BandOrder order = BandOrder.getBandOrder(bandOffsets);
+
+ int firstBand = 0;
+ switch (order) {
+ case INVERTED:
+ l.pixelType |= DOSWAP;
+ firstBand = csm.getNumBands() - 1;
+ break;
+ case DIRECT:
+ // do nothing
+ break;
+ default:
+ // unable to create the image layout;
+ return null;
+ }
+
+ l.nextRowOffset = br.getScanlineStride();
+ l.offset = br.getDataOffset(firstBand);
+ l.dataArray = br.getDataStorage();
+ l.dataType = DT_BYTE;
+
+ l.width = br.getWidth();
+ l.height = br.getHeight();
+
+ if (l.nextRowOffset == l.width * br.getPixelStride()) {
+ l.imageAtOnce = true;
+ }
+ return l;
}
- return false;
+ return null;
}
}
diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
index aa9d0bf..de8a77c 100644
--- a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
+++ b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
@@ -161,13 +161,18 @@
}
public void colorConvert(BufferedImage src, BufferedImage dst) {
- if (LCMSImageLayout.isSupported(src) &&
- LCMSImageLayout.isSupported(dst))
- {
- doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst));
- return;
- }
LCMSImageLayout srcIL, dstIL;
+
+ dstIL = LCMSImageLayout.createImageLayout(dst);
+
+ if (dstIL != null) {
+ srcIL = LCMSImageLayout.createImageLayout(src);
+ if (srcIL != null) {
+ doTransform(srcIL, dstIL);
+ return;
+ }
+ }
+
Raster srcRas = src.getRaster();
WritableRaster dstRas = dst.getRaster();
ColorModel srcCM = src.getColorModel();
@@ -439,6 +444,14 @@
public void colorConvert(Raster src, WritableRaster dst) {
LCMSImageLayout srcIL, dstIL;
+ dstIL = LCMSImageLayout.createImageLayout(dst);
+ if (dstIL != null) {
+ srcIL = LCMSImageLayout.createImageLayout(src);
+ if (srcIL != null) {
+ doTransform(srcIL, dstIL);
+ return;
+ }
+ }
// Can't pass src and dst directly to CMM, so process per scanline
SampleModel srcSM = src.getSampleModel();
SampleModel dstSM = dst.getSampleModel();
diff --git a/src/share/classes/sun/misc/ClassFileTransformer.java b/src/share/classes/sun/misc/ClassFileTransformer.java
index 61524ba..669b9e8 100644
--- a/src/share/classes/sun/misc/ClassFileTransformer.java
+++ b/src/share/classes/sun/misc/ClassFileTransformer.java
@@ -25,43 +25,31 @@
package sun.misc;
import java.util.ArrayList;
+import java.util.List;
/**
- * This is an abstract base class which is called by java.lang.ClassLoader
- * when ClassFormatError is thrown inside defineClass().
- *
- * The purpose of this class is to allow applications (e.g. Java Plug-in)
- * to have a chance to transform the byte code from one form to another
- * if necessary.
- *
- * One application of this class is used by Java Plug-in to transform
- * malformed JDK 1.1 class file into a well-formed Java 2 class file
- * on-the-fly, so JDK 1.1 applets with malformed class file in the
- * Internet may run in Java 2 after transformation.
+ * This is an abstract base class originally intended to be called by
+ * {@code java.lang.ClassLoader} when {@code ClassFormatError} is
+ * thrown inside {@code defineClass()}. It is no longer hooked into
+ * {@code ClassLoader} and will be removed in a future release.
*
* @author Stanley Man-Kit Ho
*/
-public abstract class ClassFileTransformer
-{
- // Singleton of ClassFileTransformer
- //
- private static ArrayList<ClassFileTransformer> transformerList
+@Deprecated
+public abstract class ClassFileTransformer {
+
+ private static final List<ClassFileTransformer> transformers
= new ArrayList<ClassFileTransformer>();
- private static ClassFileTransformer[] transformers
- = new ClassFileTransformer[0];
/**
* Add the class file transformer object.
*
* @param t Class file transformer instance
*/
- public static void add(ClassFileTransformer t)
- {
- synchronized(transformerList)
- {
- transformerList.add(t);
- transformers = transformerList.toArray(new ClassFileTransformer[0]);
+ public static void add(ClassFileTransformer t) {
+ synchronized (transformers) {
+ transformers.add(t);
}
}
@@ -70,13 +58,11 @@
*
* @return ClassFileTransformer object array
*/
- public static ClassFileTransformer[] getTransformers()
- {
- // transformers is not intended to be changed frequently,
- // so it is okay to not put synchronized block here
- // to speed up performance.
- //
- return transformers;
+ public static ClassFileTransformer[] getTransformers() {
+ synchronized (transformers) {
+ ClassFileTransformer[] result = new ClassFileTransformer[transformers.size()];
+ return transformers.toArray(result);
+ }
}
@@ -89,5 +75,5 @@
* @return Transformed byte array
*/
public abstract byte[] transform(byte[] b, int off, int len)
- throws ClassFormatError;
+ throws ClassFormatError;
}
diff --git a/src/share/classes/sun/print/RasterPrinterJob.java b/src/share/classes/sun/print/RasterPrinterJob.java
index 404f66c..24bece5 100644
--- a/src/share/classes/sun/print/RasterPrinterJob.java
+++ b/src/share/classes/sun/print/RasterPrinterJob.java
@@ -527,9 +527,92 @@
}
}
+ private PageFormat attributeToPageFormat(PrintService service,
+ PrintRequestAttributeSet attSet) {
+ PageFormat page = defaultPage();
+
+ if (service == null) {
+ return page;
+ }
+
+ OrientationRequested orient = (OrientationRequested)
+ attSet.get(OrientationRequested.class);
+ if (orient == null) {
+ orient = (OrientationRequested)
+ service.getDefaultAttributeValue(OrientationRequested.class);
+ }
+ if (orient == OrientationRequested.REVERSE_LANDSCAPE) {
+ page.setOrientation(PageFormat.REVERSE_LANDSCAPE);
+ } else if (orient == OrientationRequested.LANDSCAPE) {
+ page.setOrientation(PageFormat.LANDSCAPE);
+ } else {
+ page.setOrientation(PageFormat.PORTRAIT);
+ }
+
+ Media media = (Media)attSet.get(Media.class);
+ if (media == null) {
+ media =
+ (Media)service.getDefaultAttributeValue(Media.class);
+ }
+ if (!(media instanceof MediaSizeName)) {
+ media = MediaSizeName.NA_LETTER;
+ }
+ MediaSize size =
+ MediaSize.getMediaSizeForName((MediaSizeName)media);
+ if (size == null) {
+ size = MediaSize.NA.LETTER;
+ }
+ Paper paper = new Paper();
+ float dim[] = size.getSize(1); //units == 1 to avoid FP error
+ double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH);
+ double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH);
+ paper.setSize(w, h);
+ MediaPrintableArea area =
+ (MediaPrintableArea)
+ attSet.get(MediaPrintableArea.class);
+ double ix, iw, iy, ih;
+
+ if (area != null) {
+ // Should pass in same unit as updatePageAttributes
+ // to avoid rounding off errors.
+ ix = Math.rint(
+ area.getX(MediaPrintableArea.INCH) * DPI);
+ iy = Math.rint(
+ area.getY(MediaPrintableArea.INCH) * DPI);
+ iw = Math.rint(
+ area.getWidth(MediaPrintableArea.INCH) * DPI);
+ ih = Math.rint(
+ area.getHeight(MediaPrintableArea.INCH) * DPI);
+ }
+ else {
+ if (w >= 72.0 * 6.0) {
+ ix = 72.0;
+ iw = w - 2 * 72.0;
+ } else {
+ ix = w / 6.0;
+ iw = w * 0.75;
+ }
+ if (h >= 72.0 * 6.0) {
+ iy = 72.0;
+ ih = h - 2 * 72.0;
+ } else {
+ iy = h / 6.0;
+ ih = h * 0.75;
+ }
+ }
+ paper.setImageableArea(ix, iy, iw, ih);
+ page.setPaper(paper);
+ return page;
+ }
protected void updatePageAttributes(PrintService service,
PageFormat page) {
+ updateAttributesWithPageFormat(service, page, this.attributes);
+ }
+
+ protected void updateAttributesWithPageFormat(PrintService service,
+ PageFormat page,
+ PrintRequestAttributeSet attributes) {
if (service == null || page == null) {
return;
}
@@ -659,6 +742,18 @@
throw new HeadlessException();
}
+ DialogTypeSelection dlg =
+ (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
+
+ // Check for native, note that default dialog is COMMON.
+ if (dlg == DialogTypeSelection.NATIVE) {
+ PrintService pservice = getPrintService();
+ PageFormat page = pageDialog(attributeToPageFormat(pservice,
+ attributes));
+ updateAttributesWithPageFormat(pservice, page, attributes);
+ return page;
+ }
+
final GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
@@ -698,77 +793,7 @@
attributes.remove(amCategory);
}
attributes.addAll(newas);
-
- PageFormat page = defaultPage();
-
- OrientationRequested orient =
- (OrientationRequested)
- attributes.get(OrientationRequested.class);
- int pfOrient = PageFormat.PORTRAIT;
- if (orient != null) {
- if (orient == OrientationRequested.REVERSE_LANDSCAPE) {
- pfOrient = PageFormat.REVERSE_LANDSCAPE;
- } else if (orient == OrientationRequested.LANDSCAPE) {
- pfOrient = PageFormat.LANDSCAPE;
- }
- }
- page.setOrientation(pfOrient);
-
- Media media = (Media)attributes.get(Media.class);
- if (media == null) {
- media =
- (Media)service.getDefaultAttributeValue(Media.class);
- }
- if (!(media instanceof MediaSizeName)) {
- media = MediaSizeName.NA_LETTER;
- }
- MediaSize size =
- MediaSize.getMediaSizeForName((MediaSizeName)media);
- if (size == null) {
- size = MediaSize.NA.LETTER;
- }
- Paper paper = new Paper();
- float dim[] = size.getSize(1); //units == 1 to avoid FP error
- double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH);
- double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH);
- paper.setSize(w, h);
- MediaPrintableArea area =
- (MediaPrintableArea)
- attributes.get(MediaPrintableArea.class);
- double ix, iw, iy, ih;
-
- if (area != null) {
- // Should pass in same unit as updatePageAttributes
- // to avoid rounding off errors.
- ix = Math.rint(
- area.getX(MediaPrintableArea.INCH) * DPI);
- iy = Math.rint(
- area.getY(MediaPrintableArea.INCH) * DPI);
- iw = Math.rint(
- area.getWidth(MediaPrintableArea.INCH) * DPI);
- ih = Math.rint(
- area.getHeight(MediaPrintableArea.INCH) * DPI);
- }
- else {
- if (w >= 72.0 * 6.0) {
- ix = 72.0;
- iw = w - 2 * 72.0;
- } else {
- ix = w / 6.0;
- iw = w * 0.75;
- }
- if (h >= 72.0 * 6.0) {
- iy = 72.0;
- ih = h - 2 * 72.0;
- } else {
- iy = h / 6.0;
- ih = h * 0.75;
- }
- }
- paper.setImageableArea(ix, iy, iw, ih);
- page.setPaper(paper);
-
- return page;
+ return attributeToPageFormat(service, attributes);
} else {
return null;
}
@@ -795,7 +820,6 @@
throw new HeadlessException();
}
-
DialogTypeSelection dlg =
(DialogTypeSelection)attributes.get(DialogTypeSelection.class);
@@ -816,7 +840,6 @@
}
-
/* A security check has already been performed in the
* java.awt.print.printerJob.getPrinterJob method.
* So by the time we get here, it is OK for the current thread
diff --git a/src/share/classes/sun/security/jgss/GSSCredentialImpl.java b/src/share/classes/sun/security/jgss/GSSCredentialImpl.java
index 6330f71..584e178 100644
--- a/src/share/classes/sun/security/jgss/GSSCredentialImpl.java
+++ b/src/share/classes/sun/security/jgss/GSSCredentialImpl.java
@@ -29,6 +29,7 @@
import sun.security.jgss.spi.*;
import java.util.*;
import com.sun.security.jgss.*;
+import sun.security.jgss.spnego.SpNegoCredElement;
public class GSSCredentialImpl implements ExtendedGSSCredential {
@@ -87,6 +88,7 @@
throw new GSSException(GSSException.NO_CRED);
}
+ // Wrap a mech cred into a GSS cred
public GSSCredentialImpl(GSSManagerImpl gssManager,
GSSCredentialSpi mechElement) throws GSSException {
@@ -103,6 +105,11 @@
usage);
tempCred = mechElement;
hashtable.put(key, tempCred);
+ // More mechs that can use this cred, say, SPNEGO
+ if (!GSSUtil.isSpNegoMech(mechElement.getMechanism())) {
+ key = new SearchKey(GSSUtil.GSS_SPNEGO_MECH_OID, usage);
+ hashtable.put(key, new SpNegoCredElement(mechElement));
+ }
}
void init(GSSManagerImpl gssManager) {
diff --git a/src/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java b/src/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java
index 69116f5..ee5999c 100644
--- a/src/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java
+++ b/src/share/classes/sun/security/jgss/spnego/SpNegoCredElement.java
@@ -44,7 +44,7 @@
private GSSCredentialSpi cred = null;
- SpNegoCredElement(GSSCredentialSpi cred) throws GSSException {
+ public SpNegoCredElement(GSSCredentialSpi cred) throws GSSException {
this.cred = cred;
}
diff --git a/src/share/classes/sun/security/provider/PolicyFile.java b/src/share/classes/sun/security/provider/PolicyFile.java
index 5ea389b..f92e1d5 100644
--- a/src/share/classes/sun/security/provider/PolicyFile.java
+++ b/src/share/classes/sun/security/provider/PolicyFile.java
@@ -1336,10 +1336,9 @@
if (pppe.isWildcardName()) {
// a wildcard name matches any principal with the same class
- for (Principal p : principals) {
- if (pppe.principalClass.equals(p.getClass().getName())) {
- continue;
- }
+ if (wildcardPrincipalNameImplies(pppe.principalClass,
+ principals)) {
+ continue;
}
if (debug != null) {
debug.println("evaluation (principal name wildcard) failed");
@@ -1414,6 +1413,21 @@
addPerms(perms, principals, entry);
}
+ /**
+ * Returns true if the array of principals contains at least one
+ * principal of the specified class.
+ */
+ private static boolean wildcardPrincipalNameImplies(String principalClass,
+ Principal[] principals)
+ {
+ for (Principal p : principals) {
+ if (principalClass.equals(p.getClass().getName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void addPerms(Permissions perms,
Principal[] accPs,
PolicyEntry entry) {
diff --git a/src/share/classes/sun/security/provider/certpath/OCSP.java b/src/share/classes/sun/security/provider/certpath/OCSP.java
index f57c832..03c910b 100644
--- a/src/share/classes/sun/security/provider/certpath/OCSP.java
+++ b/src/share/classes/sun/security/provider/certpath/OCSP.java
@@ -89,7 +89,7 @@
new GetIntegerAction("com.sun.security.ocsp.timeout",
DEFAULT_CONNECT_TIMEOUT));
if (tmp < 0) {
- tmp = DEFAULT_CONNECT_TIMEOUT;
+ return DEFAULT_CONNECT_TIMEOUT;
}
// Convert to milliseconds, as the system property will be
// specified in seconds
diff --git a/src/share/classes/sun/swing/JLightweightFrame.java b/src/share/classes/sun/swing/JLightweightFrame.java
new file mode 100644
index 0000000..f7ea0ae
--- /dev/null
+++ b/src/share/classes/sun/swing/JLightweightFrame.java
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+package sun.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.EventQueue;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+
+import javax.swing.JLayeredPane;
+import javax.swing.JPanel;
+import javax.swing.JRootPane;
+import javax.swing.LayoutFocusTraversalPolicy;
+import javax.swing.RootPaneContainer;
+
+import sun.awt.LightweightFrame;
+
+/**
+ * The frame serves as a lightweight container which paints its content
+ * to an offscreen image and provides access to the image's data via the
+ * {@link LightweightContent} interface. Note, that it may not be shown
+ * as a standalone toplevel frame. Its purpose is to provide functionality
+ * for lightweight embedding.
+ *
+ * @author Artem Ananiev
+ * @author Anton Tarasov
+ */
+public final class JLightweightFrame extends LightweightFrame implements RootPaneContainer {
+
+ private final JRootPane rootPane = new JRootPane();
+
+ private LightweightContent content;
+
+ private Component component;
+ private JPanel contentPane;
+
+ private BufferedImage bbImage;
+
+ /**
+ * Constructs a new, initially invisible {@code JLightweightFrame}
+ * instance.
+ */
+ public JLightweightFrame() {
+ super();
+ add(rootPane, BorderLayout.CENTER);
+ setBackground(new Color(0, 0, 0, 0));
+ setFocusTraversalPolicy(new LayoutFocusTraversalPolicy());
+ }
+
+ /**
+ * Sets the {@link LightweightContent} instance for this frame.
+ * The {@code JComponent} object returned by the
+ * {@link LightweightContent#getComponent()} method is immediately
+ * added to the frame's content pane.
+ *
+ * @param content the {@link LightweightContent} instance
+ */
+ public void setContent(LightweightContent content) {
+ this.content = content;
+ this.component = content.getComponent();
+
+ initInterior();
+ }
+
+ @Override
+ public Graphics getGraphics() {
+ if (bbImage == null) return null;
+
+ Graphics2D g = bbImage.createGraphics();
+ g.setBackground(getBackground());
+ g.setColor(getForeground());
+ g.setFont(getFont());
+ return g;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see LightweightContent#focusGrabbed()
+ */
+ @Override
+ public void grabFocus() {
+ if (content != null) content.focusGrabbed();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see LightweightContent#focusUngrabbed()
+ */
+ @Override
+ public void ungrabFocus() {
+ if (content != null) content.focusUngrabbed();
+ }
+
+ private void initInterior() {
+ contentPane = new JPanel() {
+ @Override
+ public void paint(Graphics g) {
+ content.paintLock();
+ try {
+ super.paint(g);
+
+ final Rectangle clip = g.getClipBounds() != null ?
+ g.getClipBounds() : new Rectangle(0, 0, contentPane.getWidth(), contentPane.getHeight());
+
+ clip.x = Math.max(0, clip.x);
+ clip.y = Math.max(0, clip.y);
+ clip.width = Math.min(contentPane.getWidth(), clip.width);
+ clip.height = Math.min(contentPane.getHeight(), clip.height);
+
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ content.imageUpdated(clip.x, clip.y, clip.width, clip.height);
+ }
+ });
+ } finally {
+ content.paintUnlock();
+ }
+ }
+ @Override
+ protected boolean isPaintingOrigin() {
+ return true;
+ }
+ };
+ contentPane.setLayout(new BorderLayout());
+ contentPane.add(component);
+ setContentPane(contentPane);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ content.paintLock();
+ try {
+ if ((bbImage == null) || (width != bbImage.getWidth()) || (height != bbImage.getHeight())) {
+ boolean createBB = true;
+ int newW = width;
+ int newH = height;
+ if (bbImage != null) {
+ int oldW = bbImage.getWidth();
+ int oldH = bbImage.getHeight();
+ if ((oldW >= newW) && (oldH >= newH)) {
+ createBB = false;
+ } else {
+ if (oldW >= newW) {
+ newW = oldW;
+ } else {
+ newW = Math.max((int)(oldW * 1.2), width);
+ }
+ if (oldH >= newH) {
+ newH = oldH;
+ } else {
+ newH = Math.max((int)(oldH * 1.2), height);
+ }
+ }
+ }
+ if (createBB) {
+ BufferedImage oldBB = bbImage;
+ bbImage = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB_PRE);
+ if (oldBB != null) {
+ Graphics g = bbImage.getGraphics();
+ try {
+ g.drawImage(oldBB, 0, 0, newW, newH, null);
+ } finally {
+ g.dispose();
+ oldBB.flush();
+ }
+ }
+ DataBufferInt dataBuf = (DataBufferInt)bbImage.getRaster().getDataBuffer();
+ content.imageBufferReset(dataBuf.getData(), 0, 0, width, height, bbImage.getWidth());
+ } else {
+ content.imageReshaped(0, 0, width, height);
+ }
+ }
+ } finally {
+ content.paintUnlock();
+ }
+ }
+
+ @Override
+ public JRootPane getRootPane() {
+ return rootPane;
+ }
+
+ @Override
+ public void setContentPane(Container contentPane) {
+ getRootPane().setContentPane(contentPane);
+ }
+
+ @Override
+ public Container getContentPane() {
+ return getRootPane().getContentPane();
+ }
+
+ @Override
+ public void setLayeredPane(JLayeredPane layeredPane) {
+ getRootPane().setLayeredPane(layeredPane);
+ }
+
+ @Override
+ public JLayeredPane getLayeredPane() {
+ return getRootPane().getLayeredPane();
+ }
+
+ @Override
+ public void setGlassPane(Component glassPane) {
+ getRootPane().setGlassPane(glassPane);
+ }
+
+ @Override
+ public Component getGlassPane() {
+ return getRootPane().getGlassPane();
+ }
+}
diff --git a/src/share/classes/sun/swing/LightweightContent.java b/src/share/classes/sun/swing/LightweightContent.java
new file mode 100644
index 0000000..2d443fb
--- /dev/null
+++ b/src/share/classes/sun/swing/LightweightContent.java
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+package sun.swing;
+
+import javax.swing.JComponent;
+
+/**
+ * The interface by means of which the {@link JLightweightFrame} class
+ * communicates to its client application.
+ * <p>
+ * The client application implements this interface so it can response
+ * to requests and process notifications from {@code JLightweightFrame}.
+ * An implementation of this interface is associated with a {@code
+ * JLightweightFrame} instance via the {@link JLightweightFrame#setContent}
+ * method.
+ *
+ * A hierarchy of components contained in the {@code JComponent} instance
+ * returned by the {@link #getComponent} method should not contain any
+ * heavyweight components, otherwise {@code JLightweightFrame} may fail
+ * to paint it.
+ *
+ * @author Artem Ananiev
+ * @author Anton Tarasov
+ * @author Jim Graham
+ */
+public interface LightweightContent {
+
+ /**
+ * The client application overrides this method to return the {@code
+ * JComponent} instance which the {@code JLightweightFrame} container
+ * will paint as its lightweight content. A hierarchy of components
+ * contained in this component should not contain any heavyweight objects.
+ *
+ * @return the component to paint
+ */
+ public JComponent getComponent();
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that it acquires the paint lock. The client application
+ * should implement the locking mechanism in order to synchronize access
+ * to the content image data, shared between {@code JLightweightFrame}
+ * and the client application.
+ *
+ * @see #paintUnlock
+ */
+ public void paintLock();
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that it releases the paint lock. The client application
+ * should implement the locking mechanism in order to synchronize access
+ * to the content image data, shared between {@code JLightweightFrame}
+ * and the client application.
+ *
+ * @see #paintLock
+ */
+ public void paintUnlock();
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that a new data buffer has been set as a content pixel
+ * buffer. Typically this occurs when a buffer of a larger size is
+ * created in response to a content resize event. The method reports
+ * a reference to the pixel data buffer, the content image bounds
+ * within the buffer and the line stride of the buffer. These values
+ * have the following correlation.
+ * <p>
+ * The {@code width} and {@code height} matches the size of the content
+ * (the component returned from the {@link #getComponent} method). The
+ * {@code x} and {@code y} is the origin of the content, {@code (0, 0)}
+ * in the coordinate space of the content, appearing at
+ * {@code data[y * linestride + x]} in the buffer. All indices
+ * {@code data[(y + j) * linestride + (x + i)]} where
+ * {@code (0 <= i < width)} and {@code (0 <= j < height)} will represent
+ * valid pixel data, {@code (i, j)} in the coordinate space of the content.
+ *
+ * @param data the content pixel data buffer of INT_ARGB_PRE type
+ * @param x the x coordinate of the image
+ * @param y the y coordinate of the image
+ * @param width the width of the image
+ * @param height the height of the image
+ * @param linestride the line stride of the pixel buffer
+ */
+ public void imageBufferReset(int[] data,
+ int x, int y,
+ int width, int height,
+ int linestride);
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that the content image bounds have been changed within the
+ * image's pixel buffer.
+ *
+ * @param x the x coordinate of the image
+ * @param y the y coordinate of the image
+ * @param width the width of the image
+ * @param height the height of the image
+ *
+ * @see #imageBufferReset
+ */
+ public void imageReshaped(int x, int y, int width, int height);
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that a part of the content image, or the whole image has
+ * been updated. The method reports bounds of the rectangular dirty region.
+ * The {@code dirtyX} and {@code dirtyY} is the origin of the dirty
+ * rectangle, which is relative to the origin of the content, appearing
+ * at {@code data[(y + dirtyY] * linestride + (x + dirtyX)]} in the pixel
+ * buffer (see {@link #imageBufferReset}). All indices
+ * {@code data[(y + dirtyY + j) * linestride + (x + dirtyX + i)]} where
+ * {@code (0 <= i < dirtyWidth)} and {@code (0 <= j < dirtyHeight)}
+ * will represent valid pixel data, {@code (i, j)} in the coordinate space
+ * of the dirty rectangle.
+ *
+ * @param dirtyX the x coordinate of the dirty rectangle,
+ * relative to the image origin
+ * @param dirtyY the y coordinate of the dirty rectangle,
+ * relative to the image origin
+ * @param dirtyWidth the width of the dirty rectangle
+ * @param dirtyHeight the height of the dirty rectangle
+ *
+ * @see #imageBufferReset
+ * @see #imageReshaped
+ */
+ public void imageUpdated(int dirtyX, int dirtyY,
+ int dirtyWidth, int dirtyHeight);
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that the frame has grabbed focus.
+ */
+ public void focusGrabbed();
+
+ /**
+ * {@code JLightweightFrame} calls this method to notify the client
+ * application that the frame has ungrabbed focus.
+ */
+ public void focusUngrabbed();
+}
diff --git a/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java b/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
index 2f12f65..d7e3240 100644
--- a/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
+++ b/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java
@@ -33,6 +33,7 @@
import java.text.spi.DecimalFormatSymbolsProvider;
import java.text.spi.NumberFormatProvider;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -89,10 +90,7 @@
* LocaleProviderAdapter preference list. The default list is intended
* to behave the same manner in JDK7.
*/
- private static Type[] adapterPreference = {
- Type.JRE,
- Type.SPI,
- };
+ private static final List<Type> adapterPreference;
/**
* JRE Locale Data Adapter instance
@@ -129,10 +127,11 @@
static {
String order = AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("java.locale.providers"));
- // Override adapterPreference with the properties one
+ List<Type> typeList = new ArrayList<>();
+
+ // Check user specified adapter preference
if (order != null && order.length() != 0) {
String[] types = order.split(",");
- List<Type> typeList = new ArrayList<>();
for (String type : types) {
try {
Type aType = Type.valueOf(type.trim().toUpperCase(Locale.ROOT));
@@ -153,18 +152,22 @@
LocaleServiceProviderPool.config(LocaleProviderAdapter.class, e.toString());
}
}
-
- if (!typeList.isEmpty()) {
- if (!typeList.contains(Type.JRE)) {
- // Append FALLBACK as the last resort.
- fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
- typeList.add(Type.FALLBACK);
- }
- adapterPreference = typeList.toArray(new Type[0]);
- }
}
- }
+ if (!typeList.isEmpty()) {
+ if (!typeList.contains(Type.JRE)) {
+ // Append FALLBACK as the last resort.
+ fallbackLocaleProviderAdapter = new FallbackLocaleProviderAdapter();
+ typeList.add(Type.FALLBACK);
+ }
+ } else {
+ // Default preference list
+ typeList.add(Type.JRE);
+ typeList.add(Type.SPI);
+ }
+
+ adapterPreference = Collections.unmodifiableList(typeList);
+ }
/**
* Returns the singleton instance for each adapter type
@@ -202,7 +205,7 @@
/**
* Returns the preference order of LocaleProviderAdapter.Type
*/
- public static Type[] getAdapterPreference() {
+ public static List<Type> getAdapterPreference() {
return adapterPreference;
}
diff --git a/src/share/demo/java2d/J2DBench/build.xml b/src/share/demo/java2d/J2DBench/build.xml
index a36aca8..c29611d 100644
--- a/src/share/demo/java2d/J2DBench/build.xml
+++ b/src/share/demo/java2d/J2DBench/build.xml
@@ -52,7 +52,7 @@
<javac debug="flase" source="1.5" target="1.5" srcdir="${src}" destdir="${build}"/>
</target>
- <target name="run" depends="dist"
+ <target name="run" depends="dist"
description="run J2DBench" >
<java jar="${dist}/J2DBench.jar"
fork="true"
@@ -60,7 +60,7 @@
</java>
</target>
- <target name="analyze" depends="dist"
+ <target name="analyze" depends="dist"
description="run J2DAnalyzer" >
<java jar="${dist}/J2DAnalyzer.jar"
fork="true"
@@ -80,6 +80,10 @@
<copy todir="${build}/j2dbench/tests/iio/images">
<fileset dir="${resources}/images" />
</copy>
+ <mkdir dir="${build}/j2dbench/tests/cmm/images"/>
+ <copy todir="${build}/j2dbench/tests/cmm/images">
+ <fileset dir="${resources}/cmm_images" />
+ </copy>
</target>
<target name="dist" depends="compile, resources"
@@ -88,14 +92,14 @@
<mkdir dir="${dist}"/>
<!-- Put everything in ${build} into the J2DBench.jar file -->
- <jar jarfile="${dist}/J2DBench.jar" basedir="${build}"
+ <jar jarfile="${dist}/J2DBench.jar" basedir="${build}"
excludes="j2dbench/report/**" >
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="j2dbench.J2DBench"/>
</manifest>
</jar>
- <jar jarfile="${dist}/J2DAnalyzer.jar" basedir="${build}"
+ <jar jarfile="${dist}/J2DAnalyzer.jar" basedir="${build}"
includes="j2dbench/report/**" >
<manifest>
<attribute name="Built-By" value="${user.name}"/>
diff --git a/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg b/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg
new file mode 100644
index 0000000..6d61c9f
--- /dev/null
+++ b/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg
Binary files differ
diff --git a/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg b/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg
new file mode 100644
index 0000000..6b4ef3f
--- /dev/null
+++ b/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg
Binary files differ
diff --git a/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg b/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg
new file mode 100644
index 0000000..41fb2ea
--- /dev/null
+++ b/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg
Binary files differ
diff --git a/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java b/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java
index e71b188..4916929 100644
--- a/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java
+++ b/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java
@@ -51,6 +51,7 @@
DataConversionTests.init();
ColorConvertOpTests.init();
+ EmbeddedProfileTests.init();
}
protected ColorConversionTests(Group parent, String nodeName, String description) {
diff --git a/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java b/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java
new file mode 100644
index 0000000..3af6313
--- /dev/null
+++ b/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This source code is provided to illustrate the usage of a given feature
+ * or technique and has been deliberately simplified. Additional steps
+ * required for a production-quality application, such as security checks,
+ * input validation and proper error handling, might not be present in
+ * this sample code.
+ */
+
+package j2dbench.tests.cmm;
+
+import j2dbench.Group;
+import j2dbench.Option;
+import j2dbench.Result;
+import j2dbench.TestEnvironment;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.net.URL;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+/* This benchmark verifies how changes in cmm library affects image decoding */
+public class EmbeddedProfileTests extends ColorConversionTests {
+
+ protected static Group grpRoot;
+ protected static Group grpOptionsRoot;
+
+ protected static Option inputImages;
+
+ public static void init() {
+ grpRoot = new Group(colorConvRoot, "embed", "Embedded Profile Tests");
+
+ grpOptionsRoot = new Group(grpRoot, "embedOptions", "Options");
+
+ inputImages = createImageList();
+
+ new ReadImageTest();
+ }
+
+ private static enum IccImageResource {
+ SMALL("images/img_icc_small.jpg", "512x512", "Small: 512x512"),
+ MEDIUM("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048"),
+ LARGE("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096");
+
+ private IccImageResource(String file, String name, String description) {
+ this.url = CMMTests.class.getResource(file);
+ this.abbrev = name;
+ this.description = description;
+ }
+
+ public final URL url;
+ public final String abbrev;
+ public final String description;
+ }
+
+ private static Option createImageList() {
+ IccImageResource[] images = IccImageResource.values();
+
+ int num = images.length;
+
+ String[] names = new String[num];
+ String[] abbrev = new String[num];
+ String[] descr = new String[num];
+
+ for (int i = 0; i < num; i++) {
+ names[i] = images[i].toString();
+ abbrev[i] = images[i].abbrev;
+ descr[i] = images[i].description;
+ }
+
+ Option list = new Option.ObjectList(grpOptionsRoot,
+ "Images", "Input Images",
+ names, images, abbrev, descr, 1);
+
+ return list;
+ }
+
+ public EmbeddedProfileTests(Group parent, String nodeName, String description) {
+ super(parent, nodeName, description);
+ addDependencies(grpOptionsRoot, true);
+ }
+
+ private static class Context {
+ URL input;
+
+ public Context(TestEnvironment env, Result res) {
+
+ IccImageResource icc_input = (IccImageResource)
+ env.getModifier(inputImages);
+
+ input = icc_input.url;
+ }
+ }
+
+ public Object initTest(TestEnvironment env, Result res) {
+ return new Context(env, res);
+ }
+
+ public void cleanupTest(TestEnvironment env, Object o) {
+ Context ctx = (Context)o;
+ ctx.input = null;
+ }
+
+ private static class ReadImageTest extends EmbeddedProfileTests {
+ public ReadImageTest() {
+ super(grpRoot, "embd_img_read", "ImageReader.read()");
+ }
+
+ public void runTest(Object octx, int numReps) {
+ final Context ctx = (Context)octx;
+ final URL url = ctx.input;
+ ImageInputStream iis = null;
+ ImageReader reader = null;
+
+ try {
+ iis = ImageIO.createImageInputStream(url.openStream());
+ reader = ImageIO.getImageReaders(iis).next();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to run the becnhmark", e);
+ }
+
+ do {
+ try {
+ reader.setInput(iis);
+ BufferedImage img = reader.read(0);
+ reader.reset();
+
+ iis = ImageIO.createImageInputStream(url.openStream());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } while (--numReps >= 0);
+ }
+ }
+}
diff --git a/src/share/demo/jvmti/hprof/hprof_init.c b/src/share/demo/jvmti/hprof/hprof_init.c
index 328c474..aa3c820 100644
--- a/src/share/demo/jvmti/hprof/hprof_init.c
+++ b/src/share/demo/jvmti/hprof/hprof_init.c
@@ -1899,11 +1899,17 @@
*/
getSystemProperty("sun.boot.library.path", &boot_path);
md_build_library_name(lname, FILENAME_MAX, boot_path, name);
+ if ( strlen(lname) == 0 ) {
+ HPROF_ERROR(JNI_TRUE, "Could not find library");
+ }
jvmtiDeallocate(boot_path);
handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
if ( handle == NULL ) {
/* This may be necessary on Windows. */
md_build_library_name(lname, FILENAME_MAX, "", name);
+ if ( strlen(lname) == 0 ) {
+ HPROF_ERROR(JNI_TRUE, "Could not find library");
+ }
handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
if ( handle == NULL ) {
HPROF_ERROR(JNI_TRUE, err_buf);
@@ -1968,6 +1974,9 @@
getSystemProperty("sun.boot.library.path", &boot_path);
/* Load in NPT library for character conversions */
md_build_library_name(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
+ if ( strlen(npt_lib) == 0 ) {
+ HPROF_ERROR(JNI_TRUE, "Could not find npt library");
+ }
jvmtiDeallocate(boot_path);
NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
if ( gdata->npt == NULL ) {
diff --git a/src/share/native/com/sun/java/util/jar/pack/constants.h b/src/share/native/com/sun/java/util/jar/pack/constants.h
index 040d8ed..2f125e0 100644
--- a/src/share/native/com/sun/java/util/jar/pack/constants.h
+++ b/src/share/native/com/sun/java/util/jar/pack/constants.h
@@ -505,5 +505,9 @@
bc_qldc = _xldc_op+7,
bc_qldc_w = _xldc_op+8,
_xldc_limit = _xldc_op+9,
+ _invoke_int_op = _xldc_limit,
+ _invokespecial_int = _invoke_int_op+0,
+ _invokestatic_int = _invoke_int_op+1,
+ _invoke_int_limit = _invoke_int_op+2,
_xxx_3_end
};
diff --git a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
index 083fbac..44ea898 100644
--- a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
+++ b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
@@ -2950,6 +2950,9 @@
case bc_putfield:
return &bc_fieldref;
+ case _invokespecial_int:
+ case _invokestatic_int:
+ return &bc_imethodref;
case bc_invokevirtual:
case bc_invokespecial:
case bc_invokestatic:
@@ -4189,6 +4192,12 @@
}
origBC = bc;
switch (bc) {
+ case _invokestatic_int:
+ origBC = bc_invokestatic;
+ break;
+ case _invokespecial_int:
+ origBC = bc_invokespecial;
+ break;
case bc_ildc:
case bc_cldc:
case bc_fldc:
diff --git a/src/share/native/common/check_code.c b/src/share/native/common/check_code.c
index 7ecf096..e117029 100644
--- a/src/share/native/common/check_code.c
+++ b/src/share/native/common/check_code.c
@@ -206,6 +206,8 @@
#define LDC_METHOD_HANDLE_MAJOR_VERSION 51
+#define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION 51
+
#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52
#define ALLOC_STACK_SIZE 16 /* big enough */
@@ -1146,11 +1148,14 @@
int *saved_operand;
int keys;
int k, delta;
- /* 4639449, 4647081: Padding bytes must be zero. */
- unsigned char* bptr = (unsigned char*) (code + offset + 1);
- for (; bptr < (unsigned char*)lpc; bptr++) {
- if (*bptr != 0) {
- CCerror(context, "Non zero padding bytes in switch");
+
+ if (context->major_version < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) {
+ /* 4639449, 4647081: Padding bytes must be zero. */
+ unsigned char* bptr = (unsigned char*) (code + offset + 1);
+ for (; bptr < (unsigned char*)lpc; bptr++) {
+ if (*bptr != 0) {
+ CCerror(context, "Non zero padding bytes in switch");
+ }
}
}
if (opcode == JVM_OPC_tableswitch) {
diff --git a/src/share/native/java/util/zip/Inflater.c b/src/share/native/java/util/zip/Inflater.c
index b67fff2..3778ff4 100644
--- a/src/share/native/java/util/zip/Inflater.c
+++ b/src/share/native/java/util/zip/Inflater.c
@@ -27,6 +27,7 @@
* Native method support for java.util.zip.Inflater
*/
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@@ -60,12 +61,13 @@
{
z_stream *strm = calloc(1, sizeof(z_stream));
- if (strm == 0) {
+ if (strm == NULL) {
JNU_ThrowOutOfMemoryError(env, 0);
return jlong_zero;
} else {
- char *msg;
- switch (inflateInit2(strm, nowrap ? -MAX_WBITS : MAX_WBITS)) {
+ const char *msg;
+ int ret = inflateInit2(strm, nowrap ? -MAX_WBITS : MAX_WBITS);
+ switch (ret) {
case Z_OK:
return ptr_to_jlong(strm);
case Z_MEM_ERROR:
@@ -73,7 +75,13 @@
JNU_ThrowOutOfMemoryError(env, 0);
return jlong_zero;
default:
- msg = strm->msg;
+ msg = ((strm->msg != NULL) ? strm->msg :
+ (ret == Z_VERSION_ERROR) ?
+ "zlib returned Z_VERSION_ERROR: "
+ "compile time and runtime zlib implementations differ" :
+ (ret == Z_STREAM_ERROR) ?
+ "inflateInit2 returned Z_STREAM_ERROR" :
+ "unknown error initializing zlib library");
free(strm);
JNU_ThrowInternalError(env, msg);
return jlong_zero;
diff --git a/src/share/native/sun/font/layout/LookupProcessor.cpp b/src/share/native/sun/font/layout/LookupProcessor.cpp
index 60727aa..88e9f25 100644
--- a/src/share/native/sun/font/layout/LookupProcessor.cpp
+++ b/src/share/native/sun/font/layout/LookupProcessor.cpp
@@ -125,6 +125,10 @@
}
const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
+ if (lookupTable == NULL) {
+ success = LE_INTERNAL_ERROR;
+ return 0;
+ }
le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
GlyphIterator tempIterator(*glyphIterator, lookupFlags);
le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
diff --git a/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/src/share/native/sun/java2d/cmm/lcms/LCMS.c
index 7da0370..1340c82 100644
--- a/src/share/native/sun/java2d/cmm/lcms/LCMS.c
+++ b/src/share/native/sun/java2d/cmm/lcms/LCMS.c
@@ -117,6 +117,7 @@
static jfieldID IL_nextRowOffset_fID;
static jfieldID IL_width_fID;
static jfieldID IL_height_fID;
+static jfieldID IL_imageAtOnce_fID;
static jfieldID PF_ID_fID;
JavaVM *javaVM;
@@ -237,7 +238,7 @@
* Method: loadProfile
* Signature: ([B)J
*/
-JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile
+JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative
(JNIEnv *env, jobject obj, jbyteArray data)
{
jbyte* dataArray;
@@ -284,7 +285,7 @@
* Method: freeProfile
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative
(JNIEnv *env, jobject obj, jlong id)
{
storeID_t sProf;
@@ -369,48 +370,22 @@
static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
-/*
- * Class: sun_java2d_cmm_lcms_LCMS
- * Method: getTagSize
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagSize
- (JNIEnv *env, jobject obj, jlong id, jint tagSig)
-{
- storeID_t sProf;
- TagSignature_t sig;
- jint result = -1;
-
- sProf.j = id;
- sig.j = tagSig;
-
- if (tagSig == SigHead) {
- result = sizeof(cmsICCHeader);
- } else {
- if (cmsIsTag(sProf.pf, sig.cms)) {
- result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
- } else {
- JNU_ThrowByName(env, "java/awt/color/CMMException",
- "ICC profile tag not found");
- }
- }
-
- return result;
-}
/*
* Class: sun_java2d_cmm_lcms_LCMS
* Method: getTagData
* Signature: (JI[B)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData
- (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
+JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative
+ (JNIEnv *env, jobject obj, jlong id, jint tagSig)
{
storeID_t sProf;
TagSignature_t sig;
cmsInt32Number tagSize;
- jbyte* dataArray;
+ jbyte* dataArray = NULL;
+ jbyteArray data = NULL;
+
jint bufSize;
sProf.j = id;
@@ -419,12 +394,14 @@
if (tagSig == SigHead) {
cmsBool status;
- bufSize =(*env)->GetArrayLength(env, data);
+ // allocate java array
+ bufSize = sizeof(cmsICCHeader);
+ data = (*env)->NewByteArray(env, bufSize);
- if (bufSize < sizeof(cmsICCHeader)) {
- JNU_ThrowByName(env, "java/awt/color/CMMException",
- "Insufficient buffer capacity");
- return;
+ if (data == NULL) {
+ JNU_ThrowByName(env, "java/awt/color/CMMException",
+ "Unable to allocate buffer");
+ return NULL;
}
dataArray = (*env)->GetByteArrayElements (env, data, 0);
@@ -432,7 +409,7 @@
if (dataArray == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Unable to get buffer");
- return;
+ return NULL;
}
status = _getHeaderInfo(sProf.pf, dataArray, bufSize);
@@ -442,9 +419,10 @@
if (!status) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC Profile header not found");
+ return NULL;
}
- return;
+ return data;
}
if (cmsIsTag(sProf.pf, sig.cms)) {
@@ -452,16 +430,15 @@
} else {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"ICC profile tag not found");
- return;
+ return NULL;
}
- // verify data buffer capacity
- bufSize = (*env)->GetArrayLength(env, data);
-
- if (tagSize < 0 || 0 > bufSize || tagSize > bufSize) {
+ // allocate java array
+ data = (*env)->NewByteArray(env, tagSize);
+ if (data == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
- "Insufficient buffer capacity.");
- return;
+ "Unable to allocate buffer");
+ return NULL;
}
dataArray = (*env)->GetByteArrayElements (env, data, 0);
@@ -469,7 +446,7 @@
if (dataArray == NULL) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Unable to get buffer");
- return;
+ return NULL;
}
bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize);
@@ -479,8 +456,9 @@
if (bufSize != tagSize) {
JNU_ThrowByName(env, "java/awt/color/CMMException",
"Can not get tag data.");
+ return NULL;
}
- return;
+ return data;
}
/*
@@ -488,7 +466,7 @@
* Method: setTagData
* Signature: (JI[B)V
*/
-JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData
+JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative
(JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data)
{
storeID_t sProf;
@@ -586,6 +564,7 @@
char* inputRow;
char* outputRow;
jobject srcData, dstData;
+ jboolean srcAtOnce = JNI_FALSE, dstAtOnce = JNI_FALSE;
srcOffset = (*env)->GetIntField (env, src, IL_offset_fID);
srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID);
@@ -594,6 +573,9 @@
width = (*env)->GetIntField (env, src, IL_width_fID);
height = (*env)->GetIntField (env, src, IL_height_fID);
+ srcAtOnce = (*env)->GetBooleanField(env, src, IL_imageAtOnce_fID);
+ dstAtOnce = (*env)->GetBooleanField(env, dst, IL_imageAtOnce_fID);
+
sTrans.j = (*env)->GetLongField (env, trans, Trans_ID_fID);
if (sTrans.xf == NULL) {
@@ -625,10 +607,14 @@
inputRow = (char*)inputBuffer + srcOffset;
outputRow = (char*)outputBuffer + dstOffset;
- for (i = 0; i < height; i++) {
- cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
- inputRow += srcNextRowOffset;
- outputRow += dstNextRowOffset;
+ if (srcAtOnce && dstAtOnce) {
+ cmsDoTransform(sTrans.xf, inputRow, outputRow, width * height);
+ } else {
+ for (i = 0; i < height; i++) {
+ cmsDoTransform(sTrans.xf, inputRow, outputRow, width);
+ inputRow += srcNextRowOffset;
+ outputRow += dstNextRowOffset;
+ }
}
releaseILData(env, inputBuffer, srcDType, srcData);
@@ -670,6 +656,7 @@
IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I");
IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I");
IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I");
+ IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z");
IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I");
PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
diff --git a/src/share/native/sun/java2d/loops/AnyByteBinary.h b/src/share/native/sun/java2d/loops/AnyByteBinary.h
index abe7f23..3b1fa03 100644
--- a/src/share/native/sun/java2d/loops/AnyByteBinary.h
+++ b/src/share/native/sun/java2d/loops/AnyByteBinary.h
@@ -153,7 +153,10 @@
jint PREFIX ## rgb;
#define InitByteBinaryAlphaLoadData(TYPE, PREFIX, pRasInfo) \
- PREFIX ## Lut = (pRasInfo)->lutBase
+ do { \
+ PREFIX ## Lut = (pRasInfo)->lutBase; \
+ PREFIX ## rgb = 0; \
+ } while (0)
#define LoadAlphaFromByteBinaryFor4ByteArgb(TYPE, pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/share/native/sun/java2d/loops/ByteIndexed.h b/src/share/native/sun/java2d/loops/ByteIndexed.h
index 3917c23..215cfc0 100644
--- a/src/share/native/sun/java2d/loops/ByteIndexed.h
+++ b/src/share/native/sun/java2d/loops/ByteIndexed.h
@@ -202,7 +202,10 @@
jint PREFIX ## rgb;
#define InitByteIndexedAlphaLoadData(PREFIX, pRasInfo) \
- PREFIX ## Lut = (pRasInfo)->lutBase
+ do { \
+ PREFIX ## Lut = (pRasInfo)->lutBase; \
+ PREFIX ## rgb = 0; \
+ } while (0)
#define LoadAlphaFromByteIndexedFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/share/native/sun/java2d/loops/IntArgb.h b/src/share/native/sun/java2d/loops/IntArgb.h
index aec6343..f4ec005 100644
--- a/src/share/native/sun/java2d/loops/IntArgb.h
+++ b/src/share/native/sun/java2d/loops/IntArgb.h
@@ -122,7 +122,8 @@
#define DeclareIntArgbAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitIntArgbAlphaLoadData(PREFIX, pRasInfo)
+#define InitIntArgbAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromIntArgbFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/share/native/sun/java2d/loops/IntArgbBm.h b/src/share/native/sun/java2d/loops/IntArgbBm.h
index 81d5518..675fba1 100644
--- a/src/share/native/sun/java2d/loops/IntArgbBm.h
+++ b/src/share/native/sun/java2d/loops/IntArgbBm.h
@@ -133,7 +133,8 @@
#define DeclareIntArgbBmAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitIntArgbBmAlphaLoadData(PREFIX, pRasInfo)
+#define InitIntArgbBmAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromIntArgbBmFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/share/native/sun/java2d/loops/IntArgbPre.h b/src/share/native/sun/java2d/loops/IntArgbPre.h
index 5ffb9da..c45013d 100644
--- a/src/share/native/sun/java2d/loops/IntArgbPre.h
+++ b/src/share/native/sun/java2d/loops/IntArgbPre.h
@@ -153,7 +153,8 @@
#define DeclareIntArgbPreAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitIntArgbPreAlphaLoadData(PREFIX, pRasInfo)
+#define InitIntArgbPreAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromIntArgbPreFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/share/native/sun/java2d/loops/TransformHelper.c b/src/share/native/sun/java2d/loops/TransformHelper.c
index 23bba35..7233455 100644
--- a/src/share/native/sun/java2d/loops/TransformHelper.c
+++ b/src/share/native/sun/java2d/loops/TransformHelper.c
@@ -353,6 +353,9 @@
pInterpFunc = pBicubicFunc;
maxlinepix = LINE_SIZE / 16;
break;
+ default:
+ // Should not happen, but just in case.
+ return;
}
srcInfo.bounds.x1 = sx1;
diff --git a/src/share/native/sun/java2d/loops/Ushort4444Argb.h b/src/share/native/sun/java2d/loops/Ushort4444Argb.h
index 348e03b..aa50d8b 100644
--- a/src/share/native/sun/java2d/loops/Ushort4444Argb.h
+++ b/src/share/native/sun/java2d/loops/Ushort4444Argb.h
@@ -120,7 +120,8 @@
#define DeclareUshort4444ArgbAlphaLoadData(PREFIX) \
jint PREFIX;
-#define InitUshort4444ArgbAlphaLoadData(PREFIX, pRasInfo)
+#define InitUshort4444ArgbAlphaLoadData(PREFIX, pRasInfo) \
+ PREFIX = 0
#define LoadAlphaFromUshort4444ArgbFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/share/native/sun/java2d/loops/UshortIndexed.h b/src/share/native/sun/java2d/loops/UshortIndexed.h
index 7786bda..6a4b5b1 100644
--- a/src/share/native/sun/java2d/loops/UshortIndexed.h
+++ b/src/share/native/sun/java2d/loops/UshortIndexed.h
@@ -170,7 +170,10 @@
jint PREFIX ## rgb;
#define InitUshortIndexedAlphaLoadData(PREFIX, pRasInfo) \
- PREFIX ## Lut = (pRasInfo)->lutBase
+ do { \
+ PREFIX ## Lut = (pRasInfo)->lutBase; \
+ PREFIX ## rgb = 0; \
+ } while (0)
#define LoadAlphaFromUshortIndexedFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \
do { \
diff --git a/src/solaris/back/linker_md.c b/src/solaris/back/linker_md.c
index a1cbcce..dbcfc04 100644
--- a/src/solaris/back/linker_md.c
+++ b/src/solaris/back/linker_md.c
@@ -60,6 +60,7 @@
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
@@ -69,13 +70,17 @@
if (p == pathname) {
continue;
}
- (void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (p - pathname),
+ (void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (int)(p - pathname),
pathname, fname);
if (access(buffer, F_OK) == 0) {
break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
diff --git a/src/solaris/classes/sun/awt/X11/XFramePeer.java b/src/solaris/classes/sun/awt/X11/XFramePeer.java
index fdefb10..0c540b1 100644
--- a/src/solaris/classes/sun/awt/X11/XFramePeer.java
+++ b/src/solaris/classes/sun/awt/X11/XFramePeer.java
@@ -641,4 +641,6 @@
public Rectangle getBoundsPrivate() {
return getBounds();
}
+
+ public void emulateActivation(boolean doActivate) {}
}
diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java
index 7c40e82..b4fb9c7 100644
--- a/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -419,6 +419,10 @@
return peer;
}
+ public FramePeer createLightweightFrame(LightweightFrame target) {
+ return null;
+ }
+
public FramePeer createFrame(Frame target) {
FramePeer peer = new XFramePeer(target);
targetCreatedPeer(target, peer);
diff --git a/src/solaris/demo/jvmti/hprof/hprof_md.c b/src/solaris/demo/jvmti/hprof/hprof_md.c
index 1df2271..2046363 100644
--- a/src/solaris/demo/jvmti/hprof/hprof_md.c
+++ b/src/solaris/demo/jvmti/hprof/hprof_md.c
@@ -385,6 +385,7 @@
// Loosely based on os_solaris.cpp
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ':');
if (p == NULL) {
@@ -395,12 +396,16 @@
continue;
}
(void)snprintf(buffer, buflen, "%.*s/lib%s" JNI_LIB_SUFFIX,
- (p - pathname), pathname, fname);
+ (int)(p - pathname), pathname, fname);
if (access(buffer, F_OK) == 0) {
- break;
+ break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
diff --git a/src/windows/back/linker_md.c b/src/windows/back/linker_md.c
index e3ca258..ad48d3d 100644
--- a/src/windows/back/linker_md.c
+++ b/src/windows/back/linker_md.c
@@ -44,6 +44,7 @@
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
@@ -54,16 +55,20 @@
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
- (void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s%s.dll", (int)(p - pathname),
pathname, fname);
} else {
- (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (int)(p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
diff --git a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java
index 3bc2c3b..ce02e04 100644
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java
+++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java
@@ -227,15 +227,15 @@
}
@SuppressWarnings("deprecation")
- public void synthesizeWindowActivation(final boolean doActivate) {
- if (!doActivate || EventQueue.isDispatchThread()) {
- ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(doActivate);
+ public void synthesizeWindowActivation(final boolean activate) {
+ if (!activate || EventQueue.isDispatchThread()) {
+ ((WFramePeer)getPeer()).emulateActivation(activate);
} else {
// To avoid focus concurrence b/w IE and EmbeddedFrame
// activation is postponed by means of posting it to EDT.
Runnable r = new Runnable() {
public void run() {
- ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
+ ((WFramePeer)getPeer()).emulateActivation(true);
}
};
WToolkit.postEvent(WToolkit.targetToAppContext(this),
diff --git a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java
index 3b6d298..ec551e3 100644
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java
+++ b/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java
@@ -65,8 +65,6 @@
public native Rectangle getBoundsPrivate();
- public native void synthesizeWmActivate(boolean doActivate);
-
@Override
public boolean isAccelCapable() {
// REMIND: Temp workaround for issues with using HW acceleration
diff --git a/src/windows/classes/sun/awt/windows/WFramePeer.java b/src/windows/classes/sun/awt/windows/WFramePeer.java
index 368b8f6..588b3ca 100644
--- a/src/windows/classes/sun/awt/windows/WFramePeer.java
+++ b/src/windows/classes/sun/awt/windows/WFramePeer.java
@@ -200,4 +200,11 @@
public Rectangle getBoundsPrivate() {
return getBounds();
}
+
+ // TODO: implement it in peers. WLightweightFramePeer may implement lw version.
+ public void emulateActivation(boolean activate) {
+ synthesizeWmActivate(activate);
+ }
+
+ private native void synthesizeWmActivate(boolean activate);
}
diff --git a/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java b/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java
new file mode 100644
index 0000000..c2c1604
--- /dev/null
+++ b/src/windows/classes/sun/awt/windows/WLightweightFramePeer.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package sun.awt.windows;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseEvent;
+
+import sun.awt.LightweightFrame;
+
+public class WLightweightFramePeer extends WFramePeer {
+
+ public WLightweightFramePeer(LightweightFrame target) {
+ super(target);
+ }
+
+ private LightweightFrame getLwTarget() {
+ return (LightweightFrame)target;
+ }
+
+ @Override
+ public Graphics getGraphics() {
+ return getLwTarget().getGraphics();
+ }
+
+ @Override
+ public void show() {
+ super.show();
+ postEvent(new ComponentEvent((Component)getTarget(), ComponentEvent.COMPONENT_SHOWN));
+ }
+
+ @Override
+ public void hide() {
+ super.hide();
+ postEvent(new ComponentEvent((Component)getTarget(), ComponentEvent.COMPONENT_HIDDEN));
+ }
+
+ @Override
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+ postEvent(new ComponentEvent((Component) getTarget(), ComponentEvent.COMPONENT_MOVED));
+ postEvent(new ComponentEvent((Component) getTarget(), ComponentEvent.COMPONENT_RESIZED));
+ }
+
+ @Override
+ public void handleEvent(java.awt.AWTEvent e) {
+ if (e.getID() == MouseEvent.MOUSE_PRESSED) {
+ emulateActivation(true);
+ }
+ super.handleEvent(e);
+ }
+
+ @Override
+ public void grab() {
+ getLwTarget().grabFocus();
+ }
+
+ @Override
+ public void ungrab() {
+ getLwTarget().ungrabFocus();
+ }
+}
diff --git a/src/windows/classes/sun/awt/windows/WToolkit.java b/src/windows/classes/sun/awt/windows/WToolkit.java
index afbdfa6..e87b0ad 100644
--- a/src/windows/classes/sun/awt/windows/WToolkit.java
+++ b/src/windows/classes/sun/awt/windows/WToolkit.java
@@ -37,6 +37,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.awt.AWTAutoShutdown;
+import sun.awt.LightweightFrame;
import sun.awt.SunToolkit;
import sun.awt.Win32GraphicsDevice;
import sun.awt.Win32GraphicsEnvironment;
@@ -398,6 +399,12 @@
return peer;
}
+ public FramePeer createLightweightFrame(LightweightFrame target) {
+ FramePeer peer = new WLightweightFramePeer(target);
+ targetCreatedPeer(target, peer);
+ return peer;
+ }
+
public CanvasPeer createCanvas(Canvas target) {
CanvasPeer peer = new WCanvasPeer(target);
targetCreatedPeer(target, peer);
diff --git a/src/windows/demo/jvmti/hprof/hprof_md.c b/src/windows/demo/jvmti/hprof/hprof_md.c
index e5cbeda..4bd4a40 100644
--- a/src/windows/demo/jvmti/hprof/hprof_md.c
+++ b/src/windows/demo/jvmti/hprof/hprof_md.c
@@ -372,6 +372,7 @@
// Loosley based on os_windows.cpp
char *pathname = (char *)pname;
+ *buffer = '\0';
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ';');
if (p == NULL) {
@@ -382,16 +383,20 @@
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
- (void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s%s.dll", (int)(p - pathname),
pathname, fname);
} else {
- (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
+ (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (int)(p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
- pathname = p + 1;
+ if (*p == '\0') {
+ pathname = p;
+ } else {
+ pathname = p + 1;
+ }
*buffer = '\0';
}
}
diff --git a/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c b/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
index d3de6e7..cdd969c 100644
--- a/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
+++ b/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
@@ -89,6 +89,7 @@
rv = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &opt, sizeof(opt));
if (rv == SOCKET_ERROR) {
NET_ThrowNew(env, WSAGetLastError(), "Socket creation failed");
+ closesocket(fd);
return -1;
}
diff --git a/src/windows/native/sun/windows/awt_Frame.cpp b/src/windows/native/sun/windows/awt_Frame.cpp
index da1df83..41c5624 100644
--- a/src/windows/native/sun/windows/awt_Frame.cpp
+++ b/src/windows/native/sun/windows/awt_Frame.cpp
@@ -105,6 +105,7 @@
m_parentWnd = NULL;
menuBar = NULL;
m_isEmbedded = FALSE;
+ m_isLightweight = FALSE;
m_ignoreWmSize = FALSE;
m_isMenuDropped = FALSE;
m_isInputMethodWindow = FALSE;
@@ -170,14 +171,13 @@
* area of the browser is a Java Frame for parenting purposes, but
* really a Windows child window
*/
+ BOOL isEmbeddedInstance = FALSE;
+ BOOL isEmbedded = FALSE;
cls = env->FindClass("sun/awt/EmbeddedFrame");
- if (cls == NULL) {
- return NULL;
+ if (cls) {
+ isEmbeddedInstance = env->IsInstanceOf(target, cls);
}
INT_PTR handle;
- jboolean isEmbeddedInstance = env->IsInstanceOf(target, cls);
- jboolean isEmbedded = FALSE;
-
if (isEmbeddedInstance) {
handle = static_cast<INT_PTR>(env->GetLongField(target, AwtFrame::handleID));
if (handle != 0) {
@@ -186,6 +186,13 @@
}
frame->m_isEmbedded = isEmbedded;
+ BOOL isLightweight = FALSE;
+ cls = env->FindClass("sun/awt/LightweightFrame");
+ if (cls) {
+ isLightweight = env->IsInstanceOf(target, cls);
+ }
+ frame->m_isLightweight = isLightweight;
+
if (isEmbedded) {
hwndParent = (HWND)handle;
RECT rect;
@@ -230,6 +237,23 @@
rect.bottom-rect.top);
frame->InitPeerGraphicsConfig(env, self);
AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
+ } else if (isLightweight) {
+ frame->m_isUndecorated = true;
+ frame->m_peerObject = env->NewGlobalRef(self);
+ frame->RegisterClass();
+
+ DWORD exStyle = 0;
+ DWORD style = WS_POPUP;
+
+ frame->CreateHWnd(env, L"",
+ style,
+ exStyle,
+ 0, 0, 0, 0,
+ 0,
+ NULL,
+ ::GetSysColor(COLOR_WINDOWTEXT),
+ ::GetSysColor(COLOR_WINDOWFRAME),
+ self);
} else {
jint state = env->CallIntMethod(self, AwtFrame::getExtendedStateMID);
DWORD exStyle;
@@ -345,16 +369,20 @@
case WM_SETFOCUS:
if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
- if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) {
- AwtSetActiveWindow();
+ if (!sm_suppressFocusAndActivation) {
+ if (IsLightweightFrame() || IsEmbeddedFrame()) {
+ AwtSetActiveWindow();
+ }
}
mr = mrConsume;
break;
case WM_KILLFOCUS:
if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
- if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) {
- AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL);
+ if (!sm_suppressFocusAndActivation) {
+ if (IsLightweightFrame() || IsEmbeddedFrame()) {
+ AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL);
+ }
} else if (sm_restoreFocusAndActivation) {
if (AwtComponent::GetFocusedWindow() != NULL) {
@@ -640,6 +668,10 @@
HWND hwnd = GetHWnd();
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ if (IsLightweightFrame()) {
+ return;
+ }
+
DTRACE_PRINTLN3("AwtFrame::Show:%s%s%s",
m_iconic ? " iconic" : "",
m_zoomed ? " zoomed" : "",
@@ -992,6 +1024,9 @@
// b) focus is requested to some of the frame's child.
m_actualFocusedWindow = NULL;
}
+ if (IsLightweightFrame()) {
+ return TRUE;
+ }
return AwtWindow::AwtSetActiveWindow(isMouseEventCause);
}
@@ -1873,7 +1908,7 @@
}
JNIEXPORT void JNICALL
-Java_sun_awt_windows_WEmbeddedFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate)
+Java_sun_awt_windows_WFramePeer_synthesizeWmActivate(JNIEnv *env, jobject self, jboolean doActivate)
{
TRY;
diff --git a/src/windows/native/sun/windows/awt_Frame.h b/src/windows/native/sun/windows/awt_Frame.h
index f6d692b..e151c17 100644
--- a/src/windows/native/sun/windows/awt_Frame.h
+++ b/src/windows/native/sun/windows/awt_Frame.h
@@ -72,6 +72,8 @@
/* Returns whether this frame is embedded in an external native frame. */
INLINE BOOL IsEmbeddedFrame() { return m_isEmbedded; }
+ /* Returns whether this frame is lightweight. */
+ INLINE virtual BOOL IsLightweightFrame() { return m_isLightweight; }
INLINE BOOL IsSimpleWindow() { return FALSE; }
@@ -169,6 +171,9 @@
/* The frame is an EmbeddedFrame. */
BOOL m_isEmbedded;
+ /* The frame is a LightweightFrame */
+ BOOL m_isLightweight;
+
/* used so that calls to ::MoveWindow in SetMenuBar don't propogate
because they are immediately followed by calls to Component.resize */
BOOL m_ignoreWmSize;
diff --git a/src/windows/native/sun/windows/awt_Window.h b/src/windows/native/sun/windows/awt_Window.h
index 8ad2b09..0ee2332 100644
--- a/src/windows/native/sun/windows/awt_Window.h
+++ b/src/windows/native/sun/windows/awt_Window.h
@@ -143,6 +143,7 @@
INLINE HICON GetHIcon() {return m_hIcon;};
INLINE HICON GetHIconSm() {return m_hIconSm;};
INLINE BOOL IsIconInherited() {return m_iconInherited;};
+ INLINE virtual BOOL IsLightweightFrame() {return FALSE;}
/* Post events to the EventQueue */
void SendComponentEvent(jint eventId);
@@ -193,8 +194,10 @@
// Execute on Toolkit only.
INLINE static LRESULT SynthesizeWmActivate(BOOL doActivate, HWND targetHWnd, HWND oppositeHWnd) {
+ AwtWindow *win = static_cast<AwtWindow*>(AwtComponent::GetComponent(targetHWnd));
if (doActivate &&
- (!::IsWindowVisible(targetHWnd) || ::IsIconic(::GetAncestor(targetHWnd, GA_ROOT))))
+ (!::IsWindowVisible(targetHWnd) || ::IsIconic(::GetAncestor(targetHWnd, GA_ROOT))) &&
+ (win == NULL || !win->IsLightweightFrame()))
{
// The activation is rejected if either:
// - The toplevel is not visible
diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index 7adc6d2..842ffbe 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -330,6 +330,23 @@
# 8007410
tools/launcher/FXLauncherTest.java linux-all
+# 8004172
+sun/tools/jstat/jstatGcCapacityOutput1.sh generic-all
+sun/tools/jstat/jstatGcCauseOutput1.sh generic-all
+sun/tools/jstat/jstatGcOldOutput1.sh generic-all
+sun/tools/jstat/jstatGcOutput1.sh generic-all
+sun/tools/jstat/jstatGcPermCapacityOutput1.sh generic-all
+sun/tools/jstat/jstatLineCounts1.sh generic-all
+sun/tools/jstat/jstatLineCounts2.sh generic-all
+sun/tools/jstat/jstatLineCounts3.sh generic-all
+sun/tools/jstat/jstatLineCounts4.sh generic-all
+sun/tools/jstat/jstatOptions1.sh generic-all
+sun/tools/jstat/jstatTimeStamp1.sh generic-all
+sun/tools/jstatd/jstatdExternalRegistry.sh generic-all
+sun/tools/jstatd/jstatdDefaults.sh generic-all
+sun/tools/jstatd/jstatdPort.sh generic-all
+sun/tools/jstatd/jstatdServerName.sh generic-all
+
############################################################################
# jdk_jdi
diff --git a/test/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.html b/test/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.html
new file mode 100644
index 0000000..7049e82
--- /dev/null
+++ b/test/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.html
@@ -0,0 +1,43 @@
+<html>
+<!--
+ 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 6243382 8006070
+ @summary Dragging of mouse outside of a List and Choice area don't work properly on XAWT
+ @author Dmitry.Cherepanov@SUN.COM area=awt.list
+ @run applet/manual=yesno MouseDraggedOutCauseScrollingTest.html
+ -->
+<head>
+<title> ManualYesNoTest </title>
+</head>
+<body>
+
+<h1>ManualYesNoTest<br>Bug ID: </h1>
+
+<p> See the dialog box (usually in upper left corner) for instructions</p>
+
+<APPLET CODE="MouseDraggedOutCauseScrollingTest.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
diff --git a/test/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.java b/test/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.java
new file mode 100644
index 0000000..8b509a1
--- /dev/null
+++ b/test/java/awt/List/MouseDraggedOutCauseScrollingTest/MouseDraggedOutCauseScrollingTest.java
@@ -0,0 +1,246 @@
+/*
+ * 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 6243382 8006070
+ @summary Dragging of mouse outside of a List and Choice area don't work properly on XAWT
+ @author Dmitry.Cherepanov@SUN.COM area=awt.list
+ @run applet/manual=yesno MouseDraggedOutCauseScrollingTest.html
+*/
+
+import java.applet.Applet;
+import java.awt.*;
+
+public class MouseDraggedOutCauseScrollingTest extends Applet
+{
+ Choice choice;
+ List singleList;
+ List multipleList;
+
+ public void init()
+ {
+ this.setLayout (new GridLayout (1, 3));
+
+ choice = new Choice();
+ singleList = new List(3, false);
+ multipleList = new List(3, true);
+
+ choice.add("Choice");
+ for (int i = 1; i < 100; i++){
+ choice.add(""+i);
+ }
+
+ singleList.add("Single list");
+ for (int i = 1; i < 100; i++)
+ singleList.add(""+i);
+
+ multipleList.add("Multiple list");
+ for (int i = 1; i < 100; i++)
+ multipleList.add(""+i);
+
+ this.add(choice);
+ this.add(singleList);
+ this.add(multipleList);
+
+ String toolkitName = Toolkit.getDefaultToolkit().getClass().getName();
+ if (!toolkitName.equals("sun.awt.X11.XToolkit")) {
+ String[] instructions =
+ {
+ "This test is not applicable to the current platform. Press PASS"
+ };
+ Sysout.createDialogWithInstructions( instructions );
+ } else {
+ String[] instructions =
+ {
+ "0) Please note, that this is only Motif/XAWT test. At first, make the applet active",
+ "1.1) Click on the choice",
+ "1.2) Press the left button of the mouse and keep on any item of the choice, for example 5",
+ "1.3) Drag mouse out of the area of the unfurled list, at the same time hold the X coordinate of the mouse position about the same",
+ "1.4) To make sure, that when the Y coordinate of the mouse position higher of the upper bound of the list then scrolling UP of the list and selected item changes on the upper. If not, the test failed",
+ "1.5) To make sure, that when the Y coordinate of the mouse position under of the lower bound of the list then scrolling DOWN of the list and selected item changes on the lower. If not, the test failed",
+ "-----------------------------------",
+ "2.1) Click on the single list",
+ "2.2) Press the left button of the mouse and keep on any item of the list, for example 5",
+ "2.3) Drag mouse out of the area of the unfurled list, at the same time hold the X coordinate of the mouse position about the same",
+ "2.4) To make sure, that when the Y coordinate of the mouse position higher of the upper bound of the list then scrolling UP of the list and selected item changes on the upper. If not, the test failed",
+ "2.5) To make sure, that when the Y coordinate of the mouse position under of the lower bound of the list then scrolling DOWN of the list and selected item changes on the lower. If not, the test failed",
+ "-----------------------------------",
+ "3.1) Click on the multiple list",
+ "3.2) Press the left button of the mouse and keep on any item of the list, for example 5",
+ "3.3) Drag mouse out of the area of the unfurled list, at the same time hold the X coordinate of the mouse position about the same",
+ "3.4) To make sure, that when the Y coordinate of the mouse position higher of the upper bound of the list then scrolling of the list NO OCCURED and selected item NO CHANGES on the upper. If not, the test failed",
+ "3.5) To make sure, that when the Y coordinate of the mouse position under of the lower bound of the list then scrolling of the list NO OCCURED and selected item NO CHANGES on the lower. If not, the test failed",
+ "4) Test passed."
+ };
+ Sysout.createDialogWithInstructions( instructions );
+ }
+
+ }//End init()
+
+ public void start ()
+ {
+ setSize (400,100);
+ setVisible(true);
+ validate();
+
+ }// start()
+
+}// class ManualYesNoTest
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+}// TestDialog class
diff --git a/test/java/awt/Modal/ModalDialogMultiscreenTest/ModalDialogMultiscreenTest.java b/test/java/awt/Modal/ModalDialogMultiscreenTest/ModalDialogMultiscreenTest.java
new file mode 100644
index 0000000..156bfe5
--- /dev/null
+++ b/test/java/awt/Modal/ModalDialogMultiscreenTest/ModalDialogMultiscreenTest.java
@@ -0,0 +1,441 @@
+/*
+ * 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 6430802 8008379
+ @summary WM should not hang after show()/close()
+ @author anthony.petrov@sun.com: area=awt.modal
+ @run main/manual ModalDialogMultiscreenTest
+*/
+
+
+/**
+ * ModalDialogMultiscreenTest.java
+ *
+ * summary: Tests whether a WM will hang on show()/close() a modal dialog in multiscreen mode
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+
+public class ModalDialogMultiscreenTest
+{
+
+ private static class ButtonActionListener implements ActionListener {
+ JFrame frame;
+ JDialog dialog;
+ public ButtonActionListener(JFrame frame, JDialog dialog) {
+ this.frame = frame;
+ this.dialog = dialog;
+ }
+ public void actionPerformed(ActionEvent e) {
+ dialog.setLocationRelativeTo(frame);
+ dialog.setVisible(true);
+ }
+ }
+ public static class TestDialog extends JDialog {
+ public TestDialog(Frame owner, String title, boolean modal, GraphicsConfiguration gc) {
+ super(owner, title, modal, gc);
+ setSize(200, 100);
+ JButton button = new JButton("Close");
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+ });
+ getContentPane().add(button);
+ }
+ }
+
+ private static void init()
+ {
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice[] gs = ge.getScreenDevices();
+
+ Sysout.createDialog( );
+
+ if (gs.length < 2) {
+ System.out.println("Not multi-head environment, test not valid!");
+ ModalDialogMultiscreenTest.pass( );
+ }
+
+ String[] instructions =
+ {
+ "The test should be run on a multi-head X (non-xinerama) systems.",
+ "Otherwise click the Pass button right now.",
+ "You will see an open Frame on each screen your system has.",
+ "The frame has an 'Open dialog' button.",
+ "Clicking the button opens a modal dialog with a Close button.",
+ "The test procedure:",
+ "1. Open a dialog and close it with appropriate buttons.",
+ "2. Switch to another screen ($ DISPLAY=X.Y xprop)",
+ "3. Repeat steps 1-2 several times (about 3*<number-of-screens>)",
+ "If the test doesn't cause the window manager to hang, it's passed."
+ };
+ Sysout.printInstructions( instructions );
+
+
+ for (int i = 0; i < gs.length; i++) {
+ JFrame frame = new JFrame("Frame "+i,gs[i].getDefaultConfiguration());
+ JButton button = new JButton("Open Dialog");
+ button.setMinimumSize(new Dimension(200, 100));
+ button.setPreferredSize(new Dimension(200, 100));
+ button.setSize(new Dimension(200, 100));
+ button.addActionListener(new ButtonActionListener(frame, new TestDialog(frame, "Dialog #"+i, true, gs[i].getDefaultConfiguration())));
+ frame.getContentPane().add(button);
+ frame.pack();
+ frame.setVisible(true);
+ }
+
+ }//End init()
+
+
+ //ap203012: NO MORE CHANGES BELOW THIS LINE
+
+
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class ModalDialogMultiscreenTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ModalDialogMultiscreenTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ModalDialogMultiscreenTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ModalDialogMultiscreenTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ ModalDialogMultiscreenTest.pass();
+ }
+ else
+ {
+ ModalDialogMultiscreenTest.fail();
+ }
+ }
+
+}// TestDialog class
diff --git a/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
index 9136e79..5b927f8 100644
--- a/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
+++ b/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -22,8 +22,8 @@
*/
/*
- @test %I% %E%
- @bug 6572263 6571808
+ @test
+ @bug 6572263 6571808 8005920
@summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
@author dmitry.cherepanov: area=awt.modal
@run main/manual Winkey
@@ -48,12 +48,14 @@
String[] instructions =
{
+ " 0. This test is for MS Windows only, if you use other OS, press \"pass\" button.",
" 1. there is a frame with a 'show modal' button, ",
" 2. press the button to show a modal dialog, ",
" 3. the modal dialog will be shown over the frame, ",
" 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
" ",
" 5.1. press combination Windows Key and M key to minimize all windows, ",
+ " note that the modal dialog and modal blocked windows are NOT minimized",
" 5.2. press combination Windows Key and D key to show desktop, ",
" 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
" 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
diff --git a/test/java/beans/Introspector/Test7192955.java b/test/java/beans/Introspector/Test7192955.java
index 13e874b..afce427 100644
--- a/test/java/beans/Introspector/Test7192955.java
+++ b/test/java/beans/Introspector/Test7192955.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -23,17 +23,20 @@
/*
* @test
- * @bug 7192955
+ * @bug 7192955 8000183
* @summary Tests that all properties are bound
* @author Sergey Malenkov
*/
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
import java.beans.PropertyChangeListener;
+import java.beans.PropertyDescriptor;
import java.util.List;
public class Test7192955 {
- public static void main(String[] args) {
+ public static void main(String[] args) throws IntrospectionException {
if (!BeanUtils.findPropertyDescriptor(MyBean.class, "test").isBound()) {
throw new Error("a simple property is not bound");
}
@@ -43,6 +46,12 @@
if (!BeanUtils.findPropertyDescriptor(MyBean.class, "readOnly").isBound()) {
throw new Error("a read-only property is not bound");
}
+ PropertyDescriptor[] pds = Introspector.getBeanInfo(MyBean.class, BaseBean.class).getPropertyDescriptors();
+ for (PropertyDescriptor pd : pds) {
+ if (pd.getName().equals("test") && pd.isBound()) {
+ throw new Error("a simple property is bound without superclass");
+ }
+ }
}
public static class BaseBean {
diff --git a/test/java/lang/invoke/lambda/LUtils.java b/test/java/lang/invoke/lambda/LUtils.java
new file mode 100644
index 0000000..a7b013e
--- /dev/null
+++ b/test/java/lang/invoke/lambda/LUtils.java
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/*
+ * support infrastructure to invoke a java class from the command line
+ */
+class LUtils {
+ static final sun.tools.jar.Main jarTool =
+ new sun.tools.jar.Main(System.out, System.err, "jar-tool");
+ static final com.sun.tools.javac.Main javac =
+ new com.sun.tools.javac.Main();
+ static final File cwd = new File(".").getAbsoluteFile();
+ static final String JAVAHOME = System.getProperty("java.home");
+ static final boolean isWindows =
+ System.getProperty("os.name", "unknown").startsWith("Windows");
+ //static final boolean isSDK = JAVAHOME.endsWith("jre");
+ static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin");
+ static final File JAVA_CMD = new File(JAVA_BIN_FILE,
+ isWindows ? "java.exe" : "java");
+
+ protected LUtils() {
+ }
+
+ public static void compile(String... args) {
+ if (javac.compile(args) != 0) {
+ throw new RuntimeException("compilation fails");
+ }
+ }
+
+ static void createFile(File outFile, List<String> content) {
+ try {
+ Files.write(outFile.getAbsoluteFile().toPath(), content,
+ Charset.defaultCharset());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ static File getClassFile(File javaFile) {
+ return javaFile.getName().endsWith(".java")
+ ? new File(javaFile.getName().replace(".java", ".class"))
+ : null;
+ }
+
+ static String getSimpleName(File inFile) {
+ String fname = inFile.getName();
+ return fname.substring(0, fname.indexOf("."));
+ }
+
+ static TestResult doExec(String... cmds) {
+ return doExec(null, null, cmds);
+ }
+
+ /*
+ * A method which executes a java cmd and returns the results in a container
+ */
+ static TestResult doExec(Map<String, String> envToSet,
+ java.util.Set<String> envToRemove, String... cmds) {
+ String cmdStr = "";
+ for (String x : cmds) {
+ cmdStr = cmdStr.concat(x + " ");
+ }
+ ProcessBuilder pb = new ProcessBuilder(cmds);
+ Map<String, String> env = pb.environment();
+ if (envToRemove != null) {
+ for (String key : envToRemove) {
+ env.remove(key);
+ }
+ }
+ if (envToSet != null) {
+ env.putAll(envToSet);
+ }
+ BufferedReader rdr = null;
+ try {
+ List<String> outputList = new ArrayList<>();
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String in = rdr.readLine();
+ while (in != null) {
+ outputList.add(in);
+ in = rdr.readLine();
+ }
+ p.waitFor();
+ p.destroy();
+
+ return new TestResult(cmdStr, p.exitValue(), outputList,
+ env, new Throwable("current stack of the test"));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ static class TestResult {
+ String cmd;
+ int exitValue;
+ List<String> testOutput;
+ Map<String, String> env;
+ Throwable t;
+
+ public TestResult(String str, int rv, List<String> oList,
+ Map<String, String> env, Throwable t) {
+ cmd = str;
+ exitValue = rv;
+ testOutput = oList;
+ this.env = env;
+ this.t = t;
+ }
+
+ void assertZero(String message) {
+ if (exitValue != 0) {
+ System.err.println(this);
+ throw new RuntimeException(message);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ PrintWriter status = new PrintWriter(sw);
+ status.println("Cmd: " + cmd);
+ status.println("Return code: " + exitValue);
+ status.println("Environment variable:");
+ for (String x : env.keySet()) {
+ status.println("\t" + x + "=" + env.get(x));
+ }
+ status.println("Output:");
+ for (String x : testOutput) {
+ status.println("\t" + x);
+ }
+ status.println("Exception:");
+ status.println(t.getMessage());
+ t.printStackTrace(status);
+
+ return sw.getBuffer().toString();
+ }
+ }
+}
diff --git a/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java b/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java
index 8c3d1c5..e9e5cbc 100644
--- a/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java
+++ b/test/java/lang/invoke/lambda/LambdaAccessControlDoPrivilegedTest.java
@@ -26,20 +26,12 @@
* @bug 8003881
* @summary tests DoPrivileged action (implemented as lambda expressions) by
* inserting them into the BootClassPath.
- * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java
+ * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java LUtils.java
* @run main/othervm LambdaAccessControlDoPrivilegedTest
*/
-import java.io.BufferedReader;
import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
public class LambdaAccessControlDoPrivilegedTest extends LUtils {
public static void main(String... args) {
@@ -87,140 +79,3 @@
jarFile.delete();
}
}
-
-/*
- * support infrastructure to invoke a java class from the command line
- */
-class LUtils {
- static final sun.tools.jar.Main jarTool =
- new sun.tools.jar.Main(System.out, System.err, "jar-tool");
- static final com.sun.tools.javac.Main javac =
- new com.sun.tools.javac.Main();
- static final File cwd = new File(".").getAbsoluteFile();
- static final String JAVAHOME = System.getProperty("java.home");
- static final boolean isWindows =
- System.getProperty("os.name", "unknown").startsWith("Windows");
- //static final boolean isSDK = JAVAHOME.endsWith("jre");
- static final File JAVA_BIN_FILE = new File(JAVAHOME, "bin");
- static final File JAVA_CMD = new File(JAVA_BIN_FILE,
- isWindows ? "java.exe" : "java");
-
- protected LUtils() {
- }
-
- public static void compile(String... args) {
- if (javac.compile(args) != 0) {
- throw new RuntimeException("compilation fails");
- }
- }
-
- static void createFile(File outFile, List<String> content) {
- try {
- Files.write(outFile.getAbsoluteFile().toPath(), content,
- Charset.defaultCharset());
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- static File getClassFile(File javaFile) {
- return javaFile.getName().endsWith(".java")
- ? new File(javaFile.getName().replace(".java", ".class"))
- : null;
- }
-
- static String getSimpleName(File inFile) {
- String fname = inFile.getName();
- return fname.substring(0, fname.indexOf("."));
- }
-
- static TestResult doExec(String... cmds) {
- return doExec(null, null, cmds);
- }
-
- /*
- * A method which executes a java cmd and returns the results in a container
- */
- static TestResult doExec(Map<String, String> envToSet,
- java.util.Set<String> envToRemove, String... cmds) {
- String cmdStr = "";
- for (String x : cmds) {
- cmdStr = cmdStr.concat(x + " ");
- }
- ProcessBuilder pb = new ProcessBuilder(cmds);
- Map<String, String> env = pb.environment();
- if (envToRemove != null) {
- for (String key : envToRemove) {
- env.remove(key);
- }
- }
- if (envToSet != null) {
- env.putAll(envToSet);
- }
- BufferedReader rdr = null;
- try {
- List<String> outputList = new ArrayList<>();
- pb.redirectErrorStream(true);
- Process p = pb.start();
- rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
- String in = rdr.readLine();
- while (in != null) {
- outputList.add(in);
- in = rdr.readLine();
- }
- p.waitFor();
- p.destroy();
-
- return new TestResult(cmdStr, p.exitValue(), outputList,
- env, new Throwable("current stack of the test"));
- } catch (Exception ex) {
- ex.printStackTrace();
- throw new RuntimeException(ex.getMessage());
- }
- }
-
- static class TestResult {
- String cmd;
- int exitValue;
- List<String> testOutput;
- Map<String, String> env;
- Throwable t;
-
- public TestResult(String str, int rv, List<String> oList,
- Map<String, String> env, Throwable t) {
- cmd = str;
- exitValue = rv;
- testOutput = oList;
- this.env = env;
- this.t = t;
- }
-
- void assertZero(String message) {
- if (exitValue != 0) {
- System.err.println(this);
- throw new RuntimeException(message);
- }
- }
-
- @Override
- public String toString() {
- StringWriter sw = new StringWriter();
- PrintWriter status = new PrintWriter(sw);
- status.println("Cmd: " + cmd);
- status.println("Return code: " + exitValue);
- status.println("Environment variable:");
- for (String x : env.keySet()) {
- status.println("\t" + x + "=" + env.get(x));
- }
- status.println("Output:");
- for (String x : testOutput) {
- status.println("\t" + x);
- }
- status.println("Exception:");
- status.println(t.getMessage());
- t.printStackTrace(status);
-
- return sw.getBuffer().toString();
- }
- }
-}
diff --git a/test/java/lang/invoke/lambda/LambdaAccessControlTest.java b/test/java/lang/invoke/lambda/LambdaAccessControlTest.java
index 361a4cf..6ca9fb0 100644
--- a/test/java/lang/invoke/lambda/LambdaAccessControlTest.java
+++ b/test/java/lang/invoke/lambda/LambdaAccessControlTest.java
@@ -25,7 +25,7 @@
* @test
* @bug 8003881
* @summary tests Lambda expression with a a security manager at top level
- * @compile -XDignore.symbol.file LambdaAccessControlTest.java
+ * @compile -XDignore.symbol.file LambdaAccessControlTest.java LUtils.java
*
* @run main/othervm LambdaAccessControlTest
*/
diff --git a/test/java/lang/reflect/OldenCompilingWithDefaults.java b/test/java/lang/reflect/OldenCompilingWithDefaults.java
new file mode 100644
index 0000000..c8609b3
--- /dev/null
+++ b/test/java/lang/reflect/OldenCompilingWithDefaults.java
@@ -0,0 +1,54 @@
+/*
+ * 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 8009267
+ * @summary Verify uses of isAnnotationPresent compile under older source versions
+ * @compile -source 1.5 -target 1.5 OldenCompilingWithDefaults.java
+ * @compile -source 1.6 -target 1.6 OldenCompilingWithDefaults.java
+ * @compile -source 1.7 -target 1.7 OldenCompilingWithDefaults.java
+ * @compile OldenCompilingWithDefaults.java
+ */
+
+import java.lang.reflect.*;
+
+public class OldenCompilingWithDefaults {
+ public OldenCompilingWithDefaults(){}
+ static Object f;
+
+ public static void main(String... args) throws Exception {
+ Class<OldenCompilingWithDefaults> clazz = OldenCompilingWithDefaults.class;
+ Package pkg = clazz.getPackage();
+ Constructor<OldenCompilingWithDefaults> ctor = clazz.getConstructor();
+ Method m = clazz.getMethod("main", String[].class);
+ Field f = clazz.getField("f");
+
+ if(clazz.isAnnotationPresent(SuppressWarnings.class) ||
+ pkg.isAnnotationPresent(SuppressWarnings.class) ||
+ ctor.isAnnotationPresent(SuppressWarnings.class) ||
+ m.isAnnotationPresent(SuppressWarnings.class) ||
+ f.isAnnotationPresent(SuppressWarnings.class))
+ System.out.println("An annotation is present.");
+ }
+}
diff --git a/test/java/net/Socket/HttpProxy.java b/test/java/net/Socket/HttpProxy.java
new file mode 100644
index 0000000..92f14d2
--- /dev/null
+++ b/test/java/net/Socket/HttpProxy.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2010, 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 6370908
+ * @summary Add support for HTTP_CONNECT proxy in Socket class
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import static java.lang.System.out;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import sun.net.www.MessageHeader;
+
+public class HttpProxy {
+ final String proxyHost;
+ final int proxyPort;
+ static final int SO_TIMEOUT = 15000;
+
+ public static void main(String[] args) throws Exception {
+ String host;
+ int port;
+ if (args.length == 0) {
+ // Start internal proxy
+ ConnectProxyTunnelServer proxy = new ConnectProxyTunnelServer();
+ proxy.start();
+ host = "localhost";
+ port = proxy.getLocalPort();
+ out.println("Running with internal proxy: " + host + ":" + port);
+ } else if (args.length == 2) {
+ host = args[0];
+ port = Integer.valueOf(args[1]);
+ out.println("Running against specified proxy server: " + host + ":" + port);
+ } else {
+ System.err.println("Usage: java HttpProxy [<proxy host> <proxy port>]");
+ return;
+ }
+
+ HttpProxy p = new HttpProxy(host, port);
+ p.test();
+ }
+
+ public HttpProxy(String proxyHost, int proxyPort) {
+ this.proxyHost = proxyHost;
+ this.proxyPort = proxyPort;
+ }
+
+ void test() throws Exception {
+ InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
+ Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
+
+ try (ServerSocket ss = new ServerSocket(0);
+ Socket sock = new Socket(httpProxy)) {
+ sock.setSoTimeout(SO_TIMEOUT);
+ sock.setTcpNoDelay(false);
+
+ InetSocketAddress externalAddress =
+ new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort());
+
+ out.println("Trying to connect to server socket on " + externalAddress);
+ sock.connect(externalAddress);
+ try (Socket externalSock = ss.accept()) {
+ // perform some simple checks
+ check(sock.isBound(), "Socket is not bound");
+ check(sock.isConnected(), "Socket is not connected");
+ check(!sock.isClosed(), "Socket should not be closed");
+ check(sock.getSoTimeout() == SO_TIMEOUT,
+ "Socket should have a previously set timeout");
+ check(sock.getTcpNoDelay() == false, "NODELAY should be false");
+
+ simpleDataExchange(sock, externalSock);
+ }
+ }
+ }
+
+ static void check(boolean condition, String message) {
+ if (!condition) out.println(message);
+ }
+
+ static Exception unexpected(Exception e) {
+ out.println("Unexcepted Exception: " + e);
+ e.printStackTrace();
+ return e;
+ }
+
+ // performs a simple exchange of data between the two sockets
+ // and throws an exception if there is any problem.
+ void simpleDataExchange(Socket s1, Socket s2) throws Exception {
+ try (final InputStream i1 = s1.getInputStream();
+ final InputStream i2 = s2.getInputStream();
+ final OutputStream o1 = s1.getOutputStream();
+ final OutputStream o2 = s2.getOutputStream()) {
+ startSimpleWriter("simpleWriter1", o1, 100);
+ startSimpleWriter("simpleWriter2", o2, 200);
+ simpleRead(i2, 100);
+ simpleRead(i1, 200);
+ }
+ }
+
+ void startSimpleWriter(String threadName, final OutputStream os, final int start) {
+ (new Thread(new Runnable() {
+ public void run() {
+ try { simpleWrite(os, start); }
+ catch (Exception e) {unexpected(e); }
+ }}, threadName)).start();
+ }
+
+ void simpleWrite(OutputStream os, int start) throws Exception {
+ byte b[] = new byte[2];
+ for (int i=start; i<start+100; i++) {
+ b[0] = (byte) (i / 256);
+ b[1] = (byte) (i % 256);
+ os.write(b);
+ }
+ }
+
+ void simpleRead(InputStream is, int start) throws Exception {
+ byte b[] = new byte [2];
+ for (int i=start; i<start+100; i++) {
+ int x = is.read(b);
+ if (x == 1)
+ x += is.read(b,1,1);
+ if (x!=2)
+ throw new Exception("read error");
+ int r = bytes(b[0], b[1]);
+ if (r != i)
+ throw new Exception("read " + r + " expected " +i);
+ }
+ }
+
+ int bytes(byte b1, byte b2) {
+ int i1 = (int)b1 & 0xFF;
+ int i2 = (int)b2 & 0xFF;
+ return i1 * 256 + i2;
+ }
+
+ static class ConnectProxyTunnelServer extends Thread {
+
+ private final ServerSocket ss;
+
+ public ConnectProxyTunnelServer() throws IOException {
+ ss = new ServerSocket(0);
+ }
+
+ @Override
+ public void run() {
+ try (Socket clientSocket = ss.accept()) {
+ processRequest(clientSocket);
+ } catch (Exception e) {
+ out.println("Proxy Failed: " + e);
+ e.printStackTrace();
+ } finally {
+ try { ss.close(); } catch (IOException x) { unexpected(x); }
+ }
+ }
+
+ /**
+ * Returns the port on which the proxy is accepting connections.
+ */
+ public int getLocalPort() {
+ return ss.getLocalPort();
+ }
+
+ /*
+ * Processes the CONNECT request
+ */
+ private void processRequest(Socket clientSocket) throws Exception {
+ MessageHeader mheader = new MessageHeader(clientSocket.getInputStream());
+ String statusLine = mheader.getValue(0);
+
+ if (!statusLine.startsWith("CONNECT")) {
+ out.println("proxy server: processes only "
+ + "CONNECT method requests, recieved: "
+ + statusLine);
+ return;
+ }
+
+ // retrieve the host and port info from the status-line
+ InetSocketAddress serverAddr = getConnectInfo(statusLine);
+
+ //open socket to the server
+ try (Socket serverSocket = new Socket(serverAddr.getAddress(),
+ serverAddr.getPort())) {
+ Forwarder clientFW = new Forwarder(clientSocket.getInputStream(),
+ serverSocket.getOutputStream());
+ Thread clientForwarderThread = new Thread(clientFW, "ClientForwarder");
+ clientForwarderThread.start();
+ send200(clientSocket);
+ Forwarder serverFW = new Forwarder(serverSocket.getInputStream(),
+ clientSocket.getOutputStream());
+ serverFW.run();
+ clientForwarderThread.join();
+ }
+ }
+
+ private void send200(Socket clientSocket) throws IOException {
+ OutputStream out = clientSocket.getOutputStream();
+ PrintWriter pout = new PrintWriter(out);
+
+ pout.println("HTTP/1.1 200 OK");
+ pout.println();
+ pout.flush();
+ }
+
+ /*
+ * This method retrieves the hostname and port of the tunnel destination
+ * from the request line.
+ * @param connectStr
+ * of the form: <i>CONNECT server-name:server-port HTTP/1.x</i>
+ */
+ static InetSocketAddress getConnectInfo(String connectStr)
+ throws Exception
+ {
+ try {
+ int starti = connectStr.indexOf(' ');
+ int endi = connectStr.lastIndexOf(' ');
+ String connectInfo = connectStr.substring(starti+1, endi).trim();
+ // retrieve server name and port
+ endi = connectInfo.indexOf(':');
+ String name = connectInfo.substring(0, endi);
+ int port = Integer.parseInt(connectInfo.substring(endi+1));
+ return new InetSocketAddress(name, port);
+ } catch (Exception e) {
+ out.println("Proxy recieved a request: " + connectStr);
+ throw unexpected(e);
+ }
+ }
+ }
+
+ /* Reads from the given InputStream and writes to the given OutputStream */
+ static class Forwarder implements Runnable
+ {
+ private final InputStream in;
+ private final OutputStream os;
+
+ Forwarder(InputStream in, OutputStream os) {
+ this.in = in;
+ this.os = os;
+ }
+
+ @Override
+ public void run() {
+ try {
+ byte[] ba = new byte[1024];
+ int count;
+ while ((count = in.read(ba)) != -1) {
+ os.write(ba, 0, count);
+ }
+ } catch (IOException e) {
+ unexpected(e);
+ }
+ }
+ }
+}
diff --git a/test/java/nio/file/Files/CopyAndMove.java b/test/java/nio/file/Files/CopyAndMove.java
index 48ecb0d..4853b0d 100644
--- a/test/java/nio/file/Files/CopyAndMove.java
+++ b/test/java/nio/file/Files/CopyAndMove.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333 6917021 7006126 6950237
+ * @bug 4313887 6838333 6917021 7006126 6950237 8006645
* @summary Unit test for java.nio.file.Files copy and move methods
* @library ..
* @build CopyAndMove PassThroughFileSystem
@@ -37,6 +37,7 @@
import java.nio.file.attribute.*;
import java.io.*;
import java.util.*;
+import java.util.concurrent.TimeUnit;
public class CopyAndMove {
static final Random rand = new Random();
@@ -94,8 +95,8 @@
// check last modified time if not a symbolic link
if (!attrs1.isSymbolicLink()) {
- long time1 = attrs1.lastModifiedTime().toMillis();
- long time2 = attrs2.lastModifiedTime().toMillis();
+ long time1 = attrs1.lastModifiedTime().to(TimeUnit.SECONDS);
+ long time2 = attrs2.lastModifiedTime().to(TimeUnit.SECONDS);
if (time1 != time2) {
System.err.format("File time for %s is %s\n", attrs1.fileKey(), attrs1.lastModifiedTime());
diff --git a/test/java/util/Collections/ReverseOrder.java b/test/java/util/Collections/ReverseOrder.java
index d4fed08..9831b57 100644
--- a/test/java/util/Collections/ReverseOrder.java
+++ b/test/java/util/Collections/ReverseOrder.java
@@ -23,23 +23,56 @@
/*
* @test
- * @bug 4593209
+ * @bug 4593209 8001667
* @summary Reverse comparator was subtly broken
* @author Josh bloch
*/
import java.util.*;
+import java.io.*;
public class ReverseOrder {
+ static byte[] serialBytes(Object o) {
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(o);
+ oos.flush();
+ oos.close();
+ return bos.toByteArray();
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> T serialClone(T o) {
+ try {
+ ObjectInputStream ois = new ObjectInputStream
+ (new ByteArrayInputStream(serialBytes(o)));
+ T clone = (T) ois.readObject();
+ return clone;
+ } catch (Throwable t) {
+ throw new Error(t);
+ }
+ }
+
public static void main(String[] args) throws Exception {
Foo[] a = { new Foo(2), new Foo(3), new Foo(1) };
List list = Arrays.asList(a);
- Collections.sort(list, Collections.reverseOrder());
+ Comparator cmp = Collections.reverseOrder();
+ Collections.sort(list, cmp);
Foo[] golden = { new Foo(3), new Foo(2), new Foo(1) };
List goldenList = Arrays.asList(golden);
if (!list.equals(goldenList))
throw new Exception(list.toString());
+
+ Comparator clone = serialClone(cmp);
+ List list2 = Arrays.asList(a);
+ Collections.sort(list2, clone);
+ if (!list2.equals(goldenList))
+ throw new Exception(list.toString());
}
}
diff --git a/test/java/util/ComparatorsTest.java b/test/java/util/ComparatorsTest.java
new file mode 100644
index 0000000..1640c2d
--- /dev/null
+++ b/test/java/util/ComparatorsTest.java
@@ -0,0 +1,353 @@
+/*
+ * 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 8001667
+ * @run testng ComparatorsTest
+ */
+
+import java.util.Comparator;
+import java.util.Comparators;
+import java.util.AbstractMap;
+import java.util.Map;
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.ToDoubleFunction;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertSame;
+
+/**
+ * Unit tests for helper methods in Comparators
+ */
+@Test(groups = "unit")
+public class ComparatorsTest {
+ private static class Thing {
+ public final int intField;
+ public final long longField;
+ public final double doubleField;
+ public final String stringField;
+
+ private Thing(int intField, long longField, double doubleField, String stringField) {
+ this.intField = intField;
+ this.longField = longField;
+ this.doubleField = doubleField;
+ this.stringField = stringField;
+ }
+
+ public int getIntField() {
+ return intField;
+ }
+
+ public long getLongField() {
+ return longField;
+ }
+
+ public double getDoubleField() {
+ return doubleField;
+ }
+
+ public String getStringField() {
+ return stringField;
+ }
+ }
+
+ private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+ private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };
+ private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };
+
+ private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {
+ for (int i=0; i<comparisons.length; i++) {
+ assertEquals(comparisons.length + 1, things.length);
+ assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));
+ assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));
+ }
+ }
+
+ public void testIntComparator() {
+ Thing[] things = new Thing[intValues.length];
+ for (int i=0; i<intValues.length; i++)
+ things[i] = new Thing(intValues[i], 0L, 0.0, null);
+ Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<ComparatorsTest.Thing>() {
+ @Override
+ public int applyAsInt(Thing thing) {
+ return thing.getIntField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testLongComparator() {
+ Thing[] things = new Thing[longValues.length];
+ for (int i=0; i<longValues.length; i++)
+ things[i] = new Thing(0, longValues[i], 0.0, null);
+ Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<ComparatorsTest.Thing>() {
+ @Override
+ public long applyAsLong(Thing thing) {
+ return thing.getLongField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testDoubleComparator() {
+ Thing[] things = new Thing[doubleValues.length];
+ for (int i=0; i<doubleValues.length; i++)
+ things[i] = new Thing(0, 0L, doubleValues[i], null);
+ Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<ComparatorsTest.Thing>() {
+ @Override
+ public double applyAsDouble(Thing thing) {
+ return thing.getDoubleField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testComparing() {
+ Thing[] things = new Thing[doubleValues.length];
+ for (int i=0; i<doubleValues.length; i++)
+ things[i] = new Thing(0, 0L, 0.0, stringValues[i]);
+ Comparator<Thing> comp = Comparators.comparing(new Function<Thing, String>() {
+ @Override
+ public String apply(Thing thing) {
+ return thing.getStringField();
+ }
+ });
+
+ assertComparisons(things, comp, comparisons);
+ }
+
+ public void testNaturalOrderComparator() {
+ Comparator<String> comp = Comparators.naturalOrder();
+
+ assertComparisons(stringValues, comp, comparisons);
+ }
+
+ public void testReverseComparator() {
+ Comparator<String> cmpr = Comparators.reverseOrder();
+ Comparator<String> cmp = cmpr.reverseOrder();
+
+ assertEquals(cmp.reverseOrder(), cmpr);
+ assertEquals(0, cmp.compare("a", "a"));
+ assertEquals(0, cmpr.compare("a", "a"));
+ assertTrue(cmp.compare("a", "b") < 0);
+ assertTrue(cmpr.compare("a", "b") > 0);
+ assertTrue(cmp.compare("b", "a") > 0);
+ assertTrue(cmpr.compare("b", "a") < 0);
+ }
+
+ public void testReverseComparator2() {
+ Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
+ Comparator<String> cmpr = cmp.reverseOrder();
+
+ assertEquals(cmpr.reverseOrder(), cmp);
+ assertEquals(0, cmp.compare("abc", "def"));
+ assertEquals(0, cmpr.compare("abc", "def"));
+ assertTrue(cmp.compare("abcd", "def") > 0);
+ assertTrue(cmpr.compare("abcd", "def") < 0);
+ assertTrue(cmp.compare("abc", "defg") < 0);
+ assertTrue(cmpr.compare("abc", "defg") > 0);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void testReverseComparatorNPE() {
+ Comparator<String> cmp = Comparators.reverseOrder(null);
+ }
+
+ public void testComposeComparator() {
+ // Longer string in front
+ Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
+ Comparator<String> second = Comparators.naturalOrder();
+ Comparator<String> composed = Comparators.compose(first, second);
+
+ assertTrue(composed.compare("abcdefg", "abcdef") < 0);
+ assertTrue(composed.compare("abcdef", "abcdefg") > 0);
+ assertTrue(composed.compare("abcdef", "abcdef") == 0);
+ assertTrue(composed.compare("abcdef", "ghijkl") < 0);
+ assertTrue(composed.compare("ghijkl", "abcdefg") > 0);
+ }
+
+ private <K, V> void assertPairComparison(K k1, V v1, K k2, V v2,
+ Comparator<Map.Entry<K, V>> ck,
+ Comparator<Map.Entry<K, V>> cv) {
+ final Map.Entry<K, V> p11 = new AbstractMap.SimpleImmutableEntry<>(k1, v1);
+ final Map.Entry<K, V> p12 = new AbstractMap.SimpleImmutableEntry<>(k1, v2);
+ final Map.Entry<K, V> p21 = new AbstractMap.SimpleImmutableEntry<>(k2, v1);
+ final Map.Entry<K, V> p22 = new AbstractMap.SimpleImmutableEntry<>(k2, v2);
+
+ assertTrue(ck.compare(p11, p11) == 0);
+ assertTrue(ck.compare(p12, p11) == 0);
+ assertTrue(ck.compare(p11, p12) == 0);
+ assertTrue(ck.compare(p12, p22) < 0);
+ assertTrue(ck.compare(p12, p21) < 0);
+ assertTrue(ck.compare(p21, p11) > 0);
+ assertTrue(ck.compare(p21, p12) > 0);
+
+ assertTrue(cv.compare(p11, p11) == 0);
+ assertTrue(cv.compare(p12, p11) > 0);
+ assertTrue(cv.compare(p11, p12) < 0);
+ assertTrue(cv.compare(p12, p22) == 0);
+ assertTrue(cv.compare(p12, p21) > 0);
+ assertTrue(cv.compare(p21, p11) == 0);
+ assertTrue(cv.compare(p21, p12) < 0);
+
+ Comparator<Map.Entry<K, V>> cmp = Comparators.compose(ck, cv);
+ assertTrue(cmp.compare(p11, p11) == 0);
+ assertTrue(cmp.compare(p12, p11) > 0);
+ assertTrue(cmp.compare(p11, p12) < 0);
+ assertTrue(cmp.compare(p12, p22) < 0);
+ assertTrue(cmp.compare(p12, p21) < 0);
+ assertTrue(cmp.compare(p21, p11) > 0);
+ assertTrue(cmp.compare(p21, p12) > 0);
+
+ cmp = Comparators.compose(cv, ck);
+ assertTrue(cmp.compare(p11, p11) == 0);
+ assertTrue(cmp.compare(p12, p11) > 0);
+ assertTrue(cmp.compare(p11, p12) < 0);
+ assertTrue(cmp.compare(p12, p22) < 0);
+ assertTrue(cmp.compare(p12, p21) > 0);
+ assertTrue(cmp.compare(p21, p11) > 0);
+ assertTrue(cmp.compare(p21, p12) < 0);
+ }
+
+ public void testKVComparatorable() {
+ assertPairComparison(1, "ABC", 2, "XYZ",
+ Comparators.<Integer, String>naturalOrderKeys(),
+ Comparators.<Integer, String>naturalOrderValues());
+ }
+
+ private static class People {
+ final String firstName;
+ final String lastName;
+ final int age;
+
+ People(String first, String last, int age) {
+ firstName = first;
+ lastName = last;
+ this.age = age;
+ }
+
+ String getFirstName() { return firstName; }
+ String getLastName() { return lastName; }
+ int getAge() { return age; }
+ long getAgeAsLong() { return (long) age; };
+ double getAgeAsDouble() { return (double) age; };
+ }
+
+ private final People people[] = {
+ new People("John", "Doe", 34),
+ new People("Mary", "Doe", 30),
+ new People("Maria", "Doe", 14),
+ new People("Jonah", "Doe", 10),
+ new People("John", "Cook", 54),
+ new People("Mary", "Cook", 50),
+ };
+
+ public void testKVComparators() {
+ // Comparator<People> cmp = Comparators.naturalOrder(); // Should fail to compiler as People is not comparable
+ // We can use simple comparator, but those have been tested above.
+ // Thus choose to do compose for some level of interation.
+ Comparator<People> cmp1 = Comparators.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
+ Comparator<People> cmp = Comparators.compose(cmp1, cmp2);
+
+ assertPairComparison(people[0], people[0], people[1], people[1],
+ Comparators.<People, People>byKey(cmp),
+ Comparators.<People, People>byValue(cmp));
+
+ }
+
+ private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {
+ assertTrue(cmp.compare(less, greater) < 0, "less");
+ assertTrue(cmp.compare(less, less) == 0, "equal");
+ assertTrue(cmp.compare(greater, less) > 0, "greater");
+ }
+
+ public void testComparatorDefaultMethods() {
+ Comparator<People> cmp = Comparators.comparing((Function<People, String>) People::getFirstName);
+ Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
+ // reverseOrder
+ assertComparison(cmp.reverseOrder(), people[1], people[0]);
+ // thenComparing(Comparator)
+ assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
+ assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
+ // thenComparing(Function)
+ assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
+ // thenComparing(ToIntFunction)
+ assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
+ // thenComparing(ToLongFunction)
+ assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
+ // thenComparing(ToDoubleFunction)
+ assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
+ assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
+ }
+
+ public void testGreaterOf() {
+ // lesser
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (Function<People, String>) People::getFirstName))
+ .apply(people[0], people[1]),
+ people[1]);
+ // euqal
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (Function<People, String>) People::getLastName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // greater
+ assertSame(Comparators.greaterOf(Comparators.comparing(
+ (ToIntFunction<People>) People::getAge))
+ .apply(people[0], people[1]),
+ people[0]);
+ }
+
+ public void testLesserOf() {
+ // lesser
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (Function<People, String>) People::getFirstName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // euqal
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (Function<People, String>) People::getLastName))
+ .apply(people[0], people[1]),
+ people[0]);
+ // greater
+ assertSame(Comparators.lesserOf(Comparators.comparing(
+ (ToIntFunction<People>) People::getAge))
+ .apply(people[0], people[1]),
+ people[1]);
+ }
+}
\ No newline at end of file
diff --git a/test/java/util/Locale/Bug8004240.java b/test/java/util/Locale/Bug8004240.java
new file mode 100644
index 0000000..84f291b
--- /dev/null
+++ b/test/java/util/Locale/Bug8004240.java
@@ -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 8004240
+ * @summary Verify that getAdapterPreference returns an unmodifiable list.
+ * @compile -XDignore.symbol.file Bug8004240.java
+ * @run main Bug8004240
+ */
+
+import java.util.List;
+import sun.util.locale.provider.LocaleProviderAdapter;
+
+public class Bug8004240 {
+
+ public static void main(String[] args) {
+ List<LocaleProviderAdapter.Type> types = LocaleProviderAdapter.getAdapterPreference();
+
+ try {
+ types.set(0, null);
+ } catch (UnsupportedOperationException e) {
+ // success
+ return;
+ }
+
+ throw new RuntimeException("LocaleProviderAdapter.getAdapterPrefence() returned a modifiable list.");
+ }
+}
diff --git a/test/java/util/Map/ToArray.java b/test/java/util/Map/ToArray.java
new file mode 100644
index 0000000..f7a8de7
--- /dev/null
+++ b/test/java/util/Map/ToArray.java
@@ -0,0 +1,187 @@
+/*
+ * 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 8008785
+ * @summary Ensure toArray() implementations return correct results.
+ * @author Mike Duigou
+ */
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+public class ToArray {
+
+ /**
+ * Number of elements per map.
+ */
+ private static final int TEST_SIZE = 5000;
+
+ private static void realMain(String[] args) throws Throwable {
+ Map<Integer, Long>[] maps = (Map<Integer, Long>[]) new Map[]{
+ new HashMap<>(),
+ new Hashtable<>(),
+ new IdentityHashMap<>(),
+ new LinkedHashMap<>(),
+ new TreeMap<>(),
+ new WeakHashMap<>(),
+ new ConcurrentHashMap<>(),
+ new ConcurrentSkipListMap<>()
+ };
+
+ // for each map type.
+ for (Map<Integer, Long> map : maps) {
+ try {
+ testMap(map);
+ } catch(Exception all) {
+ unexpected("Failed for " + map.getClass().getName(), all);
+ }
+ }
+ }
+
+ private static final Integer[] KEYS = new Integer[TEST_SIZE];
+
+ private static final Long[] VALUES = new Long[TEST_SIZE];
+
+ static {
+ for (int each = 0; each < TEST_SIZE; each++) {
+ KEYS[each] = Integer.valueOf(each);
+ VALUES[each] = Long.valueOf(each + TEST_SIZE);
+ }
+ }
+
+
+ private static void testMap(Map<Integer, Long> map) {
+ System.out.println("Testing " + map.getClass());
+ System.out.flush();
+
+ // Fill the map
+ for (int each = 0; each < TEST_SIZE; each++) {
+ map.put(KEYS[each], VALUES[each]);
+ }
+
+ // check the keys
+ Object[] keys = map.keySet().toArray();
+ Arrays.sort(keys);
+
+ for(int each = 0; each < TEST_SIZE; each++) {
+ check( "unexpected key", keys[each] == KEYS[each]);
+ }
+
+ // check the values
+ Object[] values = map.values().toArray();
+ Arrays.sort(values);
+
+ for(int each = 0; each < TEST_SIZE; each++) {
+ check( "unexpected value", values[each] == VALUES[each]);
+ }
+
+ // check the entries
+ Map.Entry<Integer,Long>[] entries = map.entrySet().toArray(new Map.Entry[TEST_SIZE]);
+ Arrays.sort( entries,new Comparator<Map.Entry<Integer,Long>>() {
+ public int compare(Map.Entry<Integer,Long> o1, Map.Entry<Integer,Long> o2) {
+ return o1.getKey().compareTo(o2.getKey());
+ }});
+
+ for(int each = 0; each < TEST_SIZE; each++) {
+ check( "unexpected entry", entries[each].getKey() == KEYS[each] && entries[each].getValue() == VALUES[each]);
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+
+ static void pass() {
+ passed++;
+ }
+
+ static void fail() {
+ failed++;
+ (new Error("Failure")).printStackTrace(System.err);
+ }
+
+ static void fail(String msg) {
+ failed++;
+ (new Error("Failure: " + msg)).printStackTrace(System.err);
+ }
+
+ static void abort() {
+ fail();
+ System.exit(1);
+ }
+
+ static void abort(String msg) {
+ fail(msg);
+ System.exit(1);
+ }
+
+ static void unexpected(String msg, Throwable t) {
+ System.err.println("Unexpected: " + msg);
+ unexpected(t);
+ }
+
+ static void unexpected(Throwable t) {
+ failed++;
+ t.printStackTrace(System.err);
+ }
+
+ static void check(boolean cond) {
+ if (cond) {
+ pass();
+ } else {
+ fail();
+ }
+ }
+
+ static void check(String desc, boolean cond) {
+ if (cond) {
+ pass();
+ } else {
+ fail(desc);
+ }
+ }
+
+ static void equal(Object x, Object y) {
+ if (Objects.equals(x, y)) {
+ pass();
+ } else {
+ fail(x + " not equal to " + y);
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ Thread.currentThread().setName(ToArray.class.getName());
+// Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+ try {
+ realMain(args);
+ } catch (Throwable t) {
+ unexpected(t);
+ }
+
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) {
+ throw new Error("Some tests failed");
+ }
+ }
+}
diff --git a/test/java/util/concurrent/forkjoin/ThreadLessCommon.java b/test/java/util/concurrent/forkjoin/ThreadLessCommon.java
new file mode 100644
index 0000000..1dd3b66
--- /dev/null
+++ b/test/java/util/concurrent/forkjoin/ThreadLessCommon.java
@@ -0,0 +1,135 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/*
+ * @test
+ * @bug 8008378
+ * @summary Basic checks for parallelism 0, and null returning factory
+ * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 ThreadLessCommon
+ * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.threadFactory=ThreadLessCommon$NullForkJoinWorkerThreadFactory ThreadLessCommon
+ * @author Chris Hegarty
+ */
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveTask;
+
+public class ThreadLessCommon {
+
+ static final int THRESHOLD = 1000;
+ static final boolean debug = true;
+
+ private static void realMain(String[] args) throws Throwable {
+ if (debug) {
+ String pp = System.getProperty(
+ "java.util.concurrent.ForkJoinPool.common.parallelism");
+ System.out.println(
+ "java.util.concurrent.ForkJoinPool.common.parallelism:" + pp);
+ String tf = System.getProperty(
+ "java.util.concurrent.ForkJoinPool.common.threadFactory");
+ System.out.println(
+ "java.util.concurrent.ForkJoinPool.common.threadFactory:" + tf);
+ }
+
+ long from = 0, to = 50000;
+ RecursiveTask<Long> task = new SumTask(from, to, Thread.currentThread());
+ long sum = task.invoke();
+ System.out.printf("%nSum: from [%d] to [%d] = [%d]%n", from, to, sum);
+
+ task.fork();
+ sum = task.join();
+ System.out.printf("%nSum: from [%d] to [%d] = [%d]%n", from, to, sum);
+
+ sum = ForkJoinPool.commonPool().invoke(task.fork());
+ System.out.printf("%nSum: from [%d] to [%d] = [%d]%n", from, to, sum);
+ }
+
+ static class SumTask extends RecursiveTask<Long> {
+ final Thread expectedThread;
+ final long from;
+ final long to;
+ SumTask(long from, long to, Thread thread) {
+ this.from = from; this.to = to; expectedThread = thread;
+ }
+
+ @Override
+ public Long compute() {
+ check(Thread.currentThread() == expectedThread,
+ "Expected " + expectedThread + ", got " + Thread.currentThread());
+ long range = to - from;
+ if (range < THRESHOLD) {
+ long acc = 0;
+ for (long i = from; i <= to; i++)
+ acc = acc + i;
+ return acc;
+ } else {
+ long half = from + range / 2;
+ SumTask t1 = new SumTask(from, half ,expectedThread);
+ SumTask t2 = new SumTask(half+1, to ,expectedThread);
+ if (half % 2 == 0) {
+ t1.fork();
+ return t2.compute() + t1.join();
+ } else {
+ invokeAll(t1, t2);
+ try { return t1.get() + t2.get(); }
+ catch (Exception x) { unexpected(x); return 0L;}
+ }
+ }
+ }
+ }
+
+ public static class NullForkJoinWorkerThreadFactory
+ implements ForkJoinWorkerThreadFactory
+ {
+ @Override
+ public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+ return null;
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; /*Thread.dumpStack();*/}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/test/java/util/concurrent/forkjoin/ThrowingRunnable.java b/test/java/util/concurrent/forkjoin/ThrowingRunnable.java
new file mode 100644
index 0000000..47e6f35
--- /dev/null
+++ b/test/java/util/concurrent/forkjoin/ThrowingRunnable.java
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/*
+ * @test
+ * @bug 8008378
+ * @run main/othervm -Djava.util.concurrent.ForkJoinPool.common.exceptionHandler=ThrowingRunnable
+ * ThrowingRunnable
+ * @summary FJP.execute(Runnable), uncaught exception should cause worker thread
+ * to die.
+ * @author Chris Hegarty
+ */
+
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.TimeUnit;
+
+public class ThrowingRunnable implements Runnable, UncaughtExceptionHandler {
+
+ static final Phaser phaser = new Phaser(2);
+
+ private static void realMain(String[] args) throws Throwable {
+ ThrowingRunnable r = new ThrowingRunnable();
+ ForkJoinPool.commonPool().execute(r);
+ phaser.awaitAdvanceInterruptibly(phaser.arrive(), 10, TimeUnit.SECONDS);
+ pass();
+ }
+
+ @Override
+ public void run() {
+ throw new RuntimeException("This is an exception.");
+ }
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+ pass();
+ phaser.arrive();
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; /*Thread.dumpStack();*/}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond, String msg) {if (cond) pass(); else fail(msg);}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/test/javax/swing/text/html/7189299/bug7189299.java b/test/javax/swing/text/html/7189299/bug7189299.java
new file mode 100644
index 0000000..70d2057
--- /dev/null
+++ b/test/javax/swing/text/html/7189299/bug7189299.java
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+/*
+ * Portions Copyright (c) 2013 IBM Corporation
+ */
+import java.awt.BorderLayout;
+import java.awt.Toolkit;
+
+import java.awt.event.ActionListener;
+import javax.swing.DefaultButtonModel;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+import javax.swing.text.html.HTMLEditorKit;
+import sun.awt.SunToolkit;
+
+
+/*
+ * @test
+ * @bug 8008289
+ * @summary Shared ButtonModel instance should deregister previous listeners.
+ * @author Frank Ding
+ */
+public class bug7189299 {
+
+ private static JEditorPane html;
+ private static JFrame frame;
+
+ private static void setup() {
+ /**
+ * Note the input type is not restricted to "submit". Types "image",
+ * "checkbox", "radio" have the same problem.
+ */
+ html = new JEditorPane("text/html",
+ "<html><body><form action=\"http://localhost.cgi\">"
+ + "<input type=submit name=submit value=\"submit\"/>"
+ + "</form></body></html>");
+ frame = new JFrame();
+ frame.setLayout(new BorderLayout());
+ frame.add(html, BorderLayout.CENTER);
+ frame.setSize(200, 100);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setVisible(true);
+ }
+
+ private static void doTest() {
+ /*
+ * Calling updateComponentTreeUI creates a new FormView instance with
+ * its own associated JButton instance. The same DefaultButtonModel
+ * instance is used for both FormView's.
+ *
+ * The action listeners associated with (the JButton for) the first
+ * FormView should be unregistered from this common DefaultButtonModel,
+ * such that only those for the new FormView remain.
+ */
+ SwingUtilities.updateComponentTreeUI(html);
+ }
+
+ private static void verifySingleDefaultButtonModelListener() {
+ HTMLEditorKit htmlEditorKit = (HTMLEditorKit) html.getEditorKit();
+ StyleContext.NamedStyle style = ((StyleContext.NamedStyle) htmlEditorKit
+ .getInputAttributes());
+ DefaultButtonModel model = ((DefaultButtonModel) style
+ .getAttribute(StyleConstants.ModelAttribute));
+ ActionListener[] listeners = model.getActionListeners();
+ int actionListenerNum = listeners.length;
+ if (actionListenerNum != 1) {
+ throw new RuntimeException(
+ "Expected single ActionListener object registered with "
+ + "DefaultButtonModel; found " + actionListenerNum
+ + " listeners registered.");
+ }
+
+ int changeListenerNum = model.getChangeListeners().length;
+ if (changeListenerNum != 1) {
+ throw new RuntimeException(
+ "Expected at most one ChangeListener object registered "
+ + "with DefaultButtonModel; found " + changeListenerNum
+ + " listeners registered.");
+ }
+ int itemListenerNum = model.getItemListeners().length;
+ if (itemListenerNum != 1) {
+ throw new RuntimeException(
+ "Expected at most one ItemListener object registered "
+ + "with DefaultButtonModel; found " + itemListenerNum
+ + " listeners registered.");
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ final SunToolkit toolkit = ((SunToolkit) Toolkit.getDefaultToolkit());
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ setup();
+ }
+ });
+ toolkit.realSync();
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ verifySingleDefaultButtonModelListener();
+ doTest();
+ verifySingleDefaultButtonModelListener();
+ } finally {
+ frame.dispose();
+ }
+ }
+ });
+ }
+}
diff --git a/test/sun/awt/datatransfer/SuplementaryCharactersTransferTest.java b/test/sun/awt/datatransfer/SuplementaryCharactersTransferTest.java
new file mode 100644
index 0000000..75f6349
--- /dev/null
+++ b/test/sun/awt/datatransfer/SuplementaryCharactersTransferTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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 6877495
+ @summary JTextField and JTextArea does not support supplementary characters
+ @author Alexander Scherbatiy
+ @run main SuplementaryCharactersTransferTest
+*/
+
+
+import java.io.*;
+import java.util.*;
+import java.awt.*;
+import java.awt.datatransfer.*;
+import sun.awt.datatransfer.*;
+import sun.awt.datatransfer.DataTransferer.ReencodingInputStream;
+
+public class SuplementaryCharactersTransferTest {
+
+ public static final long TEXT_FORMAT = 13;
+
+ public static void main(String[] args) throws Exception {
+
+ DataTransferer dataTransferer = new TestDataTransferer();
+ dataTransferer.registerTextFlavorProperties("UNICODE TEXT", "utf-16le", "\r\n", "2");
+ ByteTransferable transferable = new ByteTransferable();
+ ReencodingInputStream is = dataTransferer.new ReencodingInputStream(transferable.getByteInputStream(), TEXT_FORMAT,
+ DataTransferer.getTextCharset(transferable.getDataFlavor()), transferable);
+
+ byte[] bytes = transferable.getBytes();
+ byte[] result = new byte[bytes.length];
+
+ is.read(result);
+
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != result[i]) {
+ throw new RuntimeException("Characters are not equal!");
+ }
+ }
+
+ }
+
+ static class ByteTransferable implements Transferable, ClipboardOwner {
+
+ private final DataFlavor dataFlavor;
+
+ public ByteTransferable() throws Exception {
+ dataFlavor = DataFlavor.getTextPlainUnicodeFlavor();
+ }
+
+ public DataFlavor getDataFlavor() {
+ return dataFlavor;
+ }
+
+ public DataFlavor[] getTransferDataFlavors() {
+ return new DataFlavor[]{dataFlavor};
+ }
+
+ public boolean isDataFlavorSupported(DataFlavor flavor) {
+ return flavor.equals(dataFlavor);
+ }
+
+ public byte[] getBytes() {
+ return new byte[]{97, 0, 64, -40, 32, -36, 98, 0};
+ }
+
+ public InputStream getByteInputStream() {
+ return new ByteArrayInputStream(getBytes());
+ }
+
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException {
+ if (flavor.equals(dataFlavor)) {
+ return getByteInputStream();
+ } else {
+ throw new UnsupportedFlavorException(flavor);
+ }
+ }
+
+ public void lostOwnership(Clipboard clipboard, Transferable contents) {
+ }
+ }
+
+ static class TestDataTransferer extends DataTransferer {
+
+ @Override
+ public String getDefaultUnicodeEncoding() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isLocaleDependentTextFormat(long format) {
+ return false;
+ }
+
+ @Override
+ public boolean isFileFormat(long format) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean isImageFormat(long format) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ protected Long getFormatForNativeAsLong(String str) {
+ return TEXT_FORMAT;
+ }
+
+ @Override
+ protected String getNativeForFormat(long format) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ protected ByteArrayOutputStream convertFileListToBytes(
+ ArrayList<String> fileList) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ protected String[] dragQueryFile(byte[] bytes) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ protected Image platformImageBytesOrStreamToImage(InputStream str,
+ byte[] bytes, long format) throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ protected byte[] imageToPlatformBytes(Image image, long format)
+ throws IOException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public ToolkitThreadBlockedHandler getToolkitThreadBlockedHandler() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/sun/misc/Cleaner/ExitOnThrow.java b/test/sun/misc/Cleaner/ExitOnThrow.java
index 03ea83d..f4fd802 100644
--- a/test/sun/misc/Cleaner/ExitOnThrow.java
+++ b/test/sun/misc/Cleaner/ExitOnThrow.java
@@ -28,21 +28,17 @@
public class ExitOnThrow {
- private static volatile boolean ran = false;
-
public static void main(String[] args) throws Exception {
Cleaner.create(new Object(),
new Runnable() {
public void run() {
- ran = true;
throw new RuntimeException("Foo!");
}
});
- while (!ran) {
+ while (true) {
System.gc();
Thread.sleep(100);
}
- System.exit(0);
}
}
diff --git a/test/sun/misc/Cleaner/exitOnThrow.sh b/test/sun/misc/Cleaner/exitOnThrow.sh
index 7506ce4..4a22114 100644
--- a/test/sun/misc/Cleaner/exitOnThrow.sh
+++ b/test/sun/misc/Cleaner/exitOnThrow.sh
@@ -25,7 +25,7 @@
#
# @test
-# @bug 4954921
+# @bug 4954921 8009259
# @summary Ensure that if a cleaner throws an exception then the VM exits
#
# @build ExitOnThrow
diff --git a/test/sun/security/krb5/auto/Context.java b/test/sun/security/krb5/auto/Context.java
index aae14f4..738f2c3 100644
--- a/test/sun/security/krb5/auto/Context.java
+++ b/test/sun/security/krb5/auto/Context.java
@@ -297,6 +297,13 @@
}
/**
+ * Returns the cred inside, if there is one
+ */
+ public GSSCredential cred() {
+ return cred;
+ }
+
+ /**
* Disposes the GSSContext within
* @throws org.ietf.jgss.GSSException
*/
diff --git a/test/sun/security/krb5/auto/SpnegoLifeTime.java b/test/sun/security/krb5/auto/SpnegoLifeTime.java
new file mode 100644
index 0000000..906cfbe
--- /dev/null
+++ b/test/sun/security/krb5/auto/SpnegoLifeTime.java
@@ -0,0 +1,58 @@
+/*
+ * 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 8000653
+ * @summary SPNEGO tests fail at context.getDelegCred().getRemainingInitLifetime(mechOid)
+ * @compile -XDignore.symbol.file SpnegoLifeTime.java
+ * @run main/othervm SpnegoLifeTime
+ */
+
+import org.ietf.jgss.Oid;
+import org.ietf.jgss.GSSCredential;
+import sun.security.jgss.GSSUtil;
+
+public class SpnegoLifeTime {
+
+ public static void main(String[] args) throws Exception {
+
+ Oid oid = GSSUtil.GSS_SPNEGO_MECH_OID;
+ new OneKDC(null).writeJAASConf();
+
+ Context c, s;
+ c = Context.fromJAAS("client");
+ s = Context.fromJAAS("server");
+
+ c.startAsClient(OneKDC.SERVER, oid);
+ c.x().requestCredDeleg(true);
+ s.startAsServer(oid);
+
+ Context.handshake(c, s);
+
+ GSSCredential cred = s.delegated().cred();
+ cred.getRemainingInitLifetime(oid);
+ cred.getUsage(oid);
+ }
+}
+
diff --git a/test/sun/security/provider/PolicyFile/WildcardPrincipalName.java b/test/sun/security/provider/PolicyFile/WildcardPrincipalName.java
new file mode 100644
index 0000000..d81149d
--- /dev/null
+++ b/test/sun/security/provider/PolicyFile/WildcardPrincipalName.java
@@ -0,0 +1,94 @@
+/*
+ * 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 8008908
+ * @summary wildcard principal names are not processed correctly
+ * @run main/othervm/policy=wildcard.policy WildcardPrincipalName
+ */
+
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.util.HashSet;
+import java.util.PropertyPermission;
+import java.util.Set;
+import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
+
+public class WildcardPrincipalName {
+
+ public static void main(String[] args) throws Exception {
+
+ X500Principal duke = new X500Principal("CN=Duke");
+ PropertyPermission pp = new PropertyPermission("user.home", "read");
+ RunAsPrivilegedUserAction runAsPrivilegedUserAction
+ = new RunAsPrivilegedUserAction(duke,
+ new CheckPermissionAction(pp));
+ AccessController.doPrivileged(runAsPrivilegedUserAction);
+ System.out.println("test PASSED");
+ }
+
+ private static class RunAsPrivilegedUserAction
+ implements PrivilegedAction<Void> {
+ private final PrivilegedAction<Void> action;
+ private final Principal principal;
+
+ RunAsPrivilegedUserAction(Principal principal,
+ PrivilegedAction<Void> action) {
+ this.principal = principal;
+ this.action = action;
+ }
+
+ @Override public Void run() {
+ Set<Principal> principals = new HashSet<>();
+ Set<Object> publicCredentials = new HashSet<>();
+ Set<Object> privateCredentials = new HashSet<>();
+
+ principals.add(principal);
+ Subject subject = new Subject(true,
+ principals,
+ publicCredentials,
+ privateCredentials);
+
+ Subject.doAsPrivileged(subject, action, null);
+ return null;
+ }
+ }
+
+ private static class CheckPermissionAction
+ implements PrivilegedAction<Void> {
+ private final Permission permission;
+
+ CheckPermissionAction(Permission permission) {
+ this.permission = permission;
+ }
+
+ @Override public Void run() {
+ AccessController.checkPermission(permission);
+ return null;
+ }
+ }
+}
diff --git a/test/sun/security/provider/PolicyFile/wildcard.policy b/test/sun/security/provider/PolicyFile/wildcard.policy
new file mode 100644
index 0000000..55e942d
--- /dev/null
+++ b/test/sun/security/provider/PolicyFile/wildcard.policy
@@ -0,0 +1,7 @@
+grant principal javax.security.auth.x500.X500Principal * {
+ permission java.util.PropertyPermission "user.home", "read";
+};
+
+grant {
+ permission javax.security.auth.AuthPermission "doAsPrivileged";
+};
diff --git a/test/tools/pack200/AttributeTests.java b/test/tools/pack200/AttributeTests.java
index 6526737..c128918 100644
--- a/test/tools/pack200/AttributeTests.java
+++ b/test/tools/pack200/AttributeTests.java
@@ -67,17 +67,7 @@
File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT);
Utils.jar("cvf", testjarFile.getName(), javaClassName);
- // pack using native --repack
- File nativejarFile = new File(cwd, "out-n" + Utils.JAR_FILE_EXT);
- Utils.repack(testjarFile, nativejarFile, false,
- "--unknown-attribute=error");
- Utils.doCompareVerify(testjarFile, nativejarFile);
-
- // pack using java --repack
- File javajarFile = new File(cwd, "out-j" + Utils.JAR_FILE_EXT);
- Utils.repack(testjarFile, javajarFile, true,
- "--unknown-attribute=error");
- Utils.doCompareBitWise(nativejarFile, javajarFile);
+ Utils.testWithRepack(testjarFile, "--unknown-attribute=error");
}
/*
* this test checks to see if we get the expected strings for output
diff --git a/test/tools/pack200/InstructionTests.java b/test/tools/pack200/InstructionTests.java
index ce92c0e..7015ae9 100644
--- a/test/tools/pack200/InstructionTests.java
+++ b/test/tools/pack200/InstructionTests.java
@@ -26,11 +26,10 @@
import java.util.ArrayList;
import java.util.List;
import static java.nio.file.StandardOpenOption.*;
-import java.util.regex.Pattern;
/*
* @test
- * @bug 8003549
+ * @bug 8003549 8007297
* @summary tests class files instruction formats introduced in JSR-335
* @compile -XDignore.symbol.file Utils.java InstructionTests.java
* @run main InstructionTests
@@ -48,52 +47,34 @@
List<String> scratch = new ArrayList<>();
final String fname = "A";
String javaFileName = fname + Utils.JAVA_FILE_EXT;
- scratch.add("interface IntIterator {");
+ scratch.add("interface I {");
scratch.add(" default void forEach(){}");
scratch.add(" static void next() {}");
scratch.add("}");
- scratch.add("class A implements IntIterator {");
- scratch.add("public void forEach(Object o){");
- scratch.add("IntIterator.super.forEach();");
- scratch.add("IntIterator.next();");
- scratch.add("}");
+ scratch.add("class A implements I {");
+ scratch.add(" public void forEach(Object o){");
+ scratch.add(" I.super.forEach();");
+ scratch.add(" I.next();");
+ scratch.add(" }");
scratch.add("}");
File cwd = new File(".");
File javaFile = new File(cwd, javaFileName);
Files.write(javaFile.toPath(), scratch, Charset.defaultCharset(),
CREATE, TRUNCATE_EXISTING);
- // make sure we have -g so that we compare LVT and LNT entries
+ // -g to compare LVT and LNT entries
Utils.compiler("-g", javaFile.getName());
+ File propsFile = new File("pack.props");
+ scratch.clear();
+ scratch.add("com.sun.java.util.jar.pack.class.format.error=error");
+ scratch.add("pack.unknown.attribute=error");
+ Files.write(propsFile.toPath(), scratch, Charset.defaultCharset(),
+ CREATE, TRUNCATE_EXISTING);
// jar the file up
File testjarFile = new File(cwd, "test" + Utils.JAR_FILE_EXT);
Utils.jar("cvf", testjarFile.getName(), ".");
- // pack using --repack
- File outjarFile = new File(cwd, "out" + Utils.JAR_FILE_EXT);
- scratch.clear();
- scratch.add(Utils.getPack200Cmd());
- scratch.add("-J-ea");
- scratch.add("-J-esa");
- scratch.add("--repack");
- scratch.add(outjarFile.getName());
- scratch.add(testjarFile.getName());
- List<String> output = Utils.runExec(scratch);
- // TODO remove this when we get bc escapes working correctly
- // this test anyhow would fail at that time
- findString("WARNING: Passing.*" + fname + Utils.CLASS_FILE_EXT,
- output);
-
- Utils.doCompareVerify(testjarFile, outjarFile);
- }
-
- static boolean findString(String str, List<String> list) {
- Pattern p = Pattern.compile(str);
- for (String x : list) {
- if (p.matcher(x).matches())
- return true;
- }
- throw new RuntimeException("Error: " + str + " not found in output");
+ Utils.testWithRepack(testjarFile, "--config-file=" + propsFile.getName());
}
}
diff --git a/test/tools/pack200/Utils.java b/test/tools/pack200/Utils.java
index 07a6459..f3d1d46 100644
--- a/test/tools/pack200/Utils.java
+++ b/test/tools/pack200/Utils.java
@@ -314,6 +314,20 @@
throw new RuntimeException("jar command failed");
}
}
+
+ static void testWithRepack(File inFile, String... repackOpts) throws IOException {
+ File cwd = new File(".");
+ // pack using --repack in native mode
+ File nativejarFile = new File(cwd, "out-n" + Utils.JAR_FILE_EXT);
+ repack(inFile, nativejarFile, false, repackOpts);
+ doCompareVerify(inFile, nativejarFile);
+
+ // ensure bit compatibility between the unpacker variants
+ File javajarFile = new File(cwd, "out-j" + Utils.JAR_FILE_EXT);
+ repack(inFile, javajarFile, true, repackOpts);
+ doCompareBitWise(javajarFile, nativejarFile);
+ }
+
static List<String> repack(File inFile, File outFile,
boolean disableNative, String... extraOpts) {
List<String> cmdList = new ArrayList<>();