提交 efcb51a1 编写于 作者: L lana

Merge

...@@ -201,3 +201,5 @@ a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70 ...@@ -201,3 +201,5 @@ a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70
b2fc8e31cecc35b76188e821d4c5dc0e0b74ac24 jdk8-b77 b2fc8e31cecc35b76188e821d4c5dc0e0b74ac24 jdk8-b77
00b7535d743f83eda763c10b3c9ea19ba4b67f55 jdk8-b78 00b7535d743f83eda763c10b3c9ea19ba4b67f55 jdk8-b78
c933505d75c2a0a671f06d6dac5d2237a9228d2d jdk8-b79 c933505d75c2a0a671f06d6dac5d2237a9228d2d jdk8-b79
dfb40f066c6ce129822f0f5dc2ac89173808781a jdk8-b80
c0f8022eba536dcdc8aae659005b33f3982b9368 jdk8-b81
...@@ -74,24 +74,24 @@ ifeq ($(PLATFORM),macosx) ...@@ -74,24 +74,24 @@ ifeq ($(PLATFORM),macosx)
UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH) UTILS_DEVTOOL_PATH=$(DEVTOOLS_PATH)
endif endif
# Utilities ifndef CONFIGURE_BUILD
ifdef CROSS_COMPILE_ARCH # Utilities
ifdef CROSS_COMPILE_ARCH
AR = $(COMPILER_PATH)ar AR = $(COMPILER_PATH)ar
AS = $(COMPILER_PATH)as AS = $(COMPILER_PATH)as
LD = $(COMPILER_PATH)ld LD = $(COMPILER_PATH)ld
MCS = $(COMPILER_PATH)mcs MCS = $(COMPILER_PATH)mcs
NM = $(COMPILER_PATH)nm NM = $(COMPILER_PATH)nm
STRIP = $(COMPILER_PATH)strip STRIP = $(COMPILER_PATH)strip
endif else
ifeq ($(PLATFORM),solaris)
AR = $(UTILS_CCS_BIN_PATH)ar AR = $(UTILS_CCS_BIN_PATH)ar
AS = $(UTILS_CCS_BIN_PATH)as AS = $(UTILS_CCS_BIN_PATH)as
LD = $(UTILS_CCS_BIN_PATH)ld LD = $(UTILS_CCS_BIN_PATH)ld
MCS = $(UTILS_CCS_BIN_PATH)mcs MCS = $(UTILS_CCS_BIN_PATH)mcs
NM = $(UTILS_CCS_BIN_PATH)nm NM = $(UTILS_CCS_BIN_PATH)nm
STRIP = $(UTILS_CCS_BIN_PATH)strip STRIP = $(UTILS_CCS_BIN_PATH)strip
endif endif
endif # CONFIGURE_BUILD
ADB = $(UTILS_COMMAND_PATH)adb ADB = $(UTILS_COMMAND_PATH)adb
BASENAME = $(UTILS_COMMAND_PATH)basename BASENAME = $(UTILS_COMMAND_PATH)basename
......
...@@ -28,6 +28,9 @@ PACKAGE = sun.java2d.cmm.lcms ...@@ -28,6 +28,9 @@ PACKAGE = sun.java2d.cmm.lcms
LIBRARY = lcms LIBRARY = lcms
PRODUCT = sun PRODUCT = sun
# Use highest level of optimization on this library
OPTIMIZATION_LEVEL = HIGHEST
include $(BUILDDIR)/common/Defs.gmk include $(BUILDDIR)/common/Defs.gmk
# #
......
...@@ -27,13 +27,12 @@ ...@@ -27,13 +27,12 @@
SUNWprivate_1.1 { SUNWprivate_1.1 {
global: global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfile; Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfile; Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData; Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getTagSize; Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagData; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagData;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert; Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
Java_sun_java2d_cmm_lcms_LCMS_getProfileID; Java_sun_java2d_cmm_lcms_LCMS_getProfileID;
Java_sun_java2d_cmm_lcms_LCMS_initLCMS; Java_sun_java2d_cmm_lcms_LCMS_initLCMS;
......
...@@ -464,12 +464,13 @@ ifeq ($(OPENJDK_TARGET_OS),windows) ...@@ -464,12 +464,13 @@ ifeq ($(OPENJDK_TARGET_OS),windows)
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d
LIBAWT_CFLAGS+=-I$(DXSDK_INCLUDE_PATH)
else else
LIBAWT_DIRS+=\ LIBAWT_DIRS+=\
$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11
endif endif
LIBAWT_CFLAGS:=-D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \ LIBAWT_CFLAGS+=-D__MEDIALIB_OLD_NAMES -D__USE_J2D_NAMES \
$(X_CFLAGS) \ $(X_CFLAGS) \
$(foreach dir,$(LIBAWT_DIRS),-I$(dir)) $(foreach dir,$(LIBAWT_DIRS),-I$(dir))
...@@ -1218,7 +1219,7 @@ ifdef OPENJDK ...@@ -1218,7 +1219,7 @@ ifdef OPENJDK
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\ OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms,\ SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms,\
LANG:=C,\ LANG:=C,\
OPTIMIZATION:=LOW, \ OPTIMIZATION:=HIGHEST, \
CFLAGS:=$(filter-out -xc99=%none,$(CFLAGS_JDKLIB)) \ CFLAGS:=$(filter-out -xc99=%none,$(CFLAGS_JDKLIB)) \
$(SHARED_LIBRARY_FLAGS) \ $(SHARED_LIBRARY_FLAGS) \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d \ -I$(JDK_TOPDIR)/src/share/native/sun/java2d \
...@@ -1461,7 +1462,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows) ...@@ -1461,7 +1462,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
-I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \
-I$(JDK_TOPDIR)/src/share/native/sun/java2d \ -I$(JDK_TOPDIR)/src/share/native/sun/java2d \
-I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \
-I$(DXSDK_INCLUDE_PATH), \
LDFLAGS:=$(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \ LDFLAGS:=$(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \
advapi32.lib $(WIN_AWT_LIB),\ advapi32.lib $(WIN_AWT_LIB),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\
...@@ -2905,7 +2907,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS,\ ...@@ -2905,7 +2907,8 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS,\
OPTIMIZATION:=LOW, \ OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \ CFLAGS:=$(CFLAGS_JDKLIB) \
$(LIBJSOUND_CFLAGS) \ $(LIBJSOUND_CFLAGS) \
-DUSE_DAUDIO=TRUE, \ -DUSE_DAUDIO=TRUE \
-I$(DXSDK_INCLUDE_PATH), \
LDFLAGS:=$(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ LDFLAGS:=$(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN),\ $(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib,\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib,\
......
...@@ -264,6 +264,13 @@ $(foreach f,$(filter $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_ISADIR)/%,$(JDK_JD ...@@ -264,6 +264,13 @@ $(foreach f,$(filter $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_ISADIR)/%,$(JDK_JD
$(foreach f,$(filter $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_ISADIR)/%,$(JDKJRE_JDKOUT_LIB_LIST)),\ $(foreach f,$(filter $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_ISADIR)/%,$(JDKJRE_JDKOUT_LIB_LIST)),\
$(eval $(call AddFileToCopy,$(JDK_OUTPUTDIR),$(JDK_OVERLAY_IMAGE_DIR)/jre,$f,JDKJRE_OVERLAY_LIB_TARGETS))) $(eval $(call AddFileToCopy,$(JDK_OUTPUTDIR),$(JDK_OVERLAY_IMAGE_DIR)/jre,$f,JDKJRE_OVERLAY_LIB_TARGETS)))
ifneq ($(PROFILE),)
# Files in lib$(PROFILE) are excluded from the generic copying routines so
# we have to add them back in here
$(foreach f,$(CUSTOM_PROFILE_JARS),\
$(eval $(call AddFileToCopy,$(IMAGES_OUTPUTDIR)/lib$(PROFILE),$(JRE_IMAGE_DIR)/lib,$f,JRE_LIB_TARGETS)))
endif
# CTE plugin security change require new empty directory lib/applet # CTE plugin security change require new empty directory lib/applet
$(JRE_IMAGE_DIR)/lib/applet: $(JRE_IMAGE_DIR)/lib/applet:
$(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@) $(ECHO) $(LOG_INFO) Creating $(patsubst $(OUTPUT_ROOT)/%,%,$@)
...@@ -739,11 +746,6 @@ jdk-overlay-image: $(JDK_OVERLAY_BIN_TARGETS) $(JDKJRE_OVERLAY_BIN_TARGETS) \ ...@@ -739,11 +746,6 @@ jdk-overlay-image: $(JDK_OVERLAY_BIN_TARGETS) $(JDKJRE_OVERLAY_BIN_TARGETS) \
$(JDKJRE_OVERLAY_STRIP_LIST) $(JDK_OVERLAY_BIN_STRIP_LIST) $(JDKJRE_OVERLAY_STRIP_LIST) $(JDK_OVERLAY_BIN_STRIP_LIST)
ifneq ($(PROFILE),) ifneq ($(PROFILE),)
# Files in lib$(PROFILE) are excluded from the generic copying routines so
# we have to add them back in here
$(foreach f,$(CUSTOM_PROFILE_JARS),\
$(eval $(call AddFileToCopy,$(IMAGES_OUTPUTDIR)/lib$(PROFILE),$(JRE_IMAGE_DIR)/lib,$f,JRE_LIB_TARGETS)))
PROFILE_IMAGE_JARS := $(filter %.jar, $(JRE_LIB_TARGETS)) PROFILE_IMAGE_JARS := $(filter %.jar, $(JRE_LIB_TARGETS))
PROFILE_IMAGE_JARS_CHECKED := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_jars_checked PROFILE_IMAGE_JARS_CHECKED := $(IMAGES_OUTPUTDIR)/lib$(PROFILE)/_jars_checked
......
...@@ -27,13 +27,12 @@ ...@@ -27,13 +27,12 @@
SUNWprivate_1.1 { SUNWprivate_1.1 {
global: global:
Java_sun_java2d_cmm_lcms_LCMS_loadProfile; Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_freeProfile; Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative;
Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; Java_sun_java2d_cmm_lcms_LCMS_getProfileSize;
Java_sun_java2d_cmm_lcms_LCMS_getProfileData; Java_sun_java2d_cmm_lcms_LCMS_getProfileData;
Java_sun_java2d_cmm_lcms_LCMS_getTagSize; Java_sun_java2d_cmm_lcms_LCMS_getTagNative;
Java_sun_java2d_cmm_lcms_LCMS_getTagData; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative;
Java_sun_java2d_cmm_lcms_LCMS_setTagData;
Java_sun_java2d_cmm_lcms_LCMS_colorConvert; Java_sun_java2d_cmm_lcms_LCMS_colorConvert;
Java_sun_java2d_cmm_lcms_LCMS_getProfileID; Java_sun_java2d_cmm_lcms_LCMS_getProfileID;
Java_sun_java2d_cmm_lcms_LCMS_initLCMS; Java_sun_java2d_cmm_lcms_LCMS_initLCMS;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,7 +34,6 @@ import javax.swing.border.Border; ...@@ -34,7 +34,6 @@ import javax.swing.border.Border;
import javax.swing.event.*; import javax.swing.event.*;
import javax.swing.plaf.*; import javax.swing.plaf.*;
import javax.swing.plaf.basic.*; import javax.swing.plaf.basic.*;
import com.apple.laf.ClientPropertyApplicator;
import com.apple.laf.ClientPropertyApplicator.Property; import com.apple.laf.ClientPropertyApplicator.Property;
import apple.laf.JRSUIConstants.Size; import apple.laf.JRSUIConstants.Size;
...@@ -142,35 +141,46 @@ public class AquaComboBoxUI extends BasicComboBoxUI implements Sizeable { ...@@ -142,35 +141,46 @@ public class AquaComboBoxUI extends BasicComboBoxUI implements Sizeable {
return new AquaComboBoxEditor(); return new AquaComboBoxEditor();
} }
class AquaComboBoxEditor extends BasicComboBoxEditor implements UIResource, DocumentListener { final class AquaComboBoxEditor extends BasicComboBoxEditor
protected AquaComboBoxEditor() { implements UIResource, DocumentListener {
AquaComboBoxEditor() {
super(); super();
editor = new AquaCustomComboTextField(); editor = new AquaCustomComboTextField();
editor.addFocusListener(this); editor.addFocusListener(this);
editor.getDocument().addDocumentListener(this); editor.getDocument().addDocumentListener(this);
} }
@Override
public void focusGained(final FocusEvent e) { public void focusGained(final FocusEvent e) {
if (arrowButton != null) {
arrowButton.repaint(); arrowButton.repaint();
} }
}
@Override
public void focusLost(final FocusEvent e) { public void focusLost(final FocusEvent e) {
if (arrowButton != null) {
arrowButton.repaint(); arrowButton.repaint();
} }
}
@Override
public void changedUpdate(final DocumentEvent e) { public void changedUpdate(final DocumentEvent e) {
editorTextChanged(); editorTextChanged();
} }
@Override
public void insertUpdate(final DocumentEvent e) { public void insertUpdate(final DocumentEvent e) {
editorTextChanged(); editorTextChanged();
} }
@Override
public void removeUpdate(final DocumentEvent e) { public void removeUpdate(final DocumentEvent e) {
editorTextChanged(); editorTextChanged();
} }
protected void editorTextChanged() { private void editorTextChanged() {
if (!popup.isVisible()) return; if (!popup.isVisible()) return;
final Object text = editor.getText(); final Object text = editor.getText();
......
...@@ -53,7 +53,7 @@ public abstract class CGraphicsConfig extends GraphicsConfiguration ...@@ -53,7 +53,7 @@ public abstract class CGraphicsConfig extends GraphicsConfiguration
@Override @Override
public Rectangle getBounds() { public Rectangle getBounds() {
final Rectangle2D nativeBounds = nativeGetBounds(device.getCoreGraphicsScreen()); final Rectangle2D nativeBounds = nativeGetBounds(device.getCGDisplayID());
return nativeBounds.getBounds(); // does integer rounding return nativeBounds.getBounds(); // does integer rounding
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,11 +25,12 @@ ...@@ -25,11 +25,12 @@
package sun.awt; package sun.awt;
import java.awt.AWTPermission;
import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.Insets;
import java.awt.Window; import java.awt.Window;
import java.awt.AWTPermission;
import java.awt.DisplayMode;
import java.util.Objects; import java.util.Objects;
import sun.java2d.opengl.CGLGraphicsConfig; import sun.java2d.opengl.CGLGraphicsConfig;
...@@ -58,9 +59,12 @@ public final class CGraphicsDevice extends GraphicsDevice { ...@@ -58,9 +59,12 @@ public final class CGraphicsDevice extends GraphicsDevice {
} }
/** /**
* Returns CGDirectDisplayID, which is the same id as @"NSScreenNumber" in
* NSScreen.
*
* @return CoreGraphics display id. * @return CoreGraphics display id.
*/ */
public int getCoreGraphicsScreen() { public int getCGDisplayID() {
return displayID; return displayID;
} }
...@@ -107,8 +111,9 @@ public final class CGraphicsDevice extends GraphicsDevice { ...@@ -107,8 +111,9 @@ public final class CGraphicsDevice extends GraphicsDevice {
return nativeGetYResolution(displayID); return nativeGetYResolution(displayID);
} }
private static native double nativeGetXResolution(int displayID); public Insets getScreenInsets() {
private static native double nativeGetYResolution(int displayID); return nativeGetScreenInsets(displayID);
}
/** /**
* Enters full-screen mode, or returns to windowed mode. * Enters full-screen mode, or returns to windowed mode.
...@@ -214,9 +219,15 @@ public final class CGraphicsDevice extends GraphicsDevice { ...@@ -214,9 +219,15 @@ public final class CGraphicsDevice extends GraphicsDevice {
return nativeGetDisplayModes(displayID); 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 static native DisplayMode nativeGetDisplayMode(int displayID);
private static native DisplayMode[] nativeGetDisplayModes(int displayID);
private native DisplayMode nativeGetDisplayMode(int displayID); private static native double nativeGetXResolution(int displayID);
private static native double nativeGetYResolution(int displayID);
private native DisplayMode[] nativeGetDisplayModes(int displayID); private static native Insets nativeGetScreenInsets(int displayID);
} }
...@@ -500,7 +500,10 @@ public class CStrike extends FontStrike { ...@@ -500,7 +500,10 @@ public class CStrike extends FontStrike {
final Iterator<Long> i = generalCache.values().iterator(); final Iterator<Long> i = generalCache.values().iterator();
while (i.hasNext()) { while (i.hasNext()) {
final long longValue = i.next().longValue(); 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 @@ public class CStrike extends FontStrike { ...@@ -512,7 +515,10 @@ public class CStrike extends FontStrike {
private static void disposeLongArray(final long[] longArray) { private static void disposeLongArray(final long[] longArray) {
for (int i = 0; i < longArray.length; i++) { for (int i = 0; i < longArray.length; i++) {
final long ptr = longArray[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
}
} }
} }
......
...@@ -85,4 +85,6 @@ class CStrikeDisposer extends FontStrikeDisposer { ...@@ -85,4 +85,6 @@ class CStrikeDisposer extends FontStrikeDisposer {
} }
private native void freeNativeScalerContext(long pContext); private native void freeNativeScalerContext(long pContext);
protected static native void removeGlyphInfoFromCache(long glyphInfo);
} }
...@@ -80,10 +80,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig ...@@ -80,10 +80,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
private ContextCapabilities oglCaps; private ContextCapabilities oglCaps;
private OGLContext context; private OGLContext context;
private final Object disposerReferent = new Object(); private final Object disposerReferent = new Object();
public static native int getDefaultPixFmt(int screennum);
private static native boolean initCGL(); 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); int swapInterval);
private static native int getOGLCapabilities(long configInfo); private static native int getOGLCapabilities(long configInfo);
...@@ -137,15 +135,16 @@ public final class CGLGraphicsConfig extends CGraphicsConfig ...@@ -137,15 +135,16 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
// Java-level context and flush the queue... // Java-level context and flush the queue...
OGLContext.invalidateCurrentContext(); OGLContext.invalidateCurrentContext();
cfginfo = getCGLConfigInfo(device.getCoreGraphicsScreen(), pixfmt, cfginfo = getCGLConfigInfo(device.getCGDisplayID(), pixfmt,
kOpenGLSwapInterval); kOpenGLSwapInterval);
if (cfginfo != 0L) {
OGLContext.setScratchSurface(cfginfo); OGLContext.setScratchSurface(cfginfo);
rq.flushAndInvokeNow(new Runnable() { rq.flushAndInvokeNow(new Runnable() {
public void run() { public void run() {
ids[0] = OGLContext.getOGLIdString(); ids[0] = OGLContext.getOGLIdString();
} }
}); });
}
} finally { } finally {
rq.unlock(); rq.unlock();
} }
...@@ -253,8 +252,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig ...@@ -253,8 +252,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
@Override @Override
public String toString() { public String toString() {
int screen = getDevice().getCoreGraphicsScreen(); int displayID = getDevice().getCGDisplayID();
return ("CGLGraphicsConfig[dev="+screen+",pixfmt="+pixfmt+"]"); return ("CGLGraphicsConfig[dev="+displayID+",pixfmt="+pixfmt+"]");
} }
@Override @Override
...@@ -413,8 +412,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig ...@@ -413,8 +412,8 @@ public final class CGLGraphicsConfig extends CGraphicsConfig
@Override @Override
public void addDeviceEventListener(AccelDeviceEventListener l) { public void addDeviceEventListener(AccelDeviceEventListener l) {
int screen = getDevice().getCoreGraphicsScreen(); int displayID = getDevice().getCGDisplayID();
AccelDeviceEventNotifier.addListener(l, screen); AccelDeviceEventNotifier.addListener(l, displayID);
} }
@Override @Override
......
...@@ -439,7 +439,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -439,7 +439,7 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
@Override @Override
public final Graphics getGraphics() { public Graphics getGraphics() {
final Graphics g = getOnscreenGraphics(); final Graphics g = getOnscreenGraphics();
if (g != null) { if (g != null) {
synchronized (getPeerTreeLock()){ synchronized (getPeerTreeLock()){
...@@ -1227,10 +1227,10 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -1227,10 +1227,10 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
protected void sendEventToDelegate(final AWTEvent e) { protected void sendEventToDelegate(final AWTEvent e) {
synchronized (getDelegateLock()) {
if (getDelegate() == null || !isShowing() || !isEnabled()) { if (getDelegate() == null || !isShowing() || !isEnabled()) {
return; return;
} }
synchronized (getDelegateLock()) {
AWTEvent delegateEvent = createDelegateEvent(e); AWTEvent delegateEvent = createDelegateEvent(e);
if (delegateEvent != null) { if (delegateEvent != null) {
AWTAccessor.getComponentAccessor() AWTAccessor.getComponentAccessor()
...@@ -1244,7 +1244,12 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent> ...@@ -1244,7 +1244,12 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
} }
} }
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; AWTEvent delegateEvent = null;
if (e instanceof MouseWheelEvent) { if (e instanceof MouseWheelEvent) {
MouseWheelEvent me = (MouseWheelEvent) e; MouseWheelEvent me = (MouseWheelEvent) e;
......
/*
* 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();
}
}
...@@ -218,6 +218,23 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { ...@@ -218,6 +218,23 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
return peer; 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 @Override
public WindowPeer createWindow(Window target) { public WindowPeer createWindow(Window target) {
PlatformComponent platformComponent = createPlatformComponent(); PlatformComponent platformComponent = createPlatformComponent();
...@@ -502,6 +519,8 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { ...@@ -502,6 +519,8 @@ public abstract class LWToolkit extends SunToolkit implements Runnable {
protected abstract PlatformComponent createPlatformComponent(); protected abstract PlatformComponent createPlatformComponent();
protected abstract PlatformComponent createLwPlatformComponent();
protected abstract FileDialogPeer createFileDialogPeer(FileDialog target); protected abstract FileDialogPeer createFileDialogPeer(FileDialog target);
// ---- UTILITY METHODS ---- // // ---- UTILITY METHODS ---- //
......
...@@ -48,7 +48,8 @@ public class LWWindowPeer ...@@ -48,7 +48,8 @@ public class LWWindowPeer
FRAME, FRAME,
DIALOG, DIALOG,
EMBEDDED_FRAME, EMBEDDED_FRAME,
VIEW_EMBEDDED_FRAME VIEW_EMBEDDED_FRAME,
LW_FRAME
} }
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer"); private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
...@@ -1090,7 +1091,7 @@ public class LWWindowPeer ...@@ -1090,7 +1091,7 @@ public class LWWindowPeer
return platformWindow.requestWindowFocus(); return platformWindow.requestWindowFocus();
} }
private boolean focusAllowedFor() { protected boolean focusAllowedFor() {
Window window = getTarget(); Window window = getTarget();
// TODO: check if modal blocked // TODO: check if modal blocked
return window.isVisible() && window.isEnabled() && isFocusableWindow(); return window.isVisible() && window.isEnabled() && isFocusableWindow();
...@@ -1113,10 +1114,15 @@ public class LWWindowPeer ...@@ -1113,10 +1114,15 @@ public class LWWindowPeer
return !(window instanceof Dialog || window instanceof Frame); return !(window instanceof Dialog || window instanceof Frame);
} }
@Override
public void emulateActivation(boolean activate) {
changeFocusedWindow(activate, null);
}
/* /*
* Changes focused window on java level. * 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)) { if (focusLog.isLoggable(PlatformLogger.FINE)) {
focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this); focusLog.fine((becomesFocused?"gaining":"loosing") + " focus window: " + this);
} }
......
...@@ -128,6 +128,15 @@ final class CDropTargetContextPeer extends SunDropTargetContextPeer { ...@@ -128,6 +128,15 @@ final class CDropTargetContextPeer extends SunDropTargetContextPeer {
} }
} }
@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: // Signal drop complete:
protected void doDropDone(boolean success, int dropAction, boolean isLocal) { protected void doDropDone(boolean success, int dropAction, boolean isLocal) {
long nativeDropTarget = this.getNativeDragContext(); long nativeDropTarget = this.getNativeDragContext();
......
...@@ -35,7 +35,7 @@ import sun.lwawt.PlatformWindow; ...@@ -35,7 +35,7 @@ import sun.lwawt.PlatformWindow;
* On OSX {@code CPlatformComponent} stores pointer to the native CAlayer which * On OSX {@code CPlatformComponent} stores pointer to the native CAlayer which
* can be used from JAWT. * can be used from JAWT.
*/ */
final class CPlatformComponent extends CFRetainedResource class CPlatformComponent extends CFRetainedResource
implements PlatformComponent { implements PlatformComponent {
private volatile PlatformWindow platformWindow; private volatile PlatformWindow platformWindow;
......
/*
* 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() {
}
}
/*
* 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;
}
}
/*
* 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;
}
}
...@@ -54,8 +54,7 @@ public class CPlatformView extends CFRetainedResource { ...@@ -54,8 +54,7 @@ public class CPlatformView extends CFRetainedResource {
} }
public void initialize(LWWindowPeer peer, CPlatformResponder responder) { public void initialize(LWWindowPeer peer, CPlatformResponder responder) {
this.peer = peer; initializeBase(peer, responder);
this.responder = responder;
if (!LWCToolkit.getSunAwtDisableCALayers()) { if (!LWCToolkit.getSunAwtDisableCALayers()) {
this.windowLayer = new CGLLayer(peer); this.windowLayer = new CGLLayer(peer);
...@@ -63,6 +62,11 @@ public class CPlatformView extends CFRetainedResource { ...@@ -63,6 +62,11 @@ public class CPlatformView extends CFRetainedResource {
setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr())); setPtr(nativeCreateView(0, 0, 0, 0, getWindowLayerPtr()));
} }
protected void initializeBase(LWWindowPeer peer, CPlatformResponder responder) {
this.peer = peer;
this.responder = responder;
}
public long getAWTView() { public long getAWTView() {
return ptr; return ptr;
} }
......
...@@ -30,6 +30,7 @@ import java.awt.Dialog.ModalityType; ...@@ -30,6 +30,7 @@ import java.awt.Dialog.ModalityType;
import java.awt.event.*; import java.awt.event.*;
import java.awt.peer.WindowPeer; import java.awt.peer.WindowPeer;
import java.beans.*; import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.util.List; import java.util.List;
import javax.swing.*; import javax.swing.*;
...@@ -44,7 +45,7 @@ import com.apple.laf.*; ...@@ -44,7 +45,7 @@ import com.apple.laf.*;
import com.apple.laf.ClientPropertyApplicator.Property; import com.apple.laf.ClientPropertyApplicator.Property;
import com.sun.awt.AWTUtilities; 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 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 nativeSetNSWindowStyleBits(long nsWindowPtr, int mask, int data);
private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr); private static native void nativeSetNSWindowMenuBar(long nsWindowPtr, long menuBarPtr);
...@@ -218,11 +219,7 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor ...@@ -218,11 +219,7 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
*/ */
@Override // PlatformWindow @Override // PlatformWindow
public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) { public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner) {
this.peer = _peer; initializeBase(_target, _peer, _owner, new CPlatformView());
this.target = _target;
if (_owner instanceof CPlatformWindow) {
this.owner = (CPlatformWindow)_owner;
}
final int styleBits = getInitialStyleBits(); final int styleBits = getInitialStyleBits();
...@@ -231,7 +228,6 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor ...@@ -231,7 +228,6 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
String warningString = target.getWarningString(); String warningString = target.getWarningString();
responder = new CPlatformResponder(peer, false); responder = new CPlatformResponder(peer, false);
contentView = new CPlatformView();
contentView.initialize(peer, responder); contentView.initialize(peer, responder);
final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(), styleBits, 0, 0, 0, 0); final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(), styleBits, 0, 0, 0, 0);
...@@ -253,6 +249,15 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor ...@@ -253,6 +249,15 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
validateSurface(); 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() { private int getInitialStyleBits() {
// defaults style bits // defaults style bits
int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE; int styleBits = DECORATED | HAS_SHADOW | CLOSEABLE | MINIMIZABLE | ZOOMABLE | RESIZABLE;
...@@ -857,7 +862,16 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor ...@@ -857,7 +862,16 @@ public final class CPlatformWindow extends CFRetainedResource implements Platfor
private void flushBuffers() { private void flushBuffers() {
if (isVisible() && !nativeBounds.isEmpty()) { 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();
}
} }
} }
......
...@@ -65,7 +65,7 @@ class CRobot implements RobotPeer { ...@@ -65,7 +65,7 @@ class CRobot implements RobotPeer {
mouseLastX = x; mouseLastX = x;
mouseLastY = y; mouseLastY = y;
mouseEvent(fDevice.getCoreGraphicsScreen(), mouseLastX, mouseLastY, mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY,
mouseButtonsState, true, true); mouseButtonsState, true, true);
} }
...@@ -79,7 +79,7 @@ class CRobot implements RobotPeer { ...@@ -79,7 +79,7 @@ class CRobot implements RobotPeer {
public void mousePress(int buttons) { public void mousePress(int buttons) {
mouseButtonsState |= buttons; mouseButtonsState |= buttons;
mouseEvent(fDevice.getCoreGraphicsScreen(), mouseLastX, mouseLastY, mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY,
buttons, true, false); buttons, true, false);
} }
...@@ -93,7 +93,7 @@ class CRobot implements RobotPeer { ...@@ -93,7 +93,7 @@ class CRobot implements RobotPeer {
public void mouseRelease(int buttons) { public void mouseRelease(int buttons) {
mouseButtonsState &= ~buttons; mouseButtonsState &= ~buttons;
mouseEvent(fDevice.getCoreGraphicsScreen(), mouseLastX, mouseLastY, mouseEvent(fDevice.getCGDisplayID(), mouseLastX, mouseLastY,
buttons, false, false); buttons, false, false);
} }
...@@ -163,7 +163,7 @@ class CRobot implements RobotPeer { ...@@ -163,7 +163,7 @@ class CRobot implements RobotPeer {
} }
private native void initRobot(); 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, int buttonsState,
boolean isButtonsDownState, boolean isButtonsDownState,
boolean isMouseMove); boolean isMouseMove);
......
...@@ -25,27 +25,33 @@ ...@@ -25,27 +25,33 @@
package sun.lwawt.macosx; package sun.lwawt.macosx;
import sun.awt.Mutex;
import sun.awt.datatransfer.ToolkitThreadBlockedHandler; import sun.awt.datatransfer.ToolkitThreadBlockedHandler;
final class CToolkitThreadBlockedHandler implements ToolkitThreadBlockedHandler { final class CToolkitThreadBlockedHandler extends Mutex implements ToolkitThreadBlockedHandler {
private final LWCToolkit toolkit = (LWCToolkit)java.awt.Toolkit.getDefaultToolkit(); private long awtRunLoopMediator = 0;
private final boolean processEvents;
public void lock() { CToolkitThreadBlockedHandler() {
} super();
this.processEvents = true;
public void unlock() {
}
protected boolean isOwned() {
return false;
} }
public void enter() { public void enter() {
// Execute the next AppKit event while we are waiting for system to if (!isOwned()) {
// finish our request - this will save us from biting our own tail throw new IllegalMonitorStateException();
toolkit.executeNextAppKitEvent(); }
awtRunLoopMediator = LWCToolkit.createAWTRunLoopMediator();
unlock();
LWCToolkit.doAWTRunLoop(awtRunLoopMediator, processEvents);
lock();
} }
public void exit() { public void exit() {
if (!isOwned()) {
throw new IllegalMonitorStateException();
}
LWCToolkit.stopAWTRunLoop(awtRunLoopMediator);
awtRunLoopMediator = 0;
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -63,8 +63,6 @@ public final class LWCToolkit extends LWToolkit { ...@@ -63,8 +63,6 @@ public final class LWCToolkit extends LWToolkit {
private static native void initIDs(); private static native void initIDs();
static native void executeNextAppKitEvent();
private static CInputMethodDescriptor sInputMethodDescriptor; private static CInputMethodDescriptor sInputMethodDescriptor;
static { static {
...@@ -160,6 +158,8 @@ public final class LWCToolkit extends LWToolkit { ...@@ -160,6 +158,8 @@ public final class LWCToolkit extends LWToolkit {
return new CPlatformEmbeddedFrame(); return new CPlatformEmbeddedFrame();
} else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) { } else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) {
return new CViewPlatformEmbeddedFrame(); return new CViewPlatformEmbeddedFrame();
} else if (peerType == PeerType.LW_FRAME) {
return new CPlatformLWWindow();
} else { } else {
assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME); assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
return new CPlatformWindow(); return new CPlatformWindow();
...@@ -171,6 +171,11 @@ public final class LWCToolkit extends LWToolkit { ...@@ -171,6 +171,11 @@ public final class LWCToolkit extends LWToolkit {
return new CPlatformComponent(); return new CPlatformComponent();
} }
@Override
protected PlatformComponent createLwPlatformComponent() {
return new CPlatformLWComponent();
}
@Override @Override
protected FileDialogPeer createFileDialogPeer(FileDialog target) { protected FileDialogPeer createFileDialogPeer(FileDialog target) {
return new CFileDialog(target); return new CFileDialog(target);
...@@ -346,22 +351,7 @@ public final class LWCToolkit extends LWToolkit { ...@@ -346,22 +351,7 @@ public final class LWCToolkit extends LWToolkit {
@Override @Override
public Insets getScreenInsets(final GraphicsConfiguration gc) { public Insets getScreenInsets(final GraphicsConfiguration gc) {
final CGraphicsConfig cgc = (CGraphicsConfig) gc; return ((CGraphicsConfig) gc).getDevice().getScreenInsets();
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);
} }
@Override @Override
...@@ -495,30 +485,6 @@ public final class LWCToolkit extends LWToolkit { ...@@ -495,30 +485,6 @@ public final class LWCToolkit extends LWToolkit {
synchronized(ret) { return ret[0]; } 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 { public static <T> T invokeAndWait(final Callable<T> callable, Component component) throws Exception {
final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable); final CallableWrapper<T> wrapper = new CallableWrapper<T>(callable);
invokeAndWait(wrapper, component); invokeAndWait(wrapper, component);
...@@ -548,10 +514,27 @@ public final class LWCToolkit extends LWToolkit { ...@@ -548,10 +514,27 @@ public final class LWCToolkit extends LWToolkit {
} }
} }
public static void invokeAndWait(Runnable event, Component component, boolean detectDeadlocks) throws InterruptedException, InvocationTargetException { // Kicks an event over to the appropriate eventqueue and waits for it to finish
long mediator = createAWTRunLoopMediator(); // 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) { if (component != null) {
AppContext appContext = SunToolkit.targetToAppContext(component); AppContext appContext = SunToolkit.targetToAppContext(component);
...@@ -564,7 +547,7 @@ public final class LWCToolkit extends LWToolkit { ...@@ -564,7 +547,7 @@ public final class LWCToolkit extends LWToolkit {
((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent); ((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent);
} }
doAWTRunLoop(mediator, true, detectDeadlocks); doAWTRunLoop(mediator, false);
Throwable eventException = invocationEvent.getException(); Throwable eventException = invocationEvent.getException();
if (eventException != null) { if (eventException != null) {
...@@ -576,7 +559,8 @@ public final class LWCToolkit extends LWToolkit { ...@@ -576,7 +559,8 @@ public final class LWCToolkit extends LWToolkit {
} }
public static void invokeLater(Runnable event, Component component) throws InvocationTargetException { 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) { if (component != null) {
final AppContext appContext = SunToolkit.targetToAppContext(component); final AppContext appContext = SunToolkit.targetToAppContext(component);
...@@ -681,31 +665,6 @@ public final class LWCToolkit extends LWToolkit { ...@@ -681,31 +665,6 @@ public final class LWCToolkit extends LWToolkit {
return false; 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; private static Boolean sunAwtDisableCALayers = null;
/** /**
...@@ -730,12 +689,20 @@ public final class LWCToolkit extends LWToolkit { ...@@ -730,12 +689,20 @@ public final class LWCToolkit extends LWToolkit {
* Native methods section * Native methods section
************************/ ************************/
// These are public because they are accessed from WebKitPluginObject in JavaDeploy static native long createAWTRunLoopMediator();
// Basic usage: /**
// createAWTRunLoopMediator. Start client code on another thread. doAWTRunLoop. When client code is finished, stopAWTRunLoop. * Method to run a nested run-loop. The nested loop is spinned in the javaRunLoop mode, so selectors sent
public static native long createAWTRunLoopMediator(); * by [JNFRunLoop performOnMainThreadWaiting] are processed.
public static native void doAWTRunLoop(long mediator, boolean awtMode, boolean detectDeadlocks); * @param mediator a native pointer to the mediator object created by createAWTRunLoopMediator
public static native void stopAWTRunLoop(long mediator); * @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); private native boolean nativeSyncQueue(long timeout);
......
...@@ -668,7 +668,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -668,7 +668,7 @@ AWT_ASSERT_APPKIT_THREAD;
- (void) setDropTarget:(CDropTarget *)target { - (void) setDropTarget:(CDropTarget *)target {
self._dropTarget = 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 ********************************/ /******************************** BEGIN NSDraggingSource Interface ********************************/
...@@ -1215,7 +1215,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod"); ...@@ -1215,7 +1215,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod");
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n"); fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
#endif // IM_DEBUG #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]; [self unmarkText];
} }
......
...@@ -567,10 +567,9 @@ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeRegisterForNo ...@@ -567,10 +567,9 @@ JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeRegisterForNo
{ {
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(_registerForNotification:) [ThreadUtilities performOnMainThread:@selector(_registerForNotification:)
onObject:[ApplicationDelegate class] on:[ApplicationDelegate class]
withObject:[NSNumber numberWithInt:notificationType] withObject:[NSNumber numberWithInt:notificationType]
waitUntilDone:NO waitUntilDone:NO]; // AWT_THREADING Safe (non-blocking)
awtMode:NO]; // AWT_THREADING Safe (non-blocking)
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);
} }
......
...@@ -120,7 +120,7 @@ static CClipboard *sClipboard = nil; ...@@ -120,7 +120,7 @@ static CClipboard *sClipboard = nil;
fClipboardOwner = JNFNewGlobalRef(inEnv, inClipboard); 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 { - (void) _nativeDeclareTypes:(NSArray *)inTypes {
...@@ -135,7 +135,7 @@ static CClipboard *sClipboard = nil; ...@@ -135,7 +135,7 @@ static CClipboard *sClipboard = nil;
- (NSArray *) javaGetTypes { - (NSArray *) javaGetTypes {
NSMutableArray *args = [NSMutableArray arrayWithCapacity:1]; 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]); //NSLog(@"CClipboard getTypes returns %@", [args lastObject]);
return [args lastObject]; return [args lastObject];
...@@ -152,7 +152,7 @@ static CClipboard *sClipboard = nil; ...@@ -152,7 +152,7 @@ static CClipboard *sClipboard = nil;
- (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat { - (void) javaSetData:(NSData *)inData forType:(NSString *) inFormat {
CClipboardUpdate *newUpdate = [[CClipboardUpdate alloc] initWithData:inData withFormat: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]; [newUpdate release];
//NSLog(@"CClipboard javaSetData forType %@", inFormat); //NSLog(@"CClipboard javaSetData forType %@", inFormat);
...@@ -170,7 +170,7 @@ static CClipboard *sClipboard = nil; ...@@ -170,7 +170,7 @@ static CClipboard *sClipboard = nil;
- (NSData *) javaGetDataForType:(NSString *) inFormat { - (NSData *) javaGetDataForType:(NSString *) inFormat {
NSMutableArray *args = [NSMutableArray arrayWithObject: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); //NSLog(@"CClipboard javaGetDataForType %@ returns an NSData", inFormat);
return [args lastObject]; return [args lastObject];
......
...@@ -390,8 +390,7 @@ extern JNFClassInfo jc_CDropTargetContextPeer; ...@@ -390,8 +390,7 @@ extern JNFClassInfo jc_CDropTargetContextPeer;
// Release dragging data if any when Java's AWT event thread is all finished. // 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. // Make sure dragging data is released on the native event thread.
[ThreadUtilities performOnMainThread:@selector(safeReleaseDraggingData:) onObject:self [ThreadUtilities performOnMainThread:@selector(safeReleaseDraggingData:) on:self withObject:draggingSequenceNumberID waitUntilDone:NO];
withObject:draggingSequenceNumberID waitUntilDone:NO awtMode:NO];
} }
- (jint)currentJavaActions { - (jint)currentJavaActions {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,7 +23,8 @@ ...@@ -23,7 +23,8 @@
* questions. * questions.
*/ */
#include "LWCToolkit.h" #import "LWCToolkit.h"
#import "ThreadUtilities.h"
/* /*
* Convert the mode string to the more convinient bits per pixel value * Convert the mode string to the more convinient bits per pixel value
...@@ -146,6 +147,47 @@ Java_sun_awt_CGraphicsDevice_nativeGetYResolution ...@@ -146,6 +147,47 @@ Java_sun_awt_CGraphicsDevice_nativeGetYResolution
return dpi; return dpi;
} }
/*
* 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 * Class: sun_awt_CGraphicsDevice
* Method: nativeSetDisplayMode * Method: nativeSetDisplayMode
......
...@@ -55,11 +55,11 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -55,11 +55,11 @@ AWT_ASSERT_APPKIT_THREAD;
//- (void)finalize { [super finalize]; } //- (void)finalize { [super finalize]; }
- (void)addJavaSubmenu:(CMenu *)submenu { - (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 { - (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 { - (void)addNativeItem_OnAppKitThread:(CMenuItem *)itemModified {
...@@ -70,7 +70,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -70,7 +70,7 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)setJavaMenuTitle:(NSString *)title { - (void)setJavaMenuTitle:(NSString *)title {
if (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 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -93,7 +93,7 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)deleteJavaItem:(jint)index { - (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 { - (void)deleteNativeJavaItem_OnAppKitThread:(NSNumber *)number {
...@@ -139,7 +139,7 @@ CMenu * createCMenu (jobject cPeerObjGlobal) { ...@@ -139,7 +139,7 @@ CMenu * createCMenu (jobject cPeerObjGlobal) {
// We use an array here only to be able to get a return value // 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]; 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]; aCMenu = (CMenu *)[args objectAtIndex: 0];
......
...@@ -197,7 +197,7 @@ static BOOL sSetupHelpMenu = NO; ...@@ -197,7 +197,7 @@ static BOOL sSetupHelpMenu = NO;
if (self == sActiveMenuBar) { if (self == sActiveMenuBar) {
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:-1], nil]; 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]; [args release];
} }
} }
...@@ -216,7 +216,7 @@ static BOOL sSetupHelpMenu = NO; ...@@ -216,7 +216,7 @@ static BOOL sSetupHelpMenu = NO;
if (self == sActiveMenuBar) { if (self == sActiveMenuBar) {
NSArray *args = [[NSArray alloc] initWithObjects:theMenu, [NSNumber numberWithInt:index], nil]; 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]; [args release];
} }
} }
...@@ -286,7 +286,7 @@ static BOOL sSetupHelpMenu = NO; ...@@ -286,7 +286,7 @@ static BOOL sSetupHelpMenu = NO;
- (void) javaDeleteMenu: (jint)index { - (void) javaDeleteMenu: (jint)index {
if (self == sActiveMenuBar) { 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) { @synchronized(self) {
...@@ -388,7 +388,7 @@ Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar ...@@ -388,7 +388,7 @@ Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar
// We use an array here only to be able to get a return value // 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]; 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]; aCMenuBar = (CMenuBar *)[args objectAtIndex: 0];
......
...@@ -386,7 +386,7 @@ JNF_COCOA_ENTER(env); ...@@ -386,7 +386,7 @@ JNF_COCOA_ENTER(env);
args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO], nil]; 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]; aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
......
...@@ -135,7 +135,7 @@ Java_sun_lwawt_macosx_CRobot_initRobot ...@@ -135,7 +135,7 @@ Java_sun_lwawt_macosx_CRobot_initRobot
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CRobot_mouseEvent Java_sun_lwawt_macosx_CRobot_mouseEvent
(JNIEnv *env, jobject peer, (JNIEnv *env, jobject peer,
jint screenIndex, jint mouseLastX, jint mouseLastY, jint buttonsState, jint displayID, jint mouseLastX, jint mouseLastY, jint buttonsState,
jboolean isButtonsDownState, jboolean isMouseMove) jboolean isButtonsDownState, jboolean isMouseMove)
{ {
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
...@@ -149,8 +149,6 @@ Java_sun_lwawt_macosx_CRobot_mouseEvent ...@@ -149,8 +149,6 @@ Java_sun_lwawt_macosx_CRobot_mouseEvent
CGError err = kCGErrorSuccess; CGError err = kCGErrorSuccess;
CGDirectDisplayID displayID =
FindCGDirectDisplayIDForScreenIndex(screenIndex);
CGRect globalDeviceBounds = CGDisplayBounds(displayID); CGRect globalDeviceBounds = CGDisplayBounds(displayID);
// Set unknown mouse location, if needed. // Set unknown mouse location, if needed.
......
...@@ -1113,20 +1113,12 @@ static NSObject *sAttributeNamesLOCK = nil; ...@@ -1113,20 +1113,12 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
id value = nil; 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) jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (focused != NULL) { if (focused != NULL) {
if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) { if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];
} }
} }
}
if (value == nil) { if (value == nil) {
value = self; value = self;
...@@ -1149,7 +1141,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged ...@@ -1149,7 +1141,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessibility_focusChanged
{ {
JNF_COCOA_ENTER(env); 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); JNF_COCOA_EXIT(env);
} }
...@@ -1164,7 +1156,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_valueChanged ...@@ -1164,7 +1156,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_valueChanged
(JNIEnv *env, jclass jklass, jlong element) (JNIEnv *env, jclass jklass, jlong element)
{ {
JNF_COCOA_ENTER(env); 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); JNF_COCOA_EXIT(env);
} }
...@@ -1177,7 +1169,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged ...@@ -1177,7 +1169,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_selectionChanged
(JNIEnv *env, jclass jklass, jlong element) (JNIEnv *env, jclass jklass, jlong element)
{ {
JNF_COCOA_ENTER(env); 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); JNF_COCOA_EXIT(env);
} }
...@@ -1191,7 +1183,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSy ...@@ -1191,7 +1183,7 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_unregisterFromCocoaAXSy
(JNIEnv *env, jclass jklass, jlong element) (JNIEnv *env, jclass jklass, jlong element)
{ {
JNF_COCOA_ENTER(env); 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); JNF_COCOA_EXIT(env);
} }
......
...@@ -44,8 +44,6 @@ extern jint* gButtonDownMasks; ...@@ -44,8 +44,6 @@ extern jint* gButtonDownMasks;
+ (void) eventCountPlusPlus; + (void) eventCountPlusPlus;
@end @end
CGDirectDisplayID FindCGDirectDisplayIDForScreenIndex(jint screenIndex);
/* /*
* Utility Macros * Utility Macros
*/ */
......
...@@ -177,39 +177,6 @@ Java_sun_lwawt_macosx_LWCToolkit_beep ...@@ -177,39 +177,6 @@ Java_sun_lwawt_macosx_LWCToolkit_beep
NSBeep(); // produces both sound and visual flash, if configured in System Preferences 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 * Class: sun_lwawt_macosx_LWCToolkit
* Method: initIDs * Method: initIDs
...@@ -332,7 +299,7 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -332,7 +299,7 @@ AWT_ASSERT_APPKIT_THREAD;
* Signature: (JZZ)V * Signature: (JZZ)V
*/ */
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_doAWTRunLoop 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; AWT_ASSERT_APPKIT_THREAD;
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
...@@ -341,25 +308,24 @@ JNF_COCOA_ENTER(env); ...@@ -341,25 +308,24 @@ JNF_COCOA_ENTER(env);
if (mediatorObject == nil) return; if (mediatorObject == nil) return;
if (!sInPerformFromJava || !detectDeadlocks) {
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 // Don't use acceptInputForMode because that doesn't setup autorelease pools properly
isRunning = [currentRunLoop runMode:mode beforeDate:distantFuture]; 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];
} }
} }
#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); CFRelease(mediatorObject);
...@@ -379,7 +345,7 @@ JNF_COCOA_ENTER(env); ...@@ -379,7 +345,7 @@ JNF_COCOA_ENTER(env);
AWTRunLoopObject* mediatorObject = (AWTRunLoopObject*)jlong_to_ptr(mediator); 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); CFRelease(mediatorObject);
...@@ -463,20 +429,3 @@ Java_sun_font_FontManager_populateFontFileNameMap ...@@ -463,20 +429,3 @@ Java_sun_font_FontManager_populateFontFileNameMap
} }
/*
* 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];
}
}
...@@ -27,11 +27,13 @@ ...@@ -27,11 +27,13 @@
#import "java_awt_geom_PathIterator.h" #import "java_awt_geom_PathIterator.h"
#import "sun_awt_SunHints.h" #import "sun_awt_SunHints.h"
#import "sun_font_CStrike.h" #import "sun_font_CStrike.h"
#import "sun_font_CStrikeDisposer.h"
#import "CGGlyphImages.h" #import "CGGlyphImages.h"
#import "CGGlyphOutlines.h" #import "CGGlyphOutlines.h"
#import "AWTStrike.h" #import "AWTStrike.h"
#import "CoreTextSupport.h" #import "CoreTextSupport.h"
//#import "jni_util.h" //#import "jni_util.h"
#include "fontscalerdefs.h"
/* Use THIS_FILE when it is available. */ /* Use THIS_FILE when it is available. */
#ifndef THIS_FILE #ifndef THIS_FILE
...@@ -423,3 +425,19 @@ JNF_COCOA_EXIT(env); ...@@ -423,3 +425,19 @@ JNF_COCOA_EXIT(env);
return metrics; 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);
}
...@@ -192,12 +192,12 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL ...@@ -192,12 +192,12 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_initCGL
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
(JNIEnv *env, jclass cglgc, (JNIEnv *env, jclass cglgc,
jint screennum, jint pixfmt, jint swapInterval) jint displayID, jint pixfmt, jint swapInterval)
{ {
jlong ret = 0L; jlong ret = 0L;
JNF_COCOA_ENTER(env); JNF_COCOA_ENTER(env);
NSMutableArray * retArray = [NSMutableArray arrayWithCapacity:3]; 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)pixfmt]];
[retArray addObject: [NSNumber numberWithInt: (int)swapInterval]]; [retArray addObject: [NSNumber numberWithInt: (int)swapInterval]];
if ([NSThread isMainThread]) { if ([NSThread isMainThread]) {
...@@ -217,7 +217,7 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo ...@@ -217,7 +217,7 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
+ (void) _getCGLConfigInfo: (NSMutableArray *)argValue { + (void) _getCGLConfigInfo: (NSMutableArray *)argValue {
AWT_ASSERT_APPKIT_THREAD; 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 pixfmt = (jint)[(NSNumber *)[argValue objectAtIndex: 1] intValue];
jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue]; jint swapInterval = (jint)[(NSNumber *)[argValue objectAtIndex: 2] intValue];
JNIEnv *env = [ThreadUtilities getJNIEnvUncached]; JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
...@@ -230,16 +230,11 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo ...@@ -230,16 +230,11 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt; CGOpenGLDisplayMask glMask = (CGOpenGLDisplayMask)pixfmt;
if (sharedContext == NULL) { if (sharedContext == NULL) {
if (glMask == 0) { if (glMask == 0) {
CGDirectDisplayID id = glMask = CGDisplayIDToOpenGLDisplayMask(displayID);
FindCGDirectDisplayIDForScreenIndex(screennum);
glMask = CGDisplayIDToOpenGLDisplayMask(id);
} }
NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAClosestPolicy, NSOpenGLPFAClosestPolicy,
NSOpenGLPFANoRecovery,
NSOpenGLPFAAccelerated,
NSOpenGLPFAFullScreen,
NSOpenGLPFAWindow, NSOpenGLPFAWindow,
NSOpenGLPFAPixelBuffer, NSOpenGLPFAPixelBuffer,
NSOpenGLPFADoubleBuffer, NSOpenGLPFADoubleBuffer,
...@@ -412,7 +407,7 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo ...@@ -412,7 +407,7 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
return; return;
} }
memset(cglinfo, 0, sizeof(CGLGraphicsConfigInfo)); memset(cglinfo, 0, sizeof(CGLGraphicsConfigInfo));
cglinfo->screen = screennum; cglinfo->screen = displayID;
cglinfo->pixfmt = sharedPixelFormat; cglinfo->pixfmt = sharedPixelFormat;
cglinfo->context = oglc; cglinfo->context = oglc;
...@@ -422,17 +417,6 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo ...@@ -422,17 +417,6 @@ Java_sun_java2d_opengl_CGLGraphicsConfig_getCGLConfigInfo
} }
@end //GraphicsConfigUtil @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 JNIEXPORT jint JNICALL
Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities Java_sun_java2d_opengl_CGLGraphicsConfig_getOGLCapabilities
(JNIEnv *env, jclass cglgc, jlong configInfo) (JNIEnv *env, jclass cglgc, jlong configInfo)
......
...@@ -122,19 +122,12 @@ do { \ ...@@ -122,19 +122,12 @@ do { \
#endif /* AWT_THREAD_ASSERTS */ #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"))) __attribute__((visibility("default")))
@interface ThreadUtilities : NSObject { } @interface ThreadUtilities { }
+ (JNIEnv*)getJNIEnv; + (JNIEnv*)getJNIEnv;
+ (JNIEnv*)getJNIEnvUncached; + (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 //Wrappers for the corresponding JNFRunLoop methods with a check for main thread
+ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block; + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
+ (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait; + (void)performOnMainThread:(SEL)aSelector on:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait;
......
...@@ -34,85 +34,6 @@ ...@@ -34,85 +34,6 @@
JavaVM *jvm = NULL; JavaVM *jvm = NULL;
static JNIEnv *appKitEnv = 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 @implementation ThreadUtilities
+ (JNIEnv*)getJNIEnv { + (JNIEnv*)getJNIEnv {
...@@ -129,36 +50,6 @@ AWT_ASSERT_APPKIT_THREAD; ...@@ -129,36 +50,6 @@ AWT_ASSERT_APPKIT_THREAD;
return env; 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 { + (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
if ([NSThread isMainThread] && wait == YES) { if ([NSThread isMainThread] && wait == YES) {
block(); block();
......
...@@ -66,7 +66,7 @@ int JLI_GetStdArgc(); ...@@ -66,7 +66,7 @@ int JLI_GetStdArgc();
#include <io.h> #include <io.h>
#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2)) #define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3)) #define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
#define JLI_Snprintf _snprintf int JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
void JLI_CmdToArgs(char *cmdline); void JLI_CmdToArgs(char *cmdline);
#define JLI_Lseek _lseeki64 #define JLI_Lseek _lseeki64
#else /* NIXES */ #else /* NIXES */
......
...@@ -569,9 +569,9 @@ JLI_ParseManifest(char *jarfile, manifest_info *info) ...@@ -569,9 +569,9 @@ JLI_ParseManifest(char *jarfile, manifest_info *info)
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif
)) == -1) )) == -1) {
return (-1); return (-1);
}
info->manifest_version = NULL; info->manifest_version = NULL;
info->main_class = NULL; info->main_class = NULL;
info->jre_version = NULL; info->jre_version = NULL;
...@@ -618,15 +618,17 @@ JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) { ...@@ -618,15 +618,17 @@ JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) {
zentry entry; zentry entry;
void *data = NULL; void *data = NULL;
fd = open(jarfile, O_RDONLY if ((fd = open(jarfile, O_RDONLY
#ifdef O_LARGEFILE #ifdef O_LARGEFILE
| O_LARGEFILE /* large file mode */ | O_LARGEFILE /* large file mode */
#endif #endif
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif
); )) == -1) {
if (fd != -1 && find_file(fd, &entry, filename) == 0) { return NULL;
}
if (find_file(fd, &entry, filename) == 0) {
data = inflate_file(fd, &entry, size); data = inflate_file(fd, &entry, size);
} }
close(fd); close(fd);
...@@ -671,8 +673,9 @@ JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data) ...@@ -671,8 +673,9 @@ JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data)
#ifdef O_BINARY #ifdef O_BINARY
| O_BINARY /* use binary mode on windows */ | O_BINARY /* use binary mode on windows */
#endif #endif
)) == -1) )) == -1) {
return (-1); return (-1);
}
if (rc = find_file(fd, &entry, manifest_name) != 0) { if (rc = find_file(fd, &entry, manifest_name) != 0) {
close(fd); close(fd);
......
...@@ -66,11 +66,14 @@ public final class MethodFinder extends AbstractFinder<Method> { ...@@ -66,11 +66,14 @@ public final class MethodFinder extends AbstractFinder<Method> {
Signature signature = new Signature(type, name, args); Signature signature = new Signature(type, name, args);
Method method = CACHE.get(signature); Method method = CACHE.get(signature);
if (method != null) { boolean cached = method != null;
if (cached && isPackageAccessible(method.getDeclaringClass())) {
return method; return method;
} }
method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods())); method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
if (!cached) {
CACHE.put(signature, method); CACHE.put(signature, method);
}
return method; return method;
} }
......
...@@ -41,6 +41,8 @@ import javax.crypto.ShortBufferException; ...@@ -41,6 +41,8 @@ import javax.crypto.ShortBufferException;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.*; import javax.crypto.spec.*;
import sun.security.util.KeyUtil;
/** /**
* This class implements the Diffie-Hellman key agreement protocol between * This class implements the Diffie-Hellman key agreement protocol between
* any number of parties. * any number of parties.
...@@ -200,6 +202,9 @@ extends KeyAgreementSpi { ...@@ -200,6 +202,9 @@ extends KeyAgreementSpi {
throw new InvalidKeyException("Incompatible parameters"); throw new InvalidKeyException("Incompatible parameters");
} }
// validate the Diffie-Hellman public key
KeyUtil.validate(dhPubKey);
// store the y value // store the y value
this.y = dhPubKey.getY(); this.y = dhPubKey.getY();
......
...@@ -1000,7 +1000,6 @@ class BandStructure { ...@@ -1000,7 +1000,6 @@ class BandStructure {
/** Write a constant pool reference. */ /** Write a constant pool reference. */
public void putRef(Entry e) { public void putRef(Entry e) {
assert(index != null);
addValue(encodeRefOrNull(e, index)); addValue(encodeRefOrNull(e, index));
} }
public void putRef(Entry e, Index index) { public void putRef(Entry e, Index index) {
...@@ -1052,6 +1051,8 @@ class BandStructure { ...@@ -1052,6 +1051,8 @@ class BandStructure {
int encodeRef(Entry e, Index ix) { int encodeRef(Entry e, Index ix) {
if (ix == null)
throw new RuntimeException("null index for " + e.stringValue());
int coding = ix.indexOf(e); int coding = ix.indexOf(e);
if (verbose > 2) if (verbose > 2)
Utils.log.fine("putRef "+coding+" => "+e); Utils.log.fine("putRef "+coding+" => "+e);
......
...@@ -1409,6 +1409,8 @@ class ConstantPool { ...@@ -1409,6 +1409,8 @@ class ConstantPool {
/** Index of all CP entries of a given tag and class. */ /** Index of all CP entries of a given tag and class. */
public Index getMemberIndex(byte tag, ClassEntry classRef) { public Index getMemberIndex(byte tag, ClassEntry classRef) {
if (classRef == null)
throw new RuntimeException("missing class reference for " + tagName(tag));
if (indexByTagAndClass == null) if (indexByTagAndClass == null)
indexByTagAndClass = new Index[CONSTANT_Limit][]; indexByTagAndClass = new Index[CONSTANT_Limit][];
Index allClasses = getIndexByTag(CONSTANT_Class); Index allClasses = getIndexByTag(CONSTANT_Class);
......
...@@ -109,6 +109,10 @@ class NativeUnpack { ...@@ -109,6 +109,10 @@ class NativeUnpack {
return (p200 == null)? null: p200._nunp; return (p200 == null)? null: p200._nunp;
} }
private synchronized long getUnpackerPtr() {
return unpackerPtr;
}
// Callback from the unpacker engine to get more data. // Callback from the unpacker engine to get more data.
private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException { private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
if (in == null) return 0; // nothing is readable if (in == null) return 0; // nothing is readable
......
...@@ -83,7 +83,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { ...@@ -83,7 +83,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
* @param out an OutputStream * @param out an OutputStream
* @exception IOException if an error is encountered. * @exception IOException if an error is encountered.
*/ */
public void pack(JarFile in, OutputStream out) throws IOException { public synchronized void pack(JarFile in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null); assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
? null ? null
...@@ -118,7 +118,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer { ...@@ -118,7 +118,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
* @param out an OutputStream * @param out an OutputStream
* @exception IOException if an error is encountered. * @exception IOException if an error is encountered.
*/ */
public void pack(JarInputStream in, OutputStream out) throws IOException { public synchronized void pack(JarInputStream in, OutputStream out) throws IOException {
assert(Utils.currentInstance.get() == null); assert(Utils.currentInstance.get() == null);
TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null : TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
TimeZone.getDefault(); TimeZone.getDefault();
......
/* /*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -106,7 +106,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker { ...@@ -106,7 +106,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
* @param out a JarOutputStream. * @param out a JarOutputStream.
* @exception IOException if an error is encountered. * @exception IOException if an error is encountered.
*/ */
public void unpack(InputStream in, JarOutputStream out) throws IOException { public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException {
if (in == null) { if (in == null) {
throw new NullPointerException("null input"); throw new NullPointerException("null input");
} }
...@@ -151,7 +151,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker { ...@@ -151,7 +151,7 @@ public class UnpackerImpl extends TLGlobals implements Pack200.Unpacker {
* @param out a JarOutputStream. * @param out a JarOutputStream.
* @exception IOException if an error is encountered. * @exception IOException if an error is encountered.
*/ */
public void unpack(File in, JarOutputStream out) throws IOException { public synchronized void unpack(File in, JarOutputStream out) throws IOException {
if (in == null) { if (in == null) {
throw new NullPointerException("null input"); throw new NullPointerException("null input");
} }
......
...@@ -36,6 +36,7 @@ import java.util.logging.Level; ...@@ -36,6 +36,7 @@ import java.util.logging.Level;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.loading.PrivateClassLoader; import javax.management.loading.PrivateClassLoader;
import sun.reflect.misc.ReflectUtil;
/** /**
* This class keeps the list of Class Loaders registered in the MBean Server. * This class keeps the list of Class Loaders registered in the MBean Server.
...@@ -192,6 +193,7 @@ final class ClassLoaderRepositorySupport ...@@ -192,6 +193,7 @@ final class ClassLoaderRepositorySupport
final ClassLoader without, final ClassLoader without,
final ClassLoader stop) final ClassLoader stop)
throws ClassNotFoundException { throws ClassNotFoundException {
ReflectUtil.checkPackageAccess(className);
final int size = list.length; final int size = list.length;
for(int i=0; i<size; i++) { for(int i=0; i<size; i++) {
try { try {
......
...@@ -54,6 +54,8 @@ import java.lang.reflect.Array; ...@@ -54,6 +54,8 @@ import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import javax.management.AttributeNotFoundException; import javax.management.AttributeNotFoundException;
import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeData;
import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
/** /**
* This class contains the methods for performing all the tests needed to verify * This class contains the methods for performing all the tests needed to verify
...@@ -526,8 +528,10 @@ public class Introspector { ...@@ -526,8 +528,10 @@ public class Introspector {
// to locate method // to locate method
readMethod = SimpleIntrospector.getReadMethod(clazz, element); readMethod = SimpleIntrospector.getReadMethod(clazz, element);
} }
if (readMethod != null) if (readMethod != null) {
return readMethod.invoke(complex); ReflectUtil.checkPackageAccess(readMethod.getDeclaringClass());
return MethodUtil.invoke(readMethod, complex, new Class[0]);
}
throw new AttributeNotFoundException( throw new AttributeNotFoundException(
"Could not find the getter method for the property " + "Could not find the getter method for the property " +
......
...@@ -51,6 +51,7 @@ import javax.management.MBeanPermission; ...@@ -51,6 +51,7 @@ import javax.management.MBeanPermission;
import javax.management.MBeanRegistrationException; import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer; import javax.management.MBeanServer;
import javax.management.MBeanServerDelegate; import javax.management.MBeanServerDelegate;
import javax.management.MBeanServerPermission;
import javax.management.NotCompliantMBeanException; import javax.management.NotCompliantMBeanException;
import javax.management.NotificationFilter; import javax.management.NotificationFilter;
import javax.management.NotificationListener; import javax.management.NotificationListener;
...@@ -1409,6 +1410,8 @@ public final class JmxMBeanServer ...@@ -1409,6 +1410,8 @@ public final class JmxMBeanServer
// Default is true. // Default is true.
final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY; final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY;
checkNewMBeanServerPermission();
// This constructor happens to disregard the value of the interceptors // This constructor happens to disregard the value of the interceptors
// flag - that is, it always uses the default value - false. // flag - that is, it always uses the default value - false.
// This is admitedly a bug, but we chose not to fix it for now // This is admitedly a bug, but we chose not to fix it for now
...@@ -1494,4 +1497,11 @@ public final class JmxMBeanServer ...@@ -1494,4 +1497,11 @@ public final class JmxMBeanServer
} }
} }
private static void checkNewMBeanServerPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
Permission perm = new MBeanServerPermission("newMBeanServer");
sm.checkPermission(perm);
}
}
} }
...@@ -32,11 +32,13 @@ import java.io.IOException; ...@@ -32,11 +32,13 @@ import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.security.Permission;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import javax.management.InstanceNotFoundException; import javax.management.InstanceNotFoundException;
import javax.management.MBeanException; import javax.management.MBeanException;
import javax.management.MBeanPermission;
import javax.management.NotCompliantMBeanException; import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.OperationsException; import javax.management.OperationsException;
...@@ -44,7 +46,7 @@ import javax.management.ReflectionException; ...@@ -44,7 +46,7 @@ import javax.management.ReflectionException;
import javax.management.RuntimeErrorException; import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException; import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException; import javax.management.RuntimeOperationsException;
import sun.reflect.misc.ConstructorUtil;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
/** /**
...@@ -56,7 +58,6 @@ import sun.reflect.misc.ReflectUtil; ...@@ -56,7 +58,6 @@ import sun.reflect.misc.ReflectUtil;
* @since 1.5 * @since 1.5
*/ */
public class MBeanInstantiator { public class MBeanInstantiator {
private final ModifiableClassLoaderRepository clr; private final ModifiableClassLoaderRepository clr;
// private MetaData meta = null; // private MetaData meta = null;
...@@ -88,6 +89,7 @@ public class MBeanInstantiator { ...@@ -88,6 +89,7 @@ public class MBeanInstantiator {
"Exception occurred during object instantiation"); "Exception occurred during object instantiation");
} }
ReflectUtil.checkPackageAccess(className);
try { try {
if (clr == null) throw new ClassNotFoundException(className); if (clr == null) throw new ClassNotFoundException(className);
theClass = clr.loadClass(className); theClass = clr.loadClass(className);
...@@ -162,6 +164,7 @@ public class MBeanInstantiator { ...@@ -162,6 +164,7 @@ public class MBeanInstantiator {
continue; continue;
} }
ReflectUtil.checkPackageAccess(signature[i]);
// Ok we do not have a primitive type ! We need to build // Ok we do not have a primitive type ! We need to build
// the signature of the method // the signature of the method
// //
...@@ -205,6 +208,9 @@ public class MBeanInstantiator { ...@@ -205,6 +208,9 @@ public class MBeanInstantiator {
*/ */
public Object instantiate(Class<?> theClass) public Object instantiate(Class<?> theClass)
throws ReflectionException, MBeanException { throws ReflectionException, MBeanException {
checkMBeanPermission(theClass, null, null, "instantiate");
Object moi; Object moi;
...@@ -260,6 +266,9 @@ public class MBeanInstantiator { ...@@ -260,6 +266,9 @@ public class MBeanInstantiator {
public Object instantiate(Class<?> theClass, Object params[], public Object instantiate(Class<?> theClass, Object params[],
String signature[], ClassLoader loader) String signature[], ClassLoader loader)
throws ReflectionException, MBeanException { throws ReflectionException, MBeanException {
checkMBeanPermission(theClass, null, null, "instantiate");
// Instantiate the new object // Instantiate the new object
// ------------------------------ // ------------------------------
...@@ -407,6 +416,8 @@ public class MBeanInstantiator { ...@@ -407,6 +416,8 @@ public class MBeanInstantiator {
throw new RuntimeOperationsException(new throw new RuntimeOperationsException(new
IllegalArgumentException(), "Null className passed in parameter"); IllegalArgumentException(), "Null className passed in parameter");
} }
ReflectUtil.checkPackageAccess(className);
Class<?> theClass; Class<?> theClass;
if (loaderName == null) { if (loaderName == null) {
// Load the class using the agent class loader // Load the class using the agent class loader
...@@ -619,13 +630,13 @@ public class MBeanInstantiator { ...@@ -619,13 +630,13 @@ public class MBeanInstantiator {
**/ **/
static Class<?> loadClass(String className, ClassLoader loader) static Class<?> loadClass(String className, ClassLoader loader)
throws ReflectionException { throws ReflectionException {
Class<?> theClass; Class<?> theClass;
if (className == null) { if (className == null) {
throw new RuntimeOperationsException(new throw new RuntimeOperationsException(new
IllegalArgumentException("The class name cannot be null"), IllegalArgumentException("The class name cannot be null"),
"Exception occurred during object instantiation"); "Exception occurred during object instantiation");
} }
ReflectUtil.checkPackageAccess(className);
try { try {
if (loader == null) if (loader == null)
loader = MBeanInstantiator.class.getClassLoader(); loader = MBeanInstantiator.class.getClassLoader();
...@@ -676,6 +687,7 @@ public class MBeanInstantiator { ...@@ -676,6 +687,7 @@ public class MBeanInstantiator {
// We need to load the class through the class // We need to load the class through the class
// loader of the target object. // loader of the target object.
// //
ReflectUtil.checkPackageAccess(signature[i]);
tab[i] = Class.forName(signature[i], false, aLoader); tab[i] = Class.forName(signature[i], false, aLoader);
} }
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
...@@ -701,7 +713,7 @@ public class MBeanInstantiator { ...@@ -701,7 +713,7 @@ public class MBeanInstantiator {
private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) { private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) {
try { try {
return c.getConstructor(params); return ConstructorUtil.getConstructor(c, params);
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
...@@ -715,4 +727,18 @@ public class MBeanInstantiator { ...@@ -715,4 +727,18 @@ public class MBeanInstantiator {
char.class, boolean.class}) char.class, boolean.class})
primitiveClasses.put(c.getName(), c); primitiveClasses.put(c.getName(), c);
} }
private static void checkMBeanPermission(Class<?> clazz,
String member,
ObjectName objectName,
String actions) {
SecurityManager sm = System.getSecurityManager();
if (clazz != null && sm != null) {
Permission perm = new MBeanPermission(clazz.getName(),
member,
objectName,
actions);
sm.checkPermission(perm);
}
}
} }
...@@ -38,6 +38,7 @@ import javax.management.NotCompliantMBeanException; ...@@ -38,6 +38,7 @@ import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.ReflectionException; import javax.management.ReflectionException;
import com.sun.jmx.mbeanserver.MXBeanMappingFactory; import com.sun.jmx.mbeanserver.MXBeanMappingFactory;
import sun.reflect.misc.ReflectUtil;
/** /**
* Base class for MBeans. There is one instance of this class for * Base class for MBeans. There is one instance of this class for
...@@ -131,6 +132,7 @@ public abstract class MBeanSupport<M> ...@@ -131,6 +132,7 @@ public abstract class MBeanSupport<M>
" is not an instance of " + mbeanInterfaceType.getName(); " is not an instance of " + mbeanInterfaceType.getName();
throw new NotCompliantMBeanException(msg); throw new NotCompliantMBeanException(msg);
} }
ReflectUtil.checkPackageAccess(mbeanInterfaceType);
this.resource = resource; this.resource = resource;
MBeanIntrospector<M> introspector = getMBeanIntrospector(); MBeanIntrospector<M> introspector = getMBeanIntrospector();
this.perInterface = introspector.getPerInterface(mbeanInterfaceType); this.perInterface = introspector.getPerInterface(mbeanInterfaceType);
......
...@@ -277,7 +277,7 @@ public class CheckboxMenuItem extends MenuItem implements ItemSelectable, Access ...@@ -277,7 +277,7 @@ public class CheckboxMenuItem extends MenuItem implements ItemSelectable, Access
* @since 1.4 * @since 1.4
*/ */
public synchronized ItemListener[] getItemListeners() { public synchronized ItemListener[] getItemListeners() {
return (ItemListener[])(getListeners(ItemListener.class)); return getListeners(ItemListener.class);
} }
/** /**
......
...@@ -163,11 +163,11 @@ public class Cursor implements java.io.Serializable { ...@@ -163,11 +163,11 @@ public class Cursor implements java.io.Serializable {
* hashtable, filesystem dir prefix, filename, and properties for custom cursors support * 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 final String systemCustomCursorDirPrefix = initCursorDir();
private static String 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")); new sun.security.action.GetPropertyAction("java.home"));
return jhome + return jhome +
File.separator + "lib" + File.separator + "images" + File.separator + "lib" + File.separator + "images" +
...@@ -298,7 +298,7 @@ public class Cursor implements java.io.Serializable { ...@@ -298,7 +298,7 @@ public class Cursor implements java.io.Serializable {
static public Cursor getSystemCustomCursor(final String name) static public Cursor getSystemCustomCursor(final String name)
throws AWTException, HeadlessException { throws AWTException, HeadlessException {
GraphicsEnvironment.checkHeadless(); GraphicsEnvironment.checkHeadless();
Cursor cursor = (Cursor)systemCustomCursors.get(name); Cursor cursor = systemCustomCursors.get(name);
if (cursor == null) { if (cursor == null) {
synchronized(systemCustomCursors) { synchronized(systemCustomCursors) {
...@@ -319,11 +319,11 @@ public class Cursor implements java.io.Serializable { ...@@ -319,11 +319,11 @@ public class Cursor implements java.io.Serializable {
final String fileName = final String fileName =
systemCustomCursorProperties.getProperty(key); systemCustomCursorProperties.getProperty(key);
String localized = (String)systemCustomCursorProperties.getProperty(prefix + DotNameSuffix); String localized = systemCustomCursorProperties.getProperty(prefix + DotNameSuffix);
if (localized == null) localized = name; if (localized == null) localized = name;
String hotspot = (String)systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix); String hotspot = systemCustomCursorProperties.getProperty(prefix + DotHotspotSuffix);
if (hotspot == null) if (hotspot == null)
throw new AWTException("no hotspot property defined for cursor: " + name); throw new AWTException("no hotspot property defined for cursor: " + name);
...@@ -348,9 +348,9 @@ public class Cursor implements java.io.Serializable { ...@@ -348,9 +348,9 @@ public class Cursor implements java.io.Serializable {
final int fy = y; final int fy = y;
final String flocalized = localized; final String flocalized = localized;
cursor = (Cursor) java.security.AccessController.doPrivileged( cursor = java.security.AccessController.<Cursor>doPrivileged(
new java.security.PrivilegedExceptionAction() { new java.security.PrivilegedExceptionAction<Cursor>() {
public Object run() throws Exception { public Cursor run() throws Exception {
Toolkit toolkit = Toolkit.getDefaultToolkit(); Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage( Image image = toolkit.getImage(
systemCustomCursorDirPrefix + fileName); systemCustomCursorDirPrefix + fileName);
...@@ -447,8 +447,8 @@ public class Cursor implements java.io.Serializable { ...@@ -447,8 +447,8 @@ public class Cursor implements java.io.Serializable {
systemCustomCursorProperties = new Properties(); systemCustomCursorProperties = new Properties();
try { try {
AccessController.doPrivileged( AccessController.<Object>doPrivileged(
new java.security.PrivilegedExceptionAction() { new java.security.PrivilegedExceptionAction<Object>() {
public Object run() throws Exception { public Object run() throws Exception {
FileInputStream fis = null; FileInputStream fis = null;
try { try {
......
...@@ -39,6 +39,7 @@ import sun.awt.PeerEvent; ...@@ -39,6 +39,7 @@ import sun.awt.PeerEvent;
import sun.awt.util.IdentityArrayList; import sun.awt.util.IdentityArrayList;
import sun.awt.util.IdentityLinkedList; import sun.awt.util.IdentityLinkedList;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import java.security.AccessControlException;
/** /**
* A Dialog is a top-level window with a title and a border * A Dialog is a top-level window with a title and a border
...@@ -128,6 +129,8 @@ public class Dialog extends Window { ...@@ -128,6 +129,8 @@ public class Dialog extends Window {
*/ */
boolean undecorated = false; boolean undecorated = false;
private transient boolean initialized = false;
/** /**
* Modal dialogs block all input to some top-level windows. * Modal dialogs block all input to some top-level windows.
* Whether a particular window is blocked depends on dialog's type * Whether a particular window is blocked depends on dialog's type
...@@ -671,6 +674,7 @@ public class Dialog extends Window { ...@@ -671,6 +674,7 @@ public class Dialog extends Window {
this.title = title; this.title = title;
setModalityType(modalityType); setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this); SunToolkit.checkAndSetPolicy(this);
initialized = true;
} }
/** /**
...@@ -722,6 +726,7 @@ public class Dialog extends Window { ...@@ -722,6 +726,7 @@ public class Dialog extends Window {
this.title = title; this.title = title;
setModalityType(modalityType); setModalityType(modalityType);
SunToolkit.checkAndSetPolicy(this); SunToolkit.checkAndSetPolicy(this);
initialized = true;
} }
/** /**
...@@ -851,12 +856,9 @@ public class Dialog extends Window { ...@@ -851,12 +856,9 @@ public class Dialog extends Window {
if (modalityType == type) { if (modalityType == type) {
return; return;
} }
if (type == ModalityType.TOOLKIT_MODAL) {
SecurityManager sm = System.getSecurityManager(); checkModalityPermission(type);
if (sm != null) {
sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION);
}
}
modalityType = type; modalityType = type;
modal = (modalityType != ModalityType.MODELESS); modal = (modalityType != ModalityType.MODELESS);
} }
...@@ -1025,6 +1027,11 @@ public class Dialog extends Window { ...@@ -1025,6 +1027,11 @@ public class Dialog extends Window {
*/ */
@Deprecated @Deprecated
public void show() { public void show() {
if (!initialized) {
throw new IllegalStateException("The dialog component " +
"has not been initialized properly");
}
beforeFirstShow = false; beforeFirstShow = false;
if (!isModal()) { if (!isModal()) {
conditionalShow(null, null); conditionalShow(null, null);
...@@ -1600,18 +1607,51 @@ public class Dialog extends Window { ...@@ -1600,18 +1607,51 @@ public class Dialog extends Window {
} }
} }
private void checkModalityPermission(ModalityType mt) {
if (mt == ModalityType.TOOLKIT_MODAL) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION
);
}
}
}
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException throws ClassNotFoundException, IOException, HeadlessException
{ {
GraphicsEnvironment.checkHeadless(); GraphicsEnvironment.checkHeadless();
s.defaultReadObject();
java.io.ObjectInputStream.GetField fields =
s.readFields();
ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
try {
checkModalityPermission(localModalityType);
} catch (AccessControlException ace) {
localModalityType = DEFAULT_MODALITY_TYPE;
}
// in 1.5 or earlier modalityType was absent, so use "modal" instead // in 1.5 or earlier modalityType was absent, so use "modal" instead
if (modalityType == null) { if (localModalityType == null) {
this.modal = fields.get("modal", false);
setModal(modal); setModal(modal);
} else {
this.modalityType = localModalityType;
} }
this.resizable = fields.get("resizable", true);
this.undecorated = fields.get("undecorated", false);
this.title = (String)fields.get("title", "");
blockedWindows = new IdentityArrayList<>(); blockedWindows = new IdentityArrayList<>();
SunToolkit.checkAndSetPolicy(this);
initialized = true;
} }
/* /*
......
...@@ -171,7 +171,7 @@ public class EventQueue { ...@@ -171,7 +171,7 @@ public class EventQueue {
* The modifiers field of the current event, if the current event is an * The modifiers field of the current event, if the current event is an
* InputEvent or ActionEvent. * InputEvent or ActionEvent.
*/ */
private WeakReference currentEvent; private WeakReference<AWTEvent> currentEvent;
/* /*
* Non-zero if a thread is waiting in getNextEvent(int) for an event of * Non-zero if a thread is waiting in getNextEvent(int) for an event of
...@@ -194,7 +194,8 @@ public class EventQueue { ...@@ -194,7 +194,8 @@ public class EventQueue {
} }
public void removeSourceEvents(EventQueue eventQueue, public void removeSourceEvents(EventQueue eventQueue,
Object source, Object source,
boolean removeAllEvents) { boolean removeAllEvents)
{
eventQueue.removeSourceEvents(source, removeAllEvents); eventQueue.removeSourceEvents(source, removeAllEvents);
} }
public boolean noEvents(EventQueue eventQueue) { public boolean noEvents(EventQueue eventQueue) {
...@@ -203,6 +204,11 @@ public class EventQueue { ...@@ -203,6 +204,11 @@ public class EventQueue {
public void wakeup(EventQueue eventQueue, boolean isShutdown) { public void wakeup(EventQueue eventQueue, boolean isShutdown) {
eventQueue.wakeup(isShutdown); eventQueue.wakeup(isShutdown);
} }
public void invokeAndWait(Object source, Runnable r)
throws InterruptedException, InvocationTargetException
{
EventQueue.invokeAndWait(source, r);
}
}); });
} }
...@@ -809,7 +815,7 @@ public class EventQueue { ...@@ -809,7 +815,7 @@ public class EventQueue {
pushPopLock.lock(); pushPopLock.lock();
try { try {
return (Thread.currentThread() == dispatchThread) return (Thread.currentThread() == dispatchThread)
? ((AWTEvent)currentEvent.get()) ? currentEvent.get()
: null; : null;
} finally { } finally {
pushPopLock.unlock(); pushPopLock.unlock();
...@@ -1167,7 +1173,7 @@ public class EventQueue { ...@@ -1167,7 +1173,7 @@ public class EventQueue {
return; return;
} }
currentEvent = new WeakReference(e); currentEvent = new WeakReference<>(e);
// This series of 'instanceof' checks should be replaced with a // This series of 'instanceof' checks should be replaced with a
// polymorphic type (for example, an interface which declares a // polymorphic type (for example, an interface which declares a
...@@ -1245,8 +1251,14 @@ public class EventQueue { ...@@ -1245,8 +1251,14 @@ public class EventQueue {
* @since 1.2 * @since 1.2
*/ */
public static void invokeAndWait(Runnable runnable) public static void invokeAndWait(Runnable runnable)
throws InterruptedException, InvocationTargetException { throws InterruptedException, InvocationTargetException
{
invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
}
static void invokeAndWait(Object source, Runnable runnable)
throws InterruptedException, InvocationTargetException
{
if (EventQueue.isDispatchThread()) { if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread"); throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
} }
...@@ -1255,8 +1267,7 @@ public class EventQueue { ...@@ -1255,8 +1267,7 @@ public class EventQueue {
Object lock = new AWTInvocationLock(); Object lock = new AWTInvocationLock();
InvocationEvent event = InvocationEvent event =
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock, new InvocationEvent(source, runnable, lock, true);
true);
synchronized (lock) { synchronized (lock) {
Toolkit.getEventQueue().postEvent(event); Toolkit.getEventQueue().postEvent(event);
......
...@@ -66,7 +66,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -66,7 +66,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
AWTAccessor.setMenuAccessor( AWTAccessor.setMenuAccessor(
new AWTAccessor.MenuAccessor() { new AWTAccessor.MenuAccessor() {
public Vector getItems(Menu menu) { public Vector<MenuComponent> getItems(Menu menu) {
return menu.items; return menu.items;
} }
}); });
...@@ -78,7 +78,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -78,7 +78,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
* @serial * @serial
* @see #countItems() * @see #countItems()
*/ */
Vector items = new Vector(); Vector<MenuComponent> items = new Vector<>();
/** /**
* This field indicates whether the menu has the * This field indicates whether the menu has the
...@@ -313,7 +313,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -313,7 +313,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
} }
int nitems = getItemCount(); int nitems = getItemCount();
Vector tempItems = new Vector(); Vector<MenuItem> tempItems = new Vector<>();
/* Remove the item at index, nitems-index times /* Remove the item at index, nitems-index times
storing them in a temporary vector in the storing them in a temporary vector in the
...@@ -330,7 +330,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -330,7 +330,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
already in the correct order in the temp vector. already in the correct order in the temp vector.
*/ */
for (int i = 0; i < tempItems.size() ; i++) { for (int i = 0; i < tempItems.size() ; i++) {
add((MenuItem)tempItems.elementAt(i)); add(tempItems.elementAt(i));
} }
} }
} }
...@@ -379,7 +379,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -379,7 +379,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
} }
int nitems = getItemCount(); int nitems = getItemCount();
Vector tempItems = new Vector(); Vector<MenuItem> tempItems = new Vector<>();
/* Remove the item at index, nitems-index times /* Remove the item at index, nitems-index times
storing them in a temporary vector in the storing them in a temporary vector in the
...@@ -396,7 +396,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -396,7 +396,7 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
already in the correct order in the temp vector. already in the correct order in the temp vector.
*/ */
for (int i = 0; i < tempItems.size() ; i++) { for (int i = 0; i < tempItems.size() ; i++) {
add((MenuItem)tempItems.elementAt(i)); add(tempItems.elementAt(i));
} }
} }
} }
...@@ -475,13 +475,13 @@ public class Menu extends MenuItem implements MenuContainer, Accessible { ...@@ -475,13 +475,13 @@ public class Menu extends MenuItem implements MenuContainer, Accessible {
return null; return null;
} }
synchronized Enumeration shortcuts() { synchronized Enumeration<MenuShortcut> shortcuts() {
Vector shortcuts = new Vector(); Vector<MenuShortcut> shortcuts = new Vector<>();
int nitems = getItemCount(); int nitems = getItemCount();
for (int i = 0 ; i < nitems ; i++) { for (int i = 0 ; i < nitems ; i++) {
MenuItem mi = getItem(i); MenuItem mi = getItem(i);
if (mi instanceof Menu) { if (mi instanceof Menu) {
Enumeration e = ((Menu)mi).shortcuts(); Enumeration<MenuShortcut> e = ((Menu)mi).shortcuts();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
shortcuts.addElement(e.nextElement()); shortcuts.addElement(e.nextElement());
} }
......
...@@ -81,7 +81,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -81,7 +81,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
return menuBar.helpMenu; return menuBar.helpMenu;
} }
public Vector getMenus(MenuBar menuBar) { public Vector<Menu> getMenus(MenuBar menuBar) {
return menuBar.menus; return menuBar.menus;
} }
}); });
...@@ -94,7 +94,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -94,7 +94,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* @serial * @serial
* @see #countMenus() * @see #countMenus()
*/ */
Vector menus = new Vector(); Vector<Menu> menus = new Vector<>();
/** /**
* This menu is a special menu dedicated to * This menu is a special menu dedicated to
...@@ -309,7 +309,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -309,7 +309,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* be called on the toolkit thread. * be called on the toolkit thread.
*/ */
final Menu getMenuImpl(int i) { final Menu getMenuImpl(int i) {
return (Menu)menus.elementAt(i); return menus.elementAt(i);
} }
/** /**
...@@ -321,10 +321,10 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -321,10 +321,10 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
* @since JDK1.1 * @since JDK1.1
*/ */
public synchronized Enumeration<MenuShortcut> shortcuts() { public synchronized Enumeration<MenuShortcut> shortcuts() {
Vector shortcuts = new Vector(); Vector<MenuShortcut> shortcuts = new Vector<>();
int nmenus = getMenuCount(); int nmenus = getMenuCount();
for (int i = 0 ; i < nmenus ; i++) { for (int i = 0 ; i < nmenus ; i++) {
Enumeration e = getMenu(i).shortcuts(); Enumeration<MenuShortcut> e = getMenu(i).shortcuts();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
shortcuts.addElement(e.nextElement()); shortcuts.addElement(e.nextElement());
} }
...@@ -438,7 +438,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible ...@@ -438,7 +438,7 @@ public class MenuBar extends MenuComponent implements MenuContainer, Accessible
// HeadlessException will be thrown from MenuComponent's readObject // HeadlessException will be thrown from MenuComponent's readObject
s.defaultReadObject(); s.defaultReadObject();
for (int i = 0; i < menus.size(); i++) { for (int i = 0; i < menus.size(); i++) {
Menu m = (Menu)menus.elementAt(i); Menu m = menus.elementAt(i);
m.parent = this; m.parent = this;
} }
} }
......
...@@ -290,7 +290,7 @@ public abstract class MenuComponent implements java.io.Serializable { ...@@ -290,7 +290,7 @@ public abstract class MenuComponent implements java.io.Serializable {
public void setFont(Font f) { public void setFont(Font f) {
font = f; font = f;
//Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font) //Fixed 6312943: NullPointerException in method MenuComponent.setFont(Font)
MenuComponentPeer peer = (MenuComponentPeer)this.peer; MenuComponentPeer peer = this.peer;
if (peer != null) { if (peer != null) {
peer.setFont(f); peer.setFont(f);
} }
...@@ -303,7 +303,7 @@ public abstract class MenuComponent implements java.io.Serializable { ...@@ -303,7 +303,7 @@ public abstract class MenuComponent implements java.io.Serializable {
*/ */
public void removeNotify() { public void removeNotify() {
synchronized (getTreeLock()) { synchronized (getTreeLock()) {
MenuComponentPeer p = (MenuComponentPeer)this.peer; MenuComponentPeer p = this.peer;
if (p != null) { if (p != null) {
Toolkit.getEventQueue().removeSourceEvents(this, true); Toolkit.getEventQueue().removeSourceEvents(this, true);
this.peer = null; this.peer = null;
......
...@@ -564,7 +564,7 @@ public class MenuItem extends MenuComponent implements Accessible { ...@@ -564,7 +564,7 @@ public class MenuItem extends MenuComponent implements Accessible {
* @since 1.4 * @since 1.4
*/ */
public synchronized ActionListener[] getActionListeners() { public synchronized ActionListener[] getActionListeners() {
return (ActionListener[])(getListeners(ActionListener.class)); return getListeners(ActionListener.class);
} }
/** /**
......
...@@ -92,7 +92,7 @@ public class RenderingHints ...@@ -92,7 +92,7 @@ public class RenderingHints
* {@code equals()} method. * {@code equals()} method.
*/ */
public abstract static class Key { public abstract static class Key {
private static HashMap identitymap = new HashMap(17); private static HashMap<Object,Object> identitymap = new HashMap<>(17);
private String getIdentity() { private String getIdentity() {
// Note that the identity string is dependent on 3 variables: // Note that the identity string is dependent on 3 variables:
...@@ -138,7 +138,7 @@ public class RenderingHints ...@@ -138,7 +138,7 @@ public class RenderingHints
} }
// Note: Use a weak reference to avoid holding on to extra // Note: Use a weak reference to avoid holding on to extra
// objects and classes after they should be unloaded. // objects and classes after they should be unloaded.
identitymap.put(identity, new WeakReference(k)); identitymap.put(identity, new WeakReference<Key>(k));
} }
private int privatekey; private int privatekey;
...@@ -195,7 +195,7 @@ public class RenderingHints ...@@ -195,7 +195,7 @@ public class RenderingHints
} }
} }
HashMap hintmap = new HashMap(7); HashMap<Object,Object> hintmap = new HashMap<>(7);
/** /**
* Antialiasing hint key. * Antialiasing hint key.
...@@ -1267,12 +1267,13 @@ public class RenderingHints ...@@ -1267,12 +1267,13 @@ public class RenderingHints
* object. * object.
* @return a clone of this instance. * @return a clone of this instance.
*/ */
@SuppressWarnings("unchecked")
public Object clone() { public Object clone() {
RenderingHints rh; RenderingHints rh;
try { try {
rh = (RenderingHints) super.clone(); rh = (RenderingHints) super.clone();
if (hintmap != null) { if (hintmap != null) {
rh.hintmap = (HashMap) hintmap.clone(); rh.hintmap = (HashMap<Object,Object>) hintmap.clone();
} }
} catch (CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable // this shouldn't happen, since we are Cloneable
......
...@@ -109,12 +109,6 @@ public class TextComponent extends Component implements Accessible { ...@@ -109,12 +109,6 @@ public class TextComponent extends Component implements Accessible {
// the background color of non-editable TextComponents. // the background color of non-editable TextComponents.
boolean backgroundSetByClientCode = false; boolean backgroundSetByClientCode = false;
/**
* True if this <code>TextComponent</code> has access
* to the System clipboard.
*/
transient private boolean canAccessClipboard;
transient protected TextListener textListener; transient protected TextListener textListener;
/* /*
...@@ -139,7 +133,6 @@ public class TextComponent extends Component implements Accessible { ...@@ -139,7 +133,6 @@ public class TextComponent extends Component implements Accessible {
GraphicsEnvironment.checkHeadless(); GraphicsEnvironment.checkHeadless();
this.text = (text != null) ? text : ""; this.text = (text != null) ? text : "";
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
checkSystemClipboardAccess();
} }
private void enableInputMethodsIfNecessary() { private void enableInputMethodsIfNecessary() {
...@@ -734,17 +727,14 @@ public class TextComponent extends Component implements Accessible { ...@@ -734,17 +727,14 @@ public class TextComponent extends Component implements Accessible {
/** /**
* Assigns a valid value to the canAccessClipboard instance variable. * Assigns a valid value to the canAccessClipboard instance variable.
*/ */
private void checkSystemClipboardAccess() { private boolean canAccessClipboard() {
canAccessClipboard = true;
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm == null) return true;
try { try {
sm.checkSystemClipboardAccess(); sm.checkSystemClipboardAccess();
} return true;
catch (SecurityException e) { } catch (SecurityException e) {}
canAccessClipboard = false; return false;
}
}
} }
/* /*
...@@ -827,7 +817,6 @@ public class TextComponent extends Component implements Accessible { ...@@ -827,7 +817,6 @@ public class TextComponent extends Component implements Accessible {
} }
} }
enableInputMethodsIfNecessary(); enableInputMethodsIfNecessary();
checkSystemClipboardAccess();
} }
......
...@@ -1206,7 +1206,7 @@ public class Window extends Container implements Accessible { ...@@ -1206,7 +1206,7 @@ public class Window extends Container implements Accessible {
} }
else { else {
try { try {
EventQueue.invokeAndWait(action); EventQueue.invokeAndWait(this, action);
} }
catch (InterruptedException e) { catch (InterruptedException e) {
System.err.println("Disposal was interrupted:"); System.err.println("Disposal was interrupted:");
......
...@@ -71,7 +71,7 @@ public class Clipboard { ...@@ -71,7 +71,7 @@ public class Clipboard {
* *
* @since 1.5 * @since 1.5
*/ */
private Set currentDataFlavors; private Set<DataFlavor> currentDataFlavors;
/** /**
* Creates a clipboard object. * Creates a clipboard object.
...@@ -313,7 +313,7 @@ public class Clipboard { ...@@ -313,7 +313,7 @@ public class Clipboard {
if (flavorListeners == null) { if (flavorListeners == null) {
return; return;
} }
Set prevDataFlavors = currentDataFlavors; Set<DataFlavor> prevDataFlavors = currentDataFlavors;
currentDataFlavors = getAvailableDataFlavorSet(); currentDataFlavors = getAvailableDataFlavorSet();
if (prevDataFlavors.equals(currentDataFlavors)) { if (prevDataFlavors.equals(currentDataFlavors)) {
return; return;
...@@ -339,8 +339,8 @@ public class Clipboard { ...@@ -339,8 +339,8 @@ public class Clipboard {
* *
* @since 1.5 * @since 1.5
*/ */
private Set getAvailableDataFlavorSet() { private Set<DataFlavor> getAvailableDataFlavorSet() {
Set set = new HashSet(); Set<DataFlavor> set = new HashSet<>();
Transferable contents = getContents(null); Transferable contents = getContents(null);
if (contents != null) { if (contents != null) {
DataFlavor[] flavors = contents.getTransferDataFlavors(); DataFlavor[] flavors = contents.getTransferDataFlavors();
......
...@@ -165,7 +165,7 @@ public class DragGestureEvent extends EventObject { ...@@ -165,7 +165,7 @@ public class DragGestureEvent extends EventObject {
* <P> * <P>
* @return an Iterator for the events comprising the gesture * @return an Iterator for the events comprising the gesture
*/ */
@SuppressWarnings("unchecked")
public Iterator<InputEvent> iterator() { return events.iterator(); } public Iterator<InputEvent> iterator() { return events.iterator(); }
/** /**
...@@ -184,7 +184,7 @@ public class DragGestureEvent extends EventObject { ...@@ -184,7 +184,7 @@ public class DragGestureEvent extends EventObject {
* <P> * <P>
* @return an array of the events comprising the gesture * @return an array of the events comprising the gesture
*/ */
@SuppressWarnings("unchecked")
public Object[] toArray(Object[] array) { return events.toArray(array); } public Object[] toArray(Object[] array) { return events.toArray(array); }
/** /**
...@@ -333,7 +333,6 @@ public class DragGestureEvent extends EventObject { ...@@ -333,7 +333,6 @@ public class DragGestureEvent extends EventObject {
component = (Component)f.get("component", null); component = (Component)f.get("component", null);
origin = (Point)f.get("origin", null); origin = (Point)f.get("origin", null);
action = f.get("action", 0); action = f.get("action", 0);
// Pre-1.4 support. 'events' was previously non-transient // Pre-1.4 support. 'events' was previously non-transient
try { try {
events = (List)f.get("events", null); events = (List)f.get("events", null);
...@@ -351,7 +350,7 @@ public class DragGestureEvent extends EventObject { ...@@ -351,7 +350,7 @@ public class DragGestureEvent extends EventObject {
/* /*
* fields * fields
*/ */
@SuppressWarnings("rawtypes")
private transient List events; private transient List events;
/** /**
......
...@@ -297,7 +297,7 @@ public abstract class DragGestureRecognizer implements Serializable { ...@@ -297,7 +297,7 @@ public abstract class DragGestureRecognizer implements Serializable {
* @return the initial event that triggered the drag gesture * @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 * Reset the Recognizer, if its currently recognizing a gesture, ignore
......
...@@ -600,7 +600,7 @@ public class DragSource implements Serializable { ...@@ -600,7 +600,7 @@ public class DragSource implements Serializable {
* @since 1.4 * @since 1.4
*/ */
public DragSourceListener[] getDragSourceListeners() { public DragSourceListener[] getDragSourceListeners() {
return (DragSourceListener[])getListeners(DragSourceListener.class); return getListeners(DragSourceListener.class);
} }
/** /**
...@@ -660,8 +660,7 @@ public class DragSource implements Serializable { ...@@ -660,8 +660,7 @@ public class DragSource implements Serializable {
* @since 1.4 * @since 1.4
*/ */
public DragSourceMotionListener[] getDragSourceMotionListeners() { public DragSourceMotionListener[] getDragSourceMotionListeners() {
return (DragSourceMotionListener[]) return getListeners(DragSourceMotionListener.class);
getListeners(DragSourceMotionListener.class);
} }
/** /**
...@@ -896,8 +895,8 @@ public class DragSource implements Serializable { ...@@ -896,8 +895,8 @@ public class DragSource implements Serializable {
* @since 1.5 * @since 1.5
*/ */
public static int getDragThreshold() { public static int getDragThreshold() {
int ts = ((Integer)AccessController.doPrivileged( int ts = AccessController.doPrivileged(
new GetIntegerAction("awt.dnd.drag.threshold", 0))).intValue(); new GetIntegerAction("awt.dnd.drag.threshold", 0)).intValue();
if (ts > 0) { if (ts > 0) {
return ts; return ts;
} else { } else {
......
...@@ -36,6 +36,8 @@ package java.awt.dnd; ...@@ -36,6 +36,8 @@ package java.awt.dnd;
public class InvalidDnDOperationException extends IllegalStateException { 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"; static private String dft_msg = "The operation requested cannot be performed by the DnD system since it is not in the appropriate state";
/** /**
......
...@@ -876,6 +876,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -876,6 +876,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
* they have not been cached. * they have not been cached.
* @see #getType * @see #getType
*/ */
@SuppressWarnings("fallthrough")
private void calculateType() { private void calculateType() {
int ret = TYPE_IDENTITY; int ret = TYPE_IDENTITY;
boolean sgn0, sgn1; boolean sgn0, sgn1;
...@@ -1038,6 +1039,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -1038,6 +1039,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
* @see #TYPE_UNIFORM_SCALE * @see #TYPE_UNIFORM_SCALE
* @since 1.2 * @since 1.2
*/ */
@SuppressWarnings("fallthrough")
public double getDeterminant() { public double getDeterminant() {
switch (state) { switch (state) {
default: default:
...@@ -1250,6 +1252,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -1250,6 +1252,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
m02 = tx * m00 + ty * m01 + m02; m02 = tx * m00 + ty * m01 + m02;
m12 = tx * m10 + ty * m11 + m12; m12 = tx * m10 + ty * m11 + m12;
...@@ -1631,6 +1634,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -1631,6 +1634,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
* Y axis direction * Y axis direction
* @since 1.2 * @since 1.2
*/ */
@SuppressWarnings("fallthrough")
public void scale(double sx, double sy) { public void scale(double sx, double sy) {
int state = this.state; int state = this.state;
switch (state) { switch (state) {
...@@ -1705,6 +1709,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -1705,6 +1709,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
case (APPLY_SHEAR | APPLY_SCALE): case (APPLY_SHEAR | APPLY_SCALE):
double M0, M1; double M0, M1;
...@@ -2224,6 +2229,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -2224,6 +2229,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
* @see #preConcatenate * @see #preConcatenate
* @since 1.2 * @since 1.2
*/ */
@SuppressWarnings("fallthrough")
public void concatenate(AffineTransform Tx) { public void concatenate(AffineTransform Tx) {
double M0, M1; double M0, M1;
double T00, T01, T10, T11; double T00, T01, T10, T11;
...@@ -2432,6 +2438,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -2432,6 +2438,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
* @see #concatenate * @see #concatenate
* @since 1.2 * @since 1.2
*/ */
@SuppressWarnings("fallthrough")
public void preConcatenate(AffineTransform Tx) { public void preConcatenate(AffineTransform Tx) {
double M0, M1; double M0, M1;
double T00, T01, T10, T11; double T00, T01, T10, T11;
...@@ -2655,6 +2662,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -2655,6 +2662,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return null;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
det = m00 * m11 - m01 * m10; det = m00 * m11 - m01 * m10;
if (Math.abs(det) <= Double.MIN_VALUE) { if (Math.abs(det) <= Double.MIN_VALUE) {
...@@ -2751,6 +2759,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -2751,6 +2759,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02; M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12; M10 = m10; M11 = m11; M12 = m12;
...@@ -2885,6 +2894,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -2885,6 +2894,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return null;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
ptDst.setLocation(x * m00 + y * m01 + m02, ptDst.setLocation(x * m00 + y * m01 + m02,
x * m10 + y * m11 + m12); x * m10 + y * m11 + m12);
...@@ -2968,6 +2978,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -2968,6 +2978,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
dst.setLocation(x * m00 + y * m01 + m02, dst.setLocation(x * m00 + y * m01 + m02,
x * m10 + y * m11 + m12); x * m10 + y * m11 + m12);
...@@ -3043,6 +3054,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3043,6 +3054,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02; M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12; M10 = m10; M11 = m11; M12 = m12;
...@@ -3157,6 +3169,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3157,6 +3169,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02; M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12; M10 = m10; M11 = m11; M12 = m12;
...@@ -3252,6 +3265,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3252,6 +3265,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02; M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12; M10 = m10; M11 = m11; M12 = m12;
...@@ -3347,6 +3361,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3347,6 +3361,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02; M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12; M10 = m10; M11 = m11; M12 = m12;
...@@ -3436,6 +3451,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3436,6 +3451,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
* inverted. * inverted.
* @since 1.2 * @since 1.2
*/ */
@SuppressWarnings("fallthrough")
public Point2D inverseTransform(Point2D ptSrc, Point2D ptDst) public Point2D inverseTransform(Point2D ptSrc, Point2D ptDst)
throws NoninvertibleTransformException throws NoninvertibleTransformException
{ {
...@@ -3547,6 +3563,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3547,6 +3563,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
M00 = m00; M01 = m01; M02 = m02; M00 = m00; M01 = m01; M02 = m02;
M10 = m10; M11 = m11; M12 = m12; M10 = m10; M11 = m11; M12 = m12;
...@@ -3679,6 +3696,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3679,6 +3696,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return null;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
case (APPLY_SHEAR | APPLY_SCALE): case (APPLY_SHEAR | APPLY_SCALE):
ptDst.setLocation(x * m00 + y * m01, x * m10 + y * m11); ptDst.setLocation(x * m00 + y * m01, x * m10 + y * m11);
...@@ -3754,6 +3772,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable { ...@@ -3754,6 +3772,7 @@ public class AffineTransform implements Cloneable, java.io.Serializable {
default: default:
stateError(); stateError();
/* NOTREACHED */ /* NOTREACHED */
return;
case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):
case (APPLY_SHEAR | APPLY_SCALE): case (APPLY_SHEAR | APPLY_SCALE):
M00 = m00; M01 = m01; M00 = m00; M01 = m01;
......
...@@ -125,4 +125,10 @@ public interface FramePeer extends WindowPeer { ...@@ -125,4 +125,10 @@ public interface FramePeer extends WindowPeer {
// into an EmbeddedFramePeer which would extend FramePeer // into an EmbeddedFramePeer which would extend FramePeer
Rectangle getBoundsPrivate(); Rectangle getBoundsPrivate();
/**
* Requests the peer to emulate window activation.
*
* @param activate activate or deactivate the window
*/
void emulateActivation(boolean activate);
} }
...@@ -27,8 +27,6 @@ package java.awt.peer; ...@@ -27,8 +27,6 @@ package java.awt.peer;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage;
/** /**
* The peer interface for {@link Window}. * The peer interface for {@link Window}.
* *
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -109,10 +109,6 @@ public class PropertyDescriptor extends FeatureDescriptor { ...@@ -109,10 +109,6 @@ public class PropertyDescriptor extends FeatureDescriptor {
if (writeMethodName != null && getWriteMethod() == null) { if (writeMethodName != null && getWriteMethod() == null) {
throw new IntrospectionException("Method not found: " + writeMethodName); 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, // If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound". // then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method. // See Introspector.getTargetPropertyInfo() method.
...@@ -163,7 +159,6 @@ public class PropertyDescriptor extends FeatureDescriptor { ...@@ -163,7 +159,6 @@ public class PropertyDescriptor extends FeatureDescriptor {
setReadMethod(read); setReadMethod(read);
setWriteMethod(write); setWriteMethod(write);
this.baseName = base; this.baseName = base;
boundInitialization(bean);
} }
/** /**
......
...@@ -1752,6 +1752,12 @@ public class ObjectInputStream ...@@ -1752,6 +1752,12 @@ public class ObjectInputStream
ObjectStreamClass desc = readClassDesc(false); ObjectStreamClass desc = readClassDesc(false);
desc.checkDeserialize(); desc.checkDeserialize();
Class<?> cl = desc.forClass();
if (cl == String.class || cl == Class.class
|| cl == ObjectStreamClass.class) {
throw new InvalidClassException("invalid class descriptor");
}
Object obj; Object obj;
try { try {
obj = desc.isInstantiable() ? desc.newInstance() : null; obj = desc.isInstantiable() ? desc.newInstance() : null;
......
...@@ -64,7 +64,9 @@ import sun.reflect.generics.repository.ConstructorRepository; ...@@ -64,7 +64,9 @@ import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope; import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import sun.reflect.annotation.*; import sun.reflect.annotation.*;
import sun.reflect.misc.ReflectUtil;
/** /**
* Instances of the class {@code Class} represent classes and * Instances of the class {@code Class} represent classes and
...@@ -251,11 +253,11 @@ public final ...@@ -251,11 +253,11 @@ public final
ClassLoader loader) ClassLoader loader)
throws ClassNotFoundException throws ClassNotFoundException
{ {
if (loader == null) { if (sun.misc.VM.isSystemDomainLoader(loader)) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
if (sm != null) { if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader(); ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl != null) { if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission( sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION); SecurityConstants.GET_CLASSLOADER_PERMISSION);
} }
...@@ -320,7 +322,7 @@ public final ...@@ -320,7 +322,7 @@ public final
throws InstantiationException, IllegalAccessException throws InstantiationException, IllegalAccessException
{ {
if (System.getSecurityManager() != null) { if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
} }
return newInstance0(); return newInstance0();
} }
...@@ -1300,7 +1302,7 @@ public final ...@@ -1300,7 +1302,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
// Privileged so this implementation can look at DECLARED classes, // Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here // something the caller might not have privilege to do. The code here
...@@ -1375,7 +1377,7 @@ public final ...@@ -1375,7 +1377,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetPublicFields(null)); return copyFields(privateGetPublicFields(null));
} }
...@@ -1426,7 +1428,7 @@ public final ...@@ -1426,7 +1428,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetPublicMethods()); return copyMethods(privateGetPublicMethods());
} }
...@@ -1475,7 +1477,7 @@ public final ...@@ -1475,7 +1477,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(true)); return copyConstructors(privateGetDeclaredConstructors(true));
} }
...@@ -1534,7 +1536,7 @@ public final ...@@ -1534,7 +1536,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Field field = getField0(name); Field field = getField0(name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
...@@ -1619,7 +1621,7 @@ public final ...@@ -1619,7 +1621,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
Method method = getMethod0(name, parameterTypes); Method method = getMethod0(name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
...@@ -1673,7 +1675,7 @@ public final ...@@ -1673,7 +1675,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.PUBLIC); return getConstructor0(parameterTypes, Member.PUBLIC);
} }
...@@ -1715,7 +1717,7 @@ public final ...@@ -1715,7 +1717,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
return getDeclaredClasses0(); return getDeclaredClasses0();
} }
...@@ -1759,7 +1761,7 @@ public final ...@@ -1759,7 +1761,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyFields(privateGetDeclaredFields(false)); return copyFields(privateGetDeclaredFields(false));
} }
...@@ -1807,7 +1809,7 @@ public final ...@@ -1807,7 +1809,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyMethods(privateGetDeclaredMethods(false)); return copyMethods(privateGetDeclaredMethods(false));
} }
...@@ -1852,7 +1854,7 @@ public final ...@@ -1852,7 +1854,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return copyConstructors(privateGetDeclaredConstructors(false)); return copyConstructors(privateGetDeclaredConstructors(false));
} }
...@@ -1896,7 +1898,7 @@ public final ...@@ -1896,7 +1898,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Field field = searchFields(privateGetDeclaredFields(false), name); Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
...@@ -1951,7 +1953,7 @@ public final ...@@ -1951,7 +1953,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes)); throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
...@@ -2001,7 +2003,7 @@ public final ...@@ -2001,7 +2003,7 @@ public final
// be very careful not to change the stack depth of this // be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons // checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess // see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader()); checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
return getConstructor0(parameterTypes, Member.DECLARED); return getConstructor0(parameterTypes, Member.DECLARED);
} }
...@@ -2171,19 +2173,27 @@ public final ...@@ -2171,19 +2173,27 @@ public final
* <p> Default policy: allow all clients access with normal Java access * <p> Default policy: allow all clients access with normal Java access
* control. * control.
*/ */
private void checkMemberAccess(int which, ClassLoader ccl) { private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
SecurityManager s = System.getSecurityManager(); SecurityManager s = System.getSecurityManager();
if (s != null) { if (s != null) {
s.checkMemberAccess(this, which); s.checkMemberAccess(this, which);
ClassLoader cl = getClassLoader0(); ClassLoader cl = getClassLoader0();
if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) { if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName(); String name = this.getName();
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
if (i != -1) { if (i != -1) {
s.checkPackageAccess(name.substring(0, i)); // skip the package access check on a proxy class in default proxy package
String pkg = name.substring(0, i);
if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
s.checkPackageAccess(pkg);
} }
} }
} }
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
} }
/** /**
......
...@@ -51,6 +51,16 @@ class DirectMethodHandle extends MethodHandle { ...@@ -51,6 +51,16 @@ class DirectMethodHandle extends MethodHandle {
private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) { private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
super(mtype, form); super(mtype, form);
if (!member.isResolved()) throw new InternalError(); if (!member.isResolved()) throw new InternalError();
if (member.getDeclaringClass().isInterface() && !member.isAbstract()) {
// Check for corner case: invokeinterface of Object method
MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
if (m != null && m.isPublic()) {
member = m;
}
}
this.member = member; this.member = member;
} }
......
...@@ -807,12 +807,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -807,12 +807,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static static
MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) { MethodHandle bindCaller(MethodHandle mh, Class<?> hostClass) {
// Do not use this function to inject calls into system classes. // Do not use this function to inject calls into system classes.
if (hostClass == null) { if (hostClass == null
hostClass = C_Trampoline; || (hostClass.isArray() ||
} else if (hostClass.isArray() ||
hostClass.isPrimitive() || hostClass.isPrimitive() ||
hostClass.getName().startsWith("java.") || hostClass.getName().startsWith("java.") ||
hostClass.getName().startsWith("sun.")) { hostClass.getName().startsWith("sun."))) {
throw new InternalError(); // does not happen, and should not anyway throw new InternalError(); // does not happen, and should not anyway
} }
// For simplicity, convert mh to a varargs-like method. // For simplicity, convert mh to a varargs-like method.
...@@ -822,23 +821,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; ...@@ -822,23 +821,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return restoreToType(bccInvoker.bindTo(vamh), mh.type()); return restoreToType(bccInvoker.bindTo(vamh), mh.type());
} }
// This class ("Trampoline") is known to be inside a dead-end class loader.
// Inject all doubtful calls into this class.
private static Class<?> C_Trampoline;
static {
Class<?> tramp = null;
try {
final int FRAME_COUNT_ARG = 1; // [0] Reflection [1] Trampoline
java.lang.reflect.Method gcc = sun.reflect.Reflection.class.getMethod("getCallerClass", int.class);
tramp = (Class<?>) sun.reflect.misc.MethodUtil.invoke(gcc, null, new Object[]{ FRAME_COUNT_ARG });
if (tramp.getClassLoader() == BindCaller.class.getClassLoader())
throw new RuntimeException(tramp.getName()+" class loader");
} catch (Throwable ex) {
throw new InternalError(ex);
}
C_Trampoline = tramp;
}
private static MethodHandle makeInjectedInvoker(Class<?> hostClass) { private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null); Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
if (hostClass.getClassLoader() != bcc.getClassLoader()) if (hostClass.getClassLoader() != bcc.getClassLoader())
......
...@@ -393,15 +393,33 @@ class MethodHandleNatives { ...@@ -393,15 +393,33 @@ class MethodHandleNatives {
*/ */
// FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive. // FIXME: Replace this pattern match by an annotation @sun.reflect.CallerSensitive.
static boolean isCallerSensitive(MemberName mem) { static boolean isCallerSensitive(MemberName mem) {
assert(mem.isInvocable()); if (!mem.isInvocable()) return false; // fields are not caller sensitive
Class<?> defc = mem.getDeclaringClass(); Class<?> defc = mem.getDeclaringClass();
switch (mem.getName()) { switch (mem.getName()) {
case "doPrivileged": case "doPrivileged":
case "doPrivilegedWithCombiner":
return defc == java.security.AccessController.class; return defc == java.security.AccessController.class;
case "checkMemberAccess":
return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
case "getUnsafe": case "getUnsafe":
return defc == sun.misc.Unsafe.class; return defc == sun.misc.Unsafe.class;
case "lookup": case "lookup":
return defc == java.lang.invoke.MethodHandles.class; return defc == java.lang.invoke.MethodHandles.class;
case "findStatic":
case "findVirtual":
case "findConstructor":
case "findSpecial":
case "findGetter":
case "findSetter":
case "findStaticGetter":
case "findStaticSetter":
case "bind":
case "unreflect":
case "unreflectSpecial":
case "unreflectConstructor":
case "unreflectGetter":
case "unreflectSetter":
return defc == java.lang.invoke.MethodHandles.Lookup.class;
case "invoke": case "invoke":
return defc == java.lang.reflect.Method.class; return defc == java.lang.reflect.Method.class;
case "get": case "get":
...@@ -455,7 +473,7 @@ class MethodHandleNatives { ...@@ -455,7 +473,7 @@ class MethodHandleNatives {
if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true; if (defc == java.util.concurrent.atomic.AtomicReferenceFieldUpdater.class) return true;
break; break;
case "getContextClassLoader": case "getContextClassLoader":
return defc == java.lang.Thread.class; return canBeCalledVirtual(mem, java.lang.Thread.class);
case "getPackage": case "getPackage":
case "getPackages": case "getPackages":
return defc == java.lang.Package.class; return defc == java.lang.Package.class;
...@@ -473,9 +491,13 @@ class MethodHandleNatives { ...@@ -473,9 +491,13 @@ class MethodHandleNatives {
break; break;
case "getCallerClassLoader": case "getCallerClassLoader":
return defc == java.lang.ClassLoader.class; return defc == java.lang.ClassLoader.class;
case "registerAsParallelCapable":
return canBeCalledVirtual(mem, java.lang.ClassLoader.class);
case "getProxyClass": case "getProxyClass":
case "newProxyInstance": case "newProxyInstance":
return defc == java.lang.reflect.Proxy.class; return defc == java.lang.reflect.Proxy.class;
case "asInterfaceInstance":
return defc == java.lang.invoke.MethodHandleProxies.class;
case "getBundle": case "getBundle":
case "clearCache": case "clearCache":
return defc == java.util.ResourceBundle.class; return defc == java.util.ResourceBundle.class;
...@@ -492,4 +514,11 @@ class MethodHandleNatives { ...@@ -492,4 +514,11 @@ class MethodHandleNatives {
throw new InternalError(e); throw new InternalError(e);
} }
} }
static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
if (symbolicRefClass == definingClass) return true;
if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false;
return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef
symbolicRefClass.isInterface()); // Mdef implements Msym
}
} }
...@@ -26,8 +26,12 @@ ...@@ -26,8 +26,12 @@
package java.lang.invoke; package java.lang.invoke;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.invoke.WrapperInstance; import sun.invoke.WrapperInstance;
import java.util.ArrayList; import java.util.ArrayList;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
/** /**
* This class consists exclusively of static methods that help adapt * This class consists exclusively of static methods that help adapt
...@@ -137,6 +141,21 @@ public class MethodHandleProxies { ...@@ -137,6 +141,21 @@ public class MethodHandleProxies {
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) { <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName()); throw new IllegalArgumentException("not a public interface: "+intfc.getName());
final MethodHandle mh;
if (System.getSecurityManager() != null) {
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
mh = ccl != null ? bindCaller(target, caller) : target;
} else {
mh = target;
}
ClassLoader proxyLoader = intfc.getClassLoader();
if (proxyLoader == null) {
ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
}
final Method[] methods = getSingleNameMethods(intfc); final Method[] methods = getSingleNameMethods(intfc);
if (methods == null) if (methods == null)
throw new IllegalArgumentException("not a single-method interface: "+intfc.getName()); throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
...@@ -144,14 +163,11 @@ public class MethodHandleProxies { ...@@ -144,14 +163,11 @@ public class MethodHandleProxies {
for (int i = 0; i < methods.length; i++) { for (int i = 0; i < methods.length; i++) {
Method sm = methods[i]; Method sm = methods[i];
MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes()); MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
MethodHandle checkTarget = target.asType(smMT); // make throw WMT MethodHandle checkTarget = mh.asType(smMT); // make throw WMT
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class)); checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount()); vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
} }
return intfc.cast(Proxy.newProxyInstance( final InvocationHandler ih = new InvocationHandler() {
intfc.getClassLoader(),
new Class<?>[]{ intfc, WrapperInstance.class },
new InvocationHandler() {
private Object getArg(String name) { private Object getArg(String name) {
if ((Object)name == "getWrapperInstanceTarget") return target; if ((Object)name == "getWrapperInstanceTarget") return target;
if ((Object)name == "getWrapperInstanceType") return intfc; if ((Object)name == "getWrapperInstanceType") return intfc;
...@@ -168,7 +184,37 @@ public class MethodHandleProxies { ...@@ -168,7 +184,37 @@ public class MethodHandleProxies {
return callObjectMethod(proxy, method, args); return callObjectMethod(proxy, method, args);
throw new InternalError("bad proxy method: "+method); throw new InternalError("bad proxy method: "+method);
} }
})); };
final Object proxy;
if (System.getSecurityManager() != null) {
// sun.invoke.WrapperInstance is a restricted interface not accessible
// by any non-null class loader.
final ClassLoader loader = proxyLoader;
proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return Proxy.newProxyInstance(
loader,
new Class<?>[]{ intfc, WrapperInstance.class },
ih);
}
});
} else {
proxy = Proxy.newProxyInstance(proxyLoader,
new Class<?>[]{ intfc, WrapperInstance.class },
ih);
}
return intfc.cast(proxy);
}
private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
if (target.isVarargsCollector()) {
MethodType type = cbmh.type();
int arity = type.parameterCount();
return cbmh.asVarargsCollector(type.parameterType(arity-1));
}
return cbmh;
} }
/** /**
......
...@@ -598,7 +598,8 @@ public class MethodHandles { ...@@ -598,7 +598,8 @@ public class MethodHandles {
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type); MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor checkSecurityManager(refc, method); // stack walk magic: do not refactor
return getDirectMethod(REF_invokeStatic, refc, method); Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
return getDirectMethod(REF_invokeStatic, refc, method, callerClass);
} }
/** /**
...@@ -652,7 +653,8 @@ public class MethodHandles { ...@@ -652,7 +653,8 @@ public class MethodHandles {
byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual); byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
MemberName method = resolveOrFail(refKind, refc, name, type); MemberName method = resolveOrFail(refKind, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor checkSecurityManager(refc, method); // stack walk magic: do not refactor
return getDirectMethod(refKind, refc, method); Class<?> callerClass = findBoundCallerClass(method);
return getDirectMethod(refKind, refc, method, callerClass);
} }
private MethodHandle findVirtualForMH(String name, MethodType type) { private MethodHandle findVirtualForMH(String name, MethodType type) {
// these names require special lookups because of the implicit MethodType argument // these names require special lookups because of the implicit MethodType argument
...@@ -736,7 +738,8 @@ public class MethodHandles { ...@@ -736,7 +738,8 @@ public class MethodHandles {
Lookup specialLookup = this.in(specialCaller); Lookup specialLookup = this.in(specialCaller);
MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type); MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor checkSecurityManager(refc, method); // stack walk magic: do not refactor
return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method); Class<?> callerClass = findBoundCallerClass(method);
return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, callerClass);
} }
/** /**
...@@ -879,7 +882,8 @@ return mh1; ...@@ -879,7 +882,8 @@ return mh1;
Class<? extends Object> refc = receiver.getClass(); // may get NPE Class<? extends Object> refc = receiver.getClass(); // may get NPE
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type); MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
checkSecurityManager(refc, method); // stack walk magic: do not refactor checkSecurityManager(refc, method); // stack walk magic: do not refactor
MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method); Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, callerClass);
return mh.bindReceiver(receiver).setVarargs(method); return mh.bindReceiver(receiver).setVarargs(method);
} }
...@@ -910,8 +914,9 @@ return mh1; ...@@ -910,8 +914,9 @@ return mh1;
if (refKind == REF_invokeSpecial) if (refKind == REF_invokeSpecial)
refKind = REF_invokeVirtual; refKind = REF_invokeVirtual;
assert(method.isMethod()); assert(method.isMethod());
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method); return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass);
} }
/** /**
...@@ -940,8 +945,9 @@ return mh1; ...@@ -940,8 +945,9 @@ return mh1;
Lookup specialLookup = this.in(specialCaller); Lookup specialLookup = this.in(specialCaller);
MemberName method = new MemberName(m, true); MemberName method = new MemberName(m, true);
assert(method.isMethod()); assert(method.isMethod());
Class<?> callerClass = findBoundCallerClass(method); // stack walk magic: do not refactor
// ignore m.isAccessible: this is a new kind of access // ignore m.isAccessible: this is a new kind of access
return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method); return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass);
} }
/** /**
...@@ -1039,8 +1045,30 @@ return mh1; ...@@ -1039,8 +1045,30 @@ return mh1;
throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
} }
/**
* Find my trustable caller class if m is a caller sensitive method.
* If this lookup object has private access, then the caller class is the lookupClass.
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This is the same caller class as is used by checkSecurityManager.
* This function performs stack walk magic: do not refactor it.
*/
Class<?> findBoundCallerClass(MemberName m) {
Class<?> callerClass = null;
if (MethodHandleNatives.isCallerSensitive(m)) {
// Do not refactor this to a more "logical" place, since it is stack walk magic.
// Note that this is the same expression as in Step 2 below in checkSecurityManager.
callerClass = ((allowedModes & PRIVATE) != 0
? lookupClass // for strong access modes, no extra check
// next line does stack walk magic; do not refactor:
: getCallerClassAtEntryPoint(true));
}
return callerClass;
}
/** /**
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>. * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Determines a trustable caller class to compare with refc, the symbolic reference class.
* If this lookup object has private access, then the caller class is the lookupClass.
* Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
* This function performs stack walk magic: do not refactor it. * This function performs stack walk magic: do not refactor it.
*/ */
void checkSecurityManager(Class<?> refc, MemberName m) { void checkSecurityManager(Class<?> refc, MemberName m) {
...@@ -1195,22 +1223,22 @@ return mh1; ...@@ -1195,22 +1223,22 @@ return mh1;
return mh.viewAsType(narrowType); return mh.viewAsType(narrowType);
} }
private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method) throws IllegalAccessException { private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
return getDirectMethodCommon(refKind, refc, method, return getDirectMethodCommon(refKind, refc, method,
(refKind == REF_invokeSpecial || (refKind == REF_invokeSpecial ||
(MethodHandleNatives.refKindHasReceiver(refKind) && (MethodHandleNatives.refKindHasReceiver(refKind) &&
restrictProtectedReceiver(method)))); restrictProtectedReceiver(method))), callerClass);
} }
private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method) throws IllegalAccessException { private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
return getDirectMethodCommon(refKind, refc, method, false); return getDirectMethodCommon(refKind, refc, method, false, callerClass);
} }
private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method, private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
boolean doRestrict) throws IllegalAccessException { boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
checkMethod(refKind, refc, method); checkMethod(refKind, refc, method);
if (method.isMethodHandleInvoke()) if (method.isMethodHandleInvoke())
return fakeMethodHandleInvoke(method); return fakeMethodHandleInvoke(method);
MethodHandle mh = DirectMethodHandle.make(refKind, refc, method); MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
mh = maybeBindCaller(method, mh); mh = maybeBindCaller(method, mh, callerClass);
mh = mh.setVarargs(method); mh = mh.setVarargs(method);
if (doRestrict) if (doRestrict)
mh = restrictReceiver(method, mh, lookupClass()); mh = restrictReceiver(method, mh, lookupClass());
...@@ -1219,12 +1247,14 @@ return mh1; ...@@ -1219,12 +1247,14 @@ return mh1;
private MethodHandle fakeMethodHandleInvoke(MemberName method) { private MethodHandle fakeMethodHandleInvoke(MemberName method) {
return throwException(method.getReturnType(), UnsupportedOperationException.class); return throwException(method.getReturnType(), UnsupportedOperationException.class);
} }
private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh) throws IllegalAccessException { private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
Class<?> callerClass)
throws IllegalAccessException {
if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method)) if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
return mh; return mh;
Class<?> hostClass = lookupClass; Class<?> hostClass = lookupClass;
if ((allowedModes & PRIVATE) == 0) // caller must use full-power lookup if ((allowedModes & PRIVATE) == 0) // caller must use full-power lookup
hostClass = null; hostClass = callerClass; // callerClass came from a security manager style stack walk
MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass); MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
// Note: caller will apply varargs after this step happens. // Note: caller will apply varargs after this step happens.
return cbmh; return cbmh;
...@@ -1262,7 +1292,7 @@ return mh1; ...@@ -1262,7 +1292,7 @@ return mh1;
} else if (MethodHandleNatives.refKindIsMethod(refKind)) { } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
MemberName method = (resolved != null) ? resolved MemberName method = (resolved != null) ? resolved
: resolveOrFail(refKind, defc, name, (MethodType) type); : resolveOrFail(refKind, defc, name, (MethodType) type);
return getDirectMethod(refKind, defc, method); return getDirectMethod(refKind, defc, method, lookupClass);
} else if (refKind == REF_newInvokeSpecial) { } else if (refKind == REF_newInvokeSpecial) {
assert(name == null || name.equals("<init>")); assert(name == null || name.equals("<init>"));
MemberName ctor = (resolved != null) ? resolved MemberName ctor = (resolved != null) ? resolved
......
...@@ -802,6 +802,11 @@ public class ManagementFactory { ...@@ -802,6 +802,11 @@ public class ManagementFactory {
*/ */
private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) { private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) {
// Make DynamicMBean out of MXBean by wrapping it with a StandardMBean // Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException {
final DynamicMBean dmbean; final DynamicMBean dmbean;
if (pmo instanceof DynamicMBean) { if (pmo instanceof DynamicMBean) {
dmbean = DynamicMBean.class.cast(pmo); dmbean = DynamicMBean.class.cast(pmo);
...@@ -811,11 +816,6 @@ public class ManagementFactory { ...@@ -811,11 +816,6 @@ public class ManagementFactory {
dmbean = new StandardMBean(pmo, null, true); dmbean = new StandardMBean(pmo, null, true);
} }
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws InstanceAlreadyExistsException,
MBeanRegistrationException,
NotCompliantMBeanException {
mbs.registerMBean(dmbean, pmo.getObjectName()); mbs.registerMBean(dmbean, pmo.getObjectName());
return null; return null;
} }
......
...@@ -27,6 +27,9 @@ package java.lang.reflect; ...@@ -27,6 +27,9 @@ package java.lang.reflect;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
...@@ -36,6 +39,9 @@ import java.util.Set; ...@@ -36,6 +39,9 @@ import java.util.Set;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import sun.misc.ProxyGenerator; import sun.misc.ProxyGenerator;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
/** /**
* {@code Proxy} provides static methods for creating dynamic proxy * {@code Proxy} provides static methods for creating dynamic proxy
...@@ -265,9 +271,69 @@ public class Proxy implements java.io.Serializable { ...@@ -265,9 +271,69 @@ public class Proxy implements java.io.Serializable {
* @param h the invocation handler for this proxy instance * @param h the invocation handler for this proxy instance
*/ */
protected Proxy(InvocationHandler h) { protected Proxy(InvocationHandler h) {
doNewInstanceCheck();
this.h = h; this.h = h;
} }
private static class ProxyAccessHelper {
// The permission is implementation specific.
static final Permission PROXY_PERMISSION =
new ReflectPermission("proxyConstructorNewInstance");
// These system properties are defined to provide a short-term
// workaround if customers need to disable the new security checks.
static final boolean allowNewInstance;
static final boolean allowNullLoader;
static {
allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
}
private static boolean getBooleanProperty(final String key) {
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(key);
}
});
return Boolean.valueOf(s);
}
static boolean needsNewInstanceCheck(Class<?> proxyClass) {
if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
return false;
}
if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
// all proxy interfaces are public
return false;
}
for (Class<?> intf : proxyClass.getInterfaces()) {
if (!Modifier.isPublic(intf.getModifiers())) {
return true;
}
}
return false;
}
}
/*
* Access check on a proxy class that implements any non-public interface.
*
* @throws SecurityException if a security manager exists, and
* the caller does not have the permission.
*/
private void doNewInstanceCheck() {
SecurityManager sm = System.getSecurityManager();
Class<?> proxyClass = this.getClass();
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
try {
sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
} catch (SecurityException e) {
throw new SecurityException("Not allowed to construct a Proxy "
+ "instance that implements a non-public interface", e);
}
}
}
/** /**
* Returns the {@code java.lang.Class} object for a proxy class * Returns the {@code java.lang.Class} object for a proxy class
* given a class loader and an array of interfaces. The proxy class * given a class loader and an array of interfaces. The proxy class
...@@ -346,6 +412,51 @@ public class Proxy implements java.io.Serializable { ...@@ -346,6 +412,51 @@ public class Proxy implements java.io.Serializable {
Class<?>... interfaces) Class<?>... interfaces)
throws IllegalArgumentException throws IllegalArgumentException
{ {
return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
}
private static void checkProxyLoader(ClassLoader ccl,
ClassLoader loader)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (loader == null && ccl != null) {
if (!ProxyAccessHelper.allowNullLoader) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
}
/*
* Generate a proxy class (caller-sensitive).
*
* To define a proxy class, it performs the access checks as in
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
* 1. "getClassLoader" permission check if loader == null
* 2. checkPackageAccess on the interfaces it implements
*
* To get a constructor and new instance of a proxy class, it performs
* the package access check on the interfaces it implements
* as in Class.getConstructor.
*
* If an interface is non-public, the proxy class must be defined by
* the defining loader of the interface. If the caller's class loader
* is not the same as the defining loader of the interface, the VM
* will throw IllegalAccessError when the generated proxy class is
* being defined via the defineClass0 method.
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
final ClassLoader ccl = caller.getClassLoader();
checkProxyLoader(ccl, loader);
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
if (interfaces.length > 65535) { if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded"); throw new IllegalArgumentException("interface limit exceeded");
} }
...@@ -497,8 +608,9 @@ public class Proxy implements java.io.Serializable { ...@@ -497,8 +608,9 @@ public class Proxy implements java.io.Serializable {
} }
} }
if (proxyPkg == null) { // if no non-public proxy interfaces, if (proxyPkg == null) {
proxyPkg = ""; // use the unnamed package // if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
} }
{ {
...@@ -598,19 +710,43 @@ public class Proxy implements java.io.Serializable { ...@@ -598,19 +710,43 @@ public class Proxy implements java.io.Serializable {
/* /*
* Look up or generate the designated proxy class. * Look up or generate the designated proxy class.
*/ */
Class<?> cl = getProxyClass(loader, interfaces); Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
/* /*
* Invoke its constructor with the designated invocation handler. * Invoke its constructor with the designated invocation handler.
*/ */
try { try {
Constructor<?> cons = cl.getConstructor(constructorParams); final Constructor<?> cons = cl.getConstructor(constructorParams);
return cons.newInstance(new Object[] { h }); final InvocationHandler ih = h;
} catch (NoSuchMethodException | SecurityManager sm = System.getSecurityManager();
IllegalAccessException | if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
InstantiationException | // create proxy instance with doPrivilege as the proxy class may
InvocationTargetException e) { // implement non-public interfaces that requires a special permission
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return newInstance(cons, ih);
}
});
} else {
return newInstance(cons, ih);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
try {
return cons.newInstance(new Object[] {h} );
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString(), e); throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} }
} }
......
/* /*
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -24,9 +24,12 @@ ...@@ -24,9 +24,12 @@
*/ */
package java.net; package java.net;
import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidObjectException; import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
/** /**
* *
...@@ -46,23 +49,105 @@ import java.io.InvalidObjectException; ...@@ -46,23 +49,105 @@ import java.io.InvalidObjectException;
* @see java.net.ServerSocket * @see java.net.ServerSocket
* @since 1.4 * @since 1.4
*/ */
public class InetSocketAddress extends SocketAddress { public class InetSocketAddress
/* The hostname of the Socket Address extends SocketAddress
* @serial {
*/ // Private implementation class pointed to by all public methods.
private String hostname = null; private static class InetSocketAddressHolder {
/* The IP address of the Socket Address // The hostname of the Socket Address
* @serial private String hostname;
*/ // The IP address of the Socket Address
private InetAddress addr = null; private InetAddress addr;
/* The port number of the Socket Address // The port number of the Socket Address
* @serial
*/
private int port; private int port;
private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
this.hostname = hostname;
this.addr = addr;
this.port = port;
}
private int getPort() {
return port;
}
private InetAddress getAddress() {
return addr;
}
private String getHostName() {
if (hostname != null)
return hostname;
if (addr != null)
return addr.getHostName();
return null;
}
private String getHostString() {
if (hostname != null)
return hostname;
if (addr != null) {
if (addr.hostName != null)
return addr.hostName;
else
return addr.getHostAddress();
}
return null;
}
private boolean isUnresolved() {
return addr == null;
}
@Override
public String toString() {
if (isUnresolved()) {
return hostname + ":" + port;
} else {
return addr.toString() + ":" + port;
}
}
@Override
public final boolean equals(Object obj) {
if (obj == null || !(obj instanceof InetSocketAddressHolder))
return false;
InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
boolean sameIP;
if (addr != null)
sameIP = addr.equals(that.addr);
else if (hostname != null)
sameIP = (that.addr == null) &&
hostname.equalsIgnoreCase(that.hostname);
else
sameIP = (that.addr == null) && (that.hostname == null);
return sameIP && (port == that.port);
}
@Override
public final int hashCode() {
if (addr != null)
return addr.hashCode() + port;
if (hostname != null)
return hostname.toLowerCase().hashCode() + port;
return port;
}
}
private final transient InetSocketAddressHolder holder;
private static final long serialVersionUID = 5076001401234631237L; private static final long serialVersionUID = 5076001401234631237L;
private InetSocketAddress() { private static int checkPort(int port) {
if (port < 0 || port > 0xFFFF)
throw new IllegalArgumentException("port out of range:" + port);
return port;
}
private static String checkHost(String hostname) {
if (hostname == null)
throw new IllegalArgumentException("hostname can't be null");
return hostname;
} }
/** /**
...@@ -97,14 +182,10 @@ public class InetSocketAddress extends SocketAddress { ...@@ -97,14 +182,10 @@ public class InetSocketAddress extends SocketAddress {
* range of valid port values. * range of valid port values.
*/ */
public InetSocketAddress(InetAddress addr, int port) { public InetSocketAddress(InetAddress addr, int port) {
if (port < 0 || port > 0xFFFF) { holder = new InetSocketAddressHolder(
throw new IllegalArgumentException("port out of range:" + port); null,
} addr == null ? InetAddress.anyLocalAddress() : addr,
this.port = port; checkPort(port));
if (addr == null)
this.addr = InetAddress.anyLocalAddress();
else
this.addr = addr;
} }
/** /**
...@@ -132,19 +213,20 @@ public class InetSocketAddress extends SocketAddress { ...@@ -132,19 +213,20 @@ public class InetSocketAddress extends SocketAddress {
* @see #isUnresolved() * @see #isUnresolved()
*/ */
public InetSocketAddress(String hostname, int port) { public InetSocketAddress(String hostname, int port) {
if (port < 0 || port > 0xFFFF) { checkHost(hostname);
throw new IllegalArgumentException("port out of range:" + port); InetAddress addr = null;
} String host = null;
if (hostname == null) {
throw new IllegalArgumentException("hostname can't be null");
}
try { try {
addr = InetAddress.getByName(hostname); addr = InetAddress.getByName(hostname);
} catch(UnknownHostException e) { } catch(UnknownHostException e) {
this.hostname = hostname; host = hostname;
addr = null;
} }
this.port = port; holder = new InetSocketAddressHolder(host, addr, checkPort(port));
}
// private constructor for creating unresolved instances
private InetSocketAddress(int port, String hostname) {
holder = new InetSocketAddressHolder(hostname, null, port);
} }
/** /**
...@@ -169,31 +251,67 @@ public class InetSocketAddress extends SocketAddress { ...@@ -169,31 +251,67 @@ public class InetSocketAddress extends SocketAddress {
* @since 1.5 * @since 1.5
*/ */
public static InetSocketAddress createUnresolved(String host, int port) { public static InetSocketAddress createUnresolved(String host, int port) {
if (port < 0 || port > 0xFFFF) { return new InetSocketAddress(checkPort(port), checkHost(host));
throw new IllegalArgumentException("port out of range:" + port);
}
if (host == null) {
throw new IllegalArgumentException("hostname can't be null");
}
InetSocketAddress s = new InetSocketAddress();
s.port = port;
s.hostname = host;
s.addr = null;
return s;
} }
private void readObject(ObjectInputStream s) /**
throws IOException, ClassNotFoundException { * @serialField hostname String
s.defaultReadObject(); * @serialField addr InetAddress
* @serialField port int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("hostname", String.class),
new ObjectStreamField("addr", InetAddress.class),
new ObjectStreamField("port", int.class)};
// Check that our invariants are satisfied private void writeObject(ObjectOutputStream out)
if (port < 0 || port > 0xFFFF) { throws IOException
throw new InvalidObjectException("port out of range:" + port); {
// Don't call defaultWriteObject()
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("hostname", holder.hostname);
pfields.put("addr", holder.addr);
pfields.put("port", holder.port);
out.writeFields();
} }
if (hostname == null && addr == null) { private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// Don't call defaultReadObject()
ObjectInputStream.GetField oisFields = in.readFields();
final String oisHostname = (String)oisFields.get("hostname", null);
final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
final int oisPort = oisFields.get("port", -1);
// Check that our invariants are satisfied
checkPort(oisPort);
if (oisHostname == null && oisAddr == null)
throw new InvalidObjectException("hostname and addr " + throw new InvalidObjectException("hostname and addr " +
"can't both be null"); "can't both be null");
InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
oisAddr,
oisPort);
UNSAFE.putObject(this, FIELDS_OFFSET, h);
}
private void readObjectNoData()
throws ObjectStreamException
{
throw new InvalidObjectException("Stream data required");
}
private static final long FIELDS_OFFSET;
private static final sun.misc.Unsafe UNSAFE;
static {
try {
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetSocketAddress.class.getDeclaredField("holder"));
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
} }
} }
...@@ -203,7 +321,7 @@ public class InetSocketAddress extends SocketAddress { ...@@ -203,7 +321,7 @@ public class InetSocketAddress extends SocketAddress {
* @return the port number. * @return the port number.
*/ */
public final int getPort() { public final int getPort() {
return port; return holder.getPort();
} }
/** /**
...@@ -213,7 +331,7 @@ public class InetSocketAddress extends SocketAddress { ...@@ -213,7 +331,7 @@ public class InetSocketAddress extends SocketAddress {
* @return the InetAdress or <code>null</code> if it is unresolved. * @return the InetAdress or <code>null</code> if it is unresolved.
*/ */
public final InetAddress getAddress() { public final InetAddress getAddress() {
return addr; return holder.getAddress();
} }
/** /**
...@@ -224,31 +342,19 @@ public class InetSocketAddress extends SocketAddress { ...@@ -224,31 +342,19 @@ public class InetSocketAddress extends SocketAddress {
* @return the hostname part of the address. * @return the hostname part of the address.
*/ */
public final String getHostName() { public final String getHostName() {
if (hostname != null) return holder.getHostName();
return hostname;
if (addr != null)
return addr.getHostName();
return null;
} }
/** /**
* Returns the hostname, or the String form of the address if it * Returns the hostname, or the String form of the address if it
* doesn't have a hostname (it was created using a literal). * doesn't have a hostname (it was created using a literal).
* This has the benefit of <b>not</b> attemptimg a reverse lookup. * This has the benefit of <b>not</b> attempting a reverse lookup.
* *
* @return the hostname, or String representation of the address. * @return the hostname, or String representation of the address.
* @since 1.7 * @since 1.7
*/ */
public final String getHostString() { public final String getHostString() {
if (hostname != null) return holder.getHostString();
return hostname;
if (addr != null) {
if (addr.hostName != null)
return addr.hostName;
else
return addr.getHostAddress();
}
return null;
} }
/** /**
...@@ -258,7 +364,7 @@ public class InetSocketAddress extends SocketAddress { ...@@ -258,7 +364,7 @@ public class InetSocketAddress extends SocketAddress {
* an <code>InetAddress</code>. * an <code>InetAddress</code>.
*/ */
public final boolean isUnresolved() { public final boolean isUnresolved() {
return addr == null; return holder.isUnresolved();
} }
/** /**
...@@ -269,12 +375,9 @@ public class InetSocketAddress extends SocketAddress { ...@@ -269,12 +375,9 @@ public class InetSocketAddress extends SocketAddress {
* *
* @return a string representation of this object. * @return a string representation of this object.
*/ */
@Override
public String toString() { public String toString() {
if (isUnresolved()) { return holder.toString();
return hostname + ":" + port;
} else {
return addr.toString() + ":" + port;
}
} }
/** /**
...@@ -297,19 +400,11 @@ public class InetSocketAddress extends SocketAddress { ...@@ -297,19 +400,11 @@ public class InetSocketAddress extends SocketAddress {
* <code>false</code> otherwise. * <code>false</code> otherwise.
* @see java.net.InetAddress#equals(java.lang.Object) * @see java.net.InetAddress#equals(java.lang.Object)
*/ */
@Override
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
if (obj == null || !(obj instanceof InetSocketAddress)) if (obj == null || !(obj instanceof InetSocketAddress))
return false; return false;
InetSocketAddress sockAddr = (InetSocketAddress) obj; return holder.equals(((InetSocketAddress) obj).holder);
boolean sameIP = false;
if (this.addr != null)
sameIP = this.addr.equals(sockAddr.addr);
else if (this.hostname != null)
sameIP = (sockAddr.addr == null) &&
this.hostname.equalsIgnoreCase(sockAddr.hostname);
else
sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null);
return sameIP && (this.port == sockAddr.port);
} }
/** /**
...@@ -317,11 +412,8 @@ public class InetSocketAddress extends SocketAddress { ...@@ -317,11 +412,8 @@ public class InetSocketAddress extends SocketAddress {
* *
* @return a hash code value for this socket address. * @return a hash code value for this socket address.
*/ */
@Override
public final int hashCode() { public final int hashCode() {
if (addr != null) return holder.hashCode();
return addr.hashCode() + port;
if (hostname != null)
return hostname.toLowerCase().hashCode() + port;
return port;
} }
} }
...@@ -34,8 +34,10 @@ ...@@ -34,8 +34,10 @@
*/ */
package java.util.concurrent; package java.util.concurrent;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.atomic.*; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*; import java.util.*;
/** /**
...@@ -491,10 +493,15 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -491,10 +493,15 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* policy limiting the number of threads. Even though it is not * policy limiting the number of threads. Even though it is not
* treated as an error, failure to create threads may result in * treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in * new tasks being rejected or existing ones remaining stuck in
* the queue. On the other hand, no special precautions exist to * the queue.
* handle OutOfMemoryErrors that might be thrown while trying to *
* create threads, since there is generally no recourse from * We go further and preserve pool invariants even in the face of
* within this class. * errors such as OutOfMemoryError, that might be thrown while
* trying to create threads. Such errors are rather common due to
* the need to allocate a native stack in Thread#start, and users
* will want to perform clean pool shutdown to clean up. There
* will likely be enough memory available for the cleanup code to
* complete without encountering yet another OutOfMemoryError.
*/ */
private volatile ThreadFactory threadFactory; private volatile ThreadFactory threadFactory;
...@@ -568,9 +575,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -568,9 +575,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* task execution. This protects against interrupts that are * task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from * intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run. We implement a simple * instead interrupting a task being run. We implement a simple
* non-reentrant mutual exclusion lock rather than use ReentrantLock * non-reentrant mutual exclusion lock rather than use
* because we do not want worker tasks to be able to reacquire the * ReentrantLock because we do not want worker tasks to be able to
* lock when they invoke pool control methods like setCorePoolSize. * reacquire the lock when they invoke pool control methods like
* setCorePoolSize. Additionally, to suppress interrupts until
* the thread actually starts running tasks, we initialize lock
* state to a negative value, and clear it upon start (in
* runWorker).
*/ */
private final class Worker private final class Worker
extends AbstractQueuedSynchronizer extends AbstractQueuedSynchronizer
...@@ -594,6 +605,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -594,6 +605,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* @param firstTask the first task (null if none) * @param firstTask the first task (null if none)
*/ */
Worker(Runnable firstTask) { Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask; this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); this.thread = getThreadFactory().newThread(this);
} }
...@@ -609,7 +621,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -609,7 +621,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
// The value 1 represents the locked state. // The value 1 represents the locked state.
protected boolean isHeldExclusively() { protected boolean isHeldExclusively() {
return getState() == 1; return getState() != 0;
} }
protected boolean tryAcquire(int unused) { protected boolean tryAcquire(int unused) {
...@@ -630,6 +642,16 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -630,6 +642,16 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
public boolean tryLock() { return tryAcquire(1); } public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); } public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); } public boolean isLocked() { return isHeldExclusively(); }
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
} }
/* /*
...@@ -728,12 +750,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -728,12 +750,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
final ReentrantLock mainLock = this.mainLock; final ReentrantLock mainLock = this.mainLock;
mainLock.lock(); mainLock.lock();
try { try {
for (Worker w : workers) { for (Worker w : workers)
try { w.interruptIfStarted();
w.thread.interrupt();
} catch (SecurityException ignore) {
}
}
} finally { } finally {
mainLock.unlock(); mainLock.unlock();
} }
...@@ -790,19 +808,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -790,19 +808,6 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
private static final boolean ONLY_ONE = true; private static final boolean ONLY_ONE = true;
/**
* Ensures that unless the pool is stopping, the current thread
* does not have its interrupt set. This requires a double-check
* of state in case the interrupt was cleared concurrently with a
* shutdownNow -- if so, the interrupt is re-enabled.
*/
private void clearInterruptsForTaskRun() {
if (runStateLessThan(ctl.get(), STOP) &&
Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))
Thread.currentThread().interrupt();
}
/* /*
* Misc utilities, most of which are also exported to * Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor * ScheduledThreadPoolExecutor
...@@ -862,12 +867,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -862,12 +867,13 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* Checks if a new worker can be added with respect to current * Checks if a new worker can be added with respect to current
* pool state and the given bound (either core or maximum). If so, * pool state and the given bound (either core or maximum). If so,
* the worker count is adjusted accordingly, and, if possible, a * the worker count is adjusted accordingly, and, if possible, a
* new worker is created and started running firstTask as its * new worker is created and started, running firstTask as its
* first task. This method returns false if the pool is stopped or * first task. This method returns false if the pool is stopped or
* eligible to shut down. It also returns false if the thread * eligible to shut down. It also returns false if the thread
* factory fails to create a thread when asked, which requires a * factory fails to create a thread when asked. If the thread
* backout of workerCount, and a recheck for termination, in case * creation fails, either due to the thread factory returning
* the existence of this worker was holding up termination. * null, or due to an exception (typically OutOfMemoryError in
* Thread#start), we roll back cleanly.
* *
* @param firstTask the task the new thread should run first (or * @param firstTask the task the new thread should run first (or
* null if none). Workers are created with an initial first task * null if none). Workers are created with an initial first task
...@@ -910,10 +916,14 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -910,10 +916,14 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
} }
} }
Worker w = new Worker(firstTask); boolean workerStarted = false;
Thread t = w.thread; boolean workerAdded = false;
Worker w = null;
try {
final ReentrantLock mainLock = this.mainLock; final ReentrantLock mainLock = this.mainLock;
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
mainLock.lock(); mainLock.lock();
try { try {
// Recheck while holding lock. // Recheck while holding lock.
...@@ -922,34 +932,49 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -922,34 +932,49 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
int c = ctl.get(); int c = ctl.get();
int rs = runStateOf(c); int rs = runStateOf(c);
if (t == null || if (rs < SHUTDOWN ||
(rs >= SHUTDOWN && (rs == SHUTDOWN && firstTask == null)) {
! (rs == SHUTDOWN && if (t.isAlive()) // precheck that t is startable
firstTask == null))) { throw new IllegalThreadStateException();
decrementWorkerCount();
tryTerminate();
return false;
}
workers.add(w); workers.add(w);
int s = workers.size(); int s = workers.size();
if (s > largestPoolSize) if (s > largestPoolSize)
largestPoolSize = s; largestPoolSize = s;
workerAdded = true;
}
} finally { } finally {
mainLock.unlock(); mainLock.unlock();
} }
if (workerAdded) {
t.start(); t.start();
// It is possible (but unlikely) for a thread to have been workerStarted = true;
// added to workers, but not yet started, during transition to }
// STOP, which could result in a rare missed interrupt, }
// because Thread.interrupt is not guaranteed to have any effect } finally {
// on a non-yet-started Thread (see Thread#interrupt). if (! workerStarted)
if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted()) addWorkerFailed(w);
t.interrupt(); }
return workerStarted;
}
return true; /**
* Rolls back the worker thread creation.
* - removes worker from workers, if present
* - decrements worker count
* - rechecks for termination, in case the existence of this
* worker was holding up termination
*/
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
workers.remove(w);
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
} }
/** /**
...@@ -1096,15 +1121,25 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -1096,15 +1121,25 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
* @param w the worker * @param w the worker
*/ */
final void runWorker(Worker w) { final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask; Runnable task = w.firstTask;
w.firstTask = null; w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true; boolean completedAbruptly = true;
try { try {
while (task != null || (task = getTask()) != null) { while (task != null || (task = getTask()) != null) {
w.lock(); w.lock();
clearInterruptsForTaskRun(); // If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try { try {
beforeExecute(w.thread, task); beforeExecute(wt, task);
Throwable thrown = null; Throwable thrown = null;
try { try {
task.run(); task.run();
...@@ -2064,3 +2099,4 @@ public class ThreadPoolExecutor extends AbstractExecutorService { ...@@ -2064,3 +2099,4 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
} }
} }
} }
...@@ -34,6 +34,7 @@ import java.security.CodeSigner; ...@@ -34,6 +34,7 @@ import java.security.CodeSigner;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.AccessController; import java.security.AccessController;
import java.security.CodeSource; import java.security.CodeSource;
import sun.misc.IOUtils;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier; import sun.security.util.ManifestEntryVerifier;
import sun.misc.SharedSecrets; import sun.misc.SharedSecrets;
...@@ -334,6 +335,9 @@ class JarFile extends ZipFile { ...@@ -334,6 +335,9 @@ class JarFile extends ZipFile {
if (names != null) { if (names != null) {
for (int i = 0; i < names.length; i++) { for (int i = 0; i < names.length; i++) {
JarEntry e = getJarEntry(names[i]); JarEntry e = getJarEntry(names[i]);
if (e == null) {
throw new JarException("corrupted jar file");
}
if (!e.isDirectory()) { if (!e.isDirectory()) {
if (mev == null) { if (mev == null) {
mev = new ManifestEntryVerifier mev = new ManifestEntryVerifier
...@@ -353,6 +357,10 @@ class JarFile extends ZipFile { ...@@ -353,6 +357,10 @@ class JarFile extends ZipFile {
// treat the jar file as being unsigned // treat the jar file as being unsigned
jv = null; jv = null;
verify = false; verify = false;
if (JarVerifier.debug != null) {
JarVerifier.debug.println("jarfile parsing error!");
ex.printStackTrace();
}
} }
// if after initializing the verifier we have nothing // if after initializing the verifier we have nothing
...@@ -380,11 +388,9 @@ class JarFile extends ZipFile { ...@@ -380,11 +388,9 @@ class JarFile extends ZipFile {
* META-INF files. * META-INF files.
*/ */
private byte[] getBytes(ZipEntry ze) throws IOException { private byte[] getBytes(ZipEntry ze) throws IOException {
byte[] b = new byte[(int)ze.getSize()]; try (InputStream is = super.getInputStream(ze)) {
try (DataInputStream is = new DataInputStream(super.getInputStream(ze))) { return IOUtils.readFully(is, (int)ze.getSize(), true);
is.readFully(b, 0, b.length);
} }
return b;
} }
/** /**
...@@ -540,11 +546,7 @@ class JarFile extends ZipFile { ...@@ -540,11 +546,7 @@ class JarFile extends ZipFile {
if (!isKnownNotToHaveSpecialAttributes()) { if (!isKnownNotToHaveSpecialAttributes()) {
JarEntry manEntry = getManEntry(); JarEntry manEntry = getManEntry();
if (manEntry != null) { if (manEntry != null) {
byte[] b = new byte[(int)manEntry.getSize()]; byte[] b = getBytes(manEntry);
try (DataInputStream dis = new DataInputStream(
super.getInputStream(manEntry))) {
dis.readFully(b, 0, b.length);
}
if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT)) if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
hasClassPathAttribute = true; hasClassPathAttribute = true;
if (match(PROFILE_CHARS, b, PROFILE_LASTOCC, PROFILE_OPTOSFT)) if (match(PROFILE_CHARS, b, PROFILE_LASTOCC, PROFILE_OPTOSFT))
......
...@@ -24,6 +24,10 @@ ...@@ -24,6 +24,10 @@
*/ */
package java.util.logging; package java.util.logging;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
/** /**
...@@ -59,7 +63,6 @@ import java.util.ResourceBundle; ...@@ -59,7 +63,6 @@ import java.util.ResourceBundle;
*/ */
public class Level implements java.io.Serializable { public class Level implements java.io.Serializable {
private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
private static String defaultBundle = "sun.util.logging.resources.logging"; private static String defaultBundle = "sun.util.logging.resources.logging";
/** /**
...@@ -77,6 +80,9 @@ public class Level implements java.io.Serializable { ...@@ -77,6 +80,9 @@ public class Level implements java.io.Serializable {
*/ */
private final String resourceBundleName; private final String resourceBundleName;
// localized level name
private String localizedLevelName;
/** /**
* OFF is a special level that can be used to turn off logging. * OFF is a special level that can be used to turn off logging.
* This level is initialized to <CODE>Integer.MAX_VALUE</CODE>. * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
...@@ -202,9 +208,8 @@ public class Level implements java.io.Serializable { ...@@ -202,9 +208,8 @@ public class Level implements java.io.Serializable {
this.name = name; this.name = name;
this.value = value; this.value = value;
this.resourceBundleName = resourceBundleName; this.resourceBundleName = resourceBundleName;
synchronized (Level.class) { this.localizedLevelName = resourceBundleName == null ? name : null;
known.add(this); KnownLevel.add(this);
}
} }
/** /**
...@@ -236,12 +241,76 @@ public class Level implements java.io.Serializable { ...@@ -236,12 +241,76 @@ public class Level implements java.io.Serializable {
* @return localized name * @return localized name
*/ */
public String getLocalizedName() { public String getLocalizedName() {
return getLocalizedLevelName();
}
// package-private getLevelName() is used by the implementation
// instead of getName() to avoid calling the subclass's version
final String getLevelName() {
return this.name;
}
final synchronized String getLocalizedLevelName() {
if (localizedLevelName != null) {
return localizedLevelName;
}
try { try {
ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName); ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
return rb.getString(name); localizedLevelName = rb.getString(name);
} catch (Exception ex) { } catch (Exception ex) {
return name; localizedLevelName = name;
}
return localizedLevelName;
}
// Returns a mirrored Level object that matches the given name as
// specified in the Level.parse method. Returns null if not found.
//
// It returns the same Level object as the one returned by Level.parse
// method if the given name is a non-localized name or integer.
//
// If the name is a localized name, findLevel and parse method may
// return a different level value if there is a custom Level subclass
// that overrides Level.getLocalizedName() to return a different string
// than what's returned by the default implementation.
//
static Level findLevel(String name) {
if (name == null) {
throw new NullPointerException();
}
KnownLevel level;
// Look for a known Level with the given non-localized name.
level = KnownLevel.findByName(name);
if (level != null) {
return level.mirroredLevel;
}
// Now, check if the given name is an integer. If so,
// first look for a Level with the given value and then
// if necessary create one.
try {
int x = Integer.parseInt(name);
level = KnownLevel.findByValue(x);
if (level == null) {
// add new Level
Level levelObject = new Level(name, x);
level = KnownLevel.findByValue(x);
} }
return level.mirroredLevel;
} catch (NumberFormatException ex) {
// Not an integer.
// Drop through.
}
level = KnownLevel.findByLocalizedLevelName(name);
if (level != null) {
return level.mirroredLevel;
}
return null;
} }
/** /**
...@@ -268,21 +337,15 @@ public class Level implements java.io.Serializable { ...@@ -268,21 +337,15 @@ public class Level implements java.io.Serializable {
// Serialization magic to prevent "doppelgangers". // Serialization magic to prevent "doppelgangers".
// This is a performance optimization. // This is a performance optimization.
private Object readResolve() { private Object readResolve() {
synchronized (Level.class) { KnownLevel o = KnownLevel.matches(this);
for (int i = 0; i < known.size(); i++) { if (o != null) {
Level other = known.get(i); return o.levelObject;
if (this.name.equals(other.name) && this.value == other.value
&& (this.resourceBundleName == other.resourceBundleName ||
(this.resourceBundleName != null &&
this.resourceBundleName.equals(other.resourceBundleName)))) {
return other;
}
} }
// Woops. Whoever sent us this object knows // Woops. Whoever sent us this object knows
// about a new log level. Add it to our list. // about a new log level. Add it to our list.
known.add(this); Level level = new Level(this.name, this.value, this.resourceBundleName);
return this; return level;
}
} }
/** /**
...@@ -296,6 +359,7 @@ public class Level implements java.io.Serializable { ...@@ -296,6 +359,7 @@ public class Level implements java.io.Serializable {
* <li> "SEVERE" * <li> "SEVERE"
* <li> "1000" * <li> "1000"
* </ul> * </ul>
*
* @param name string to be parsed * @param name string to be parsed
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
* @throws IllegalArgumentException if the value is not valid. * @throws IllegalArgumentException if the value is not valid.
...@@ -315,12 +379,12 @@ public class Level implements java.io.Serializable { ...@@ -315,12 +379,12 @@ public class Level implements java.io.Serializable {
// Check that name is not null. // Check that name is not null.
name.length(); name.length();
KnownLevel level;
// Look for a known Level with the given non-localized name. // Look for a known Level with the given non-localized name.
for (int i = 0; i < known.size(); i++) { level = KnownLevel.findByName(name);
Level l = known.get(i); if (level != null) {
if (name.equals(l.name)) { return level.levelObject;
return l;
}
} }
// Now, check if the given name is an integer. If so, // Now, check if the given name is an integer. If so,
...@@ -328,14 +392,13 @@ public class Level implements java.io.Serializable { ...@@ -328,14 +392,13 @@ public class Level implements java.io.Serializable {
// if necessary create one. // if necessary create one.
try { try {
int x = Integer.parseInt(name); int x = Integer.parseInt(name);
for (int i = 0; i < known.size(); i++) { level = KnownLevel.findByValue(x);
Level l = known.get(i); if (level == null) {
if (l.value == x) { // add new Level
return l; Level levelObject = new Level(name, x);
} level = KnownLevel.findByValue(x);
} }
// Create a new Level. return level.levelObject;
return new Level(name, x);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
// Not an integer. // Not an integer.
// Drop through. // Drop through.
...@@ -344,11 +407,9 @@ public class Level implements java.io.Serializable { ...@@ -344,11 +407,9 @@ public class Level implements java.io.Serializable {
// Finally, look for a known level with the given localized name, // Finally, look for a known level with the given localized name,
// in the current default locale. // in the current default locale.
// This is relatively expensive, but not excessively so. // This is relatively expensive, but not excessively so.
for (int i = 0; i < known.size(); i++) { level = KnownLevel.findByLocalizedName(name);
Level l = known.get(i); if (level != null) {
if (name.equals(l.getLocalizedName())) { return level.levelObject;
return l;
}
} }
// OK, we've tried everything and failed // OK, we've tried everything and failed
...@@ -375,4 +436,124 @@ public class Level implements java.io.Serializable { ...@@ -375,4 +436,124 @@ public class Level implements java.io.Serializable {
public int hashCode() { public int hashCode() {
return this.value; return this.value;
} }
// KnownLevel class maintains the global list of all known levels.
// The API allows multiple custom Level instances of the same name/value
// be created. This class provides convenient methods to find a level
// by a given name, by a given value, or by a given localized name.
//
// KnownLevel wraps the following Level objects:
// 1. levelObject: standard Level object or custom Level object
// 2. mirroredLevel: Level object representing the level specified in the
// logging configuration.
//
// Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
// are non-final but the name and resource bundle name are parameters to
// the Level constructor. Use the mirroredLevel object instead of the
// levelObject to prevent the logging framework to execute foreign code
// implemented by untrusted Level subclass.
//
// Implementation Notes:
// If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
// were final, the following KnownLevel implementation can be removed.
// Future API change should take this into consideration.
static final class KnownLevel {
private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
final Level levelObject; // instance of Level class or Level subclass
final Level mirroredLevel; // instance of Level class
KnownLevel(Level l) {
this.levelObject = l;
if (l.getClass() == Level.class) {
this.mirroredLevel = l;
} else {
this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName);
}
}
static synchronized void add(Level l) {
// the mirroredLevel object is always added to the list
// before the custom Level instance
KnownLevel o = new KnownLevel(l);
List<KnownLevel> list = nameToLevels.get(l.name);
if (list == null) {
list = new ArrayList<>();
nameToLevels.put(l.name, list);
}
list.add(o);
list = intToLevels.get(l.value);
if (list == null) {
list = new ArrayList<>();
intToLevels.put(l.value, list);
}
list.add(o);
}
// Returns a KnownLevel with the given non-localized name.
static synchronized KnownLevel findByName(String name) {
List<KnownLevel> list = nameToLevels.get(name);
if (list != null) {
return list.get(0);
}
return null;
}
// Returns a KnownLevel with the given value.
static synchronized KnownLevel findByValue(int value) {
List<KnownLevel> list = intToLevels.get(value);
if (list != null) {
return list.get(0);
}
return null;
}
// Returns a KnownLevel with the given localized name matching
// by calling the Level.getLocalizedLevelName() method (i.e. found
// from the resourceBundle associated with the Level object).
// This method does not call Level.getLocalizedName() that may
// be overridden in a subclass implementation
static synchronized KnownLevel findByLocalizedLevelName(String name) {
for (List<KnownLevel> levels : nameToLevels.values()) {
for (KnownLevel l : levels) {
String lname = l.levelObject.getLocalizedLevelName();
if (name.equals(lname)) {
return l;
}
}
}
return null;
}
// Returns a KnownLevel with the given localized name matching
// by calling the Level.getLocalizedName() method
static synchronized KnownLevel findByLocalizedName(String name) {
for (List<KnownLevel> levels : nameToLevels.values()) {
for (KnownLevel l : levels) {
String lname = l.levelObject.getLocalizedName();
if (name.equals(lname)) {
return l;
}
}
}
return null;
}
static synchronized KnownLevel matches(Level l) {
List<KnownLevel> list = nameToLevels.get(l.name);
if (list != null) {
for (KnownLevel level : list) {
Level other = level.mirroredLevel;
if (l.value == other.value &&
(l.resourceBundleName == other.resourceBundleName ||
(l.resourceBundleName != null &&
l.resourceBundleName.equals(other.resourceBundleName)))) {
return level;
}
}
}
return null;
}
}
} }
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
package java.util.logging; package java.util.logging;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
...@@ -311,6 +313,40 @@ public class Logger { ...@@ -311,6 +313,40 @@ public class Logger {
} }
} }
// Until all JDK code converted to call sun.util.logging.PlatformLogger
// (see 7054233), we need to determine if Logger.getLogger is to add
// a system logger or user logger.
//
// As an interim solution, if the immediate caller whose caller loader is
// null, we assume it's a system logger and add it to the system context.
// These system loggers only set the resource bundle to the given
// resource bundle name (rather than the default system resource bundle).
private static class SystemLoggerHelper {
static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
private static boolean getBooleanProperty(final String key) {
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty(key);
}
});
return Boolean.valueOf(s);
}
}
private static Logger demandLogger(String name, String resourceBundleName) {
LogManager manager = LogManager.getLogManager();
SecurityManager sm = System.getSecurityManager();
if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
// 0: Reflection 1: Logger.demandLogger 2: Logger.getLogger 3: caller
final int SKIP_FRAMES = 3;
Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
if (caller.getClassLoader() == null) {
return manager.demandSystemLogger(name, resourceBundleName);
}
}
return manager.demandLogger(name, resourceBundleName);
}
/** /**
* Find or create a logger for a named subsystem. If a logger has * Find or create a logger for a named subsystem. If a logger has
* already been created with the given name it is returned. Otherwise * already been created with the given name it is returned. Otherwise
...@@ -352,8 +388,7 @@ public class Logger { ...@@ -352,8 +388,7 @@ public class Logger {
// would throw an IllegalArgumentException in the second call // would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace // because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null. // the existing "resourceBundleForFoo" with null.
LogManager manager = LogManager.getLogManager(); return demandLogger(name, null);
return manager.demandLogger(name);
} }
/** /**
...@@ -400,8 +435,7 @@ public class Logger { ...@@ -400,8 +435,7 @@ public class Logger {
// Synchronization is not required here. All synchronization for // Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger(). // adding a new Logger object is handled by LogManager.addLogger().
public static Logger getLogger(String name, String resourceBundleName) { public static Logger getLogger(String name, String resourceBundleName) {
LogManager manager = LogManager.getLogManager(); Logger result = demandLogger(name, resourceBundleName);
Logger result = manager.demandLogger(name);
// MissingResourceException or IllegalArgumentException can be // MissingResourceException or IllegalArgumentException can be
// thrown by setupResourceInfo(). // thrown by setupResourceInfo().
...@@ -409,6 +443,17 @@ public class Logger { ...@@ -409,6 +443,17 @@ public class Logger {
return result; return result;
} }
// package-private
// Add a platform logger to the system context.
// i.e. caller of sun.util.logging.PlatformLogger.getLogger
static Logger getPlatformLogger(String name) {
LogManager manager = LogManager.getLogManager();
// all loggers in the system context will default to
// the system logger's resource bundle
Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME);
return result;
}
/** /**
* Create an anonymous Logger. The newly created Logger is not * Create an anonymous Logger. The newly created Logger is not
...@@ -561,7 +606,7 @@ public class Logger { ...@@ -561,7 +606,7 @@ public class Logger {
private void doLog(LogRecord lr) { private void doLog(LogRecord lr) {
lr.setLoggerName(name); lr.setLoggerName(name);
String ebname = getEffectiveResourceBundleName(); String ebname = getEffectiveResourceBundleName();
if (ebname != null) { if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
lr.setResourceBundleName(ebname); lr.setResourceBundleName(ebname);
lr.setResourceBundle(findResourceBundle(ebname)); lr.setResourceBundle(findResourceBundle(ebname));
} }
...@@ -1538,6 +1583,23 @@ public class Logger { ...@@ -1538,6 +1583,23 @@ public class Logger {
return useParentHandlers; return useParentHandlers;
} }
static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
private static ResourceBundle findSystemResourceBundle(final Locale locale) {
// the resource bundle is in a restricted package
return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
public ResourceBundle run() {
try {
return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
locale,
ClassLoader.getSystemClassLoader());
} catch (MissingResourceException e) {
throw new InternalError(e.toString());
}
}
});
}
/** /**
* Private utility method to map a resource bundle name to an * Private utility method to map a resource bundle name to an
* actual resource bundle, using a simple one-entry cache. * actual resource bundle, using a simple one-entry cache.
...@@ -1562,6 +1624,13 @@ public class Logger { ...@@ -1562,6 +1624,13 @@ public class Logger {
return catalog; return catalog;
} }
if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
catalog = findSystemResourceBundle(currentLocale);
catalogName = name;
catalogLocale = currentLocale;
return catalog;
}
// Use the thread's context ClassLoader. If there isn't one, use the // Use the thread's context ClassLoader. If there isn't one, use the
// {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}. // {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}.
ClassLoader cl = Thread.currentThread().getContextClassLoader(); ClassLoader cl = Thread.currentThread().getContextClassLoader();
......
...@@ -34,7 +34,7 @@ import java.util.ArrayList; ...@@ -34,7 +34,7 @@ import java.util.ArrayList;
* *
* The <tt>LoggingMXBean</tt> interface provides a standard * The <tt>LoggingMXBean</tt> interface provides a standard
* method for management access to the individual * method for management access to the individual
* java.util.Logger objects available at runtime. * {@code Logger} objects available at runtime.
* *
* @author Ron Mann * @author Ron Mann
* @author Mandy Chung * @author Mandy Chung
...@@ -75,7 +75,7 @@ class Logging implements LoggingMXBean { ...@@ -75,7 +75,7 @@ class Logging implements LoggingMXBean {
if (level == null) { if (level == null) {
return EMPTY_STRING; return EMPTY_STRING;
} else { } else {
return level.getName(); return level.getLevelName();
} }
} }
...@@ -85,7 +85,6 @@ class Logging implements LoggingMXBean { ...@@ -85,7 +85,6 @@ class Logging implements LoggingMXBean {
} }
Logger logger = logManager.getLogger(loggerName); Logger logger = logManager.getLogger(loggerName);
if (logger == null) { if (logger == null) {
throw new IllegalArgumentException("Logger " + loggerName + throw new IllegalArgumentException("Logger " + loggerName +
"does not exist"); "does not exist");
...@@ -94,7 +93,10 @@ class Logging implements LoggingMXBean { ...@@ -94,7 +93,10 @@ class Logging implements LoggingMXBean {
Level level = null; Level level = null;
if (levelName != null) { if (levelName != null) {
// parse will throw IAE if logLevel is invalid // parse will throw IAE if logLevel is invalid
level = Level.parse(levelName); level = Level.findLevel(levelName);
if (level == null) {
throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
}
} }
logger.setLevel(level); logger.setLevel(level);
......
...@@ -37,7 +37,8 @@ class LoggingProxyImpl implements LoggingProxy { ...@@ -37,7 +37,8 @@ class LoggingProxyImpl implements LoggingProxy {
@Override @Override
public Object getLogger(String name) { public Object getLogger(String name) {
return Logger.getLogger(name); // always create a platform logger with the resource bundle name
return Logger.getPlatformLogger(name);
} }
@Override @Override
...@@ -92,12 +93,16 @@ class LoggingProxyImpl implements LoggingProxy { ...@@ -92,12 +93,16 @@ class LoggingProxyImpl implements LoggingProxy {
@Override @Override
public Object parseLevel(String levelName) { public Object parseLevel(String levelName) {
return Level.parse(levelName); Level level = Level.findLevel(levelName);
if (level == null) {
throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
}
return level;
} }
@Override @Override
public String getLevelName(Object level) { public String getLevelName(Object level) {
return ((Level) level).getName(); return ((Level) level).getLevelName();
} }
@Override @Override
......
...@@ -162,7 +162,7 @@ public class SimpleFormatter extends Formatter { ...@@ -162,7 +162,7 @@ public class SimpleFormatter extends Formatter {
dat, dat,
source, source,
record.getLoggerName(), record.getLoggerName(),
record.getLevel().getLocalizedName(), record.getLevel().getLocalizedLevelName(),
message, message,
throwable); throwable);
} }
......
...@@ -387,13 +387,14 @@ public class JFrame extends Frame implements WindowConstants, ...@@ -387,13 +387,14 @@ public class JFrame extends Frame implements WindowConstants,
operation != EXIT_ON_CLOSE) { 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"); 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) { if (operation == EXIT_ON_CLOSE) {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) { if (security != null) {
security.checkExit(0); security.checkExit(0);
} }
} }
if (this.defaultCloseOperation != operation) {
int oldValue = this.defaultCloseOperation; int oldValue = this.defaultCloseOperation;
this.defaultCloseOperation = operation; this.defaultCloseOperation = operation;
firePropertyChange("defaultCloseOperation", oldValue, operation); firePropertyChange("defaultCloseOperation", oldValue, operation);
......
...@@ -781,16 +781,12 @@ public class JTable extends JComponent implements TableModelListener, Scrollable ...@@ -781,16 +781,12 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER); scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
if (corner == null || corner instanceof UIResource){ if (corner == null || corner instanceof UIResource){
corner = null; corner = null;
Object componentClass = UIManager.get(
"Table.scrollPaneCornerComponent");
if (componentClass instanceof Class){
try { try {
corner = (Component) corner = (Component) UIManager.get(
((Class)componentClass).newInstance(); "Table.scrollPaneCornerComponent");
} catch (Exception e) { } catch (Exception e) {
// just ignore and don't set corner // just ignore and don't set corner
} }
}
scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER, scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
corner); corner);
} }
......
...@@ -356,7 +356,7 @@ public class SwingUtilities implements SwingConstants ...@@ -356,7 +356,7 @@ public class SwingUtilities implements SwingConstants
sourceEvent.getYOnScreen(), sourceEvent.getYOnScreen(),
sourceEvent.getClickCount(), sourceEvent.getClickCount(),
sourceEvent.isPopupTrigger(), sourceEvent.isPopupTrigger(),
MouseEvent.NOBUTTON ); sourceEvent.getButton());
} }
return newEvent; return newEvent;
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册