--- a/jdk/make/common/Defs-linux.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/Defs-linux.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -50,13 +50,13 @@
CC_DEPEND_FILTER = $(SED) -e 's!$*\.$(OBJECT_SUFFIX)!$(dir $@)& $(dir $@)$*.$(DEPEND_SUFFIX)!g'
ifndef PLATFORM_SRC
- PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris
+ PLATFORM_SRC = $(BUILDDIR)/../src/solaris
endif # PLATFORM_SRC
# Platform specific closed sources
ifndef OPENJDK
ifndef CLOSED_PLATFORM_SRC
- CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris
+ CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris
endif
endif
--- a/jdk/make/common/Defs-solaris.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/Defs-solaris.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -45,13 +45,13 @@
include $(JDK_MAKE_SHARED_DIR)/Defs.gmk
ifndef PLATFORM_SRC
-PLATFORM_SRC = $(JDK_TOPDIR)/src/solaris
+PLATFORM_SRC = $(BUILDDIR)/../src/solaris
endif # PLATFORM_SRC
# Platform specific closed sources
ifndef OPENJDK
ifndef CLOSED_PLATFORM_SRC
- CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/solaris
+ CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/solaris
endif
endif
--- a/jdk/make/common/Defs-windows.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/Defs-windows.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -51,13 +51,13 @@
endif # LIB_LOCATION
ifndef PLATFORM_SRC
- PLATFORM_SRC = $(JDK_TOPDIR)/src/windows
+ PLATFORM_SRC = $(BUILDDIR)/../src/windows
endif # PLATFORM_SRC
# Platform specific closed sources
ifndef OPENJDK
ifndef CLOSED_PLATFORM_SRC
- CLOSED_PLATFORM_SRC = $(JDK_TOPDIR)/src/closed/windows
+ CLOSED_PLATFORM_SRC = $(BUILDDIR)/../src/closed/windows
endif
endif
@@ -367,7 +367,7 @@
endif
# Settings for the VERSIONINFO tap on windows.
-VERSIONINFO_RESOURCE = $(JDK_TOPDIR)/src/windows/resource/version.rc
+VERSIONINFO_RESOURCE = $(BUILDDIR)/../src/windows/resource/version.rc
ifneq ($(JDK_BUILD_NUMBER),)
COOKED_BUILD_NUMBER = $(shell $(ECHO) $(JDK_BUILD_NUMBER) | $(SED) -e 's/^b//' -e 's/^0//')
--- a/jdk/make/common/Defs.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/Defs.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -41,7 +41,15 @@
SUN_MAKE_TEST:sh = echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33
ifndef JDK_TOPDIR
- JDK_TOPDIR=$(BUILDDIR)/..
+ ifdef BUILDDIR
+ JDK_TOPDIR=$(BUILDDIR)/..
+ else
+ JDK_TOPDIR:=$(error "ERROR: Cannot define top of jdk repository")
+ endif
+endif
+ifndef BUILDDIR
+ # Hack, due to deploy repository using this file.
+ BUILDDIR=$(JDK_TOPDIR)/make
endif
ifndef JDK_MAKE_SHARED_DIR
JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared
@@ -59,13 +67,13 @@
# there yet.
#
ifndef SHARE_SRC
- SHARE_SRC = $(JDK_TOPDIR)/src/share
+ SHARE_SRC = $(BUILDDIR)/../src/share
endif
# Files that cannot be included in the OpenJDK distribution are
# collected under a parent directory which contains just those files.
ifndef CLOSED_SRC
- CLOSED_SRC = $(JDK_TOPDIR)/src/closed
+ CLOSED_SRC = $(BUILDDIR)/../src/closed
endif
# If we have no closed directory, force it to an openjdk build
@@ -170,14 +178,6 @@
endif
endif # OPENJDK
-# Default output directory
-ifdef OPENJDK
-_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX)
-else
-_OUTPUTDIR=$(JDK_TOPDIR)/build/$(PLATFORM)-$(ARCH)
-endif
-
-
#
# Get platform definitions
#
--- a/jdk/make/common/shared/Defs-control.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/shared/Defs-control.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -36,7 +36,7 @@
endif
ifndef CONTROL_TOPDIR
- CONTROL_TOPDIR=$(TOPDIR)/control
+ CONTROL_TOPDIR=$(TOPDIR)
endif
ifndef HOTSPOT_TOPDIR
HOTSPOT_TOPDIR=$(TOPDIR)/hotspot
@@ -70,7 +70,8 @@
include $(JDK_MAKE_SHARED_DIR)/Platform.gmk
# Default output directory
-_OUTPUTDIR=$(CONTROL_TOPDIR)/build/$(PLATFORM)-$(ARCH)
+BUILD_PARENT_DIRECTORY=$(TOPDIR)
+_OUTPUTDIR=$(TOPDIR)/build/$(PLATFORM)-$(ARCH)
# Get platform specific settings
include $(JDK_MAKE_SHARED_DIR)/Defs.gmk
--- a/jdk/make/common/shared/Defs.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/shared/Defs.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -55,7 +55,10 @@
# Simple pwd path
define PwdPath
-$(shell cd $1 2> $(DEV_NULL) && pwd)
+$(shell $(CD) $1 2> $(DEV_NULL) && $(PWD))
+endef
+define AbsPwdPathCheck
+$(shell $(CD) .. 2> $(DEV_NULL) && $(CD) $1 2> $(DEV_NULL) && $(PWD))
endef
# Checks an ALT value for spaces (should be one word),
@@ -422,23 +425,54 @@
CACERTS_FILE:=$(call AltCheckValue,CACERTS_FILE)
# OUTPUTDIR: Location of all output for the build
-_BACKUP_OUTPUTDIR = $(TEMP_DISK)/$(USER)/jdk-outputdir
ifdef ALT_OUTPUTDIR
- _POSSIBLE_OUTPUTDIR =$(subst \,/,$(ALT_OUTPUTDIR))
+ OUTPUTDIR:=$(subst \,/,$(ALT_OUTPUTDIR))
+ # Assumes this is absolute (checks later)
+ ABS_OUTPUTDIR:=$(OUTPUTDIR)
else
ifndef _OUTPUTDIR
- _OUTPUTDIR = $(_BACKUP_OUTPUTDIR)
+ # Default: Get "build" parent directory, which should always exist
+ ifndef BUILD_PARENT_DIRECTORY
+ BUILD_PARENT_DIRECTORY=$(BUILDDIR)/..
+ endif
+ ABS_BUILD_PARENT_DIRECTORY:=$(call FullPath,$(BUILD_PARENT_DIRECTORY))
+ ifdef OPENJDK
+ _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)$(OPENJDK_SUFFIX)
+ else
+ _OUTPUTDIRNAME=$(PLATFORM)-$(ARCH)
+ endif
+ _OUTPUTDIR=$(BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME)
+ ABS_OUTPUTDIR:=$(ABS_BUILD_PARENT_DIRECTORY)/build/$(_OUTPUTDIRNAME)
endif
- _POSSIBLE_OUTPUTDIR =$(_OUTPUTDIR)
+ OUTPUTDIR:=$(_OUTPUTDIR)
endif
-_create_outputdir1:=$(shell mkdir -p $(_POSSIBLE_OUTPUTDIR) > $(DEV_NULL) 2>&1)
-OUTPUTDIR:=$(call WriteDirExists,$(_POSSIBLE_OUTPUTDIR),$(_BACKUP_OUTPUTDIR))
-_create_outputdir2:=$(shell mkdir -p $(OUTPUTDIR) > $(DEV_NULL) 2>&1)
-ifeq "$(OUTPUTDIR)" "$(_BACKUP_OUTPUTDIR)"
- _outputdir_warning:=$(warning "WARNING: OUTPUTDIR '$(_POSSIBLE_OUTPUTDIR)' not writable, will use '$(_BACKUP_OUTPUTDIR)'")
-endif
+# Check for spaces and null value
OUTPUTDIR:=$(call AltCheckSpaces,OUTPUTDIR)
OUTPUTDIR:=$(call AltCheckValue,OUTPUTDIR)
+# Create the output directory and make sure it exists and is writable
+_create_outputdir:=$(shell $(MKDIR) -p "$(OUTPUTDIR)" > $(DEV_NULL) 2>&1)
+ifeq ($(call WriteDirExists,$(OUTPUTDIR),/dev/null),/dev/null)
+ _outputdir_error:=$(error "ERROR: OUTPUTDIR '$(OUTPUTDIR)' not created or not writable")
+endif
+# Define absolute path if needed and check for spaces and null value
+ifndef ABS_OUTPUTDIR
+ ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR))
+endif
+ABS_OUTPUTDIR:=$(call AltCheckSpaces,ABS_OUTPUTDIR)
+ABS_OUTPUTDIR:=$(call AltCheckValue,ABS_OUTPUTDIR)
+# Make doubly sure this is a full path
+ifeq ($(call AbsPwdPathCheck,$(ABS_OUTPUTDIR)), )
+ ifdef ALT_OUTPUTDIR
+ _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)', was ALT_OUTPUTDIR '$(ALT_OUTPUTDIR)' an absolute path?")
+ else
+ _outputdir_error:=$(error "ERROR: Trouble with the absolute path for OUTPUTDIR '$(OUTPUTDIR)'")
+ endif
+endif
+_dir1:=$(call FullPath,$(ABS_OUTPUTDIR))
+_dir2:=$(call FullPath,$(OUTPUTDIR))
+ifneq ($(_dir1),$(_dir2))
+ _outputdir_error:=$(error "ERROR: ABS_OUTPUTDIR '$(ABS_OUTPUTDIR)' is not the same directory as OUTPUTDIR '$(OUTPUTDIR)', '$(_dir1)'!='$(_dir2)'")
+endif
# Bin directory
# NOTE: ISA_DIR is usually empty, on Solaris it might be /sparcv9 or /amd64
@@ -475,9 +509,6 @@
COPYRIGHT_YEAR = $(shell $(DATE) '+%Y')
endif
-# Absolute path to output directory
-ABS_OUTPUTDIR:=$(call FullPath,$(OUTPUTDIR))
-
# Get shared compiler settings
include $(JDK_MAKE_SHARED_DIR)/Compiler.gmk
--- a/jdk/make/common/shared/Platform.gmk Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/common/shared/Platform.gmk Fri Mar 28 12:56:34 2008 -0700
@@ -93,20 +93,18 @@
# Normal boot jdk is previous release, but a hard requirement is a 1.5 boot
REQUIRED_BOOT_VER = 1.5
-#This is specific to OpenJDK build
-ifdef OPENJDK
- REQUIRED_FREETYPE_VERSION=2.3.0
-endif
+# If we are using freetype, this is the required version
+REQUIRED_FREETYPE_VERSION=2.3.0
#
# Prune out all known SCM (Source Code Management) directories
# so they will not be included when copying directory trees
# or packaging up .jar files, etc. This applies to all workspaces.
#
-SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
+SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files .hgignore .hgtags
# When changing SCM_DIRs also change SCM_DIRS_rexp and SCM_DIRS_prune:
-SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files"
-SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files \) -prune
+SCM_DIRS_rexp = ".hg|.svn|CVS|RCS|SCCS|Codemgr_wsdata|deleted_files|.hgignore|.hgtags"
+SCM_DIRS_prune = \( -name .hg -o -name .svn -o -name CVS -o -name RCS -o -name SCCS -o -name Codemgr_wsdata -o -name deleted_files -o -name .hgignore -o -name .hgtags \) -prune
# Don't define this unless it's not defined
ifndef VARIANT
--- a/jdk/make/java/nio/Makefile Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/java/nio/Makefile Fri Mar 28 12:56:34 2008 -0700
@@ -191,7 +191,7 @@
GEN_BUFFER_SH = genBuffer.sh
-GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) \
+GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) SH=$(SH) \
$(SH) $(GEN_BUFFER_SH)
# Public abstract buffer classes
@@ -582,7 +582,7 @@
GEN_CODER_SH = genCoder.sh
-GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) $(SH) $(GEN_CODER_SH)
+GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_CODER_SH)
$(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
$(prep-target)
@@ -602,7 +602,7 @@
GEN_EX_SH = genExceptions.sh
-GEN_EX_CMD = NAWK=$(NAWK) $(SHELL) $(GEN_EX_SH)
+GEN_EX_CMD = NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_EX_SH)
$(CH_GEN)/%Exception.java: genExceptions.sh $(CH_SRC)/exceptions
$(prep-target)
@@ -635,8 +635,8 @@
$(HASHER_JARFILE) $(SCS_SRC)/standard-charsets
$(prep-target)
@$(RM) $@.temp
- NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) \
+ NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) SH=$(SH) \
HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \
- $(SHELL) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
+ $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
.PHONY: sources
--- a/jdk/make/java/nio/genCharsetProvider.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/java/nio/genCharsetProvider.sh Fri Mar 28 12:56:34 2008 -0700
@@ -48,7 +48,7 @@
# Header
#
-$SHELL addNotices.sh "$COPYRIGHT_YEARS" > $OUT
+$SH ./addNotices.sh "$COPYRIGHT_YEARS" > $OUT
cat <<__END__ >>$OUT
--- a/jdk/make/java/nio/genExceptions.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/java/nio/genExceptions.sh Fri Mar 28 12:56:34 2008 -0700
@@ -41,7 +41,7 @@
echo '-->' $DST/$ID.java
out=$DST/${ID}.java
- $SHELL addNotices.sh "$COPYRIGHT_YEARS" > $out
+ $SH ./addNotices.sh "$COPYRIGHT_YEARS" > $out
cat >>$out <<__END__
--- a/jdk/make/sun/splashscreen/Makefile Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/sun/splashscreen/Makefile Fri Mar 28 12:56:34 2008 -0700
@@ -85,3 +85,13 @@
CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen
CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
+ifeq ($(PLATFORM), linux)
+ ifeq ($(ARCH_DATA_MODEL), 64)
+ # 64-bit gcc has problems compiling MMX instructions.
+ # Google it for more details. Possibly the newer versions of
+ # the PNG-library and/or the new compiler will not need this
+ # option in the future.
+ CPPFLAGS += -DPNG_NO_MMX_CODE
+ endif
+endif
+
--- a/jdk/make/sun/xawt/Makefile Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/sun/xawt/Makefile Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -246,7 +246,7 @@
@if [ "$(DOCOMPARE)$(suffix $@)" = "true.64" ]; then \
$(ECHO) COMPARING $@ and $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
$(DIFF) $@ $(STORED_SIZES_TMPL_$(PLATFORM)_$(LIBARCH)); \
- fi
+ fi
$(TEMPDIR)/.gen.wrappers: $(SIZES) $(WRAPPER_GENERATOR_CLASS) $(XLIBTYPES)
$(BOOT_JAVA_CMD) -cp $(WRAPPER_GENERATOR_TEMPDIR) WrapperGenerator \
@@ -256,10 +256,11 @@
$(MKDIR) -p $(TEMPDIR)
$(TOUCH) $(TEMPDIR)/.gen.wrappers
-generated.clean:
+generated.clean:
$(RM) -r $(WRAPPER_GENERATOR_TEMPDIR)
$(RM) -r $(WRAPPER_GENERATOR_DIR)
$(RM) -r $(GEN_DIR)/*.java
+ $(RM) -r $(TEMPDIR)/.gen_icons
ifdef OPENJDK
ICONS_PATH_PREFIX=$(PLATFORM_SRC)
--- a/jdk/make/tools/freetypecheck/Makefile Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/make/tools/freetypecheck/Makefile Fri Mar 28 12:56:34 2008 -0700
@@ -38,7 +38,14 @@
all: $(FT_TEST_PATH)
-FT_OPTIONS = -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2
+# Start with CFLAGS (which gets us the required -xarch setting on solaris)
+ifeq ($(PLATFORM), windows)
+ FT_OPTIONS =
+else
+ FT_OPTIONS = $(CFLAGS)
+endif
+
+FT_OPTIONS += -I$(FT_HEADERS) -I$(FT_HEADERS)/freetype2
FT_OPTIONS += $(XARCH)
#add runtime library search path
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/OpenConverter.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/OpenConverter.java Fri Mar 28 12:56:34 2008 -0700
@@ -1118,11 +1118,11 @@
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
Class targetClass = getTargetClass();
- Constructor[] constrs = targetClass.getConstructors();
+ Constructor<?>[] constrs = targetClass.getConstructors();
// Applicable if and only if there are any annotated constructors
- List<Constructor> annotatedConstrList = newList();
- for (Constructor constr : constrs) {
+ List<Constructor<?>> annotatedConstrList = newList();
+ for (Constructor<?> constr : constrs) {
if (Modifier.isPublic(constr.getModifiers())
&& constr.getAnnotation(propertyNamesClass) != null)
annotatedConstrList.add(constr);
@@ -1152,7 +1152,7 @@
// Also remember the set of properties in that constructor
// so we can test unambiguity.
Set<BitSet> getterIndexSets = newSet();
- for (Constructor constr : annotatedConstrList) {
+ for (Constructor<?> constr : annotatedConstrList) {
String[] propertyNames =
constr.getAnnotation(propertyNamesClass).value();
@@ -1309,10 +1309,10 @@
}
private static class Constr {
- final Constructor constructor;
+ final Constructor<?> constructor;
final int[] paramIndexes;
final BitSet presentParams;
- Constr(Constructor constructor, int[] paramIndexes,
+ Constr(Constructor<?> constructor, int[] paramIndexes,
BitSet presentParams) {
this.constructor = constructor;
this.paramIndexes = paramIndexes;
--- a/jdk/src/share/classes/com/sun/management/package.html Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/com/sun/management/package.html Fri Mar 28 12:56:34 2008 -0700
@@ -1,4 +1,4 @@
-CTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<!--
--- a/jdk/src/share/classes/java/awt/Component.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/Component.java Fri Mar 28 12:56:34 2008 -0700
@@ -634,6 +634,11 @@
*/
private PropertyChangeSupport changeSupport;
+ private transient final Object changeSupportLock = new Object();
+ private Object getChangeSupportLock() {
+ return changeSupportLock;
+ }
+
boolean isPacked = false;
/**
@@ -935,24 +940,26 @@
*/
public GraphicsConfiguration getGraphicsConfiguration() {
synchronized(getTreeLock()) {
- GraphicsConfiguration gc = graphicsConfig;
- Component parent = getParent();
- while ((gc == null) && (parent != null)) {
- gc = parent.getGraphicsConfiguration();
- parent = parent.getParent();
- }
- return gc;
+ if (graphicsConfig != null) {
+ return graphicsConfig;
+ } else if (getParent() != null) {
+ return getParent().getGraphicsConfiguration();
+ } else {
+ return null;
+ }
}
}
final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
- GraphicsConfiguration gc = this.graphicsConfig;
- Component par = this.parent;
- while ((gc == null) && (par != null)) {
- gc = par.getGraphicsConfiguration_NoClientCode();
- par = par.parent;
- }
- return gc;
+ GraphicsConfiguration graphicsConfig = this.graphicsConfig;
+ Container parent = this.parent;
+ if (graphicsConfig != null) {
+ return graphicsConfig;
+ } else if (parent != null) {
+ return parent.getGraphicsConfiguration_NoClientCode();
+ } else {
+ return null;
+ }
}
/**
@@ -4602,7 +4609,8 @@
e.isPopupTrigger(),
e.getScrollType(),
e.getScrollAmount(),
- e.getWheelRotation());
+ e.getWheelRotation(),
+ e.getPreciseWheelRotation());
((AWTEvent)e).copyPrivateDataInto(newMWE);
// When dispatching a wheel event to
// ancestor, there is no need trying to find descendant
@@ -6484,7 +6492,7 @@
// will need some help.
Container parent = this.parent;
if (parent != null && parent.peer instanceof LightweightPeer) {
- nativeInLightFixer = new NativeInLightFixer();
+ relocateComponent();
}
}
invalidate();
@@ -6595,10 +6603,6 @@
}
}
- if (nativeInLightFixer != null) {
- nativeInLightFixer.uninstall();
- }
-
ComponentPeer p = peer;
if (p != null) {
boolean isLightweight = isLightweight();
@@ -7836,15 +7840,17 @@
* @see #getPropertyChangeListeners
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
*/
- public synchronized void addPropertyChangeListener(
+ public void addPropertyChangeListener(
PropertyChangeListener listener) {
- if (listener == null) {
- return;
- }
- if (changeSupport == null) {
- changeSupport = new PropertyChangeSupport(this);
- }
- changeSupport.addPropertyChangeListener(listener);
+ synchronized (getChangeSupportLock()) {
+ if (listener == null) {
+ return;
+ }
+ if (changeSupport == null) {
+ changeSupport = new PropertyChangeSupport(this);
+ }
+ changeSupport.addPropertyChangeListener(listener);
+ }
}
/**
@@ -7860,12 +7866,14 @@
* @see #getPropertyChangeListeners
* @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
*/
- public synchronized void removePropertyChangeListener(
+ public void removePropertyChangeListener(
PropertyChangeListener listener) {
- if (listener == null || changeSupport == null) {
- return;
- }
- changeSupport.removePropertyChangeListener(listener);
+ synchronized (getChangeSupportLock()) {
+ if (listener == null || changeSupport == null) {
+ return;
+ }
+ changeSupport.removePropertyChangeListener(listener);
+ }
}
/**
@@ -7882,11 +7890,13 @@
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
* @since 1.4
*/
- public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
- if (changeSupport == null) {
- return new PropertyChangeListener[0];
- }
- return changeSupport.getPropertyChangeListeners();
+ public PropertyChangeListener[] getPropertyChangeListeners() {
+ synchronized (getChangeSupportLock()) {
+ if (changeSupport == null) {
+ return new PropertyChangeListener[0];
+ }
+ return changeSupport.getPropertyChangeListeners();
+ }
}
/**
@@ -7920,16 +7930,18 @@
* @see #getPropertyChangeListeners(java.lang.String)
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
*/
- public synchronized void addPropertyChangeListener(
+ public void addPropertyChangeListener(
String propertyName,
PropertyChangeListener listener) {
- if (listener == null) {
- return;
- }
- if (changeSupport == null) {
- changeSupport = new PropertyChangeSupport(this);
- }
- changeSupport.addPropertyChangeListener(propertyName, listener);
+ synchronized (getChangeSupportLock()) {
+ if (listener == null) {
+ return;
+ }
+ if (changeSupport == null) {
+ changeSupport = new PropertyChangeSupport(this);
+ }
+ changeSupport.addPropertyChangeListener(propertyName, listener);
+ }
}
/**
@@ -7948,13 +7960,15 @@
* @see #getPropertyChangeListeners(java.lang.String)
* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
*/
- public synchronized void removePropertyChangeListener(
+ public void removePropertyChangeListener(
String propertyName,
PropertyChangeListener listener) {
- if (listener == null || changeSupport == null) {
- return;
- }
- changeSupport.removePropertyChangeListener(propertyName, listener);
+ synchronized (getChangeSupportLock()) {
+ if (listener == null || changeSupport == null) {
+ return;
+ }
+ changeSupport.removePropertyChangeListener(propertyName, listener);
+ }
}
/**
@@ -7971,12 +7985,14 @@
* @see #getPropertyChangeListeners
* @since 1.4
*/
- public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+ public PropertyChangeListener[] getPropertyChangeListeners(
String propertyName) {
- if (changeSupport == null) {
- return new PropertyChangeListener[0];
- }
- return changeSupport.getPropertyChangeListeners(propertyName);
+ synchronized (getChangeSupportLock()) {
+ if (changeSupport == null) {
+ return new PropertyChangeListener[0];
+ }
+ return changeSupport.getPropertyChangeListeners(propertyName);
+ }
}
/**
@@ -7991,7 +8007,10 @@
*/
protected void firePropertyChange(String propertyName,
Object oldValue, Object newValue) {
- PropertyChangeSupport changeSupport = this.changeSupport;
+ PropertyChangeSupport changeSupport;
+ synchronized (getChangeSupportLock()) {
+ changeSupport = this.changeSupport;
+ }
if (changeSupport == null ||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
return;
@@ -8491,8 +8510,6 @@
setComponentOrientation(orientation);
}
- transient NativeInLightFixer nativeInLightFixer;
-
/**
* Checks that this component meets the prerequesites to be focus owner:
* - it is enabled, visible, focusable
@@ -8518,188 +8535,25 @@
}
/**
- * This odd class is to help out a native component that has been
- * embedded in a lightweight component. Moving lightweight
- * components around and changing their visibility is not seen
- * by the native window system. This is a feature for lightweights,
- * but a problem for native components that depend upon the
- * lightweights. An instance of this class listens to the lightweight
- * parents of an associated native component (the outer class).
- *
- * @author Timothy Prinzing
- */
- final class NativeInLightFixer implements ComponentListener, ContainerListener {
-
- NativeInLightFixer() {
- lightParents = new Vector();
- install(parent);
- }
-
- void install(Container parent) {
- lightParents.clear();
- Container p = parent;
- boolean isLwParentsVisible = true;
- // stash a reference to the components that are being observed so that
- // we can reliably remove ourself as a listener later.
- for (; p.peer instanceof LightweightPeer; p = p.parent) {
-
- // register listeners and stash a reference
- p.addComponentListener(this);
- p.addContainerListener(this);
- lightParents.addElement(p);
- isLwParentsVisible &= p.isVisible();
- }
- // register with the native host (native parent of associated native)
- // to get notified if the top-level lightweight is removed.
- nativeHost = p;
- p.addContainerListener(this);
-
- // kick start the fixup. Since the event isn't looked at
- // we can simulate movement notification.
- componentMoved(null);
- if (!isLwParentsVisible) {
- synchronized (getTreeLock()) {
- if (peer != null) {
- peer.hide();
- }
- }
- }
- }
-
- void uninstall() {
- if (nativeHost != null) {
- removeReferences();
- }
- }
-
- // --- ComponentListener -------------------------------------------
-
- /**
- * Invoked when one of the lightweight parents has been resized.
- * This doesn't change the position of the native child so it
- * is ignored.
- */
- public void componentResized(ComponentEvent e) {
- }
-
- /**
- * Invoked when one of the lightweight parents has been moved.
- * The native peer must be told of the new position which is
- * relative to the native container that is hosting the
- * lightweight components.
- */
- public void componentMoved(ComponentEvent e) {
- synchronized (getTreeLock()) {
- int nativeX = x;
- int nativeY = y;
- for(Component c = parent; (c != null) &&
- (c.peer instanceof LightweightPeer);
- c = c.parent) {
-
- nativeX += c.x;
- nativeY += c.y;
- }
- if (peer != null) {
- peer.setBounds(nativeX, nativeY, width, height,
- ComponentPeer.SET_LOCATION);
- }
- }
- }
-
- /**
- * Invoked when a lightweight parent component has been
- * shown. The associated native component must also be
- * shown if it hasn't had an overriding hide done on it.
- */
- public void componentShown(ComponentEvent e) {
- if (shouldShow()) {
- synchronized (getTreeLock()) {
- if (peer != null) {
- peer.show();
- }
- }
- }
- }
-
- /**
- * Invoked when one of the lightweight parents become visible.
- * Returns true if component and all its lightweight
- * parents are visible.
- */
- private boolean shouldShow() {
- boolean isLwParentsVisible = visible;
- for (int i = lightParents.size() - 1;
- i >= 0 && isLwParentsVisible;
- i--)
+ * Fix the location of the HW component in a LW container hierarchy.
+ */
+ final void relocateComponent() {
+ synchronized (getTreeLock()) {
+ if (peer == null) {
+ return;
+ }
+ int nativeX = x;
+ int nativeY = y;
+ for (Component cont = getContainer();
+ cont != null && cont.isLightweight();
+ cont = cont.getContainer())
{
- isLwParentsVisible &=
- ((Container) lightParents.elementAt(i)).isVisible();
- }
- return isLwParentsVisible;
- }
-
- /**
- * Invoked when component has been hidden.
- */
- public void componentHidden(ComponentEvent e) {
- if (visible) {
- synchronized (getTreeLock()) {
- if (peer != null) {
- peer.hide();
- }
- }
- }
- }
-
- // --- ContainerListener ------------------------------------
-
- /**
- * Invoked when a component has been added to a lightweight
- * parent. This doesn't effect the native component.
- */
- public void componentAdded(ContainerEvent e) {
- }
-
- /**
- * Invoked when a lightweight parent has been removed.
- * This means the services of this listener are no longer
- * required and it should remove all references (ie
- * registered listeners).
- */
- public void componentRemoved(ContainerEvent e) {
- Component c = e.getChild();
- if (c == Component.this) {
- removeReferences();
- } else {
- int n = lightParents.size();
- for (int i = 0; i < n; i++) {
- Container p = (Container) lightParents.elementAt(i);
- if (p == c) {
- removeReferences();
- break;
- }
- }
- }
- }
-
- /**
- * Removes references to this object so it can be
- * garbage collected.
- */
- void removeReferences() {
- int n = lightParents.size();
- for (int i = 0; i < n; i++) {
- Container c = (Container) lightParents.elementAt(i);
- c.removeComponentListener(this);
- c.removeContainerListener(this);
- }
- nativeHost.removeContainerListener(this);
- lightParents.clear();
- nativeHost = null;
- }
-
- Vector lightParents;
- Container nativeHost;
+ nativeX += cont.x;
+ nativeY += cont.y;
+ }
+ peer.setBounds(nativeX, nativeY, width, height,
+ ComponentPeer.SET_LOCATION);
+ }
}
/**
@@ -9453,6 +9307,19 @@
// ************************** MIXING CODE *******************************
/**
+ * Check whether we can trust the current bounds of the component.
+ * The return value of false indicates that the container of the
+ * component is invalid, and therefore needs to be layed out, which would
+ * probably mean changing the bounds of its children.
+ * Null-layout of the container or absence of the container mean
+ * the bounds of the component are final and can be trusted.
+ */
+ private boolean areBoundsValid() {
+ Container cont = getContainer();
+ return cont == null || cont.isValid() || cont.getLayout() == null;
+ }
+
+ /**
* Applies the shape to the component
* @param shape Shape to be applied to the component
*/
@@ -9475,7 +9342,7 @@
// to modify the object outside of the mixing code.
this.compoundShape = shape;
- if (isValid()) {
+ if (areBoundsValid()) {
Point compAbsolute = getLocationOnWindow();
if (mixingLog.isLoggable(Level.FINER)) {
@@ -9602,7 +9469,7 @@
void applyCurrentShape() {
checkTreeLock();
- if (!isValid()) {
+ if (!areBoundsValid()) {
return; // Because applyCompoundShape() ignores such components anyway
}
if (mixingLog.isLoggable(Level.FINE)) {
--- a/jdk/src/share/classes/java/awt/Container.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/Container.java Fri Mar 28 12:56:34 2008 -0700
@@ -832,16 +832,8 @@
}
if (!comp.isLightweight() && isLightweight()) {
// If component is heavyweight and one of the containers is lightweight
- // some NativeInLightFixer activity should be performed
- if (!curParent.isLightweight()) {
- // Moving from heavyweight container to lightweight container - should create NativeInLightFixer
- // since addNotify does this
- comp.nativeInLightFixer = new NativeInLightFixer();
- } else {
- // Component already has NativeInLightFixer - just reinstall it
- // because hierarchy changed and he needs to rebuild list of parents to listen.
- comp.nativeInLightFixer.install(this);
- }
+ // the location of the component should be fixed.
+ comp.relocateComponent();
}
}
}
@@ -2267,53 +2259,56 @@
EventTargetFilter filter,
boolean searchHeavyweightChildren,
boolean searchHeavyweightDescendants) {
- int ncomponents = this.ncomponents;
- Component component[] = this.component;
-
- for (int i = 0 ; i < ncomponents ; i++) {
- Component comp = component[i];
- if (comp != null && comp.visible &&
- ((!searchHeavyweightChildren &&
- comp.peer instanceof LightweightPeer) ||
- (searchHeavyweightChildren &&
- !(comp.peer instanceof LightweightPeer))) &&
- comp.contains(x - comp.x, y - comp.y)) {
-
- // found a component that intersects the point, see if there is
- // a deeper possibility.
- if (comp instanceof Container) {
- Container child = (Container) comp;
- Component deeper = child.getMouseEventTarget(x - child.x,
- y - child.y,
- includeSelf,
- filter,
- searchHeavyweightDescendants);
- if (deeper != null) {
- return deeper;
- }
- } else {
- if (filter.accept(comp)) {
- // there isn't a deeper target, but this component is a
- // target
- return comp;
+ synchronized (getTreeLock()) {
+ int ncomponents = this.ncomponents;
+ Component component[] = this.component;
+
+ for (int i = 0 ; i < ncomponents ; i++) {
+ Component comp = component[i];
+ if (comp != null && comp.visible &&
+ ((!searchHeavyweightChildren &&
+ comp.peer instanceof LightweightPeer) ||
+ (searchHeavyweightChildren &&
+ !(comp.peer instanceof LightweightPeer))) &&
+ comp.contains(x - comp.x, y - comp.y)) {
+
+ // found a component that intersects the point, see if there
+ // is a deeper possibility.
+ if (comp instanceof Container) {
+ Container child = (Container) comp;
+ Component deeper = child.getMouseEventTarget(
+ x - child.x,
+ y - child.y,
+ includeSelf,
+ filter,
+ searchHeavyweightDescendants);
+ if (deeper != null) {
+ return deeper;
+ }
+ } else {
+ if (filter.accept(comp)) {
+ // there isn't a deeper target, but this component
+ // is a target
+ return comp;
+ }
}
}
}
+
+ boolean isPeerOK;
+ boolean isMouseOverMe;
+
+ isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
+ isMouseOverMe = contains(x,y);
+
+ // didn't find a child target, return this component if it's
+ // a possible target
+ if (isMouseOverMe && isPeerOK && filter.accept(this)) {
+ return this;
+ }
+ // no possible target
+ return null;
}
-
- boolean isPeerOK;
- boolean isMouseOverMe;
-
- isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
- isMouseOverMe = contains(x,y);
-
- // didn't find a child target, return this component if it's a possible
- // target
- if (isMouseOverMe && isPeerOK && filter.accept(this)) {
- return this;
- }
- // no possible target
- return null;
}
static interface EventTargetFilter {
@@ -3950,6 +3945,83 @@
}
}
+ private void recursiveShowHeavyweightChildren() {
+ if (!hasHeavyweightDescendants() || !isVisible()) {
+ return;
+ }
+ for (int index = 0; index < getComponentCount(); index++) {
+ Component comp = getComponent(index);
+ if (comp.isLightweight()) {
+ if (comp instanceof Container) {
+ ((Container)comp).recursiveShowHeavyweightChildren();
+ }
+ } else {
+ if (comp.isVisible()) {
+ ComponentPeer peer = comp.getPeer();
+ if (peer != null) {
+ peer.show();
+ }
+ }
+ }
+ }
+ }
+
+ private void recursiveHideHeavyweightChildren() {
+ if (!hasHeavyweightDescendants()) {
+ return;
+ }
+ for (int index = 0; index < getComponentCount(); index++) {
+ Component comp = getComponent(index);
+ if (comp.isLightweight()) {
+ if (comp instanceof Container) {
+ ((Container)comp).recursiveHideHeavyweightChildren();
+ }
+ } else {
+ if (comp.isVisible()) {
+ ComponentPeer peer = comp.getPeer();
+ if (peer != null) {
+ peer.hide();
+ }
+ }
+ }
+ }
+ }
+
+ private void recursiveRelocateHeavyweightChildren(Point origin) {
+ for (int index = 0; index < getComponentCount(); index++) {
+ Component comp = getComponent(index);
+ if (comp.isLightweight()) {
+ if (comp instanceof Container &&
+ ((Container)comp).hasHeavyweightDescendants())
+ {
+ final Point newOrigin = new Point(origin);
+ newOrigin.translate(comp.getX(), comp.getY());
+ ((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
+ }
+ } else {
+ ComponentPeer peer = comp.getPeer();
+ if (peer != null) {
+ peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
+ comp.getWidth(), comp.getHeight(),
+ ComponentPeer.SET_LOCATION);
+ }
+ }
+ }
+ }
+
+ /*
+ * Consider the heavyweight container hides or shows the HW descendants
+ * automatically. Therefore we care of LW containers' visibility only.
+ */
+ private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
+ if (!isLightweight()) {
+ return true;
+ }
+ return isVisible() && (getContainer() == null ||
+ getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
+ }
+
+ @Override
void mixOnShowing() {
synchronized (getTreeLock()) {
if (mixingLog.isLoggable(Level.FINE)) {
@@ -3958,6 +4030,10 @@
boolean isLightweight = isLightweight();
+ if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
+ recursiveShowHeavyweightChildren();
+ }
+
if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
recursiveApplyCurrentShape();
}
@@ -3966,6 +4042,42 @@
}
}
+ @Override
+ void mixOnHiding(boolean isLightweight) {
+ synchronized (getTreeLock()) {
+ if (mixingLog.isLoggable(Level.FINE)) {
+ mixingLog.fine("this = " + this +
+ "; isLightweight=" + isLightweight);
+ }
+ if (isLightweight) {
+ recursiveHideHeavyweightChildren();
+ }
+ super.mixOnHiding(isLightweight);
+ }
+ }
+
+ @Override
+ void mixOnReshaping() {
+ synchronized (getTreeLock()) {
+ if (mixingLog.isLoggable(Level.FINE)) {
+ mixingLog.fine("this = " + this);
+ }
+ if (isLightweight() && hasHeavyweightDescendants()) {
+ final Point origin = new Point(getX(), getY());
+ for (Container cont = getContainer();
+ cont != null && cont.isLightweight();
+ cont = cont.getContainer())
+ {
+ origin.translate(cont.getX(), cont.getY());
+ }
+
+ recursiveRelocateHeavyweightChildren(origin);
+ }
+ super.mixOnReshaping();
+ }
+ }
+
+ @Override
void mixOnZOrderChanging(int oldZorder, int newZorder) {
synchronized (getTreeLock()) {
if (mixingLog.isLoggable(Level.FINE)) {
@@ -4431,7 +4543,8 @@
e.isPopupTrigger(),
((MouseWheelEvent)e).getScrollType(),
((MouseWheelEvent)e).getScrollAmount(),
- ((MouseWheelEvent)e).getWheelRotation());
+ ((MouseWheelEvent)e).getWheelRotation(),
+ ((MouseWheelEvent)e).getPreciseWheelRotation());
}
else {
retargeted = new MouseEvent(target,
--- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Fri Mar 28 12:56:34 2008 -0700
@@ -154,7 +154,7 @@
private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
boolean clearOnFailure)
{
- if (toFocus.isShowing() && toFocus.isFocusable() &&
+ if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() &&
toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) {
return true;
} else {
--- a/jdk/src/share/classes/java/awt/Window.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/Window.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
*/
package java.awt;
-import java.applet.Applet;
import java.awt.event.*;
import java.awt.im.InputContext;
import java.awt.image.BufferStrategy;
@@ -355,18 +354,21 @@
static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
final WeakReference<Window> owner;
final WeakReference weakThis;
- final AppContext context;
+ final WeakReference<AppContext> context;
WindowDisposerRecord(AppContext context, Window victim) {
owner = new WeakReference<Window>(victim.getOwner());
weakThis = victim.weakThis;
- this.context = context;
+ this.context = new WeakReference<AppContext>(context);
}
public void dispose() {
Window parent = owner.get();
if (parent != null) {
parent.removeOwnedWindow(weakThis);
}
- Window.removeFromWindowList(context, weakThis);
+ AppContext ac = context.get();
+ if (null != ac) {
+ Window.removeFromWindowList(ac, weakThis);
+ }
}
}
@@ -824,7 +826,10 @@
static private final AtomicBoolean
beforeFirstWindowShown = new AtomicBoolean(true);
- static final void closeSplashScreen() {
+ final void closeSplashScreen() {
+ if (isTrayIconWindow) {
+ return;
+ }
if (beforeFirstWindowShown.getAndSet(false)) {
SunToolkit.closeSplashScreen();
}
--- a/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/datatransfer/SystemFlavorMap.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,6 @@
import sun.awt.datatransfer.DataTransferer;
-
/**
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
@@ -117,16 +116,51 @@
/**
* Maps native Strings to Lists of DataFlavors (or base type Strings for
* text DataFlavors).
+ * Do not use the field directly, use getNativeToFlavor() instead.
*/
private Map nativeToFlavor = new HashMap();
/**
+ * Accessor to nativeToFlavor map. Since we use lazy initialization we must
+ * use this accessor instead of direct access to the field which may not be
+ * initialized yet. This method will initialize the field if needed.
+ *
+ * @return nativeToFlavor
+ */
+ private Map getNativeToFlavor() {
+ if (!isMapInitialized) {
+ initSystemFlavorMap();
+ }
+ return nativeToFlavor;
+ }
+
+ /**
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
* native Strings.
+ * Do not use the field directly, use getFlavorToNative() instead.
*/
private Map flavorToNative = new HashMap();
/**
+ * Accessor to flavorToNative map. Since we use lazy initialization we must
+ * use this accessor instead of direct access to the field which may not be
+ * initialized yet. This method will initialize the field if needed.
+ *
+ * @return flavorToNative
+ */
+ private synchronized Map getFlavorToNative() {
+ if (!isMapInitialized) {
+ initSystemFlavorMap();
+ }
+ return flavorToNative;
+ }
+
+ /**
+ * Shows if the object has been initialized.
+ */
+ private boolean isMapInitialized = false;
+
+ /**
* Caches the result of getNativesForFlavor(). Maps DataFlavors to
* SoftReferences which reference Lists of String natives.
*/
@@ -169,15 +203,24 @@
return fm;
}
+ private SystemFlavorMap() {
+ }
+
/**
- * Constructs a SystemFlavorMap by reading flavormap.properties and
+ * Initializes a SystemFlavorMap by reading flavormap.properties and
* AWT.DnD.flavorMapFileURL.
+ * For thread-safety must be called under lock on this.
*/
- private SystemFlavorMap() {
- BufferedReader flavormapDotProperties = (BufferedReader)
+ private void initSystemFlavorMap() {
+ if (isMapInitialized) {
+ return;
+ }
+
+ isMapInitialized = true;
+ BufferedReader flavormapDotProperties =
java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
+ new java.security.PrivilegedAction<BufferedReader>() {
+ public BufferedReader run() {
String fileName =
System.getProperty("java.home") +
File.separator +
@@ -197,12 +240,11 @@
}
});
- BufferedReader flavormapURL = (BufferedReader)
+ BufferedReader flavormapURL =
java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- String url = Toolkit.getDefaultToolkit().getProperty
- ("AWT.DnD.flavorMapFileURL", null);
+ new java.security.PrivilegedAction<BufferedReader>() {
+ public BufferedReader run() {
+ String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
if (url == null) {
return null;
@@ -237,7 +279,6 @@
}
}
}
-
/**
* Copied code from java.util.Properties. Parsing the data ourselves is the
* only way to handle duplicate keys and values.
@@ -388,11 +429,11 @@
// For text/* flavors, store mappings in separate maps to
// enable dynamic mapping generation at a run-time.
if ("text".equals(flavor.getPrimaryType())) {
- store(value, key, flavorToNative);
- store(key, value, nativeToFlavor);
+ store(value, key, getFlavorToNative());
+ store(key, value, getNativeToFlavor());
} else {
- store(flavor, key, flavorToNative);
- store(key, flavor, nativeToFlavor);
+ store(flavor, key, getFlavorToNative());
+ store(key, flavor, getNativeToFlavor());
}
}
}
@@ -494,7 +535,7 @@
* only if the specified native is encoded as a Java MIME type.
*/
private List nativeToFlavorLookup(String nat) {
- List flavors = (List)nativeToFlavor.get(nat);
+ List flavors = (List)getNativeToFlavor().get(nat);
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
DataTransferer transferer = DataTransferer.getInstance();
@@ -530,15 +571,15 @@
if (flavor != null) {
flavors = new ArrayList(1);
- nativeToFlavor.put(nat, flavors);
+ getNativeToFlavor().put(nat, flavors);
flavors.add(flavor);
getFlavorsForNativeCache.remove(nat);
getFlavorsForNativeCache.remove(null);
- List natives = (List)flavorToNative.get(flavor);
+ List natives = (List)getFlavorToNative().get(flavor);
if (natives == null) {
natives = new ArrayList(1);
- flavorToNative.put(flavor, natives);
+ getFlavorToNative().put(flavor, natives);
}
natives.add(nat);
getNativesForFlavorCache.remove(flavor);
@@ -559,7 +600,7 @@
*/
private List flavorToNativeLookup(final DataFlavor flav,
final boolean synthesize) {
- List natives = (List)flavorToNative.get(flav);
+ List natives = (List)getFlavorToNative().get(flav);
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
DataTransferer transferer = DataTransferer.getInstance();
@@ -584,15 +625,15 @@
if (synthesize) {
String encoded = encodeDataFlavor(flav);
natives = new ArrayList(1);
- flavorToNative.put(flav, natives);
+ getFlavorToNative().put(flav, natives);
natives.add(encoded);
getNativesForFlavorCache.remove(flav);
getNativesForFlavorCache.remove(null);
- List flavors = (List)nativeToFlavor.get(encoded);
+ List flavors = (List)getNativeToFlavor().get(encoded);
if (flavors == null) {
flavors = new ArrayList(1);
- nativeToFlavor.put(encoded, flavors);
+ getNativeToFlavor().put(encoded, flavors);
}
flavors.add(flav);
getFlavorsForNativeCache.remove(encoded);
@@ -645,7 +686,7 @@
}
if (flav == null) {
- retval = new ArrayList(nativeToFlavor.keySet());
+ retval = new ArrayList(getNativeToFlavor().keySet());
} else if (disabledMappingGenerationKeys.contains(flav)) {
// In this case we shouldn't synthesize a native for this flavor,
// since its mappings were explicitly specified.
@@ -655,7 +696,7 @@
// For text/* flavors, flavor-to-native mappings specified in
// flavormap.properties are stored per flavor's base type.
if ("text".equals(flav.getPrimaryType())) {
- retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
+ retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
if (retval != null) {
// To prevent the List stored in the map from modification.
retval = new ArrayList(retval);
@@ -663,7 +704,7 @@
}
// Also include text/plain natives, but don't duplicate Strings
- List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE);
+ List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
if (textPlainList != null && !textPlainList.isEmpty()) {
// To prevent the List stored in the map from modification.
@@ -699,7 +740,7 @@
}
}
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
- retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
+ retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
if (retval == null || retval.isEmpty()) {
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
@@ -1025,10 +1066,10 @@
throw new NullPointerException("null arguments not permitted");
}
- List natives = (List)flavorToNative.get(flav);
+ List natives = (List)getFlavorToNative().get(flav);
if (natives == null) {
natives = new ArrayList(1);
- flavorToNative.put(flav, natives);
+ getFlavorToNative().put(flav, natives);
} else if (natives.contains(nat)) {
return;
}
@@ -1071,7 +1112,7 @@
throw new NullPointerException("null arguments not permitted");
}
- flavorToNative.remove(flav);
+ getFlavorToNative().remove(flav);
for (int i = 0; i < natives.length; i++) {
addUnencodedNativeForFlavor(flav, natives[i]);
}
@@ -1105,10 +1146,10 @@
throw new NullPointerException("null arguments not permitted");
}
- List flavors = (List)nativeToFlavor.get(nat);
+ List flavors = (List)getNativeToFlavor().get(nat);
if (flavors == null) {
flavors = new ArrayList(1);
- nativeToFlavor.put(nat, flavors);
+ getNativeToFlavor().put(nat, flavors);
} else if (flavors.contains(flav)) {
return;
}
@@ -1150,7 +1191,7 @@
throw new NullPointerException("null arguments not permitted");
}
- nativeToFlavor.remove(nat);
+ getNativeToFlavor().remove(nat);
for (int i = 0; i < flavors.length; i++) {
addFlavorForUnencodedNative(nat, flavors[i]);
}
--- a/jdk/src/share/classes/java/awt/dnd/DropTarget.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/dnd/DropTarget.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -110,7 +110,11 @@
setActive(act);
}
- if (fm != null) flavorMap = fm;
+ if (fm != null) {
+ flavorMap = fm;
+ } else {
+ flavorMap = SystemFlavorMap.getDefaultFlavorMap();
+ }
}
/**
@@ -850,5 +854,5 @@
* The FlavorMap
*/
- private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
+ private transient FlavorMap flavorMap;
}
--- a/jdk/src/share/classes/java/awt/event/MouseWheelEvent.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/awt/event/MouseWheelEvent.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,6 +74,19 @@
* methods for conforming to the underlying platform settings. These
* platform settings can be changed at any time by the user. MouseWheelEvents
* reflect the most recent settings.
+ * <P>
+ * The <code>MouseWheelEvent</code> class includes methods for
+ * getting the number of "clicks" by which the mouse wheel is rotated.
+ * The {@link #getWheelRotation} method returns the integer number
+ * of "clicks" corresponding to the number of notches by which the wheel was
+ * rotated. In addition to this method, the <code>MouseWheelEvent</code>
+ * class provides the {@link #getPreciseWheelRotation} method which returns
+ * a double number of "clicks" in case a partial rotation occurred.
+ * The {@link #getPreciseWheelRotation} method is useful if a mouse supports
+ * a high-resolution wheel, such as a freely rotating wheel with no
+ * notches. Applications can benefit by using this method to process
+ * mouse wheel events more precisely, and thus, making visual perception
+ * smoother.
*
* @author Brent Christian
* @see MouseWheelListener
@@ -131,6 +144,13 @@
*/
int wheelRotation;
+ /**
+ * Indicates how far the mouse wheel was rotated.
+ *
+ * @see #getPreciseWheelRotation
+ */
+ double preciseWheelRotation;
+
/*
* serialVersionUID
*/
@@ -165,8 +185,8 @@
* <code>WHEEL_BLOCK_SCROLL</code>
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
* the number of units to be scrolled
- * @param wheelRotation the amount that the mouse wheel was rotated (the
- * number of "clicks")
+ * @param wheelRotation the integer number of "clicks" by which the mouse
+ * wheel was rotated
*
* @throws IllegalArgumentException if <code>source</code> is null
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
@@ -211,8 +231,8 @@
* <code>WHEEL_BLOCK_SCROLL</code>
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
* the number of units to be scrolled
- * @param wheelRotation the amount that the mouse wheel was rotated (the
- * number of "clicks")
+ * @param wheelRotation the integer number of "clicks" by which the mouse
+ * wheel was rotated
*
* @throws IllegalArgumentException if <code>source</code> is null
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
@@ -223,12 +243,68 @@
int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
int scrollType, int scrollAmount, int wheelRotation) {
+ this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger,
+ scrollType, scrollAmount, wheelRotation, wheelRotation);
+
+ }
+
+
+ /**
+ * Constructs a <code>MouseWheelEvent</code> object with the specified
+ * source component, type, modifiers, coordinates, absolute coordinates,
+ * scroll type, scroll amount, and wheel rotation.
+ * <p>Note that passing in an invalid <code>id</code> parameter results
+ * in unspecified behavior. This method throws an
+ * <code>IllegalArgumentException</code> if <code>source</code> equals
+ * <code>null</code>.
+ * <p>Even if inconsistent values for relative and absolute coordinates
+ * are passed to the constructor, a <code>MouseWheelEvent</code> instance
+ * is still created and no exception is thrown.
+ *
+ * @param source the <code>Component</code> that originated the event
+ * @param id the integer value that identifies the event
+ * @param when a long value that gives the time when the event occurred
+ * @param modifiers the modifier keys down during event
+ * (shift, ctrl, alt, meta)
+ * @param x the horizontal <code>x</code> coordinate for the
+ * mouse location
+ * @param y the vertical <code>y</code> coordinate for the
+ * mouse location
+ * @param xAbs the absolute horizontal <code>x</code> coordinate for
+ * the mouse location
+ * @param yAbs the absolute vertical <code>y</code> coordinate for
+ * the mouse location
+ * @param clickCount the number of mouse clicks associated with the event
+ * @param popupTrigger a boolean value, <code>true</code> if this event is a trigger
+ * for a popup-menu
+ * @param scrollType the type of scrolling which should take place in
+ * response to this event; valid values are
+ * <code>WHEEL_UNIT_SCROLL</code> and
+ * <code>WHEEL_BLOCK_SCROLL</code>
+ * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
+ * the number of units to be scrolled
+ * @param wheelRotation the integer number of "clicks" by which the mouse wheel
+ * was rotated
+ * @param preciseWheelRotation the double number of "clicks" by which the mouse wheel
+ * was rotated
+ *
+ * @throws IllegalArgumentException if <code>source</code> is null
+ * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
+ * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
+ * @since 1.7
+ */
+ public MouseWheelEvent (Component source, int id, long when, int modifiers,
+ int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
+ int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) {
+
super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
popupTrigger, MouseEvent.NOBUTTON);
this.scrollType = scrollType;
this.scrollAmount = scrollAmount;
this.wheelRotation = wheelRotation;
+ this.preciseWheelRotation = preciseWheelRotation;
+
}
/**
@@ -267,17 +343,35 @@
}
/**
- * Returns the number of "clicks" the mouse wheel was rotated.
+ * Returns the number of "clicks" the mouse wheel was rotated, as an integer.
+ * A partial rotation may occur if the mouse supports a high-resolution wheel.
+ * In this case, the method returns zero until a full "click" has been accumulated.
*
* @return negative values if the mouse wheel was rotated up/away from
* the user, and positive values if the mouse wheel was rotated down/
* towards the user
+ * @see #getPreciseWheelRotation
*/
public int getWheelRotation() {
return wheelRotation;
}
/**
+ * Returns the number of "clicks" the mouse wheel was rotated, as a double.
+ * A partial rotation may occur if the mouse supports a high-resolution wheel.
+ * In this case, the return value will include a fractional "click".
+ *
+ * @return negative values if the mouse wheel was rotated up or away from
+ * the user, and positive values if the mouse wheel was rotated down or
+ * towards the user
+ * @see #getWheelRotation
+ * @since 1.7
+ */
+ public double getPreciseWheelRotation() {
+ return preciseWheelRotation;
+ }
+
+ /**
* This is a convenience method to aid in the implementation of
* the common-case MouseWheelListener - to scroll a ScrollPane or
* JScrollPane by an amount which conforms to the platform settings.
@@ -348,6 +442,6 @@
}
return super.paramString()+",scrollType="+scrollTypeStr+
",scrollAmount="+getScrollAmount()+",wheelRotation="+
- getWheelRotation();
+ getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation();
}
}
--- a/jdk/src/share/classes/java/beans/MetaData.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/beans/MetaData.java Fri Mar 28 12:56:34 2008 -0700
@@ -1553,7 +1553,7 @@
private static String[] getConstructorProperties(Class type) {
String[] names = null;
int length = 0;
- for (Constructor constructor : type.getConstructors()) {
+ for (Constructor<?> constructor : type.getConstructors()) {
String[] value = getAnnotationValue(constructor);
if ((value != null) && (length < value.length) && isValid(constructor, value)) {
names = value;
@@ -1563,14 +1563,14 @@
return names;
}
- private static String[] getAnnotationValue(Constructor constructor) {
+ private static String[] getAnnotationValue(Constructor<?> constructor) {
ConstructorProperties annotation = constructor.getAnnotation(ConstructorProperties.class);
return (annotation != null)
? annotation.value()
: null;
}
- private static boolean isValid(Constructor constructor, String[] names) {
+ private static boolean isValid(Constructor<?> constructor, String[] names) {
Class[] parameters = constructor.getParameterTypes();
if (names.length != parameters.length) {
return false;
--- a/jdk/src/share/classes/java/lang/instrument/Instrumentation.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/java/lang/instrument/Instrumentation.java Fri Mar 28 12:56:34 2008 -0700
@@ -636,7 +636,11 @@
* @param transformer
* The ClassFileTransformer which wraps using this prefix.
* @param prefix
- * The prefix which has been applied to wrapped native methods.
+ * The prefix to apply to wrapped native methods when
+ * retrying a failed native method resolution. If prefix
+ * is either <code>null</code> or the empty string, then
+ * failed native method resolutions are not retried for
+ * this transformer.
* @throws java.lang.NullPointerException if passed a <code>null</code> transformer.
* @throws java.lang.UnsupportedOperationException if the current configuration of
* the JVM does not allow setting a native method prefix
--- a/jdk/src/share/classes/javax/management/MBeanServer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java Fri Mar 28 12:56:34 2008 -0700
@@ -50,7 +50,7 @@
* server. A Java object cannot be registered in the MBean server
* unless it is a JMX compliant MBean.</p>
*
- * <p>When an MBean is registered or unregistered in the MBean server
+ * <p id="notif">When an MBean is registered or unregistered in the MBean server
* a {@link javax.management.MBeanServerNotification
* MBeanServerNotification} Notification is emitted. To register an
* object as listener to MBeanServerNotifications you should call the
@@ -258,27 +258,43 @@
*/
public interface MBeanServer extends MBeanServerConnection {
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ * <p>If this method successfully creates an MBean, a notification
+ * is sent as described <a href="#notif">above</a>.</p>
+ */
public ObjectInstance createMBean(String className, ObjectName name)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException;
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ * <p>If this method successfully creates an MBean, a notification
+ * is sent as described <a href="#notif">above</a>.</p>
+ */
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName)
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException, InstanceNotFoundException;
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ * <p>If this method successfully creates an MBean, a notification
+ * is sent as described <a href="#notif">above</a>.</p>
+ */
public ObjectInstance createMBean(String className, ObjectName name,
Object params[], String signature[])
throws ReflectionException, InstanceAlreadyExistsException,
MBeanRegistrationException, MBeanException,
NotCompliantMBeanException;
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ * <p>If this method successfully creates an MBean, a notification
+ * is sent as described <a href="#notif">above</a>.</p>
+ */
public ObjectInstance createMBean(String className, ObjectName name,
ObjectName loaderName, Object params[],
String signature[])
@@ -287,12 +303,15 @@
NotCompliantMBeanException, InstanceNotFoundException;
/**
- * Registers a pre-existing object as an MBean with the MBean
+ * <p>Registers a pre-existing object as an MBean with the MBean
* server. If the object name given is null, the MBean must
* provide its own name by implementing the {@link
* javax.management.MBeanRegistration MBeanRegistration} interface
* and returning the name from the {@link
- * MBeanRegistration#preRegister preRegister} method.
+ * MBeanRegistration#preRegister preRegister} method.</p>
+ *
+ * <p>If this method successfully registers an MBean, a notification
+ * is sent as described <a href="#notif">above</a>.</p>
*
* @param object The MBean to be registered as an MBean.
* @param name The object name of the MBean. May be null.
@@ -319,7 +338,12 @@
throws InstanceAlreadyExistsException, MBeanRegistrationException,
NotCompliantMBeanException;
- // doc comment inherited from MBeanServerConnection
+ /**
+ * {@inheritDoc}
+ *
+ * <p>If this method successfully unregisters an MBean, a notification
+ * is sent as described <a href="#notif">above</a>.</p>
+ */
public void unregisterMBean(ObjectName name)
throws InstanceNotFoundException, MBeanRegistrationException;
--- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Fri Mar 28 12:56:34 2008 -0700
@@ -48,6 +48,7 @@
import java.util.Map;
import java.util.Set;
+import java.util.Vector;
import javax.management.Attribute;
import javax.management.AttributeChangeNotification;
import javax.management.AttributeChangeNotificationFilter;
@@ -132,8 +133,6 @@
* and operations will be executed */
private Object managedResource = null;
- private static final String currClass = "RequiredModelMBean";
-
/* records the registering in MBeanServer */
private boolean registered = false;
private transient MBeanServer server = null;
@@ -2488,10 +2487,13 @@
}
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
+ Vector<String> enabledAttrs = currFilter.getEnabledAttributes();
+ String s = (enabledAttrs.size() > 1) ?
+ "[" + enabledAttrs.firstElement() + ", ...]" :
+ enabledAttrs.toString();
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(), mth,
- "Set attribute change filter to " +
- currFilter.getEnabledAttributes().firstElement());
+ "Set attribute change filter to " + s);
}
attributeBroadcaster.addNotificationListener(inlistener,currFilter,
--- a/jdk/src/share/classes/sun/awt/AppContext.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/sun/awt/AppContext.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,8 @@
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
@@ -126,6 +128,7 @@
* @author Fred Ecks
*/
public final class AppContext {
+ private static final Logger log = Logger.getLogger("sun.awt.AppContext");
/* Since the contents of an AppContext are unique to each Java
* session, this class should never be serialized. */
@@ -143,13 +146,15 @@
* Returns a set containing all <code>AppContext</code>s.
*/
public static Set<AppContext> getAppContexts() {
- return new HashSet<AppContext>(threadGroup2appContext.values());
+ synchronized (threadGroup2appContext) {
+ return new HashSet<AppContext>(threadGroup2appContext.values());
+ }
}
/* The main "system" AppContext, used by everything not otherwise
contained in another AppContext.
*/
- private static AppContext mainAppContext = null;
+ private static volatile AppContext mainAppContext = null;
/*
* The hash map associated with this AppContext. A private delegate
@@ -174,31 +179,30 @@
public static final String DISPOSED_PROPERTY_NAME = "disposed";
public static final String GUI_DISPOSED = "guidisposed";
- private boolean isDisposed = false; // true if AppContext is disposed
+ private volatile boolean isDisposed = false; // true if AppContext is disposed
public boolean isDisposed() {
return isDisposed;
}
-
static {
// On the main Thread, we get the ThreadGroup, make a corresponding
// AppContext, and instantiate the Java EventQueue. This way, legacy
// code is unaffected by the move to multiple AppContext ability.
AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- ThreadGroup currentThreadGroup =
- Thread.currentThread().getThreadGroup();
- ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
- while (parentThreadGroup != null) {
- // Find the root ThreadGroup to construct our main AppContext
- currentThreadGroup = parentThreadGroup;
- parentThreadGroup = currentThreadGroup.getParent();
+ public Object run() {
+ ThreadGroup currentThreadGroup =
+ Thread.currentThread().getThreadGroup();
+ ThreadGroup parentThreadGroup = currentThreadGroup.getParent();
+ while (parentThreadGroup != null) {
+ // Find the root ThreadGroup to construct our main AppContext
+ currentThreadGroup = parentThreadGroup;
+ parentThreadGroup = currentThreadGroup.getParent();
+ }
+ mainAppContext = new AppContext(currentThreadGroup);
+ numAppContexts = 1;
+ return mainAppContext;
}
- mainAppContext = new AppContext(currentThreadGroup);
- numAppContexts = 1;
- return mainAppContext;
- }
});
}
@@ -209,7 +213,7 @@
* number is 1. If so, it returns the sole AppContext without
* checking Thread.currentThread().
*/
- private static int numAppContexts;
+ private static volatile int numAppContexts;
/*
* The context ClassLoader that was used to create this AppContext.
@@ -236,14 +240,15 @@
threadGroup2appContext.put(threadGroup, this);
this.contextClassLoader =
- (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
}
- private static MostRecentThreadAppContext mostRecentThreadAppContext = null;
+ private static final ThreadLocal<AppContext> threadAppContext =
+ new ThreadLocal<AppContext>();
/**
* Returns the appropriate AppContext for the caller,
@@ -260,59 +265,46 @@
if (numAppContexts == 1) // If there's only one system-wide,
return mainAppContext; // return the main system AppContext.
- final Thread currentThread = Thread.currentThread();
-
- AppContext appContext = null;
-
- // Note: this most recent Thread/AppContext caching is thread-hot.
- // A simple test using SwingSet found that 96.8% of lookups
- // were matched using the most recent Thread/AppContext. By
- // instantiating a simple MostRecentThreadAppContext object on
- // cache misses, the cache hits can be processed without
- // synchronization.
+ AppContext appContext = threadAppContext.get();
- MostRecentThreadAppContext recent = mostRecentThreadAppContext;
- if ((recent != null) && (recent.thread == currentThread)) {
- appContext = recent.appContext; // Cache hit
- } else {
- appContext = (AppContext)AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- // Get the current ThreadGroup, and look for it and its
- // parents in the hash from ThreadGroup to AppContext --
- // it should be found, because we use createNewContext()
- // when new AppContext objects are created.
- ThreadGroup currentThreadGroup = currentThread.getThreadGroup();
- ThreadGroup threadGroup = currentThreadGroup;
- AppContext context = threadGroup2appContext.get(threadGroup);
- while (context == null) {
- threadGroup = threadGroup.getParent();
- if (threadGroup == null) {
- // If we get here, we're running under a ThreadGroup that
- // has no AppContext associated with it. This should never
- // happen, because createNewContext() should be used by the
- // toolkit to create the ThreadGroup that everything runs
- // under.
- throw new RuntimeException("Invalid ThreadGroup");
+ if (null == appContext) {
+ appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
+ {
+ public AppContext run() {
+ // Get the current ThreadGroup, and look for it and its
+ // parents in the hash from ThreadGroup to AppContext --
+ // it should be found, because we use createNewContext()
+ // when new AppContext objects are created.
+ ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
+ ThreadGroup threadGroup = currentThreadGroup;
+ AppContext context = threadGroup2appContext.get(threadGroup);
+ while (context == null) {
+ threadGroup = threadGroup.getParent();
+ if (threadGroup == null) {
+ // If we get here, we're running under a ThreadGroup that
+ // has no AppContext associated with it. This should never
+ // happen, because createNewContext() should be used by the
+ // toolkit to create the ThreadGroup that everything runs
+ // under.
+ throw new RuntimeException("Invalid ThreadGroup");
+ }
+ context = threadGroup2appContext.get(threadGroup);
+ }
+ // In case we did anything in the above while loop, we add
+ // all the intermediate ThreadGroups to threadGroup2appContext
+ // so we won't spin again.
+ for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
+ threadGroup2appContext.put(tg, context);
+ }
+ // Now we're done, so we cache the latest key/value pair.
+ // (we do this before checking with any AWTSecurityManager, so if
+ // this Thread equates with the main AppContext in the cache, it
+ // still will)
+ threadAppContext.set(context);
+
+ return context;
}
- context = threadGroup2appContext.get(threadGroup);
- }
- // In case we did anything in the above while loop, we add
- // all the intermediate ThreadGroups to threadGroup2appContext
- // so we won't spin again.
- for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) {
- threadGroup2appContext.put(tg, context);
- }
- // Now we're done, so we cache the latest key/value pair.
- // (we do this before checking with any AWTSecurityManager, so if
- // this Thread equates with the main AppContext in the cache, it
- // still will)
- mostRecentThreadAppContext =
- new MostRecentThreadAppContext(currentThread, context);
-
- return context;
- }
- });
+ });
}
if (appContext == mainAppContext) {
@@ -321,9 +313,9 @@
// allow it to choose the AppContext to return.
SecurityManager securityManager = System.getSecurityManager();
if ((securityManager != null) &&
- (securityManager instanceof AWTSecurityManager)) {
- AWTSecurityManager awtSecMgr =
- (AWTSecurityManager)securityManager;
+ (securityManager instanceof AWTSecurityManager))
+ {
+ AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
AppContext secAppContext = awtSecMgr.getAppContext();
if (secAppContext != null) {
appContext = secAppContext; // Return what we're told
@@ -385,7 +377,13 @@
public void run() {
Window[] windowsToDispose = Window.getOwnerlessWindows();
for (Window w : windowsToDispose) {
- w.dispose();
+ try {
+ w.dispose();
+ } catch (Throwable t) {
+ if (log.isLoggable(Level.FINER)) {
+ log.log(Level.FINER, "exception occured while disposing app context", t);
+ }
+ }
}
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
@@ -444,7 +442,7 @@
// Threads in the ThreadGroup to exit.
long startTime = System.currentTimeMillis();
- long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
+ long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
while ((this.threadGroup.activeCount() > 0) &&
(System.currentTimeMillis() < endTime)) {
try {
@@ -459,7 +457,7 @@
// Threads in the ThreadGroup to die.
startTime = System.currentTimeMillis();
- endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
+ endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
while ((this.threadGroup.activeCount() > 0) &&
(System.currentTimeMillis() < endTime)) {
try {
@@ -478,10 +476,7 @@
}
threadGroup2appContext.remove(this.threadGroup);
- MostRecentThreadAppContext recent = mostRecentThreadAppContext;
- if ((recent != null) && (recent.appContext == this))
- mostRecentThreadAppContext = null;
- // If the "most recent" points to this, clear it for GC
+ threadAppContext.set(null);
// Finally, we destroy the ThreadGroup entirely.
try {
@@ -664,6 +659,7 @@
* Returns a string representation of this AppContext.
* @since 1.2
*/
+ @Override
public String toString() {
return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
}
@@ -769,15 +765,6 @@
}
}
-final class MostRecentThreadAppContext {
- final Thread thread;
- final AppContext appContext;
- MostRecentThreadAppContext(Thread key, AppContext value) {
- thread = key;
- appContext = value;
- }
-}
-
final class MostRecentKeyValue {
Object key;
Object value;
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -270,62 +270,58 @@
* instead, null will be returned.
*/
public static DataTransferer getInstance() {
- if (transferer == null) {
- synchronized (DataTransferer.class) {
- if (transferer == null) {
- final String name = SunToolkit.
- getDataTransfererClassName();
- if (name != null) {
- PrivilegedAction action = new PrivilegedAction() {
- public Object run() {
- Class cls = null;
- Method method = null;
- Object ret = null;
+ synchronized (DataTransferer.class) {
+ if (transferer == null) {
+ final String name = SunToolkit.getDataTransfererClassName();
+ if (name != null) {
+ PrivilegedAction<DataTransferer> action = new PrivilegedAction<DataTransferer>()
+ {
+ public DataTransferer run() {
+ Class cls = null;
+ Method method = null;
+ DataTransferer ret = null;
- try {
- cls = Class.forName(name);
- } catch (ClassNotFoundException e) {
- ClassLoader cl = ClassLoader.
- getSystemClassLoader();
- if (cl != null) {
- try {
- cls = cl.loadClass(name);
- } catch (ClassNotFoundException ee) {
- ee.printStackTrace();
- throw new AWTError("DataTransferer not found: " + name);
- }
+ try {
+ cls = Class.forName(name);
+ } catch (ClassNotFoundException e) {
+ ClassLoader cl = ClassLoader.
+ getSystemClassLoader();
+ if (cl != null) {
+ try {
+ cls = cl.loadClass(name);
+ } catch (ClassNotFoundException ee) {
+ ee.printStackTrace();
+ throw new AWTError("DataTransferer not found: " + name);
}
}
- if (cls != null) {
- try {
- method = cls.getDeclaredMethod
- ("getInstanceImpl");
- method.setAccessible(true);
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new AWTError("Cannot instantiate DataTransferer: " + name);
- } catch (SecurityException e) {
- e.printStackTrace();
- throw new AWTError("Access is denied for DataTransferer: " + name);
- }
+ }
+ if (cls != null) {
+ try {
+ method = cls.getDeclaredMethod("getInstanceImpl");
+ method.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ throw new AWTError("Cannot instantiate DataTransferer: " + name);
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ throw new AWTError("Access is denied for DataTransferer: " + name);
}
- if (method != null) {
- try {
- ret = method.invoke(null);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- throw new AWTError("Cannot instantiate DataTransferer: " + name);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- throw new AWTError("Cannot access DataTransferer: " + name);
- }
+ }
+ if (method != null) {
+ try {
+ ret = (DataTransferer) method.invoke(null);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ throw new AWTError("Cannot instantiate DataTransferer: " + name);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ throw new AWTError("Cannot access DataTransferer: " + name);
}
- return ret;
}
- };
- transferer = (DataTransferer)
- AccessController.doPrivileged(action);
- }
+ return ret;
+ }
+ };
+ transferer = AccessController.doPrivileged(action);
}
}
}
--- a/jdk/src/share/classes/sun/instrument/InstrumentationImpl.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/sun/instrument/InstrumentationImpl.java Fri Mar 28 12:56:34 2008 -0700
@@ -303,39 +303,78 @@
NoSuchMethodException firstExc = null;
boolean twoArgAgent = false;
- // The agent class has a premain or agentmain method that has 1 or 2
- // arguments. We first check for a signature of (String, Instrumentation),
- // and if not found we check for (String). If neither is found then we
- // throw the NoSuchMethodException from the first attempt so that the
- // exception text indicates the lookup failed for the 2-arg method
- // (same as JDK5.0).
+ // The agent class must have a premain or agentmain method that
+ // has 1 or 2 arguments. We check in the following order:
+ //
+ // 1) declared with a signature of (String, Instrumentation)
+ // 2) declared with a signature of (String)
+ // 3) inherited with a signature of (String, Instrumentation)
+ // 4) inherited with a signature of (String)
+ //
+ // So the declared version of either 1-arg or 2-arg always takes
+ // primary precedence over an inherited version. After that, the
+ // 2-arg version takes precedence over the 1-arg version.
+ //
+ // If no method is found then we throw the NoSuchMethodException
+ // from the first attempt so that the exception text indicates
+ // the lookup failed for the 2-arg method (same as JDK5.0).
try {
- m = javaAgentClass.getMethod( methodname,
- new Class[] {
- String.class,
- java.lang.instrument.Instrumentation.class
- }
- );
+ m = javaAgentClass.getDeclaredMethod( methodname,
+ new Class[] {
+ String.class,
+ java.lang.instrument.Instrumentation.class
+ }
+ );
twoArgAgent = true;
} catch (NoSuchMethodException x) {
// remember the NoSuchMethodException
firstExc = x;
}
- // check for the 1-arg method
if (m == null) {
+ // now try the declared 1-arg method
+ try {
+ m = javaAgentClass.getDeclaredMethod(methodname,
+ new Class[] { String.class });
+ } catch (NoSuchMethodException x) {
+ // ignore this exception because we'll try
+ // two arg inheritance next
+ }
+ }
+
+ if (m == null) {
+ // now try the inherited 2-arg method
try {
- m = javaAgentClass.getMethod(methodname, new Class[] { String.class });
+ m = javaAgentClass.getMethod( methodname,
+ new Class[] {
+ String.class,
+ java.lang.instrument.Instrumentation.class
+ }
+ );
+ twoArgAgent = true;
} catch (NoSuchMethodException x) {
- // Neither method exists so we throw the first NoSuchMethodException
- // as per 5.0
+ // ignore this exception because we'll try
+ // one arg inheritance next
+ }
+ }
+
+ if (m == null) {
+ // finally try the inherited 1-arg method
+ try {
+ m = javaAgentClass.getMethod(methodname,
+ new Class[] { String.class });
+ } catch (NoSuchMethodException x) {
+ // none of the methods exists so we throw the
+ // first NoSuchMethodException as per 5.0
throw firstExc;
}
}
// the premain method should not be required to be public,
// make it accessible so we can call it
+ // Note: The spec says the following:
+ // The agent class must implement a public static premain method...
setAccessible(m, true);
// invoke the 1 or 2-arg method
--- a/jdk/src/share/classes/sun/management/Flag.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/classes/sun/management/Flag.java Fri Mar 28 12:56:34 2008 -0700
@@ -64,7 +64,8 @@
}
VMOption getVMOption() {
- return new VMOption(name, value.toString(), writeable, origin);
+ String val = value == null ? "" : value.toString();
+ return new VMOption(name, val, writeable, origin);
}
static Flag getFlag(String name) {
--- a/jdk/src/share/instrument/InvocationAdapter.c Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/instrument/InvocationAdapter.c Fri Mar 28 12:56:34 2008 -0700
@@ -626,6 +626,7 @@
jvmtiError jvmtierr;
jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile);
+ check_phase_ret_1(jvmtierr);
if (jvmtierr == JVMTI_ERROR_NONE) {
return 0;
@@ -634,6 +635,7 @@
jvmtiError err;
err = (*jvmtienv)->GetPhase(jvmtienv, &phase);
+ /* can be called from any phase */
jplis_assert(err == JVMTI_ERROR_NONE);
if (phase == JVMTI_PHASE_LIVE) {
@@ -805,6 +807,8 @@
/* print warning if boot class path not updated */
if (jvmtierr != JVMTI_ERROR_NONE) {
+ check_phase_blob_ret(jvmtierr, free(path));
+
fprintf(stderr, "WARNING: %s not added to bootstrap class loader search: ", path);
switch (jvmtierr) {
case JVMTI_ERROR_ILLEGAL_ARGUMENT :
--- a/jdk/src/share/instrument/JPLISAgent.c Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/instrument/JPLISAgent.c Fri Mar 28 12:56:34 2008 -0700
@@ -179,6 +179,7 @@
jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
jvmtienv,
(void**)&environment);
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if (jvmtierror == JVMTI_ERROR_NONE) {
@@ -230,6 +231,7 @@
/* don't leak envs */
if ( initerror != JPLIS_INIT_ERROR_NONE ) {
jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
}
@@ -259,7 +261,7 @@
agent->mNormalEnvironment.mIsRetransformer = JNI_FALSE;
agent->mRetransformEnvironment.mJVMTIEnv = NULL; /* NULL until needed */
agent->mRetransformEnvironment.mAgent = agent;
- agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;
+ agent->mRetransformEnvironment.mIsRetransformer = JNI_FALSE; /* JNI_FALSE until mJVMTIEnv is set */
agent->mAgentmainCaller = NULL;
agent->mInstrumentationImpl = NULL;
agent->mPremainCaller = NULL;
@@ -277,18 +279,25 @@
jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
jvmtienv,
&(agent->mNormalEnvironment));
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
/* check what capabilities are available */
checkCapabilities(agent);
/* check phase - if live phase then we don't need the VMInit event */
- jvmtierror == (*jvmtienv)->GetPhase(jvmtienv, &phase);
+ jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if (phase == JVMTI_PHASE_LIVE) {
return JPLIS_INIT_ERROR_NONE;
}
+ if (phase != JVMTI_PHASE_ONLOAD) {
+ /* called too early or called too late; either way bail out */
+ return JPLIS_INIT_ERROR_FAILURE;
+ }
+
/* now turn on the VMInit event */
if ( jvmtierror == JVMTI_ERROR_NONE ) {
jvmtiEventCallbacks callbacks;
@@ -298,6 +307,7 @@
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
&callbacks,
sizeof(callbacks));
+ check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -307,6 +317,7 @@
JVMTI_ENABLE,
JVMTI_EVENT_VM_INIT,
NULL /* all threads */);
+ check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -622,6 +633,7 @@
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
&callbacks,
sizeof(callbacks));
+ check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
@@ -632,6 +644,7 @@
JVMTI_DISABLE,
JVMTI_EVENT_VM_INIT,
NULL /* all threads */);
+ check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -642,6 +655,7 @@
JVMTI_ENABLE,
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
NULL /* all threads */);
+ check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -660,6 +674,7 @@
memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));
jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
+ check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if ( jvmtierror == JVMTI_ERROR_NONE ) {
@@ -681,9 +696,11 @@
jvmtiError jvmtierror;
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
desiredCapabilities.can_set_native_method_prefix = 1;
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
+ check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -715,9 +732,11 @@
jvmtiError jvmtierror;
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
desiredCapabilities.can_maintain_original_method_order = 1;
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
+ check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -732,9 +751,11 @@
if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
+ /* can be called from any phase */
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
desiredCapabilities.can_redefine_classes = 1;
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
+ check_phase_ret(jvmtierror);
/*
* With mixed premain/agentmain agents then it's possible that the
@@ -998,6 +1019,7 @@
if (jvmtierror == JVMTI_ERROR_NONE) {
// install the retransforming environment
agent->mRetransformEnvironment.mJVMTIEnv = retransformerEnv;
+ agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;
// Make it for ClassFileLoadHook handling
jvmtierror = (*retransformerEnv)->SetEnvironmentLocalStorage(
@@ -1025,6 +1047,7 @@
jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
clazz,
&is_modifiable);
+ check_phase_ret_false(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
return is_modifiable;
@@ -1032,7 +1055,7 @@
jboolean
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) {
- return retransformableEnvironment(agent) != NULL;
+ return agent->mRetransformEnvironment.mIsRetransformer;
}
void
@@ -1075,6 +1098,12 @@
numClasses = (*jnienv)->GetArrayLength(jnienv, classes);
errorOccurred = checkForThrowable(jnienv);
jplis_assert(!errorOccurred);
+
+ if (!errorOccurred && numClasses == 0) {
+ jplis_assert(numClasses != 0);
+ errorOccurred = JNI_TRUE;
+ errorCode = JVMTI_ERROR_NULL_POINTER;
+ }
}
if (!errorOccurred) {
@@ -1096,6 +1125,13 @@
if (errorOccurred) {
break;
}
+
+ if (classArray[index] == NULL) {
+ jplis_assert(classArray[index] != NULL);
+ errorOccurred = JNI_TRUE;
+ errorCode = JVMTI_ERROR_NULL_POINTER;
+ break;
+ }
}
}
@@ -1217,6 +1253,7 @@
if (!errorOccurred) {
jvmtiError errorCode = JVMTI_ERROR_NONE;
errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
+ check_phase_blob_ret(errorCode, deallocate(jvmtienv, (void*)classDefs));
errorOccurred = (errorCode != JVMTI_ERROR_NONE);
if ( errorOccurred ) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
@@ -1250,6 +1287,7 @@
classLoader,
&classCount,
&classes);
+ check_phase_ret_blob(jvmtierror, localArray);
errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
jplis_assert(!errorOccurred);
@@ -1311,6 +1349,7 @@
jvmtiError jvmtierror = JVMTI_ERROR_NONE;
jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
+ check_phase_ret_0(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
if ( jvmtierror != JVMTI_ERROR_NONE ) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
@@ -1360,6 +1399,7 @@
} else {
jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
}
+ check_phase_ret(jvmtierror);
if ( jvmtierror != JVMTI_ERROR_NONE ) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
@@ -1450,6 +1490,7 @@
}
err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
+ /* can be called from any phase */
jplis_assert(err == JVMTI_ERROR_NONE);
for (i = 0; i < inx; i++) {
--- a/jdk/src/share/instrument/JPLISAgent.h Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/instrument/JPLISAgent.h Fri Mar 28 12:56:34 2008 -0700
@@ -266,6 +266,48 @@
#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv
+/*
+ * A set of macros for insulating the JLI method callers from
+ * JVMTI_ERROR_WRONG_PHASE return codes.
+ */
+
+/* for a JLI method where "blob" is executed before simply returning */
+#define check_phase_blob_ret(ret, blob) \
+ if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
+ blob; \
+ return; \
+ }
+
+/* for a JLI method where simply returning is benign */
+#define check_phase_ret(ret) \
+ if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
+ return; \
+ }
+
+/* for a JLI method where returning zero (0) is benign */
+#define check_phase_ret_0(ret) \
+ if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
+ return 0; \
+ }
+
+/* for a JLI method where returning one (1) is benign */
+#define check_phase_ret_1(ret) \
+ if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
+ return 1; \
+ }
+
+/* for a case where a specific "blob" must be returned */
+#define check_phase_ret_blob(ret, blob) \
+ if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
+ return (blob); \
+ }
+
+/* for a JLI method where returning false is benign */
+#define check_phase_ret_false(ret) \
+ if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
+ return (jboolean) 0; \
+ }
+
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
--- a/jdk/src/share/instrument/JarFacade.c Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/instrument/JarFacade.c Fri Mar 28 12:56:34 2008 -0700
@@ -23,6 +23,14 @@
* have any questions.
*/
+#ifdef _WIN32
+/*
+ * Win* needs this include. However, Linux and Solaris do not.
+ * Having this include on Solaris SPARC breaks having non US-ASCII
+ * characters in the value of the Premain-Class attribute.
+ */
+#include <ctype.h>
+#endif /* _WIN32 */
#include <string.h>
#include <stdlib.h>
@@ -45,11 +53,37 @@
if (attribute->name == NULL) {
free(attribute);
} else {
- attribute->value = strdup(value);
+ char *begin = (char *)value;
+ char *end;
+ size_t value_len;
+
+ /* skip any leading white space */
+ while (isspace(*begin)) {
+ begin++;
+ }
+
+ /* skip any trailing white space */
+ end = &begin[strlen(begin)];
+ while (end > begin && isspace(end[-1])) {
+ end--;
+ }
+
+ if (begin == end) {
+ /* no value so skip this attribute */
+ free(attribute->name);
+ free(attribute);
+ return;
+ }
+
+ value_len = (size_t)(end - begin);
+ attribute->value = malloc(value_len + 1);
if (attribute->value == NULL) {
free(attribute->name);
free(attribute);
} else {
+ /* save the value without leading or trailing whitespace */
+ strncpy(attribute->value, begin, value_len);
+ attribute->value[value_len] = '\0';
attribute->next = NULL;
if (context->head == NULL) {
context->head = attribute;
--- a/jdk/src/share/instrument/Reentrancy.c Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/instrument/Reentrancy.c Fri Mar 28 12:56:34 2008 -0700
@@ -74,6 +74,7 @@
jvmtienv,
thread,
newValue);
+ check_phase_ret_blob(error, error);
#if JPLISASSERT_ENABLEASSERTIONS
assertTLSValue( jvmtienv,
@@ -96,6 +97,7 @@
jvmtienv,
thread,
&test);
+ check_phase_ret(error);
jplis_assert(error == JVMTI_ERROR_NONE);
jplis_assert(test == expected);
}
@@ -111,6 +113,7 @@
jvmtienv,
thread,
&storedValue);
+ check_phase_ret_false(error);
jplis_assert(error == JVMTI_ERROR_NONE);
if ( error == JVMTI_ERROR_NONE ) {
/* if this thread is already inside, just return false and short-circuit */
--- a/jdk/src/share/instrument/Utilities.c Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/share/instrument/Utilities.c Fri Mar 28 12:56:34 2008 -0700
@@ -46,6 +46,7 @@
error = (*jvmtienv)->Allocate(jvmtienv,
bytecount,
(unsigned char**) &resultBuffer);
+ /* may be called from any phase */
jplis_assert(error == JVMTI_ERROR_NONE);
if ( error != JVMTI_ERROR_NONE ) {
resultBuffer = NULL;
@@ -66,6 +67,7 @@
error = (*jvmtienv)->Deallocate(jvmtienv,
(unsigned char*)buffer);
+ /* may be called from any phase */
jplis_assert_msg(error == JVMTI_ERROR_NONE, "Can't deallocate memory");
return;
}
--- a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDConstants.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,8 @@
* @since 1.5
*/
class MotifDnDConstants {
+ // utility class can not be instantiated
+ private MotifDnDConstants() {}
// Note that offsets in all native structures below do not depend on the
// architecture.
private static final Unsafe unsafe = XlibWrapper.unsafe;
@@ -55,8 +57,7 @@
XAtom.get("XmTRANSFER_SUCCESS");
static final XAtom XA_XmTRANSFER_FAILURE =
XAtom.get("XmTRANSFER_FAILURE");
- static final XSelection MotifDnDSelection =
- new XSelection(XA_MOTIF_ATOM_0, null);
+ static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0);
public static final byte MOTIF_DND_PROTOCOL_VERSION = 0;
@@ -231,6 +232,9 @@
}
public static final class Swapper {
+ // utility class can not be instantiated
+ private Swapper() {}
+
public static short swap(short s) {
return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8));
}
--- a/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -933,7 +933,7 @@
XSelection selection = XSelection.getSelection(selectionAtom);
if (selection == null) {
- selection = new XSelection(selectionAtom, null);
+ selection = new XSelection(selectionAtom);
}
return selection.getData(format, time_stamp);
@@ -1056,7 +1056,7 @@
// the original structure can be freed before this
// SunDropTargetEvent is dispatched.
if (xclient != null) {
- int size = new XClientMessageEvent(nativeCtxt).getSize();
+ int size = XClientMessageEvent.getSize();
nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.awt.X11;
+
+interface OwnershipListener {
+ public void ownershipChanged(final boolean isOwner);
+}
--- a/jdk/src/solaris/classes/sun/awt/X11/XAtom.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XAtom.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@
import sun.misc.Unsafe;
import java.util.HashMap;
-public class XAtom {
+public final class XAtom {
// Order of lock: XAWTLock -> XAtom.class
@@ -175,7 +175,7 @@
public static XAtom get(String name) {
XAtom xatom = lookup(name);
if (xatom == null) {
- xatom = new XAtom(name);
+ xatom = new XAtom(XToolkit.getDisplay(), name);
}
return xatom;
}
@@ -232,10 +232,6 @@
this(display, name, true);
}
- private XAtom(String name) {
- this(XToolkit.getDisplay(), name, true);
- }
-
public XAtom(String name, boolean autoIntern) {
this(XToolkit.getDisplay(), name, autoIntern);
}
@@ -262,7 +258,7 @@
* @since 1.5
*/
- public XAtom(long display, String name, boolean autoIntern) {
+ private XAtom(long display, String name, boolean autoIntern) {
this.name = name;
this.display = display;
if (autoIntern) {
@@ -651,28 +647,6 @@
}
}
- /**
- * Initializes atom with name and display values
- */
- public void setValues(long display, String name, boolean autoIntern) {
- this.display = display;
- this.name = name;
- if (autoIntern) {
- XToolkit.awtLock();
- try {
- atom = XlibWrapper.InternAtom(display,name,0);
- } finally {
- XToolkit.awtUnlock();
- }
- }
- register();
- }
-
- public void setValues(long display, long atom) {
- this.display = display;
- this.atom = atom;
- register();
- }
public void setValues(long display, String name, long atom) {
this.display = display;
this.atom = atom;
--- a/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,30 +26,32 @@
package sun.awt.X11;
import java.awt.datatransfer.Transferable;
-
import java.util.SortedMap;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.HashSet;
-
import java.io.IOException;
-
import java.security.AccessController;
-
+import java.util.HashMap;
+import java.util.Map;
+import sun.awt.UNIXToolkit;
import sun.awt.datatransfer.DataTransferer;
import sun.awt.datatransfer.SunClipboard;
import sun.awt.datatransfer.ClipboardTransferable;
-
import sun.security.action.GetIntegerAction;
-
-
/**
* A class which interfaces with the X11 selection service in order to support
* data transfer via Clipboard operations.
*/
-public class XClipboard extends SunClipboard implements Runnable {
+public final class XClipboard extends SunClipboard implements OwnershipListener
+{
private final XSelection selection;
+ // Time of calling XConvertSelection().
+ private long convertSelectionTime;
+ // The flag used not to call XConvertSelection() if the previous SelectionNotify
+ // has not been processed by checkChange().
+ private volatile boolean isSelectionNotifyProcessed;
+ // The property in which the owner should place requested targets
+ // when tracking changes of available data flavors (practically targets).
+ private volatile XAtom targetsPropertyAtom;
private static final Object classLock = new Object();
@@ -57,31 +59,33 @@
private static int pollInterval;
- private static Set listenedClipboards;
-
+ private static Map<Long, XClipboard> targetsAtom2Clipboard;
/**
* Creates a system clipboard object.
*/
public XClipboard(String name, String selectionName) {
super(name);
- selection = new XSelection(XAtom.get(selectionName), this);
+ selection = new XSelection(XAtom.get(selectionName));
+ selection.registerOwershipListener(this);
}
- /**
- * The action to be run when we lose ownership
+ /*
* NOTE: This method may be called by privileged threads.
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
*/
- public void run() {
- lostOwnershipImpl();
+ public void ownershipChanged(final boolean isOwner) {
+ if (isOwner) {
+ checkChangeHere(contents);
+ } else {
+ lostOwnershipImpl();
+ }
}
protected synchronized void setContentsNative(Transferable contents) {
SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
(contents, DataTransferer.adaptFlavorMap(flavorMap));
- long[] formats =
- DataTransferer.getInstance().keysToLongArray(formatMap);
+ long[] formats = DataTransferer.keysToLongArray(formatMap);
if (!selection.setOwner(contents, formatMap, formats,
XToolkit.getCurrentServerTime())) {
@@ -94,6 +98,7 @@
return selection.getSelectionAtom().getAtom();
}
+ @Override
public synchronized Transferable getContents(Object requestor) {
if (contents != null) {
return contents;
@@ -115,62 +120,163 @@
return selection.getData(format, XToolkit.getCurrentServerTime());
}
- // Called on the toolkit thread under awtLock.
- public void checkChange(long[] formats) {
- if (!selection.isOwner()) {
- super.checkChange(formats);
- }
- }
-
- void checkChangeHere(Transferable contents) {
+ private void checkChangeHere(Transferable contents) {
if (areFlavorListenersRegistered()) {
- super.checkChange(DataTransferer.getInstance().
+ checkChange(DataTransferer.getInstance().
getFormatsForTransferableAsArray(contents, flavorMap));
}
}
+ private static int getPollInterval() {
+ synchronized (XClipboard.classLock) {
+ if (pollInterval <= 0) {
+ pollInterval = AccessController.doPrivileged(
+ new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
+ defaultPollInterval));
+ if (pollInterval <= 0) {
+ pollInterval = defaultPollInterval;
+ }
+ }
+ return pollInterval;
+ }
+ }
+
+ private XAtom getTargetsPropertyAtom() {
+ if (null == targetsPropertyAtom) {
+ targetsPropertyAtom =
+ XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName());
+ }
+ return targetsPropertyAtom;
+ }
+
protected void registerClipboardViewerChecked() {
- if (pollInterval <= 0) {
- pollInterval = ((Integer)AccessController.doPrivileged(
- new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
- defaultPollInterval))).intValue();
- if (pollInterval <= 0) {
- pollInterval = defaultPollInterval;
+ // for XConvertSelection() to be called for the first time in getTargetsDelayed()
+ isSelectionNotifyProcessed = true;
+
+ boolean mustSchedule = false;
+ synchronized (XClipboard.classLock) {
+ if (targetsAtom2Clipboard == null) {
+ targetsAtom2Clipboard = new HashMap<Long, XClipboard>(2);
+ }
+ mustSchedule = targetsAtom2Clipboard.isEmpty();
+ targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this);
+ if (mustSchedule) {
+ XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
+ new SelectionNotifyHandler());
}
}
- selection.initializeSelectionForTrackingChanges();
- boolean mustSchedule = false;
- synchronized (XClipboard.classLock) {
- if (listenedClipboards == null) {
- listenedClipboards = new HashSet(2);
- }
- mustSchedule = listenedClipboards.isEmpty();
- listenedClipboards.add(this);
- }
if (mustSchedule) {
- XToolkit.schedule(new CheckChangeTimerTask(), pollInterval);
+ XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval());
}
}
private static class CheckChangeTimerTask implements Runnable {
public void run() {
- for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) {
- XClipboard clpbrd = (XClipboard)iter.next();
- clpbrd.selection.getTargetsDelayed();
+ for (XClipboard clpbrd : targetsAtom2Clipboard.values()) {
+ clpbrd.getTargetsDelayed();
}
synchronized (XClipboard.classLock) {
- if (listenedClipboards != null && !listenedClipboards.isEmpty()) {
- XToolkit.schedule(this, pollInterval);
+ if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
+ XToolkit.schedule(this, XClipboard.getPollInterval());
+ }
+ }
+ }
+ }
+
+ private static class SelectionNotifyHandler implements XEventDispatcher {
+ public void dispatchEvent(XEvent ev) {
+ if (ev.get_type() == XlibWrapper.SelectionNotify) {
+ final XSelectionEvent xse = ev.get_xselection();
+ XClipboard clipboard = null;
+ synchronized (XClipboard.classLock) {
+ if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
+ XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
+ return;
+ }
+ final long propertyAtom = xse.get_property();
+ clipboard = targetsAtom2Clipboard.get(propertyAtom);
+ }
+ if (null != clipboard) {
+ clipboard.checkChange(xse);
}
}
}
}
protected void unregisterClipboardViewerChecked() {
- selection.deinitializeSelectionForTrackingChanges();
+ isSelectionNotifyProcessed = false;
synchronized (XClipboard.classLock) {
- listenedClipboards.remove(this);
+ targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom());
+ }
+ }
+
+ // checkChange() will be called on SelectionNotify
+ private void getTargetsDelayed() {
+ XToolkit.awtLock();
+ try {
+ long curTime = System.currentTimeMillis();
+ if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout()))
+ {
+ convertSelectionTime = curTime;
+ XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
+ selection.getSelectionAtom().getAtom(),
+ XDataTransferer.TARGETS_ATOM.getAtom(),
+ getTargetsPropertyAtom().getAtom(),
+ XWindow.getXAWTRootWindow().getWindow(),
+ XlibWrapper.CurrentTime);
+ isSelectionNotifyProcessed = false;
+ }
+ } finally {
+ XToolkit.awtUnlock();
}
}
+ /*
+ * Tracks changes of available formats.
+ * NOTE: This method may be called by privileged threads.
+ * DO NOT INVOKE CLIENT CODE ON THIS THREAD!
+ */
+ private void checkChange(XSelectionEvent xse) {
+ final long propertyAtom = xse.get_property();
+ if (propertyAtom != getTargetsPropertyAtom().getAtom()) {
+ // wrong atom
+ return;
+ }
+
+ final XAtom selectionAtom = XAtom.get(xse.get_selection());
+ final XSelection changedSelection = XSelection.getSelection(selectionAtom);
+
+ if (null == changedSelection || changedSelection != selection) {
+ // unknown selection - do nothing
+ return;
+ }
+
+ isSelectionNotifyProcessed = true;
+
+ if (selection.isOwner()) {
+ // selection is owner - do not need formats
+ return;
+ }
+
+ long[] formats = null;
+
+ if (propertyAtom == XlibWrapper.None) {
+ // We treat None property atom as "empty selection".
+ formats = new long[0];
+ } else {
+ WindowPropertyGetter targetsGetter =
+ new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
+ XAtom.get(propertyAtom), 0,
+ XSelection.MAX_LENGTH, true,
+ XlibWrapper.AnyPropertyType);
+ try {
+ targetsGetter.execute();
+ formats = XSelection.getFormats(targetsGetter);
+ } finally {
+ targetsGetter.dispose();
+ }
+ }
+
+ checkChange(formats);
+ }
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,17 +31,13 @@
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
-import java.awt.DefaultKeyboardFocusManager;
import java.awt.Dimension;
-import java.awt.Event;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
-import java.awt.MenuBar;
-import java.awt.Point;
import java.awt.Rectangle;
import java.awt.SystemColor;
import java.awt.Toolkit;
@@ -60,12 +56,9 @@
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.image.VolatileImage;
-import java.awt.peer.CanvasPeer;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
import java.awt.peer.LightweightPeer;
-import java.awt.peer.PanelPeer;
-import java.awt.peer.WindowPeer;
import java.lang.reflect.*;
import java.security.*;
import java.util.Collection;
@@ -821,7 +814,7 @@
public void setFont(Font f) {
synchronized (getStateLock()) {
if (f == null) {
- f = defaultFont;
+ f = XWindow.getDefaultFont();
}
font = f;
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XContentWindow.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,16 +39,37 @@
* This class implements window which serves as content window for decorated frames.
* Its purpose to provide correct events dispatching for the complex
* constructs such as decorated frames.
+ *
+ * It should always be located at (- left inset, - top inset) in the associated
+ * decorated window. So coordinates in it would be the same as java coordinates.
*/
-public class XContentWindow extends XWindow implements XConstants {
+public final class XContentWindow extends XWindow implements XConstants {
private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
- XDecoratedPeer parentFrame;
+ static XContentWindow createContent(XDecoratedPeer parentFrame) {
+ final WindowDimensions dims = parentFrame.getDimensions();
+ Rectangle rec = dims.getBounds();
+ // Fix for - set the location of the content window to the (-left inset, -top inset)
+ Insets ins = dims.getInsets();
+ if (ins != null) {
+ rec.x = -ins.left;
+ rec.y = -ins.top;
+ } else {
+ rec.x = 0;
+ rec.y = 0;
+ }
+ final XContentWindow cw = new XContentWindow(parentFrame, rec);
+ cw.xSetVisible(true);
+ return cw;
+ }
+
+ private final XDecoratedPeer parentFrame;
// A list of expose events that come when the parentFrame is iconified
- private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
+ private final java.util.List<SavedExposeEvent> iconifiedExposeEvents =
+ new java.util.ArrayList<SavedExposeEvent>();
- XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
+ private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
this.parentFrame = parentFrame;
}
@@ -63,9 +84,6 @@
}
}
- void initialize() {
- xSetVisible(true);
- }
protected String getWMName() {
return "Content window";
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -36,7 +36,7 @@
import sun.awt.ComponentAccessor;
import sun.awt.SunToolkit;
-class XDecoratedPeer extends XWindowPeer {
+abstract class XDecoratedPeer extends XWindowPeer {
private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
@@ -98,8 +98,7 @@
// happen after the X window is created.
initResizability();
updateSizeHints(dimensions);
- content = createContent(dimensions);
- content.initialize();
+ content = XContentWindow.createContent(this);
if (warningWindow != null) {
warningWindow.toFront();
}
@@ -160,20 +159,6 @@
}
}
- XContentWindow createContent(WindowDimensions dims) {
- Rectangle rec = dims.getBounds();
- // Fix for - set the location of the content window to the (-left inset, -top inset)
- Insets ins = dims.getInsets();
- if (ins != null) {
- rec.x = -ins.left;
- rec.y = -ins.top;
- } else {
- rec.x = 0;
- rec.y = 0;
- }
- return new XContentWindow(this, rec);
- }
-
XFocusProxyWindow createFocusProxy() {
return new XFocusProxyWindow(this);
}
@@ -286,7 +271,7 @@
return;
}
Component t = (Component)target;
- if (getDecorations() == winAttr.AWT_DECOR_NONE) {
+ if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
setReparented(true);
insets_corrected = true;
reshape(dimensions, SET_SIZE, false);
@@ -471,6 +456,15 @@
if (insLog.isLoggable(Level.FINE)) {
insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
}
+ if (userReshape) {
+ // We handle only userReshape == true cases. It means that
+ // if the window manager or any other part of the windowing
+ // system sets inappropriate size for this window, we can
+ // do nothing but accept it.
+ Rectangle reqBounds = newDimensions.getBounds();
+ Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
+ newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet());
+ }
XToolkit.awtLock();
try {
if (!isReparented() || !isVisible()) {
@@ -586,6 +580,49 @@
reshape(dims, operation, userReshape);
}
+ // This method gets overriden in XFramePeer & XDialogPeer.
+ abstract boolean isTargetUndecorated();
+
+ @Override
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't restrict the setBounds() operation if the code is trusted.
+ if (!hasWarningWindow()) {
+ return new Rectangle(x, y, width, height);
+ }
+
+ // If it's undecorated or is not currently visible,
+ // apply the same constraints as for the Window.
+ if (!isVisible() || isTargetUndecorated()) {
+ return super.constrainBounds(x, y, width, height);
+ }
+
+ // If it's visible & decorated, constraint the size only
+ int newX = x;
+ int newY = y;
+ int newW = width;
+ int newH = height;
+
+ GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+ Rectangle sB = gc.getBounds();
+ Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+ Rectangle curBounds = getBounds();
+
+ int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width);
+ int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height);
+
+ // First make sure the size is withing the visible part of the screen
+ if (newW > maxW) {
+ newW = maxW;
+ }
+
+ if (newH > maxH) {
+ newH = maxH;
+ }
+
+ return new Rectangle(newX, newY, newW, newH);
+ }
+
/**
* @see java.awt.peer.ComponentPeer#setBounds
*/
@@ -651,12 +688,12 @@
}
if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
&& !XWM.isNonReparentingWM()
- && getDecorations() != winAttr.AWT_DECOR_NONE) {
+ && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
insLog.fine("- visible but not reparented, skipping");
return;
}
//Last chance to correct insets
- if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) {
+ if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
long parent = XlibUtil.getParentWindow(window);
Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
if (insLog.isLoggable(Level.FINER)) {
@@ -824,7 +861,7 @@
fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE);
}
winAttr.functions = fs;
- XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false);
+ XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
}
}
@@ -870,7 +907,7 @@
return getSize().height;
}
- public WindowDimensions getDimensions() {
+ final public WindowDimensions getDimensions() {
return dimensions;
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -88,7 +88,8 @@
}
}
- private boolean isTargetUndecorated() {
+ @Override
+ boolean isTargetUndecorated() {
if (undecorated != null) {
return undecorated.booleanValue();
} else {
--- a/jdk/src/solaris/classes/sun/awt/X11/XDnDConstants.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDnDConstants.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,8 +48,7 @@
static final XAtom XA_XdndStatus = XAtom.get("XdndStatus");
static final XAtom XA_XdndFinished = XAtom.get("XdndFinished");
- static final XSelection XDnDSelection =
- new XSelection(XA_XdndSelection, null);
+ static final XSelection XDnDSelection = new XSelection(XA_XdndSelection);
public static final int XDND_MIN_PROTOCOL_VERSION = 3;
public static final int XDND_PROTOCOL_VERSION = 5;
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedCanvasPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -647,12 +647,6 @@
}
if (isXEmbedActive()) {
switch ((int)msg.get_data(1)) {
- case _SUN_XEMBED_START:
- // Child has finished initialization and waits for notify
- xembed.processXEmbedInfo();
-
- notifyChildEmbedded();
- break;
case XEMBED_REQUEST_FOCUS:
requestXEmbedFocus();
break;
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Fri Mar 28 12:56:34 2008 -0700
@@ -74,7 +74,6 @@
XToolkit.awtUnlock();
}
}
- notifyReady();
}
void handleClientMessage(XEvent xev) {
@@ -84,7 +83,6 @@
if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
switch ((int)msg.get_data(1)) {
case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
- // NOTE: May be called two times because we send _SUN_XEMBED_START
active = true;
server = getEmbedder(embedded, msg);
// Check if window is reparented. If not - it was created with
@@ -223,13 +221,4 @@
long getX11Mods(AWTKeyStroke stroke) {
return XWindow.getXModifiers(stroke);
}
-
- void notifyReady() {
- long wnd = server;
- if (wnd == 0) {
- // Server is still 0, get the parent
- wnd = embedded.getParentWindowHandle();
- }
- sendMessage(wnd, _SUN_XEMBED_START);
- }
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedHelper.java Fri Mar 28 12:56:34 2008 -0700
@@ -58,7 +58,6 @@
final static int XEMBED_REGISTER_ACCELERATOR = 12;
final static int XEMBED_UNREGISTER_ACCELERATOR= 13;
final static int XEMBED_ACTIVATE_ACCELERATOR = 14;
- final static int _SUN_XEMBED_START = 1119;
final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
@@ -151,8 +150,6 @@
return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
- case _SUN_XEMBED_START:
- return "XEMBED_START";
case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
return "KeyPress";
case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedServerTester.java Fri Mar 28 12:56:34 2008 -0700
@@ -177,13 +177,6 @@
embedCompletely();
}
- public void test3_2() {
- embedCompletely();
- int res = getEventPos();
- sendMessage(XEmbedHelper._SUN_XEMBED_START);
- waitEmbeddedNotify(res);
- }
-
public void test3_3() {
reparent = true;
embedCompletely();
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -184,6 +184,12 @@
}
}
+ @Override
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't constrain the bounds of the EmbeddedFrames
+ return new Rectangle(x, y, width, height);
+ }
+
// don't use getBounds() inherited from XDecoratedPeer
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
--- a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,15 +24,18 @@
*/
package sun.awt.X11;
-import java.util.Vector;
-import java.awt.*;
-import java.awt.peer.*;
-import java.awt.event.*;
-import sun.awt.im.*;
-import sun.awt.*;
-import java.util.logging.*;
-import java.lang.reflect.Field;
-import java.util.*;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.MenuBar;
+import java.awt.Rectangle;
+import java.awt.peer.FramePeer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
@@ -92,7 +95,8 @@
}
}
- private boolean isTargetUndecorated() {
+ @Override
+ boolean isTargetUndecorated() {
if (undecorated != null) {
return undecorated.booleanValue();
} else {
@@ -285,19 +289,20 @@
* Let's see if this is a window state protocol message, and
* if it is - decode a new state in terms of java constants.
*/
- Integer newState = XWM.getWM().isStateChange(this, ev);
- if (newState == null) {
+ if (!XWM.getWM().isStateChange(this, ev)) {
+ stateLog.finer("either not a state atom or state has not been changed");
return;
}
- int changed = state ^ newState.intValue();
+ final int newState = XWM.getWM().getState(this);
+ int changed = state ^ newState;
if (changed == 0) {
stateLog.finer("State is the same: " + state);
return;
}
int old_state = state;
- state = newState.intValue();
+ state = newState;
if ((changed & Frame.ICONIFIED) != 0) {
if ((state & Frame.ICONIFIED) != 0) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XMenuItemPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -218,7 +218,7 @@
Font getTargetFont() {
if (target == null) {
- return XWindow.defaultFont;
+ return XWindow.getDefaultFont();
}
try {
return (Font)m_getFont.invoke(target, new Object[0]);
@@ -227,7 +227,7 @@
} catch (InvocationTargetException e) {
e.printStackTrace();
}
- return XWindow.defaultFont;
+ return XWindow.getDefaultFont();
}
String getTargetLabel() {
--- a/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XNETProtocol.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,17 +26,15 @@
package sun.awt.X11;
-import java.awt.*;
+import java.awt.Frame;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.logging.LogManager;
-import java.awt.*;
-import java.awt.image.*;
-import java.util.*;
-class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
- final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
+final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
+{
+ private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol");
+ private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol");
/**
* XStateProtocol
@@ -276,6 +274,7 @@
boolean doStateProtocol() {
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
+ stateLog.finer("doStateProtocol() returns " + res);
return res;
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XPopupMenuPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -187,7 +187,7 @@
//Fix for 6267144: PIT: Popup menu label is not shown, XToolkit
Font getTargetFont() {
if (popupMenuTarget == null) {
- return XWindow.defaultFont;
+ return XWindow.getDefaultFont();
}
try {
return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]);
@@ -196,7 +196,7 @@
} catch (InvocationTargetException e) {
e.printStackTrace();
}
- return XWindow.defaultFont;
+ return XWindow.getDefaultFont();
}
String getTargetLabel() {
--- a/jdk/src/solaris/classes/sun/awt/X11/XSelection.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XSelection.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,9 +32,6 @@
import java.util.Hashtable;
import java.util.Map;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
@@ -45,7 +42,7 @@
/**
* A class which interfaces with the X11 selection service.
*/
-public class XSelection {
+public final class XSelection {
/* Maps atoms to XSelection instances. */
private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
@@ -69,8 +66,6 @@
XToolkit.awtUnlock();
}
}
- /* The selection timeout. */
- private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
/* The PropertyNotify event handler for incremental data transfer. */
private static final XEventDispatcher incrementalTransferHandler =
@@ -84,11 +79,6 @@
/* The X atom for the underlying selection. */
private final XAtom selectionAtom;
- /*
- * XClipboard.run() is to be called when we lose ownership.
- * XClipbioard.checkChange() is to be called when tracking changes of flavors.
- */
- private final XClipboard clipboard;
/*
* Owner-related variables - protected with synchronized (this).
@@ -109,17 +99,8 @@
private long ownershipTime = 0;
// True if we are the owner of this selection.
private boolean isOwner;
- // The property in which the owner should place requested targets
- // when tracking changes of available data flavors (practically targets).
- private volatile XAtom targetsPropertyAtom;
- // A set of these property atoms.
- private static volatile Set targetsPropertyAtoms;
- // The flag used not to call XConvertSelection() if the previous SelectionNotify
- // has not been processed by checkChange().
- private volatile boolean isSelectionNotifyProcessed;
- // Time of calling XConvertSelection().
- private long convertSelectionTime;
-
+ private OwnershipListener ownershipListener = null;
+ private final Object stateLock = new Object();
static {
XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
@@ -141,12 +122,11 @@
* @param clpbrd the corresponding clipoboard
* @exception NullPointerException if atom is <code>null</code>.
*/
- public XSelection(XAtom atom, XClipboard clpbrd) {
+ public XSelection(XAtom atom) {
if (atom == null) {
throw new NullPointerException("Null atom");
}
selectionAtom = atom;
- clipboard = clpbrd;
table.put(selectionAtom, this);
}
@@ -154,25 +134,9 @@
return selectionAtom;
}
- void initializeSelectionForTrackingChanges() {
- targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName());
- if (targetsPropertyAtoms == null) {
- targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2));
- }
- targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom()));
- // for XConvertSelection() to be called for the first time in getTargetsDelayed()
- isSelectionNotifyProcessed = true;
- }
-
- void deinitializeSelectionForTrackingChanges() {
- if (targetsPropertyAtoms != null && targetsPropertyAtom != null) {
- targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom()));
- }
- isSelectionNotifyProcessed = false;
- }
-
public synchronized boolean setOwner(Transferable contents, Map formatMap,
- long[] formats, long time) {
+ long[] formats, long time)
+ {
long owner = XWindow.getXAWTRootWindow().getWindow();
long selection = selectionAtom.getAtom();
@@ -192,15 +156,12 @@
XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
selection, owner, time);
if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
- selection) != owner) {
-
+ selection) != owner)
+ {
reset();
return false;
}
- isOwner = true;
- if (clipboard != null) {
- clipboard.checkChangeHere(contents);
- }
+ setOwnerProp(true);
return true;
} finally {
XToolkit.awtUnlock();
@@ -217,7 +178,7 @@
do {
DataTransferer.getInstance().processDataConversionRequests();
XToolkit.awtLockWait(250);
- } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT);
+ } while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout());
} finally {
XToolkit.awtUnlock();
}
@@ -232,11 +193,9 @@
throw new Error("UNIMPLEMENTED");
}
- long[] formats = null;
+ long[] targets = null;
synchronized (lock) {
- SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
-
WindowPropertyGetter targetsGetter =
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
selectionPropertyAtom, 0, MAX_LENGTH,
@@ -267,23 +226,25 @@
} finally {
XToolkit.awtUnlock();
}
- formats = getFormats(targetsGetter);
+ targets = getFormats(targetsGetter);
} finally {
targetsGetter.dispose();
}
}
- return formats;
+ return targets;
}
- private static long[] getFormats(WindowPropertyGetter targetsGetter) {
+ static long[] getFormats(WindowPropertyGetter targetsGetter) {
long[] formats = null;
if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() &&
(targetsGetter.getActualType() == XAtom.XA_ATOM ||
targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) &&
- targetsGetter.getActualFormat() == 32) {
-
- int count = (int)targetsGetter.getNumberOfItems();
+ targetsGetter.getActualFormat() == 32)
+ {
+ // we accept property with TARGETS type to be compatible with old jdks
+ // see 6607163
+ int count = targetsGetter.getNumberOfItems();
if (count > 0) {
long atoms = targetsGetter.getData();
formats = new long[count];
@@ -297,26 +258,6 @@
return formats != null ? formats : new long[0];
}
- // checkChange() will be called on SelectionNotify
- void getTargetsDelayed() {
- XToolkit.awtLock();
- try {
- long curTime = System.currentTimeMillis();
- if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) {
- convertSelectionTime = curTime;
- XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
- getSelectionAtom().getAtom(),
- XDataTransferer.TARGETS_ATOM.getAtom(),
- targetsPropertyAtom.getAtom(),
- XWindow.getXAWTRootWindow().getWindow(),
- XlibWrapper.CurrentTime);
- isSelectionNotifyProcessed = false;
- }
- } finally {
- XToolkit.awtUnlock();
- }
- }
-
/*
* Requests the selection data in the specified format and returns
* the data provided by the owner.
@@ -329,8 +270,6 @@
byte[] data = null;
synchronized (lock) {
- SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
-
WindowPropertyGetter dataGetter =
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
selectionPropertyAtom, 0, MAX_LENGTH,
@@ -379,7 +318,7 @@
dataGetter.getActualFormat());
}
- int count = (int)dataGetter.getNumberOfItems();
+ int count = dataGetter.getNumberOfItems();
if (count <= 0) {
throw new IOException("INCR data is missed.");
@@ -455,7 +394,7 @@
incrDataGetter.getActualFormat());
}
- count = (int)incrDataGetter.getNumberOfItems();
+ count = incrDataGetter.getNumberOfItems();
if (count == 0) {
break;
@@ -489,7 +428,7 @@
dataGetter.getActualFormat());
}
- int count = (int)dataGetter.getNumberOfItems();
+ int count = dataGetter.getNumberOfItems();
if (count > 0) {
data = new byte[count];
long ptr = dataGetter.getData();
@@ -511,11 +450,14 @@
return isOwner;
}
- public void lostOwnership() {
- isOwner = false;
- if (clipboard != null) {
- clipboard.run();
- }
+ // To be MT-safe this method should be called under awtLock.
+ private void setOwnerProp(boolean f) {
+ isOwner = f;
+ fireOwnershipChanges(isOwner);
+ }
+
+ private void lostOwnership() {
+ setOwnerProp(false);
}
public synchronized void reset() {
@@ -595,125 +537,39 @@
private void handleSelectionRequest(XSelectionRequestEvent xsre) {
long property = xsre.get_property();
- long requestor = xsre.get_requestor();
- long requestTime = xsre.get_time();
- long format = xsre.get_target();
- int dataFormat = 0;
+ final long requestor = xsre.get_requestor();
+ final long requestTime = xsre.get_time();
+ final long format = xsre.get_target();
boolean conversionSucceeded = false;
if (ownershipTime != 0 &&
- (requestTime == XlibWrapper.CurrentTime ||
- requestTime >= ownershipTime)) {
-
- property = xsre.get_property();
-
+ (requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime))
+ {
// Handle MULTIPLE requests as per ICCCM.
if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
- // The property cannot be 0 for a MULTIPLE request.
- if (property != 0) {
- // First retrieve the list of requested targets.
- WindowPropertyGetter wpg =
- new WindowPropertyGetter(requestor, XAtom.get(property), 0,
- MAX_LENGTH, false,
- XlibWrapper.AnyPropertyType);
- try {
- wpg.execute();
-
- if (wpg.getActualFormat() == 32 &&
- (wpg.getNumberOfItems() % 2) == 0) {
- long count = wpg.getNumberOfItems() / 2;
- long pairsPtr = wpg.getData();
- boolean writeBack = false;
- for (int i = 0; i < count; i++) {
- long target = Native.getLong(pairsPtr, 2*i);
- long prop = Native.getLong(pairsPtr, 2*i + 1);
-
- if (!convertAndStore(requestor, target, prop)) {
- // To report failure, we should replace the
- // target atom with 0 in the MULTIPLE property.
- Native.putLong(pairsPtr, 2*i, 0);
- writeBack = true;
- }
- }
- if (writeBack) {
- XToolkit.awtLock();
- try {
- XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
- property,
- wpg.getActualType(),
- wpg.getActualFormat(),
- XlibWrapper.PropModeReplace,
- wpg.getData(),
- wpg.getNumberOfItems());
- } finally {
- XToolkit.awtUnlock();
- }
- }
- conversionSucceeded = true;
- }
- } finally {
- wpg.dispose();
- }
- }
+ conversionSucceeded = handleMultipleRequest(requestor, property);
} else {
-
// Support for obsolete clients as per ICCCM.
- if (property == 0) {
+ if (property == XlibWrapper.None) {
property = format;
}
if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
- long nativeDataPtr = 0;
- int count = 0;
- dataFormat = 32;
-
- // Use a local copy to avoid synchronization.
- long[] formatsLocal = formats;
-
- if (formatsLocal == null) {
- throw new IllegalStateException("Not an owner.");
- }
-
- count = formatsLocal.length;
-
- try {
- if (count > 0) {
- nativeDataPtr = Native.allocateLongArray(count);
- Native.put(nativeDataPtr, formatsLocal);
- }
-
- conversionSucceeded = true;
-
- XToolkit.awtLock();
- try {
- XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
- property, format, dataFormat,
- XlibWrapper.PropModeReplace,
- nativeDataPtr, count);
- } finally {
- XToolkit.awtUnlock();
- }
- } finally {
- if (nativeDataPtr != 0) {
- XlibWrapper.unsafe.freeMemory(nativeDataPtr);
- nativeDataPtr = 0;
- }
- }
+ conversionSucceeded = handleTargetsRequest(property, requestor);
} else {
- conversionSucceeded = convertAndStore(requestor, format,
- property);
+ conversionSucceeded = convertAndStore(requestor, format, property);
}
}
}
if (!conversionSucceeded) {
- // Zero property indicates conversion failure.
- property = 0;
+ // None property indicates conversion failure.
+ property = XlibWrapper.None;
}
XSelectionEvent xse = new XSelectionEvent();
try {
- xse.set_type((int)XlibWrapper.SelectionNotify);
+ xse.set_type(XlibWrapper.SelectionNotify);
xse.set_send_event(true);
xse.set_requestor(requestor);
xse.set_selection(selectionAtom.getAtom());
@@ -733,40 +589,123 @@
}
}
- private static void checkChange(XSelectionEvent xse) {
- if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) {
- // We are not tracking changes.
- return;
+ private boolean handleMultipleRequest(final long requestor, long property) {
+ if (XlibWrapper.None == property) {
+ // The property cannot be None for a MULTIPLE request.
+ return false;
+ }
+
+ boolean conversionSucceeded = false;
+
+ // First retrieve the list of requested targets.
+ WindowPropertyGetter wpg =
+ new WindowPropertyGetter(requestor, XAtom.get(property),
+ 0, MAX_LENGTH, false,
+ XlibWrapper.AnyPropertyType);
+ try {
+ wpg.execute();
+
+ if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) {
+ final long count = wpg.getNumberOfItems() / 2;
+ final long pairsPtr = wpg.getData();
+ boolean writeBack = false;
+
+ for (int i = 0; i < count; i++) {
+ long target = Native.getLong(pairsPtr, 2 * i);
+ long prop = Native.getLong(pairsPtr, 2 * i + 1);
+
+ if (!convertAndStore(requestor, target, prop)) {
+ // To report failure, we should replace the
+ // target atom with 0 in the MULTIPLE property.
+ Native.putLong(pairsPtr, 2 * i, 0);
+ writeBack = true;
+ }
+ }
+ if (writeBack) {
+ XToolkit.awtLock();
+ try {
+ XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
+ requestor,
+ property,
+ wpg.getActualType(),
+ wpg.getActualFormat(),
+ XlibWrapper.PropModeReplace,
+ wpg.getData(),
+ wpg.getNumberOfItems());
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
+ conversionSucceeded = true;
+ }
+ } finally {
+ wpg.dispose();
}
- long propertyAtom = xse.get_property();
- long[] formats = null;
+ return conversionSucceeded;
+ }
+
+ private boolean handleTargetsRequest(long property, long requestor)
+ throws IllegalStateException
+ {
+ boolean conversionSucceeded = false;
+ // Use a local copy to avoid synchronization.
+ long[] formatsLocal = formats;
+
+ if (formatsLocal == null) {
+ throw new IllegalStateException("Not an owner.");
+ }
+
+ long nativeDataPtr = 0;
+
+ try {
+ final int count = formatsLocal.length;
+ final int dataFormat = 32;
- if (propertyAtom == XlibWrapper.None) {
- // We threat None property atom as "empty selection".
- formats = new long[0];
- } else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) {
- return;
- } else {
- WindowPropertyGetter targetsGetter =
- new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
- XAtom.get(propertyAtom), 0, MAX_LENGTH,
- true, XlibWrapper.AnyPropertyType);
+ if (count > 0) {
+ nativeDataPtr = Native.allocateLongArray(count);
+ Native.put(nativeDataPtr, formatsLocal);
+ }
+
+ conversionSucceeded = true;
+
+ XToolkit.awtLock();
try {
- targetsGetter.execute();
- formats = getFormats(targetsGetter);
+ XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
+ property, XAtom.XA_ATOM, dataFormat,
+ XlibWrapper.PropModeReplace,
+ nativeDataPtr, count);
} finally {
- targetsGetter.dispose();
+ XToolkit.awtUnlock();
+ }
+ } finally {
+ if (nativeDataPtr != 0) {
+ XlibWrapper.unsafe.freeMemory(nativeDataPtr);
+ nativeDataPtr = 0;
}
}
+ return conversionSucceeded;
+ }
- XAtom selectionAtom = XAtom.get(xse.get_selection());
- XSelection selection = getSelection(selectionAtom);
- if (selection != null) {
- selection.isSelectionNotifyProcessed = true;
- if (selection.clipboard != null) {
- selection.clipboard.checkChange(formats);
- }
+ private void fireOwnershipChanges(final boolean isOwner) {
+ OwnershipListener l = null;
+ synchronized (stateLock) {
+ l = ownershipListener;
+ }
+ if (null != l) {
+ l.ownershipChanged(isOwner);
+ }
+ }
+
+ void registerOwershipListener(OwnershipListener l) {
+ synchronized (stateLock) {
+ ownershipListener = l;
+ }
+ }
+
+ void unregisterOwnershipListener() {
+ synchronized (stateLock) {
+ ownershipListener = null;
}
}
@@ -774,10 +713,9 @@
public void dispatchEvent(XEvent ev) {
switch (ev.get_type()) {
case XlibWrapper.SelectionNotify: {
- XSelectionEvent xse = ev.get_xselection();
- checkChange(xse);
XToolkit.awtLock();
try {
+ XSelectionEvent xse = ev.get_xselection();
// Ignore the SelectionNotify event if it is not the response to our last request.
if (propertyGetter != null && xse.get_time() == lastRequestServerTime) {
// The property will be None in case of convertion failure.
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,9 @@
package sun.awt.X11;
import java.awt.*;
-import java.awt.event.*;
-import java.awt.peer.*;
-import java.beans.PropertyChangeListener;
-import sun.awt.*;
-import java.util.*;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.datatransfer.Clipboard;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureEvent;
@@ -37,20 +35,27 @@
import java.awt.dnd.MouseDragGestureRecognizer;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
-import java.awt.image.*;
-import java.security.*;
import java.awt.im.InputMethodHighlight;
import java.awt.im.spi.InputMethodDescriptor;
-import java.awt.datatransfer.Clipboard;
+import java.awt.image.ColorModel;
+import java.awt.peer.*;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
-import java.util.logging.*;
+import sun.awt.*;
import sun.font.FontManager;
import sun.misc.PerformanceLogger;
import sun.print.PrintJob2D;
-import java.lang.reflect.*;
-public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
+public final class XToolkit extends UNIXToolkit implements Runnable, XConstants
+{
private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit");
private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
@@ -1871,9 +1876,7 @@
}
public boolean isAlwaysOnTopSupported() {
- Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator();
- while (iter.hasNext()) {
- XLayerProtocol proto = (XLayerProtocol)iter.next();
+ for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) {
if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
return true;
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTrayIconPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,8 @@
import sun.awt.*;
import java.awt.image.*;
import java.text.BreakIterator;
-import java.util.Vector;
-import java.lang.reflect.Field;
import java.util.logging.Logger;
import java.util.logging.Level;
-import java.util.AbstractQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -629,7 +626,7 @@
final static int TOOLTIP_MAX_LENGTH = 64;
final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
- final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont;
+ final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
super(parent, Color.black);
--- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,20 +31,23 @@
package sun.awt.X11;
import sun.misc.Unsafe;
-import java.util.regex.*;
+import java.awt.Insets;
import java.awt.Frame;
import java.awt.Rectangle;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.logging.Level;
-import java.util.logging.LogManager;
import java.util.logging.Logger;
-import java.awt.Insets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Class incapsulating knowledge about window managers in general
* Descendants should provide some information about specific window manager.
*/
-class XWM implements MWMConstants, XUtilConstants {
+final class XWM implements MWMConstants, XUtilConstants
+{
private final static Logger log = Logger.getLogger("sun.awt.X11.XWM");
private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM");
@@ -1026,21 +1029,21 @@
/*****************************************************************************\
* Protocols support
*/
- HashMap<Class<?>, Collection<XProtocol>> protocolsMap = new HashMap<Class<?>, Collection<XProtocol>>();
+ private HashMap<Class<?>, Collection<?>> protocolsMap = new HashMap<Class<?>, Collection<?>>();
/**
* Returns all protocols supporting given protocol interface
*/
- Collection<XProtocol> getProtocols(Class protocolInterface) {
- Collection<XProtocol> res = protocolsMap.get(protocolInterface);
+ <T> Collection<T> getProtocols(Class<T> protocolInterface) {
+ Collection<T> res = (Collection<T>) protocolsMap.get(protocolInterface);
if (res != null) {
- return (Collection<XProtocol>)res;
+ return res;
} else {
- return new LinkedList<XProtocol>();
+ return new LinkedList<T>();
}
}
- void addProtocol(Class protocolInterface, XProtocol protocol) {
- Collection<XProtocol> protocols = getProtocols(protocolInterface);
+ private <T> void addProtocol(Class<T> protocolInterface, T protocol) {
+ Collection<T> protocols = getProtocols(protocolInterface);
protocols.add(protocol);
protocolsMap.put(protocolInterface, protocols);
}
@@ -1085,9 +1088,7 @@
}
/* FALLTROUGH */
case Frame.MAXIMIZED_BOTH:
- Iterator iter = getProtocols(XStateProtocol.class).iterator();
- while (iter.hasNext()) {
- XStateProtocol proto = (XStateProtocol)iter.next();
+ for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
if (proto.supportsState(state)) {
return true;
}
@@ -1105,10 +1106,8 @@
int getExtendedState(XWindowPeer window) {
- Iterator iter = getProtocols(XStateProtocol.class).iterator();
int state = 0;
- while (iter.hasNext()) {
- XStateProtocol proto = (XStateProtocol)iter.next();
+ for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
state |= proto.getState(window);
}
if (state != 0) {
@@ -1127,18 +1126,17 @@
/*
* Check if property change is a window state protocol message.
- * If it is - return the new state as Integer, otherwise return null
*/
- Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) {
+ boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) {
if (!window.isShowing()) {
stateLog.finer("Window is not showing");
- return null;
+ return false;
}
int wm_state = window.getWMState();
if (wm_state == XlibWrapper.WithdrawnState) {
stateLog.finer("WithdrawnState");
- return null;
+ return false;
} else {
stateLog.finer("Window WM_STATE is " + wm_state);
}
@@ -1147,26 +1145,26 @@
is_state_change = true;
}
- Iterator iter = getProtocols(XStateProtocol.class).iterator();
- while (iter.hasNext()) {
- XStateProtocol proto = (XStateProtocol)iter.next();
+ for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
is_state_change |= proto.isStateChange(e);
+ stateLog.finest(proto + ": is state changed = " + is_state_change);
}
- int res = 0;
+ return is_state_change;
+ }
- if (is_state_change) {
- if (wm_state == XlibWrapper.IconicState) {
- res = Frame.ICONIFIED;
- } else {
- res = Frame.NORMAL;
- }
- res |= getExtendedState(window);
+ /*
+ * Returns current state (including extended) of a given window.
+ */
+ int getState(XDecoratedPeer window) {
+ int res = 0;
+ final int wm_state = window.getWMState();
+ if (wm_state == XlibWrapper.IconicState) {
+ res = Frame.ICONIFIED;
+ } else {
+ res = Frame.NORMAL;
}
- if (is_state_change) {
- return Integer.valueOf(res);
- } else {
- return null;
- }
+ res |= getExtendedState(window);
+ return res;
}
/*****************************************************************************\
@@ -1180,9 +1178,7 @@
* in XLayerProtocol
*/
void setLayer(XWindowPeer window, int layer) {
- Iterator iter = getProtocols(XLayerProtocol.class).iterator();
- while (iter.hasNext()) {
- XLayerProtocol proto = (XLayerProtocol)iter.next();
+ for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) {
if (proto.supportsLayer(layer)) {
proto.setLayer(window, layer);
}
@@ -1191,9 +1187,7 @@
}
void setExtendedState(XWindowPeer window, int state) {
- Iterator iter = getProtocols(XStateProtocol.class).iterator();
- while (iter.hasNext()) {
- XStateProtocol proto = (XStateProtocol)iter.next();
+ for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
if (proto.supportsState(state)) {
proto.setState(window, state);
break;
@@ -1239,9 +1233,7 @@
void unshadeKludge(XDecoratedPeer window) {
assert(window.isShowing());
- Iterator iter = getProtocols(XStateProtocol.class).iterator();
- while (iter.hasNext()) {
- XStateProtocol proto = (XStateProtocol)iter.next();
+ for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
proto.unshadeKludge(window);
}
XToolkit.XSync();
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,8 +92,16 @@
SurfaceData surfaceData;
XRepaintArea paintArea;
+
// fallback default font object
- final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
+ private static Font defaultFont;
+
+ static synchronized Font getDefaultFont() {
+ if (null == defaultFont) {
+ defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
+ }
+ return defaultFont;
+ }
/*
* Keeps all buttons which were pressed at the time of the last mouse
@@ -333,7 +341,7 @@
}
Font font = afont;
if (font == null) {
- font = defaultFont;
+ font = XWindow.getDefaultFont();
}
return new SunGraphics2D(surfData, fgColor, bgColor, font);
}
@@ -902,13 +910,11 @@
super.handleConfigureNotifyEvent(xev);
insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
- new Object[] {xev, isEventDisabled(xev)});
+ new Object[] {xev.get_xconfigure(), isEventDisabled(xev)});
if (isEventDisabled(xev)) {
return;
}
- long eventWindow = xev.get_xany().get_window();
-
// if ( Check if it's a resize, a move, or a stacking order change )
// {
Rectangle bounds = getBounds();
@@ -982,7 +988,6 @@
// called directly from this package, unlike handleKeyRelease.
// un-final it if you need to override it in a subclass.
final void handleKeyPress(XKeyEvent ev) {
- int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
long keysym[] = new long[2];
char unicodeKey = 0;
keysym[0] = NoSymbol;
@@ -1066,7 +1071,6 @@
}
// un-private it if you need to call it from elsewhere
private void handleKeyRelease(XKeyEvent ev) {
- int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
long keysym[] = new long[2];
char unicodeKey = 0;
keysym[0] = NoSymbol;
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -112,9 +112,6 @@
PARENT_WINDOW, Long.valueOf(0)}));
}
- // fallback default font object
- static Font defaultFont;
-
/*
* This constant defines icon size recommended for using.
* Apparently, we should use XGetIconSizes which should
@@ -162,10 +159,7 @@
Font f = target.getFont();
if (f == null) {
- if (defaultFont == null) {
- defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
- }
- f = defaultFont;
+ f = XWindow.getDefaultFont();
target.setFont(f);
// we should not call setFont because it will call a repaint
// which the peer may not be ready to do yet.
@@ -188,6 +182,9 @@
GraphicsConfiguration gc = getGraphicsConfiguration();
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
+
+ Rectangle bounds = (Rectangle)(params.get(BOUNDS));
+ params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height));
}
private void initWMProtocols() {
@@ -437,6 +434,56 @@
return ownerPeer;
}
+ // This method is overriden at the XDecoratedPeer to handle
+ // decorated windows a bit differently.
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't restrict the setBounds() operation if the code is trusted.
+ if (!hasWarningWindow()) {
+ return new Rectangle(x, y, width, height);
+ }
+
+ // The window bounds should be within the visible part of the screen
+ int newX = x;
+ int newY = y;
+ int newW = width;
+ int newH = height;
+
+ // Now check each point is within the visible part of the screen
+ GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+ Rectangle sB = gc.getBounds();
+ Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+ int screenX = sB.x + sIn.left;
+ int screenY = sB.y + sIn.top;
+ int screenW = sB.width - sIn.left - sIn.right;
+ int screenH = sB.height - sIn.top - sIn.bottom;
+
+
+ // First make sure the size is withing the visible part of the screen
+ if (newW > screenW) {
+ newW = screenW;
+ }
+
+ if (newH > screenH) {
+ newH = screenH;
+ }
+
+ // Tweak the location if needed
+ if (newX < screenX) {
+ newX = screenX;
+ } else if (newX + newW > screenX + screenW) {
+ newX = screenX + screenW - newW;
+ }
+
+ if (newY < screenY) {
+ newY = screenY;
+ } else if (newY + newH > screenY + screenH) {
+ newY = screenY + screenH - newH;
+ }
+
+ return new Rectangle(newX, newY, newW, newH);
+ }
+
//Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
//the window but fails to revalidate, Sol-CDE
//This bug is regression for
@@ -445,10 +492,14 @@
//Note that this function is overriden in XDecoratedPeer so event
//posting is not changing for decorated peers
public void setBounds(int x, int y, int width, int height, int op) {
+ Rectangle newBounds = constrainBounds(x, y, width, height);
+
XToolkit.awtLock();
try {
Rectangle oldBounds = getBounds();
- super.setBounds(x, y, width, height, op);
+
+ super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
+
Rectangle bounds = getBounds();
XSizeHints hints = getHints();
@@ -1035,7 +1086,7 @@
return !(target instanceof Frame || target instanceof Dialog);
}
boolean hasWarningWindow() {
- return warningWindow != null;
+ return ((Window)target).getWarningString() != null;
}
// The height of menu bar window
--- a/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -102,4 +102,9 @@
public void blockWindows(java.util.List<Window> toBlock) {
// do nothing
}
+
+ @Override
+ final boolean isTargetUndecorated() {
+ return ((Dialog)target).isUndecorated();
+ }
}
--- a/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -204,4 +204,10 @@
}
public native Rectangle getBoundsPrivate();
+
+ @Override
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't constrain the bounds of the EmbeddedFrames
+ return new Rectangle(x, y, width, height);
+ }
}
--- a/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -503,4 +503,9 @@
public Rectangle getBoundsPrivate() {
return getBounds();
}
+
+ @Override
+ final boolean isTargetUndecorated() {
+ return ((Frame)target).isUndecorated();
+ }
}
--- a/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -113,6 +113,12 @@
insets.right = getInset("awt.frame.rightInset", -1);
}
+ Rectangle bounds = target.getBounds();
+ sysX = bounds.x;
+ sysY = bounds.y;
+ sysW = bounds.width;
+ sysH = bounds.height;
+
super.init(target);
InputMethodManager imm = InputMethodManager.getInstance();
String menuString = imm.getTriggerMenuString();
@@ -150,6 +156,7 @@
GraphicsConfiguration gc = getGraphicsConfiguration();
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
+
}
/* Support for multiple icons is not implemented in MAWT */
@@ -246,6 +253,8 @@
// NOTE: This method may be called by privileged threads.
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public void handleResize(int width, int height) {
+ sysW = width;
+ sysH = height;
// REMIND: Is this secure? Can client code subclass input method?
if (!tcList.isEmpty() &&
@@ -268,6 +277,8 @@
}
public void handleMoved(int x, int y) {
+ sysX = x;
+ sysY = y;
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
}
@@ -505,4 +516,87 @@
}
return false;
}
+
+ private final boolean hasWarningWindow() {
+ return ((Window)target).getWarningString() != null;
+ }
+
+ // This method is overriden at Dialog and Frame peers.
+ boolean isTargetUndecorated() {
+ return true;
+ }
+
+ private volatile int sysX = 0;
+ private volatile int sysY = 0;
+ private volatile int sysW = 0;
+ private volatile int sysH = 0;
+
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't restrict the setBounds() operation if the code is trusted.
+ if (!hasWarningWindow()) {
+ return new Rectangle(x, y, width, height);
+ }
+
+ int newX = x;
+ int newY = y;
+ int newW = width;
+ int newH = height;
+
+ GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+ Rectangle sB = gc.getBounds();
+ Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+ int screenW = sB.width - sIn.left - sIn.right;
+ int screenH = sB.height - sIn.top - sIn.bottom;
+
+ // If it's undecorated or is not currently visible,
+ // then check each point is within the visible part of the screen
+ if (!target.isVisible() || isTargetUndecorated()) {
+ int screenX = sB.x + sIn.left;
+ int screenY = sB.y + sIn.top;
+
+ // First make sure the size is withing the visible part of the screen
+ if (newW > screenW) {
+ newW = screenW;
+ }
+
+ if (newH > screenH) {
+ newH = screenH;
+ }
+
+ // Tweak the location if needed
+ if (newX < screenX) {
+ newX = screenX;
+ } else if (newX + newW > screenX + screenW) {
+ newX = screenX + screenW - newW;
+ }
+
+ if (newY < screenY) {
+ newY = screenY;
+ } else if (newY + newH > screenY + screenH) {
+ newY = screenY + screenH - newH;
+ }
+ } else {
+ int maxW = Math.max(screenW, sysW);
+ int maxH = Math.max(screenH, sysH);
+
+ // Make sure the size is withing the visible part of the screen
+ // OR is less that the current size of the window.
+ if (newW > maxW) {
+ newW = maxW;
+ }
+
+ if (newH > maxH) {
+ newH = maxH;
+ }
+ }
+
+ return new Rectangle(newX, newY, newW, newH);
+ }
+
+ public void setBounds(int x, int y, int width, int height, int op) {
+ Rectangle newBounds = constrainBounds(x, y, width, height);
+ super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
+ }
+
}
--- a/jdk/src/solaris/hpi/native_threads/src/sys_api_td.c Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/solaris/hpi/native_threads/src/sys_api_td.c Fri Mar 28 12:56:34 2008 -0700
@@ -63,15 +63,8 @@
#define CLOSEIO
#endif /* NO_INTERRUPTIBLE_IO */
-/*
- * Linux <sys/resource.h> does not define rlim_t (solaris
- * does). THIS IS PROBABLY NOT THE RIGHT THING TO DO, so
- * somebody please fix this.
- */
-#ifdef __linux__
-typedef int rlim_t ;
-#endif
-
+/* Get typedef for rlim_t */
+#include <sys/resource.h>
#ifdef CLOSEIO
--- a/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -108,11 +108,18 @@
}
}
+ @Override
+ boolean isTargetUndecorated() {
+ return ((Dialog)target).isUndecorated();
+ }
+
public void reshape(int x, int y, int width, int height) {
+ Rectangle newBounds = constrainBounds(x, y, width, height);
+
if (((Dialog)target).isUndecorated()) {
- super.reshape(x,y,width,height);
+ super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
} else {
- reshapeFrame(x,y,width,height);
+ reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
}
}
--- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -65,4 +65,10 @@
public native Rectangle getBoundsPrivate();
public native void synthesizeWmActivate(boolean doActivate);
+
+ @Override
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't constrain the bounds of the EmbeddedFrames
+ return new Rectangle(x, y, width, height);
+ }
}
--- a/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -64,11 +64,18 @@
}
}
+ @Override
+ boolean isTargetUndecorated() {
+ return ((Frame)target).isUndecorated();
+ }
+
public void reshape(int x, int y, int width, int height) {
+ Rectangle newBounds = constrainBounds(x, y, width, height);
+
if (((Frame)target).isUndecorated()) {
- super.reshape(x,y,width,height);
+ super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
} else {
- reshapeFrame(x,y,width,height);
+ reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
}
}
--- a/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WObjectPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,12 @@
initIDs();
}
- long pData; // The Windows handle for the native widget.
- Object target; // The associated AWT object.
+ // The Windows handle for the native widget.
+ long pData;
+ // if the native peer has been destroyed
+ boolean destroyed = false;
+ // The associated AWT object.
+ Object target;
private volatile boolean disposed;
--- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Fri Mar 28 12:56:34 2008 -0700
@@ -434,6 +434,97 @@
private native void nativeGrab();
private native void nativeUngrab();
+ private final boolean hasWarningWindow() {
+ return ((Window)target).getWarningString() != null;
+ }
+
+ boolean isTargetUndecorated() {
+ return true;
+ }
+
+ // These are the peer bounds. They get updated at:
+ // 1. the WWindowPeer.setBounds() method.
+ // 2. the native code (on WM_SIZE/WM_MOVE)
+ private volatile int sysX = 0;
+ private volatile int sysY = 0;
+ private volatile int sysW = 0;
+ private volatile int sysH = 0;
+
+ Rectangle constrainBounds(int x, int y, int width, int height) {
+ // We don't restrict the setBounds() operation if the code is trusted.
+ if (!hasWarningWindow()) {
+ return new Rectangle(x, y, width, height);
+ }
+
+ int newX = x;
+ int newY = y;
+ int newW = width;
+ int newH = height;
+
+ GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
+ Rectangle sB = gc.getBounds();
+ Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
+
+ int screenW = sB.width - sIn.left - sIn.right;
+ int screenH = sB.height - sIn.top - sIn.bottom;
+
+ // If it's undecorated or is not currently visible
+ if (!((Window)target).isVisible() || isTargetUndecorated()) {
+ // Now check each point is within the visible part of the screen
+ int screenX = sB.x + sIn.left;
+ int screenY = sB.y + sIn.top;
+
+ // First make sure the size is withing the visible part of the screen
+ if (newW > screenW) {
+ newW = screenW;
+ }
+
+ if (newH > screenH) {
+ newH = screenH;
+ }
+
+ // Tweak the location if needed
+ if (newX < screenX) {
+ newX = screenX;
+ } else if (newX + newW > screenX + screenW) {
+ newX = screenX + screenW - newW;
+ }
+
+ if (newY < screenY) {
+ newY = screenY;
+ } else if (newY + newH > screenY + screenH) {
+ newY = screenY + screenH - newH;
+ }
+ } else {
+ int maxW = Math.max(screenW, sysW);
+ int maxH = Math.max(screenH, sysH);
+
+ // Make sure the size is withing the visible part of the screen
+ // OR less that the current size of the window.
+ if (newW > maxW) {
+ newW = maxW;
+ }
+
+ if (newH > maxH) {
+ newH = maxH;
+ }
+ }
+
+ return new Rectangle(newX, newY, newW, newH);
+ }
+
+ @Override
+ public void setBounds(int x, int y, int width, int height, int op) {
+ Rectangle newBounds = constrainBounds(x, y, width, height);
+
+ sysX = newBounds.x;
+ sysY = newBounds.y;
+ sysW = newBounds.width;
+ sysH = newBounds.height;
+
+ super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
+ }
+
/*
* The method maps the list of the active windows to the window's AppContext,
* then the method registers ActiveWindowListener, GuiDisposedListener listeners;
--- a/jdk/src/windows/native/sun/windows/awt.h Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt.h Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
JNI_CHECK_NULL_GOTO(peer, "peer", where); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
- JNU_ThrowNullPointerException(env, "null pData"); \
+ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
goto where; \
} \
}
@@ -63,7 +63,7 @@
JNI_CHECK_NULL_RETURN(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
- JNU_ThrowNullPointerException(env, "null pData"); \
+ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return; \
} \
}
@@ -96,7 +96,7 @@
JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
- JNU_ThrowNullPointerException(env, "null pData"); \
+ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return 0; \
} \
}
@@ -105,16 +105,27 @@
JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
pData = JNI_GET_PDATA(peer); \
if (pData == NULL) { \
- JNU_ThrowNullPointerException(env, "null pData"); \
+ THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
return val; \
} \
}
+#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \
+ jboolean destroyed = JNI_GET_DESTROYED(peer); \
+ if (destroyed != JNI_TRUE) { \
+ JNU_ThrowNullPointerException(env, "null pData"); \
+ } \
+}
+
#define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
+#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID)
#define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \
- AwtObject::pDataID, \
- (jlong)data)
+ AwtObject::pDataID, \
+ (jlong)data)
+#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \
+ AwtObject::destroyedID, \
+ JNI_TRUE)
/* /NEW JNI */
/*
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -226,6 +226,8 @@
CriticalSection windowMoveLock;
BOOL windowMoveLockHeld = FALSE;
+int AwtComponent::sm_wheelRotationAmount = 0;
+
/************************************************************************
* AwtComponent methods
*/
@@ -2074,6 +2076,8 @@
sm_realFocusOpposite = NULL;
}
+ sm_wheelRotationAmount = 0;
+
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
return mrDoDefault;
@@ -2105,6 +2109,7 @@
}
sm_focusOwner = NULL;
+ sm_wheelRotationAmount = 0;
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
return mrDoDefault;
@@ -2190,8 +2195,11 @@
DWORD fgProcessID;
::GetWindowThreadProcessId(fgWindow, &fgProcessID);
- if (fgProcessID != ::GetCurrentProcessId()) {
- // fix for 6458497. we shouldn't request focus if it is out of our application.
+ if (fgProcessID != ::GetCurrentProcessId()
+ && !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
+ {
+ // fix for 6458497. we shouldn't request focus if it is out of both
+ // our and embedder process.
return FALSE;
}
}
@@ -2619,9 +2627,13 @@
BOOL result;
UINT platformLines;
+ sm_wheelRotationAmount += wheelRotation;
+
// AWT interprets wheel rotation differently than win32, so we need to
// decode wheel amount.
- jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA);
+ jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA);
+ jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
+
MSG msg;
if (IS_WIN95 && !IS_WIN98) {
@@ -2654,7 +2666,9 @@
SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(),
eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
- scrollLines, newWheelRotation, &msg);
+ scrollLines, roundedWheelRotation, preciseWheelRotation, &msg);
+
+ sm_wheelRotationAmount %= WHEEL_DELTA;
return mrConsume;
}
@@ -4986,8 +5000,8 @@
AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
jint modifiers, jint clickCount,
jboolean popupTrigger, jint scrollType,
- jint scrollAmount, jint wheelRotation,
- MSG *pMsg)
+ jint scrollAmount, jint roundedWheelRotation,
+ jdouble preciseWheelRotation, MSG *pMsg)
{
/* Code based not so loosely on AwtComponent::SendMouseEvent */
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -5015,7 +5029,7 @@
if (mouseWheelEventConst == NULL) {
mouseWheelEventConst =
env->GetMethodID(mouseWheelEventCls, "<init>",
- "(Ljava/awt/Component;IJIIIIZIII)V");
+ "(Ljava/awt/Component;IJIIIIIIZIIID)V");
DASSERT(mouseWheelEventConst);
}
if (env->EnsureLocalCapacity(2) < 0) {
@@ -5023,14 +5037,16 @@
}
jobject target = GetTarget(env);
DTRACE_PRINTLN("creating MWE in JNI");
+
jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
mouseWheelEventConst,
target,
id, when, modifiers,
x+insets.left, y+insets.top,
+ 0, 0,
clickCount, popupTrigger,
scrollType, scrollAmount,
- wheelRotation);
+ roundedWheelRotation, preciseWheelRotation);
if (safe_ExceptionOccurred(env)) {
env->ExceptionDescribe();
env->ExceptionClear();
@@ -5400,6 +5416,7 @@
if (m_peerObject) {
env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
+ JNI_SET_DESTROYED(m_peerObject);
env->DeleteGlobalRef(m_peerObject);
m_peerObject = NULL;
}
@@ -5408,7 +5425,13 @@
void AwtComponent::Enable(BOOL bEnable)
{
sm_suppressFocusAndActivation = TRUE;
+
+ if (bEnable && IsTopLevel()) {
+ // we should not enable blocked toplevels
+ bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
+ }
::EnableWindow(GetHWnd(), bEnable);
+
sm_suppressFocusAndActivation = FALSE;
CriticalSection::Lock l(GetLock());
VerifyState();
--- a/jdk/src/windows/native/sun/windows/awt_Component.h Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Component.h Fri Mar 28 12:56:34 2008 -0700
@@ -392,7 +392,7 @@
jint modifiers, jint clickCount,
jboolean popupTrigger, jint scrollType,
jint scrollAmount, jint wheelRotation,
- MSG *msg = NULL);
+ jdouble preciseWheelRotation, MSG *msg = NULL);
/*
* Allocate and initialize a new java.awt.event.FocusEvent, and
@@ -785,7 +785,9 @@
int windowMoveLockPosCX;
int windowMoveLockPosCY;
-private:
+ // 6524352: support finer-resolution
+ static int sm_wheelRotationAmount;
+
/*
* The association list of children's IDs and corresponding components.
* Some components like Choice or List are required their sizes while
--- a/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Dialog.cpp Fri Mar 28 12:56:34 2008 -0700
@@ -273,6 +273,10 @@
{
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
HWND topMostBlocker = blocker;
+ HWND prevForegroundWindow = ::GetForegroundWindow();
+ if (::IsWindow(blocker)) {
+ ::BringWindowToTop(hWnd);
+ }
while (::IsWindow(blocker)) {
topMostBlocker = blocker;
::BringWindowToTop(blocker);
@@ -282,7 +286,7 @@
// no beep/flash if the mouse was clicked in the taskbar menu
// or the dialog is currently inactive
if ((::WindowFromPoint(mhs->pt) == hWnd) &&
- (::GetForegroundWindow() == topMostBlocker))
+ (prevForegroundWindow == topMostBlocker))
{
::MessageBeep(MB_OK);
// some heuristics: 3 times x 64 milliseconds
@@ -292,6 +296,7 @@
::BringWindowToTop(topMostBlocker);
::SetForegroundWindow(topMostBlocker);
}
+ return 1;
}
}
}
--- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -221,8 +221,7 @@
// Update target's dimensions to reflect this embedded window.
::GetClientRect(frame->m_hwnd, &rect);
- ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect,
- 2);
+ ::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
env->SetIntField(target, AwtComponent::xID, rect.left);
env->SetIntField(target, AwtComponent::yID, rect.top);
@@ -231,6 +230,7 @@
env->SetIntField(target, AwtComponent::heightID,
rect.bottom-rect.top);
frame->InitPeerGraphicsConfig(env, self);
+ AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
} else {
jint state = env->GetIntField(target, AwtFrame::stateID);
DWORD exStyle;
@@ -408,8 +408,9 @@
* message. This breaks Java focus. To workaround the problem we
* set the toplevel being shown foreground programmatically.
* The fix is localized to non-foreground process case only.
+ * (See also: 6599270)
*/
- if (show == TRUE && status == 0) {
+ if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
HWND fgHWnd = ::GetForegroundWindow();
if (fgHWnd != NULL) {
DWORD fgProcessID;
@@ -495,7 +496,7 @@
::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
r.right-r.left, r.bottom-r.top,
- SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER |
+ SWP_NOACTIVATE | SWP_NOZORDER |
SWP_NOCOPYBITS | SWP_DEFERERASE);
}
return mrConsume;
--- a/jdk/src/windows/native/sun/windows/awt_Object.cpp Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
*/
jfieldID AwtObject::pDataID;
+jfieldID AwtObject::destroyedID;
jfieldID AwtObject::targetID;
jclass AwtObject::wObjectPeerClass;
jmethodID AwtObject::getPeerForTargetMID;
@@ -223,6 +224,7 @@
AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
+ AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
AwtObject::targetID = env->GetFieldID(cls, "target",
"Ljava/lang/Object;");
@@ -233,6 +235,7 @@
AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
DASSERT(AwtObject::pDataID != NULL);
+ DASSERT(AwtObject::destroyedID != NULL);
DASSERT(AwtObject::targetID != NULL);
DASSERT(AwtObject::getPeerForTargetMID != NULL);
DASSERT(AwtObject::createErrorID != NULL);
--- a/jdk/src/windows/native/sun/windows/awt_Object.h Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Object.h Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,7 @@
/* sun.awt.windows.WObjectPeer field and method ids */
static jfieldID pDataID;
+ static jfieldID destroyedID;
static jfieldID targetID;
static jmethodID getPeerForTargetMID;
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -354,6 +354,7 @@
m_dllHandle = NULL;
m_displayChanged = FALSE;
+ m_embedderProcessID = 0;
// XXX: keyboard mapping should really be moved out of AwtComponent
AwtComponent::InitDynamicKeyMapTable();
@@ -1442,49 +1443,17 @@
}
}
-/*
- * Returns a reference to the class java.awt.Component.
- */
-jclass
-getComponentClass(JNIEnv *env)
+// for now we support only one embedder, but should be ready for future
+void AwtToolkit::RegisterEmbedderProcessId(HWND embedder)
{
- static jclass componentCls = NULL;
-
- // get global reference of java/awt/Component class (run only once)
- if (componentCls == NULL) {
- jclass componentClsLocal = env->FindClass("java/awt/Component");
- DASSERT(componentClsLocal != NULL);
- if (componentClsLocal == NULL) {
- /* exception already thrown */
- return NULL;
- }
- componentCls = (jclass)env->NewGlobalRef(componentClsLocal);
- env->DeleteLocalRef(componentClsLocal);
+ if (m_embedderProcessID) {
+ // we already set embedder process and do not expect
+ // two different processes to embed the same AwtToolkit
+ return;
}
- return componentCls;
-}
-
-/*
- * Returns a reference to the class java.awt.MenuComponent.
- */
-jclass
-getMenuComponentClass(JNIEnv *env)
-{
- static jclass menuComponentCls = NULL;
-
- // get global reference of java/awt/MenuComponent class (run only once)
- if (menuComponentCls == NULL) {
- jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent");
- DASSERT(menuComponentClsLocal != NULL);
- if (menuComponentClsLocal == NULL) {
- /* exception already thrown */
- return NULL;
- }
- menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal);
- env->DeleteLocalRef(menuComponentClsLocal);
- }
- return menuComponentCls;
+ embedder = ::GetAncestor(embedder, GA_ROOT);
+ ::GetWindowThreadProcessId(embedder, &m_embedderProcessID);
}
JNIEnv* AwtToolkit::m_env;
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h Fri Mar 28 12:56:34 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -426,10 +426,17 @@
*/
private:
BOOL m_displayChanged; /* Tracks displayChanged events */
+ // 0 means we are not embedded.
+ DWORD m_embedderProcessID;
public:
BOOL HasDisplayChanged() { return m_displayChanged; }
void ResetDisplayChanged() { m_displayChanged = FALSE; }
+ void RegisterEmbedderProcessId(HWND);
+ BOOL IsEmbedderProcessId(const DWORD processID) const
+ {
+ return m_embedderProcessID && (processID == m_embedderProcessID);
+ }
private:
static JNIEnv *m_env;
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Mar 28 12:56:34 2008 -0700
@@ -125,6 +125,11 @@
jclass AwtWindow::wwindowPeerCls;
jmethodID AwtWindow::getActiveWindowsMID;
+jfieldID AwtWindow::sysXID;
+jfieldID AwtWindow::sysYID;
+jfieldID AwtWindow::sysWID;
+jfieldID AwtWindow::sysHID;
+
int AwtWindow::ms_instanceCounter = 0;
HHOOK AwtWindow::ms_hCBTFilter;
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
@@ -180,7 +185,6 @@
}
::RemoveProp(GetHWnd(), ModalBlockerProp);
- ::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
if (m_grabbedWindow == this) {
Ungrab();
@@ -330,8 +334,11 @@
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
- if (comp != NULL && comp->IsTopLevel() && !((AwtWindow*)comp)->IsFocusableWindow()) {
- return 1; // Don't change focus/activation.
+ if (comp != NULL && comp->IsTopLevel()) {
+ AwtWindow* win = (AwtWindow*)comp;
+ if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) {
+ return 1; // Don't change focus/activation.
+ }
}
}
return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
@@ -1053,6 +1060,8 @@
(env)->SetIntField(target, AwtComponent::xID, rect.left);
(env)->SetIntField(target, AwtComponent::yID, rect.top);
+ (env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
+ (env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
env->DeleteLocalRef(target);
@@ -1116,6 +1125,11 @@
(env)->SetIntField(target, AwtComponent::widthID, newWidth);
(env)->SetIntField(target, AwtComponent::heightID, newHeight);
+
+ jobject peer = GetPeer(env);
+ (env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
+ (env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
+
if (!AwtWindow::IsResizing()) {
WindowResized();
}
@@ -1455,20 +1469,17 @@
if (!::IsWindow(window)) {
return;
}
- DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE);
+
if (::IsWindow(blocker)) {
- // save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
- DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
- ::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle));
- ::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW);
::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
+ ::EnableWindow(window, FALSE);
} else {
- // restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
- DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp));
- ::SetWindowLong(window, GWL_EXSTYLE,
- (exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle);
- ::RemoveProp(window, ModalSaveWSEXProp);
::RemoveProp(window, ModalBlockerProp);
+ AwtComponent *comp = AwtComponent::GetComponent(window);
+ // we don't expect to be called with non-java HWNDs
+ DASSERT(comp && comp->IsTopLevel());
+ // we should not unblock disabled toplevels
+ ::EnableWindow(window, comp->isEnabled());
}
}
@@ -1754,17 +1765,22 @@
// Fix for 4459064 : do not enforce thresholds for embedded frames
if (!p->IsEmbeddedFrame())
{
+ jobject peer = p->GetPeer(env);
int minWidth = ::GetSystemMetrics(SM_CXMIN);
int minHeight = ::GetSystemMetrics(SM_CYMIN);
if (w < minWidth)
{
env->SetIntField(target, AwtComponent::widthID,
w = minWidth);
+ env->SetIntField(peer, AwtWindow::sysWID,
+ w);
}
if (h < minHeight)
{
env->SetIntField(target, AwtComponent::heightID,
h = minHeight);
+ env->SetIntField(peer, AwtWindow::sysHID,
+ h);
}
}
env->DeleteLocalRef(target);
@@ -2148,6 +2164,11 @@
env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J");
DASSERT(AwtWindow::getActiveWindowsMID != NULL);
+ AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I");
+ AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I");
+ AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I");
+ AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I");
+
CATCH_BAD_ALLOC;
}
--- a/jdk/src/windows/native/sun/windows/awt_Window.h Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Window.h Fri Mar 28 12:56:34 2008 -0700
@@ -33,7 +33,6 @@
// property name tagging windows disabled by modality
static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
-static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp");
static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
#ifndef WH_MOUSE_LL
@@ -63,6 +62,12 @@
/* long[] getActiveWindowHandles() method in WWindowPeer */
static jmethodID getActiveWindowsMID;
+ // The coordinates at the peer.
+ static jfieldID sysXID;
+ static jfieldID sysYID;
+ static jfieldID sysWID;
+ static jfieldID sysHID;
+
AwtWindow();
virtual ~AwtWindow();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/HotSpotDiagnosticMXBean/GetDiagnosticOptions.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6658779
+ * @summary Basic Test for HotSpotDiagnosticMXBean.getDiagnosticOptions()
+ * @author Daniel Fuchs
+ *
+ * @run main GetDiagnosticOptions
+ */
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+import javax.management.MBeanServer;
+
+public class GetDiagnosticOptions {
+ private static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
+ "com.sun.management:type=HotSpotDiagnostic";
+
+ public static void main(String[] args) throws Exception {
+ HotSpotDiagnosticMXBean mbean =
+ sun.management.ManagementFactory.getDiagnosticMXBean();
+ checkDiagnosticOptions(mbean);
+
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ mbean = ManagementFactory.newPlatformMXBeanProxy(mbs,
+ HOTSPOT_DIAGNOSTIC_MXBEAN_NAME,
+ HotSpotDiagnosticMXBean.class);
+ checkDiagnosticOptions(mbean);
+ }
+
+ private static void checkDiagnosticOptions(HotSpotDiagnosticMXBean mbean) {
+ List<VMOption> options = mbean.getDiagnosticOptions();
+ for (VMOption opt : options) {
+ System.out.println("option: "+opt.getName()+"="+opt.getValue());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/NonFocusableResizableTooSmall/NonFocusableResizableTooSmall.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test
+ @bug 6581927
+ @summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing
+ @library ../../regtesthelpers
+ @build Util
+ @author anthony.petrov@...: area=awt.toplevel
+ @run main NonFocusableResizableTooSmall
+*/
+
+/**
+ * NonFocusableResizableTooSmall.java
+ *
+ * summary: Non-focusable frame should honor the size of the frame buttons/decorations when resizing
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class NonFocusableResizableTooSmall
+{
+
+ //*** test-writer defined static variables go here ***
+
+
+ private static void init()
+ {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ "This is an AUTOMATIC test, simply wait until it is done.",
+ "The result (passed or failed) will be shown in the",
+ "message window below."
+ };
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+ final Frame frame = new Frame();
+ frame.setFocusableWindowState(false);
+ frame.setSize(200, 100);
+ frame.setVisible(true);
+
+ final Robot robot = Util.createRobot();
+ robot.setAutoDelay(20);
+
+ // To be sure the window is shown and packed
+ Util.waitForIdle(robot);
+
+ final Insets insets = frame.getInsets();
+ System.out.println("The insets of the frame: " + insets);
+ if (insets.right == 0 || insets.bottom == 0) {
+ System.out.println("The test environment must have non-zero right & bottom insets!");
+ pass();
+ return;
+ }
+
+ // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
+ final Rectangle bounds1 = frame.getBounds();
+ System.out.println("The bounds before resizing: " + bounds1);
+
+ robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1);
+
+ // ... and start resizing to some very small
+ robot.mousePress( InputEvent.BUTTON1_MASK );
+
+ // Now resize the frame so that the width is smaller
+ // than the widths of the left and the right borders.
+ // The sum of widths of the icon of the frame + the control-buttons
+ // (close, minimize, etc.) should be definitely larger!
+ robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1);
+ Util.waitForIdle(robot);
+
+ robot.mouseRelease( InputEvent.BUTTON1_MASK );
+
+ Util.waitForIdle(robot);
+
+ // Check the current bounds of the frame
+ final Rectangle bounds2 = frame.getBounds();
+ System.out.println("The bounds after resizing: " + bounds2);
+
+ if (bounds2.width <= (insets.left + insets.right)) {
+ fail("The frame has been resized to very small.");
+ }
+ pass();
+ }//End init()
+
+
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ // Not sure about what happens if multiple of this test are
+ // instantiated in the same VM. Being static (and using
+ // static vars), it aint gonna work. Not worrying about
+ // it for now.
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test pass nor test fail has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ //The test harness may have interrupted the test. If so, rethrow the exception
+ // so that the harness gets it and deals with it.
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class NonFocusableResizableTooSmall
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// if want to make listeners, here is the recommended place for them, then instantiate
+// them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ NonFocusableResizableTooSmall.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ NonFocusableResizableTooSmall.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ System.out.println(messageIn);
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/RestoreFocusOnDisabledComponentTest/RestoreFocusOnDisabledComponentTest.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test %W% %E%
+ @bug 6598089
+ @summary Tests restoring focus on a single disabled coponent
+ @author Anton Tarasov: area=awt-focus
+ @library ../../regtesthelpers
+ @build Util
+ @run main RestoreFocusOnDisabledComponentTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import java.applet.Applet;
+import test.java.awt.regtesthelpers.Util;
+
+/*
+ * The bug is not reproducible on Windows.
+ */
+public class RestoreFocusOnDisabledComponentTest extends Applet {
+ Frame frame = new Frame("Frame") {public String toString() {return "FRAME";}};
+ Button b0 = new Button("button0") {public String toString() {return "B-0";}};
+ Button b1 = new Button("button1") {public String toString() {return "B-1";}};
+ volatile int nFocused;
+ Robot robot;
+
+ public static void main(String[] args) {
+ RestoreFocusOnDisabledComponentTest app = new RestoreFocusOnDisabledComponentTest();
+ app.init();
+ app.start();
+ }
+
+ public void init() {
+ robot = Util.createRobot();
+ }
+
+ public void start() {
+ frame.add(b0);
+ frame.add(b1);
+ frame.setLayout(new FlowLayout());
+ frame.pack();
+
+ frame.setVisible(true);
+
+ Util.waitForIdle(robot);
+ KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() {
+ public boolean dispatchEvent(AWTEvent e) {
+ if (e.getID() == FocusEvent.FOCUS_GAINED) {
+ // Trying to emulate timings. b1 should be disabled just by the time it gets
+ // FOCUS_GAINED event. The latter is a result of disabling b0 that initiates
+ // focus auto transfer.
+ if (e.getSource() == b1) {
+ b1.setEnabled(false);
+
+ } else if (e.getSource() == b0) {
+ if (++nFocused > 10) {
+ nFocused = -1;
+ throw new TestFailedException("Focus went into busy loop!");
+ }
+ }
+ }
+ return super.dispatchEvent(e);
+ }
+ });
+ // Initiating focus auto transfer.
+ // Focus will be requested to b1. When FOCUS_GAINED is being dispatched to b1, it will
+ // be disabled. This will trigger focus restoring. Focus will be requested to b0 (the
+ // last opposite component). When FOCUS_GAINED is being dispatched to b0, it will
+ // also be disabled. However, the last opposite component (and the most recent focus owner)
+ // will still be b0. When DKFM initiates focus restoring it should detect restoring
+ // on the same component and break.
+ b0.setEnabled(false);
+
+ Util.waitForIdle(robot);
+ if (nFocused != -1) {
+ System.out.println("Test passed.");
+ }
+ }
+}
+
+class TestFailedException extends RuntimeException {
+ TestFailedException(String msg) {
+ super("Test failed: " + msg);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mixing/ValidBounds.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test
+ @bug 6637796
+ @summary Shape should be correctly updated on invalid components
+ @author anthony.petrov@...: area=awt.mixing
+ @library ../regtesthelpers
+ @build Util
+ @run main ValidBounds
+*/
+
+/**
+ * ValidBounds.java
+ *
+ * summary: Shape should be correctly updated on invalid components
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class ValidBounds
+{
+
+ static volatile boolean clickPassed = false;
+
+ private static void init()
+ {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ "This is an AUTOMATIC test, simply wait until it is done.",
+ "The result (passed or failed) will be shown in the",
+ "message window below."
+ };
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+
+ // Create the frame and the button
+ Frame f = new Frame();
+ f.setBounds(100, 100, 400, 300);
+
+ Button b = new Button("OK");
+
+ f.setLayout(null);
+ f.add(b);
+ b.setBounds(50, 50, 200, 50);
+
+ b.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent e) {
+ clickPassed = true;
+ }
+ });
+
+ f.setVisible(true);
+
+ // Let's make the button much smaller first...
+ Robot robot = Util.createRobot();
+ robot.setAutoDelay(20);
+
+ Util.waitForIdle(robot);
+
+ b.setBounds(50, 50, 5, 5);
+ Util.waitForIdle(robot);
+
+ // ... and now let's enlarge it.
+ b.setBounds(50, 50, 200, 50);
+ Util.waitForIdle(robot);
+
+ // If the button doesn't receive the click, it means that the test
+ // failed: the shape of the button was not enlarged.
+ Point heavyLoc = b.getLocationOnScreen();
+ robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20);
+
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ Util.waitForIdle(robot);
+
+ if (clickPassed) {
+ pass();
+ } else {
+ fail("The button cannot be clicked.");
+ }
+ }//End init()
+
+
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ // Not sure about what happens if multiple of this test are
+ // instantiated in the same VM. Being static (and using
+ // static vars), it aint gonna work. Not worrying about
+ // it for now.
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test pass nor test fail has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ //The test harness may have interrupted the test. If so, rethrow the exception
+ // so that the harness gets it and deals with it.
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class ValidBounds
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// if want to make listeners, here is the recommended place for them, then instantiate
+// them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ValidBounds.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ValidBounds.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ System.out.println(messageIn);
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/WsDisabledStyle/CloseBlocker/CloseBlocker.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test %I% %E%
+ @bug 4080029
+ @summary Modal Dialog block input to all frame windows not just its parent.
+ @author dmitry.cherepanov: area=awt.modal
+ @run main/manual CloseBlocker
+*/
+
+/**
+ * ManualMainTest.java
+ *
+ * summary: The test opens and closes blocker dialog, the test verifies
+ * that active window is correct when the dialog is closed.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class CloseBlocker
+{
+
+ private static void init()
+ {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ " the test will be run 6 times, to start next test just close all ",
+ " windows of previous; the instructions are the same for all tests: ",
+ " 1) there are two frames (one the frames has 'show modal' button), ",
+ " 2) press the button to show a dialog, ",
+ " 3) close the dialog (an alternative scenario - activate another",
+ " native window before closing the dialog), ",
+ " 4) the frame with button should become next active window, ",
+ " if it's true, then the test passed, otherwise, it failed. ",
+ " Press 'pass' button only after all of the 6 tests are completed, ",
+ " the number of the currently executed test is displayed on the ",
+ " output window. "
+ };
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+ test(true, true, false);
+ test(true, true, true);
+ test(false, true, false); // 3rd parameter has no affect for ownerless
+
+ test(true, false, false);
+ test(true, false, true);
+ test(false, false, false); // 3rd parameter has no affect for ownerless
+
+ }//End init()
+
+ private static final Object obj = new Object();
+ private static int counter = 0;
+
+ /*
+ * The ownerless parameter indicates whether the blocker dialog
+ * has owner. The usual parameter indicates whether the blocker
+ * dialog is a Java dialog (non-native dialog like file dialog).
+ */
+ private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) {
+
+ Sysout.print(" * test #" + (++counter) + " is running ... ");
+
+ final Frame active = new Frame();
+ final Frame nonactive = new Frame();
+ Button button = new Button("show modal");
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ Dialog dialog = null;
+ Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive);
+ if (usual) {
+ dialog = new Dialog(parent, "Sample", true);
+ } else {
+ dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
+ }
+ dialog.addWindowListener(new WindowAdapter(){
+ public void windowClosing(WindowEvent e){
+ e.getWindow().dispose();
+ }
+ });
+ dialog.setBounds(200, 200, 200, 200);
+ dialog.setVisible(true);
+ }
+ });
+
+ active.add(button);
+ active.setBounds(200, 400, 200, 200);
+ WindowAdapter adapter = new WindowAdapter(){
+ public void windowClosing(WindowEvent e){
+ active.dispose();
+ nonactive.dispose();
+ synchronized(obj) {
+ obj.notify();
+ }
+ }
+ };
+ active.addWindowListener(adapter);
+ active.setVisible(true);
+
+ nonactive.setBounds(400, 400, 200, 200);
+ nonactive.addWindowListener(adapter);
+ nonactive.setVisible(true);
+
+ synchronized(obj) {
+ try{
+ obj.wait();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ Sysout.println(" completed. ");
+
+ }
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ManualMainTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ManualMainTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn, true );
+ }
+
+ public static void print( String messageIn )
+ {
+ dialog.displayMessage( messageIn, false );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn, boolean nextLine )
+ {
+ messageText.append( messageIn + (nextLine? "\n" : "") );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ManualMainTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ CloseBlocker.pass();
+ }
+ else
+ {
+ CloseBlocker.fail();
+ }
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/WsDisabledStyle/OverBlocker/OverBlocker.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test %I% %E%
+ @bug 4080029
+ @summary Modal Dialog block input to all frame windows not just its parent.
+ @author dmitry.cherepanov: area=awt.modal
+ @run main/manual OverBlocker
+*/
+
+/**
+ * OverBlocker.java
+ *
+ * summary: The test verifies that if user tries to activate the blocked dialog
+ * then the blocker dialog appears over the other windows
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class OverBlocker
+{
+
+ private static void init()
+ {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ " the test will be run 4 times, to start next test just close all ",
+ " windows of previous; the instructions are the same for all tests: ",
+ " 1) there is a frame with 'show modal' button, ",
+ " 2) press the button to show a dialog, ",
+ " 3) activate any non-Java application, move the app over the dialog, ",
+ " 4) click on the frame by mouse, ",
+ " 5) make sure that the dialog comes up from the application and ",
+ " now the dialog overlaps the app as well as the frame, ",
+ " if it's true, then the test passed, otherwise, it failed. ",
+ " Press 'pass' button only after all of the 4 tests are completed, ",
+ " the number of the currently executed test is displayed on the ",
+ " output window. "
+ };
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+ test(false, true);
+ test(true, true);
+ test(true, false);
+ test(false, false);
+
+ }//End init()
+
+ private static final Object obj = new Object();
+ private static int counter = 0;
+
+ /*
+ * The ownerless parameter indicates whether the blocker dialog
+ * has owner. The usual parameter indicates whether the blocker
+ * dialog is a Java dialog (non-native dialog like file dialog).
+ */
+ private static void test(final boolean ownerless, final boolean usual) {
+
+ Sysout.print(" * test #" + (++counter) + " is running ... ");
+
+ final Frame frame = new Frame();
+ Button button = new Button("show modal");
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ Dialog dialog = null;
+ Frame parent = ownerless ? null : frame;
+ if (usual) {
+ dialog = new Dialog(parent, "Sample", true);
+ } else {
+ dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
+ }
+ dialog.addWindowListener(new WindowAdapter(){
+ public void windowClosing(WindowEvent e){
+ e.getWindow().dispose();
+ }
+ });
+ dialog.setBounds(200, 200, 200, 200);
+ dialog.setVisible(true);
+ }
+ });
+ frame.add(button);
+ frame.setBounds(400, 400, 200, 200);
+ frame.addWindowListener(new WindowAdapter(){
+ public void windowClosing(WindowEvent e){
+ e.getWindow().dispose();
+ synchronized(obj) {
+ obj.notify();
+ }
+ }
+ });
+ frame.setVisible(true);
+
+ synchronized(obj) {
+ try{
+ obj.wait();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ Sysout.println(" completed. ");
+
+ }
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ManualMainTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ManualMainTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn, true );
+ }
+
+ public static void print( String messageIn )
+ {
+ dialog.displayMessage( messageIn, false );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn, boolean nextLine )
+ {
+ messageText.append( messageIn + (nextLine? "\n" : "") );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ManualMainTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ OverBlocker.pass();
+ }
+ else
+ {
+ OverBlocker.fail();
+ }
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test %I% %E%
+ @bug 6572263 6571808
+ @summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
+ @author dmitry.cherepanov: area=awt.modal
+ @run main/manual Winkey
+*/
+
+/**
+ * Winkey.java
+ *
+ * summary: the test verifies that pressing combination of Windows key
+ * and M key to minimize all windows doesn't break AWT modality
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class Winkey
+{
+
+ private static void init()
+ {
+ //*** Create instructions for the user here ***
+
+ String[] instructions =
+ {
+ " 1. there is a frame with a 'show modal' button, ",
+ " 2. press the button to show a modal dialog, ",
+ " 3. the modal dialog will be shown over the frame, ",
+ " 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
+ " ",
+ " 5.1. press combination Windows Key and M key to minimize all windows, ",
+ " 5.2. press combination Windows Key and D key to show desktop, ",
+ " 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
+ " 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
+ " ",
+ " 6. make sure that the dialog and the frame are visible, ",
+ " the bounds of the windows should be the same as before, ",
+ " if it's true, then the test passed; otherwise, it failed. "
+ };
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+ final Frame frame = new Frame();
+ Button button = new Button("show modal");
+ button.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD);
+ dialog.setVisible(true);
+ }
+ });
+ frame.add(button);
+ frame.setBounds(400, 400, 200, 200);
+ frame.setVisible(true);
+
+ }//End init()
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ManualMainTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ManualMainTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ManualMainTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ Winkey.pass();
+ }
+ else
+ {
+ Winkey.fail();
+ }
+ }
+
+}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ @test %W% %E% %I%, %G%
+ @bug 6524352
+ @summary support for high-resolution mouse wheel
+ @author dmitry cherepanov: area=awt.event
+ @run main/manual SmoothWheel
+*/
+
+/**
+ * SmoothWheel.java
+ *
+ * summary:
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class SmoothWheel
+{
+
+ //*** test-writer defined static variables go here ***
+
+
+ private static void init()
+ {
+ String[] instructions =
+ {
+ "1. the test is for high-resolution mouse wheel only, ",
+ " refer to the cr# 6524352 for more info about such devices, ",
+ "2. you'll see a frame, the frame contains a checkbox, ",
+ "3. initially, the state of the checkbox is off, ",
+ " use mouse wheel over the frame, ",
+ " and the frame will change its size gradually, ",
+ "4. turn on the checkbox, ",
+ " use mouse wheel again over the frame, ",
+ " now the frame will change its size smoothly, ",
+ "5. if the frame has always the same size or",
+ " if the frame changes its size equally in 3,4 cases, ",
+ " then the test failed. Otherwise, it passed."
+ };
+
+ Sysout.createDialog( );
+ Sysout.printInstructions( instructions );
+
+ final Frame frame = new Frame();
+ final Checkbox checkbox = new Checkbox("smooth wheel?");
+ checkbox.setState(false);
+
+ frame.setLayout (new FlowLayout());
+ frame.add(checkbox);
+
+ frame.addMouseWheelListener(new MouseWheelListener() {
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ Sysout.println(e.toString());
+ double wheelRotation = 0;
+ if (checkbox.getState()) {
+ wheelRotation = e.getPreciseWheelRotation();
+ } else {
+ wheelRotation = e.getWheelRotation();
+ }
+ Dimension size = frame.getSize();
+ size.width += 10 * wheelRotation;
+ size.height += 10 * wheelRotation;
+ frame.setSize(size);
+ }
+ });
+
+ frame.setBounds(200, 200, 200, 200);
+ frame.setVisible(true);
+
+ }//End init()
+
+
+
+ /*****************************************************
+ * Standard Test Machinery Section
+ * DO NOT modify anything in this section -- it's a
+ * standard chunk of code which has all of the
+ * synchronisation necessary for the test harness.
+ * By keeping it the same in all tests, it is easier
+ * to read and understand someone else's test, as
+ * well as insuring that all tests behave correctly
+ * with the test harness.
+ * There is a section following this for test-defined
+ * classes
+ ******************************************************/
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main( String args[] ) throws InterruptedException
+ {
+ mainThread = Thread.currentThread();
+ try
+ {
+ init();
+ }
+ catch( TestPassedException e )
+ {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try
+ {
+ Thread.sleep( sleepTime );
+ //Timed out, so fail the test
+ throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
+ }
+ catch (InterruptedException e)
+ {
+ if( ! testGeneratedInterrupt ) throw e;
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if ( theTestPassed == false )
+ {
+ throw new RuntimeException( failureMessage );
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo( int seconds )
+ {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass()
+ {
+ Sysout.println( "The test passed." );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //first check if this is executing in main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ if (mainThread != null){
+ mainThread.interrupt();
+ }
+ }//pass()
+
+ public static synchronized void fail()
+ {
+ //test writer didn't specify why test failed, so give generic
+ fail( "it just plain failed! :-)" );
+ }
+
+ public static synchronized void fail( String whyFailed )
+ {
+ Sysout.println( "The test failed: " + whyFailed );
+ Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
+ //check if this called from main thread
+ if ( mainThread == Thread.currentThread() )
+ {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException( whyFailed );
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }//fail()
+
+}// class ManualMainTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+{
+}
+
+//*********** End Standard Test Machinery Section **********
+
+
+//************ Begin classes defined for the test ****************
+
+// make listeners in a class defined here, and instantiate them in init()
+
+/* Example of a class which may be written as part of a test
+class NewClass implements anInterface
+ {
+ static int newVar = 0;
+
+ public void eventDispatched(AWTEvent e)
+ {
+ //Counting events to see if we get enough
+ eventCount++;
+
+ if( eventCount == 20 )
+ {
+ //got enough events, so pass
+
+ ManualMainTest.pass();
+ }
+ else if( tries == 20 )
+ {
+ //tried too many times without getting enough events so fail
+
+ ManualMainTest.fail();
+ }
+
+ }// eventDispatched()
+
+ }// NewClass class
+
+*/
+
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+ private static boolean numbering = false;
+ private static int messageNumber = 0;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+
+ /* Enables message counting for the tester. */
+ public static void enableNumbering(boolean enable){
+ numbering = enable;
+ }
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ if (numbering) {
+ messageIn = "" + messageNumber + " " + messageIn;
+ messageNumber++;
+ }
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button( "pass" );
+ Button failB = new Button( "fail" );
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ passB = new Button( "pass" );
+ passB.setActionCommand( "pass" );
+ passB.addActionListener( this );
+ buttonP.add( "East", passB );
+
+ failB = new Button( "fail" );
+ failB.setActionCommand( "fail" );
+ failB.addActionListener( this );
+ buttonP.add( "West", failB );
+
+ add( "South", buttonP );
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //ManualMainTest
+ public void actionPerformed( ActionEvent e )
+ {
+ if( e.getActionCommand() == "pass" )
+ {
+ SmoothWheel.pass();
+ }
+ else
+ {
+ SmoothWheel.fail();
+ }
+ }
+
+}// TestDialog class
--- a/jdk/test/java/lang/instrument/BootClassPath/BootClassPathTest.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/BootClassPath/BootClassPathTest.sh Fri Mar 28 12:56:34 2008 -0700
@@ -23,8 +23,10 @@
# @test
# @bug 5055293
-# @summary Test non US-ASCII characters in the value of the Boot-Class-Path
+# @summary Test non US-ASCII characters in the value of the Boot-Class-Path
# attribute.
+#
+# @run shell/timeout=240 BootClassPathTest.sh
if [ "${TESTJAVA}" = "" ]
then
@@ -72,7 +74,7 @@
echo "Running test..."
-"${JAVA}" -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
+"${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTCLASSES}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
result=$?
echo "Cleanup..."
--- a/jdk/test/java/lang/instrument/MakeJAR2.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/MakeJAR2.sh Fri Mar 28 12:56:34 2008 -0700
@@ -70,9 +70,11 @@
cp ${TESTSRC}/${AGENT}.java .
cp ${TESTSRC}/${APP}.java .
rm -rf ilib
-cp -r ${TESTSRC}/ilib .
-mkdir bootpath
-cp -r ${TESTSRC}/bootreporter bootpath
+mkdir ilib
+cp ${TESTSRC}/ilib/*.java ilib
+rm -rf bootpath
+mkdir -p bootpath/bootreporter
+cp ${TESTSRC}/bootreporter/*.java bootpath/bootreporter
cd bootpath
${JAVAC} bootreporter/*.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ManifestTest.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,483 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6274276
+# @summary JLI JAR manifest processing should ignore leading and trailing white space.
+# @author Daniel D. Daugherty
+#
+# @run build ManifestTestApp
+# @run shell/timeout=900 ManifestTest.sh
+#
+
+make_a_JAR() {
+ # version_line and premain_line are required
+ version_line="Manifest-Version: 1.0"
+ premain_line="Premain-Class: ${AGENT}"
+ boot_cp_line=""
+ expect_boot_cp_line="ExampleForBootClassPath was not loaded."
+ can_redef_line=""
+ expect_redef_line="isRedefineClassesSupported()=false"
+ can_retrans_line=""
+ expect_retrans_line="isRetransformClassesSupported()=false"
+ can_set_nmp_line=""
+ expect_set_nmp_line="isNativeMethodPrefixSupported()=false"
+
+ while [ $# != 0 ] ; do
+ case "$1" in
+ defaults)
+ # just use the defaults for the test
+ ;;
+
+ boot_cp_line1)
+ boot_cp_line="Boot-Class-Path: no_white_space"
+ expect_boot_cp_line="ExampleForBootClassPath was loaded."
+ mkdir -p no_white_space
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class no_white_space
+ ;;
+
+ boot_cp_line2)
+ boot_cp_line="Boot-Class-Path: has_leading_blank"
+ expect_boot_cp_line="ExampleForBootClassPath was loaded."
+ mkdir -p has_leading_blank " has_leading_blank"
+ # the good class is in the directory without the blank
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
+ has_leading_blank
+ # the bad class is in the directory with the blank
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
+ " has_leading_blank"/ExampleForBootClassPath.class
+ ;;
+
+ boot_cp_line3)
+ boot_cp_line="Boot-Class-Path: has_trailing_blank "
+ expect_boot_cp_line="ExampleForBootClassPath was loaded."
+ mkdir -p has_trailing_blank "has_trailing_blank "
+ # the good class is in the directory without the blank
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
+ has_trailing_blank
+ # the bad class is in the directory with the blank
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
+ "has_trailing_blank "/ExampleForBootClassPath.class
+ ;;
+
+ boot_cp_line4)
+ boot_cp_line="Boot-Class-Path: has_leading_and_trailing_blank "
+ expect_boot_cp_line="ExampleForBootClassPath was loaded."
+ mkdir -p has_leading_and_trailing_blank \
+ " has_leading_and_trailing_blank "
+ # the good class is in the directory without the blanks
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class \
+ has_leading_and_trailing_blank
+ # the bad class is in the directory with the blanks
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
+ " has_leading_and_trailing_blank "/ExampleForBootClassPath.class
+ ;;
+
+ boot_cp_line5)
+ boot_cp_line="Boot-Class-Path: has_embedded blank"
+ expect_boot_cp_line="ExampleForBootClassPath was loaded."
+ mkdir -p has_embedded "has_embedded blank"
+ # the good class is in the first blank separated word
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class has_embedded
+ # the bad class is in the directory with the blank
+ cp -p $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad \
+ "has_embedded blank"/ExampleForBootClassPath.class
+ ;;
+
+ can_redef_line1)
+ can_redef_line="Can-Redefine-Classes: true"
+ expect_redef_line="isRedefineClassesSupported()=true"
+ ;;
+
+ can_redef_line2)
+ can_redef_line="Can-Redefine-Classes: true"
+ expect_redef_line="isRedefineClassesSupported()=true"
+ ;;
+
+ can_redef_line3)
+ can_redef_line="Can-Redefine-Classes: true "
+ expect_redef_line="isRedefineClassesSupported()=true"
+ ;;
+
+ can_redef_line4)
+ can_redef_line="Can-Redefine-Classes: true "
+ expect_redef_line="isRedefineClassesSupported()=true"
+ ;;
+
+ can_redef_line5)
+ can_redef_line="Can-Redefine-Classes: false"
+ ;;
+
+ can_redef_line6)
+ can_redef_line="Can-Redefine-Classes: false"
+ ;;
+
+ can_redef_line7)
+ can_redef_line="Can-Redefine-Classes: false "
+ ;;
+
+ can_redef_line8)
+ can_redef_line="Can-Redefine-Classes: false "
+ ;;
+
+ can_redef_line9)
+ # this line makes the jar command unhappy and that's
+ # not what we're testing so skip this case
+ can_redef_line="Can-Redefine-Classes:"
+ ;;
+
+ can_redef_line10)
+ can_redef_line="Can-Redefine-Classes: "
+ ;;
+
+ can_redef_line11)
+ can_redef_line="Can-Redefine-Classes: "
+ ;;
+
+ can_retrans_line1)
+ can_retrans_line="Can-Retransform-Classes: true"
+ expect_retrans_line="isRetransformClassesSupported()=true"
+ ;;
+
+ can_retrans_line2)
+ can_retrans_line="Can-Retransform-Classes: true"
+ expect_retrans_line="isRetransformClassesSupported()=true"
+ ;;
+
+ can_retrans_line3)
+ can_retrans_line="Can-Retransform-Classes: true "
+ expect_retrans_line="isRetransformClassesSupported()=true"
+ ;;
+
+ can_retrans_line4)
+ can_retrans_line="Can-Retransform-Classes: true "
+ expect_retrans_line="isRetransformClassesSupported()=true"
+ ;;
+
+ can_retrans_line5)
+ can_retrans_line="Can-Retransform-Classes: false"
+ ;;
+
+ can_retrans_line6)
+ can_retrans_line="Can-Retransform-Classes: false"
+ ;;
+
+ can_retrans_line7)
+ can_retrans_line="Can-Retransform-Classes: false "
+ ;;
+
+ can_retrans_line8)
+ can_retrans_line="Can-Retransform-Classes: false "
+ ;;
+
+ can_retrans_line9)
+ # this line makes the jar command unhappy and that's
+ # not what we're testing so skip this case
+ can_retrans_line="Can-Retransform-Classes:"
+ ;;
+
+ can_retrans_line10)
+ can_retrans_line="Can-Retransform-Classes: "
+ ;;
+
+ can_retrans_line11)
+ can_retrans_line="Can-Retransform-Classes: "
+ ;;
+
+ can_set_nmp_line1)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: true"
+ expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
+ ;;
+
+ can_set_nmp_line2)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: true"
+ expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
+ ;;
+
+ can_set_nmp_line3)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: true "
+ expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
+ ;;
+
+ can_set_nmp_line4)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: true "
+ expect_set_nmp_line="isNativeMethodPrefixSupported()=true"
+ ;;
+
+ can_set_nmp_line5)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: false"
+ ;;
+
+ can_set_nmp_line6)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: false"
+ ;;
+
+ can_set_nmp_line7)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: false "
+ ;;
+
+ can_set_nmp_line8)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: false "
+ ;;
+
+ can_set_nmp_line9)
+ # this line makes the jar command unhappy and that's
+ # not what we're testing so skip this case
+ can_set_nmp_line="Can-Set-Native-Method-Prefix:"
+ ;;
+
+ can_set_nmp_line10)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: "
+ ;;
+
+ can_set_nmp_line11)
+ can_set_nmp_line="Can-Set-Native-Method-Prefix: "
+ ;;
+
+ premain_line1)
+ premain_line="Premain-Class: ${AGENT}"
+ ;;
+
+ premain_line2)
+ premain_line="Premain-Class: ${AGENT} "
+ ;;
+
+ premain_line3)
+ premain_line="Premain-Class: ${AGENT} "
+ ;;
+
+ version_line1)
+ version_line="Manifest-Version: 1.0"
+ ;;
+
+ version_line2)
+ version_line="Manifest-Version: 1.0 "
+ ;;
+
+ version_line3)
+ version_line="Manifest-Version: 1.0 "
+ ;;
+
+ *)
+ echo "ERROR: invalid test token"
+ exit 1
+ esac
+ shift
+ done
+
+ echo "${version_line}" > ${AGENT}.mf
+ echo "${premain_line}" >> ${AGENT}.mf
+
+ if [ -n "$boot_cp_line" ]; then
+ echo "${boot_cp_line}" >> ${AGENT}.mf
+ fi
+
+ if [ -n "$can_redef_line" ]; then
+ echo "${can_redef_line}" >> ${AGENT}.mf
+ fi
+
+ if [ -n "$can_retrans_line" ]; then
+ echo "${can_retrans_line}" >> ${AGENT}.mf
+ fi
+
+ if [ -n "$can_set_nmp_line" ]; then
+ echo "${can_set_nmp_line}" >> ${AGENT}.mf
+ fi
+
+ rm -f ${AGENT}.jar
+ ${JAR} cvfm ${AGENT}.jar ${AGENT}.mf ${AGENT}.class
+
+ echo "$expect_boot_cp_line" > expect_boot_cp_line
+ echo "$expect_redef_line" > expect_redef_line
+ echo "$expect_retrans_line" > expect_retrans_line
+ echo "$expect_set_nmp_line" > expect_set_nmp_line
+}
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAR="${TESTJAVA}/bin/jar"
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+# Now that ManifestTestApp.class is built, we move
+# ExampleForBootClassPath.class so that it cannot be found
+# by default
+OUT_OF_THE_WAY=out_of_the_way
+mkdir $OUT_OF_THE_WAY
+mv "${TESTCLASSES}/ExampleForBootClassPath.class" $OUT_OF_THE_WAY
+
+# create a bad version of ExampleForBootClassPath.class
+# so we can tell when the wrong version is run
+sed 's/return 15/return 42/' "${TESTSRC}"/ExampleForBootClassPath.java \
+ > ExampleForBootClassPath.java
+"$JAVAC" ExampleForBootClassPath.java
+mv ExampleForBootClassPath.class \
+ $OUT_OF_THE_WAY/ExampleForBootClassPath.class.bad
+mv ExampleForBootClassPath.java \
+ $OUT_OF_THE_WAY/ExampleForBootClassPath.java.bad
+
+AGENT=ManifestTestAgent
+# We compile the agent in the working directory instead of with
+# a build task because we construct a different agent JAR file
+# for each test case.
+${JAVAC} -d . ${TESTSRC}/${AGENT}.java
+
+FAIL_MARKER=fail_marker
+rm -f $FAIL_MARKER
+
+while read token; do
+ echo
+ echo "===== begin test case: $token ====="
+ make_a_JAR "$token"
+
+ "${JAVA}" ${TESTVMOPTS} -javaagent:${AGENT}.jar \
+ -classpath "${TESTCLASSES}" ManifestTestApp > output.log 2>&1
+ result=$?
+
+ cat output.log
+
+ if [ "$result" = 0 ]; then
+ echo "PASS: ManifestTestApp exited with status of 0."
+ else
+ echo "FAIL: ManifestTestApp exited with status of $result"
+ touch $FAIL_MARKER
+ fi
+
+ MESG="Hello from ${AGENT}!"
+ grep -s "$MESG" output.log > /dev/null
+ result=$?
+ if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+ else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+ touch $FAIL_MARKER
+ fi
+
+ MESG=`cat expect_boot_cp_line`
+ grep -s "$MESG" output.log > /dev/null
+ result=$?
+ if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+ else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+ touch $FAIL_MARKER
+ fi
+
+ MESG=`cat expect_redef_line`
+ grep -s "$MESG" output.log > /dev/null
+ result=$?
+ if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+ else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+ touch $FAIL_MARKER
+ fi
+
+ MESG=`cat expect_retrans_line`
+ grep -s "$MESG" output.log > /dev/null
+ result=$?
+ if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+ else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+ touch $FAIL_MARKER
+ fi
+
+ MESG=`cat expect_set_nmp_line`
+ grep -s "$MESG" output.log > /dev/null
+ result=$?
+ if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+ else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+ touch $FAIL_MARKER
+ fi
+
+ echo "===== end test case: $token ====="
+ echo
+done << EOF
+defaults
+version_line1
+version_line2
+version_line3
+premain_line1
+premain_line2
+premain_line3
+boot_cp_line1
+boot_cp_line2
+boot_cp_line3
+boot_cp_line4
+boot_cp_line5
+can_redef_line1
+can_redef_line2
+can_redef_line3
+can_redef_line4
+can_redef_line5
+can_redef_line6
+can_redef_line7
+can_redef_line8
+can_redef_line10
+can_redef_line11
+can_retrans_line1
+can_retrans_line2
+can_retrans_line3
+can_retrans_line4
+can_retrans_line5
+can_retrans_line6
+can_retrans_line7
+can_retrans_line8
+can_retrans_line10
+can_retrans_line11
+can_set_nmp_line1
+can_set_nmp_line2
+can_set_nmp_line3
+can_set_nmp_line4
+can_set_nmp_line5
+can_set_nmp_line6
+can_set_nmp_line7
+can_set_nmp_line8
+can_set_nmp_line10
+can_set_nmp_line11
+EOF
+
+if [ -f $FAIL_MARKER ]; then
+ exit 1
+else
+ exit 0
+fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ManifestTestAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.Instrumentation;
+
+public class ManifestTestAgent {
+ private static Instrumentation instrumentation;
+
+ private ManifestTestAgent() {
+ }
+
+ public static void premain(String agentArgs, Instrumentation inst) {
+ System.out.println("Hello from ManifestTestAgent!");
+ System.out.println("isNativeMethodPrefixSupported()=" +
+ inst.isNativeMethodPrefixSupported());
+ System.out.println("isRedefineClassesSupported()=" +
+ inst.isRedefineClassesSupported());
+ System.out.println("isRetransformClassesSupported()=" +
+ inst.isRetransformClassesSupported());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ManifestTestApp.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+public class ManifestTestApp {
+ public static void main(String args[]) {
+ System.out.println("Hello from ManifestTestApp!");
+
+ new ManifestTestApp().doTest();
+ System.exit(0);
+ }
+
+ private void doTest() {
+ try {
+ // load the class only found via the Boot-Class-Path attribute
+ Object instance = loadExampleClass();
+ if (instance.getClass().getClassLoader() == null) {
+ System.out.println("PASS: ExampleForBootClassPath was loaded" +
+ " by the boot class path loader.");
+ } else {
+ System.out.println("FAIL: ExampleForBootClassPath was loaded" +
+ " by a non-boot class path loader.");
+ System.exit(1);
+ }
+ } catch (NoClassDefFoundError ncdfe) {
+ // This message just lets ManifestTest.sh know whether or
+ // not ExampleForBootClassPath was loaded. Depending on
+ // the current test case, that will be either a PASSing
+ // condition or a FAILing condition as determined by
+ // ManifestTest.sh.
+ System.out.println("ExampleForBootClassPath was not loaded.");
+ }
+ }
+
+ Object loadExampleClass() {
+ ExampleForBootClassPath instance = new ExampleForBootClassPath();
+ System.out.println("ExampleForBootClassPath was loaded.");
+ if (instance.fifteen() == 15) {
+ System.out.println("PASS: the correct" +
+ " ExampleForBootClassPath was loaded.");
+ } else {
+ System.out.println("FAIL: the wrong ExampleForBootClassPath" +
+ " was loaded.");
+ System.out.println("FAIL: instance.fifteen()=" +
+ instance.fifteen());
+ System.exit(1);
+ }
+ return instance;
+ }
+}
--- a/jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/NativeMethodPrefixAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -27,7 +27,7 @@
* @summary test setNativeMethodPrefix
* @author Robert Field, Sun Microsystems
*
- * @run shell MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true'
+ * @run shell/timeout=240 MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true'
* @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ParallelTransformerLoader.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,72 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 5088398
+# @summary Test parallel class loading by parallel transformers.
+# @author Daniel D. Daugherty as modified from the code of Daryl Puryear @ Wily
+#
+# @run shell MakeJAR3.sh ParallelTransformerLoaderAgent
+# @run build ParallelTransformerLoaderApp
+# @run shell/timeout=240 ParallelTransformerLoader.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAR="${TESTJAVA}"/bin/jar
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+"${JAVAC}" -d . \
+ "${TESTSRC}"/TestClass1.java \
+ "${TESTSRC}"/TestClass2.java \
+ "${TESTSRC}"/TestClass3.java
+
+"${JAR}" cvf Test.jar Test*.class
+# Removing the test class files is important. If these
+# .class files are available on the classpath other
+# than via Test.jar, then the deadlock will not reproduce.
+rm -f Test*.class
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:ParallelTransformerLoaderAgent.jar=Test.jar \
+ -classpath "${TESTCLASSES}" ParallelTransformerLoaderApp
+result=$?
+echo "result=$result"
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ParallelTransformerLoaderAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.*;
+import java.net.*;
+import java.io.*;
+import java.security.*;
+
+/**
+ * Test Java Agent
+ *
+ * @author Daryl Puryear
+ * @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
+ */
+public class ParallelTransformerLoaderAgent
+{
+ private static URL sURL;
+ private static ClassLoader sClassLoader;
+
+ public static synchronized ClassLoader
+ getClassLoader()
+ {
+ return sClassLoader;
+ }
+
+ public static synchronized void
+ generateNewClassLoader()
+ {
+ sClassLoader = new URLClassLoader(new URL[] {sURL});
+ }
+
+ public static void
+ premain( String agentArgs,
+ Instrumentation instrumentation)
+ throws Exception
+ {
+ if (agentArgs == null || agentArgs == "")
+ {
+ System.err.println("Error: No jar file name provided, test will not run.");
+ return;
+ }
+
+ sURL = (new File(agentArgs)).toURL();
+ System.out.println("Using jar file: " + sURL);
+ generateNewClassLoader();
+
+ instrumentation.addTransformer(new TestTransformer());
+ }
+
+ private static class TestTransformer
+ implements ClassFileTransformer
+ {
+ public byte[]
+ transform( ClassLoader loader,
+ String className,
+ Class classBeingRedefined,
+ ProtectionDomain protectionDomain,
+ byte[] classfileBuffer)
+ throws IllegalClassFormatException
+ {
+ String tName = Thread.currentThread().getName();
+ // In 160_03 and older, transform() is called
+ // with the "system_loader_lock" held and that
+ // prevents the bootstrap class loaded from
+ // running in parallel. If we add a slight sleep
+ // delay here when the transform() call is not
+ // main or TestThread, then the deadlock in
+ // 160_03 and older is much more reproducible.
+ if (!tName.equals("main") && !tName.equals("TestThread")) {
+ System.out.println("Thread '" + tName +
+ "' has called transform()");
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ie) {
+ }
+ }
+
+ // load additional classes when called from other threads
+ if (!tName.equals("main"))
+ {
+ loadClasses(3);
+ }
+ return null;
+ }
+
+ public static void
+ loadClasses( int index)
+ {
+ ClassLoader loader = ParallelTransformerLoaderAgent.getClassLoader();
+ try
+ {
+ Class.forName("TestClass" + index, true, loader);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ParallelTransformerLoaderApp.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Test Java Program
+ *
+ * @author Daryl Puryear
+ * @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
+ */
+public class ParallelTransformerLoaderApp
+{
+ private static final int kNumIterations = 1000;
+
+ public static void
+ main( String[] args)
+ throws Exception
+ {
+ System.out.println();
+ System.out.print("Starting test with " + kNumIterations + " iterations");
+ for (int i = 0; i < kNumIterations; i++)
+ {
+ // load some classes from multiple threads (this thread and one other)
+ Thread testThread = new TestThread(2);
+ testThread.start();
+ loadClasses(1);
+
+ // log that it completed and reset for the next iteration
+ testThread.join();
+ System.out.print(".");
+ ParallelTransformerLoaderAgent.generateNewClassLoader();
+ }
+
+ System.out.println();
+ System.out.println("Test completed successfully");
+ }
+
+ private static class TestThread
+ extends Thread
+ {
+ private final int fIndex;
+
+ public
+ TestThread( int index)
+ {
+ super("TestThread");
+
+ fIndex = index;
+ }
+
+ public void
+ run()
+ {
+ loadClasses(fIndex);
+ }
+ }
+
+ public static void
+ loadClasses( int index)
+ {
+ ClassLoader loader = ParallelTransformerLoaderAgent.getClassLoader();
+ try
+ {
+ Class.forName("TestClass" + index, true, loader);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
--- a/jdk/test/java/lang/instrument/PremainClass/DummyMain.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/PremainClass/DummyMain.java Fri Mar 28 12:56:34 2008 -0700
@@ -22,11 +22,10 @@
*/
/*
- *
- *
- * Used by PremainClassTest.sh - dummy "main application" which doesn't do anything
+ * dummy "Hello World"ish application for "premain" tests
*/
public class DummyMain {
public static void main(String[] args) {
+ System.out.println("Hello from DummyMain!");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0001.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,0,0,1): declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0001
+ * @run main/othervm -javaagent:InheritAgent0001.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0001 extends InheritAgent0001Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0001!");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent0001Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0010.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,0,1,0): declared 2-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0010
+ * @run main/othervm -javaagent:InheritAgent0010.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0010 extends InheritAgent0010Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent0010!");
+ }
+}
+
+class InheritAgent0010Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0011.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,0,1,1): declared 2-arg and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0011
+ * @run main/othervm -javaagent:InheritAgent0011.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0011 extends InheritAgent0011Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0011!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent0011!");
+ }
+}
+
+class InheritAgent0011Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0100.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,1,0,0): inherited 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0100
+ * @run main/othervm -javaagent:InheritAgent0100.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0100 extends InheritAgent0100Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent0100Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0100Super!");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0101.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,1,0,1): inherited 1-arg and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0101
+ * @run main/othervm -javaagent:InheritAgent0101.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0101 extends InheritAgent0101Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0101!");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent0101Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0101Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0110.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,1,1,0): inherited 1-arg and declared 2-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0110
+ * @run main/othervm -javaagent:InheritAgent0110.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0110 extends InheritAgent0110Super {
+
+ // This agent does NOT have a one argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent0110!");
+ }
+}
+
+class InheritAgent0110Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0110Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent0111.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (0,1,1,1): inherited 1-arg, declared 2-arg and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent0111
+ * @run main/othervm -javaagent:InheritAgent0111.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent0111 extends InheritAgent0111Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0111!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent0111!");
+ }
+
+}
+
+class InheritAgent0111Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent0111Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1000.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,0,0,0): inherited 2-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1000
+ * @run main/othervm -javaagent:InheritAgent1000.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1000 extends InheritAgent1000Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent1000Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1000Super!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1001.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,0,0,1): inherited 2-arg, and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1001
+ * @run main/othervm -javaagent:InheritAgent1001.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1001 extends InheritAgent1001Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1001!");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent1001Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1001Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1010.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,0,1,0): inherited 2-arg, and declared 2-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1010
+ * @run main/othervm -javaagent:InheritAgent1010.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1010 extends InheritAgent1010Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1010!");
+ }
+}
+
+class InheritAgent1010Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1010Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1011.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,0,1,1): inherited 2-arg, declared 2-arg and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1011
+ * @run main/othervm -javaagent:InheritAgent1011.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1011 extends InheritAgent1011Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1011!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1011!");
+ }
+}
+
+class InheritAgent1011Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1011Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1100.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,1,0,0): inherited 2-arg and inherited 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1100
+ * @run main/othervm -javaagent:InheritAgent1100.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1100 extends InheritAgent1100Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent1100Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1100Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1100Super!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1101.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,1,0,1): inherited 2-arg, inherited 1-arg, and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1101
+ * @run main/othervm -javaagent:InheritAgent1101.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1101 extends InheritAgent1101Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1101!");
+ }
+
+ // This agent does NOT have a double argument premain() method.
+}
+
+class InheritAgent1101Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1101Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1101Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1110.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,1,1,0): inherited 2-arg, inherited 1-arg, and declared 2-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1110
+ * @run main/othervm -javaagent:InheritAgent1110.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1110 extends InheritAgent1110Super {
+
+ // This agent does NOT have a single argument premain() method.
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1110!");
+ }
+}
+
+class InheritAgent1110Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1110Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1110Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/InheritAgent1111.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6289149
+ * @summary test config (1,1,1,1): inherited 2-arg, inherited 1-arg, declared 2-arg and declared 1-arg in agent class
+ * @author Daniel D. Daugherty, Sun Microsystems
+ *
+ * @run shell ../MakeJAR3.sh InheritAgent1111
+ * @run main/othervm -javaagent:InheritAgent1111.jar DummyMain
+ */
+
+import java.lang.instrument.*;
+
+class InheritAgent1111 extends InheritAgent1111Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1111!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1111!");
+ }
+}
+
+class InheritAgent1111Super {
+
+ //
+ // This agent has a single argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs) {
+ System.out.println("Hello from Single-Arg InheritAgent1111Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+
+ //
+ // This agent has a double argument premain() method which
+ // is NOT the one that should be called.
+ //
+ public static void premain (String agentArgs, Instrumentation instArg) {
+ System.out.println("Hello from Double-Arg InheritAgent1111Super!");
+ throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN CALLED.");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/NoPremainAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.*;
+
+class NoPremainAgent {
+
+ // This agent is missing the premain() function.
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/NoPremainAgent.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,68 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6289149
+# @summary test when the agent's class is missing the premain() function.
+# @author Daniel D. Daugherty, Sun Microsystems
+#
+# @run build DummyMain
+# @run shell ../MakeJAR3.sh NoPremainAgent
+# @run shell NoPremainAgent.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:NoPremainAgent.jar \
+ -classpath "${TESTCLASSES}" DummyMain > output.log 2>&1
+cat output.log
+
+MESG="java.lang.NoSuchMethodException"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+fi
+
+exit $result
--- a/jdk/test/java/lang/instrument/PremainClass/PremainClassTest.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/PremainClass/PremainClassTest.sh Fri Mar 28 12:56:34 2008 -0700
@@ -49,7 +49,7 @@
"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/DummyMain.java
-"${JAVA}" -javaagent:"${TESTSRC}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
+"${JAVA}" ${TESTVMOPTS} -javaagent:"${TESTSRC}"/Agent.jar -classpath "${TESTCLASSES}" DummyMain
result=$?
exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/ZeroArgPremainAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.*;
+
+class ZeroArgPremainAgent {
+
+ // This agent has a zero arg premain() function.
+ public static void premain () {
+ System.out.println("Hello from ZeroArgInheritAgent!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/PremainClass/ZeroArgPremainAgent.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,68 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6289149
+# @summary test when the agent's class has a zero arg premain() function.
+# @author Daniel D. Daugherty, Sun Microsystems
+#
+# @run build DummyMain
+# @run shell ../MakeJAR3.sh ZeroArgPremainAgent
+# @run shell ZeroArgPremainAgent.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:ZeroArgPremainAgent.jar \
+ -classpath "${TESTCLASSES}" DummyMain > output.log 2>&1
+cat output.log
+
+MESG="java.lang.NoSuchMethodException"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "PASS: found '$MESG' in the test output"
+else
+ echo "FAIL: did NOT find '$MESG' in the test output"
+fi
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineClassWithNativeMethod.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,81 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 5003341 4917140 6545149
+# @summary Redefine a class with a native method.
+# @author Daniel D. Daugherty as modified from the test submitted by clovis@par.univie.ac.at
+#
+# @run shell MakeJAR3.sh RedefineClassWithNativeMethodAgent 'Can-Redefine-Classes: true'
+# @run build RedefineClassWithNativeMethodApp
+# @run shell RedefineClassWithNativeMethod.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+"${JAVA}" ${TESTVMOPTS} \
+ -javaagent:RedefineClassWithNativeMethodAgent.jar=java/lang/Thread.class \
+ -classpath "${TESTCLASSES}" RedefineClassWithNativeMethodApp \
+ > output.log 2>&1
+result=$?
+
+cat output.log
+
+if [ "$result" = 0 ]; then
+ echo "PASS: RedefineClassWithNativeMethodApp exited with status of 0."
+else
+ echo "FAIL: RedefineClassWithNativeMethodApp exited with status of $result"
+ exit "$result"
+fi
+
+MESG="Exception"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "FAIL: found '$MESG' in the test output"
+ result=1
+else
+ echo "PASS: did NOT find '$MESG' in the test output"
+ result=0
+fi
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineClassWithNativeMethodAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.*;
+import java.net.*;
+import java.util.*;
+import java.io.*;
+
+public class RedefineClassWithNativeMethodAgent {
+ static Class clz;
+
+ // just read the original class and redefine it via a Timer
+ public static void premain(String agentArgs, final Instrumentation inst) throws Exception {
+ String s = agentArgs.substring(0, agentArgs.indexOf(".class"));
+ clz = Class.forName(s.replace('/', '.'));
+ ClassLoader loader =
+ RedefineClassWithNativeMethodAgent.class.getClassLoader();
+ URL classURL = loader.getResource(agentArgs);
+ if (classURL == null) {
+ throw new Exception("Cannot find class: " + agentArgs);
+ }
+
+ int redefineLength;
+ InputStream redefineStream;
+
+ System.out.println("Reading test class from " + classURL);
+ if (classURL.getProtocol().equals("file")) {
+ File f = new File(classURL.getFile());
+ redefineStream = new FileInputStream(f);
+ redefineLength = (int) f.length();
+ } else {
+ URLConnection conn = classURL.openConnection();
+ redefineStream = conn.getInputStream();
+ redefineLength = conn.getContentLength();
+ }
+
+ final byte[] buffer = new byte[redefineLength];
+ new BufferedInputStream(redefineStream).read(buffer);
+ new Timer(true).schedule(new TimerTask() {
+ public void run() {
+ try {
+ System.out.println("Instrumenting");
+ ClassDefinition cld = new ClassDefinition(clz, buffer);
+ inst.redefineClasses(new ClassDefinition[] { cld });
+ }
+ catch (Exception e) { e.printStackTrace(); }
+ }
+ }, 500);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineClassWithNativeMethodApp.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+public class RedefineClassWithNativeMethodApp {
+ public static void main(String[] args) throws Exception {
+ try {
+ // give the agent a chance to redefine the target class
+ Thread.sleep(2000);
+ } catch (InterruptedException ie) {
+ }
+
+ System.out.println("Creating instance of " +
+ RedefineClassWithNativeMethodAgent.clz);
+ RedefineClassWithNativeMethodAgent.clz.newInstance();
+
+ System.exit(0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodAddInvoke.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,82 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6667089
+# @summary Reflexive invocation of newly added methods broken.
+# @author Daniel D. Daugherty
+#
+# @run shell MakeJAR3.sh RedefineMethodAddInvokeAgent 'Can-Redefine-Classes: true'
+# @run build RedefineMethodAddInvokeApp
+# @run shell RedefineMethodAddInvoke.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_1.java \
+ RedefineMethodAddInvokeTarget.java
+"${JAVAC}" -d . RedefineMethodAddInvokeTarget.java
+mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_1.java
+mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_1.class
+
+cp "${TESTSRC}"/RedefineMethodAddInvokeTarget_2.java \
+ RedefineMethodAddInvokeTarget.java
+"${JAVAC}" -d . RedefineMethodAddInvokeTarget.java
+mv RedefineMethodAddInvokeTarget.java RedefineMethodAddInvokeTarget_2.java
+mv RedefineMethodAddInvokeTarget.class RedefineMethodAddInvokeTarget_2.class
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodAddInvokeAgent.jar \
+ -classpath "${TESTCLASSES}" RedefineMethodAddInvokeApp > output.log 2>&1
+cat output.log
+
+MESG="Exception"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "FAIL: found '$MESG' in the test output"
+ result=1
+else
+ echo "PASS: did NOT find '$MESG' in the test output"
+ result=0
+fi
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodAddInvokeAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.Instrumentation;
+
+public class RedefineMethodAddInvokeAgent {
+ private static Instrumentation instrumentation;
+
+ private RedefineMethodAddInvokeAgent() {
+ }
+
+ public static void premain(String agentArgs, Instrumentation inst) {
+ System.out.println("Hello from RedefineMethodAddInvokeAgent!");
+ System.out.println("isRedefineClassesSupported()=" +
+ inst.isRedefineClassesSupported());
+
+ instrumentation = inst;
+ }
+
+ public static Instrumentation getInstrumentation() {
+ return instrumentation;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodAddInvokeApp.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+import java.lang.instrument.*;
+
+public class RedefineMethodAddInvokeApp {
+ public static void main(String args[]) throws Exception {
+ System.out.println("Hello from RedefineMethodAddInvokeApp!");
+
+ new RedefineMethodAddInvokeApp().doTest();
+
+ System.exit(0);
+ }
+
+ private void doTest() throws Exception {
+ RedefineMethodAddInvokeTarget target =
+ new RedefineMethodAddInvokeTarget();
+
+ System.out.println("RedefineMethodAddInvokeApp: invoking myMethod()");
+ target.test(0); // invoke the original myMethod()
+
+ // add myMethod1()
+ do_redefine(1);
+
+ System.out.println("RedefineMethodAddInvokeApp: invoking myMethod1()");
+ target.test(1); // invoke myMethod1()
+
+ // add myMethod2()
+ do_redefine(2);
+
+ System.out.println("RedefineMethodAddInvokeApp: invoking myMethod2()");
+ target.test(2); // invoke myMethod2()
+ }
+
+ private static void do_redefine(int counter) throws Exception {
+ File f = new File("RedefineMethodAddInvokeTarget_" + counter +
+ ".class");
+ System.out.println("Reading test class from " + f);
+ InputStream redefineStream = new FileInputStream(f);
+
+ byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream);
+
+ ClassDefinition redefineParamBlock = new ClassDefinition(
+ RedefineMethodAddInvokeTarget.class, redefineBuffer);
+
+ RedefineMethodAddInvokeAgent.getInstrumentation().redefineClasses(
+ new ClassDefinition[] {redefineParamBlock});
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodAddInvokeTarget.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.reflect.Method;
+
+public class RedefineMethodAddInvokeTarget {
+ public void test(int counter) throws Exception {
+ Method method = getClass().getDeclaredMethod("myMethod" +
+ (counter == 0 ? "" : counter));
+ method.setAccessible(true);
+ method.invoke(this);
+ }
+
+ public void myMethod() {
+ System.out.println("Hello from the original myMethod()!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodAddInvokeTarget_1.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.reflect.Method;
+
+public class RedefineMethodAddInvokeTarget {
+ public void test(int counter) throws Exception {
+ Method method = getClass().getDeclaredMethod("myMethod" +
+ (counter == 0 ? "" : counter));
+ method.setAccessible(true);
+ method.invoke(this);
+ }
+
+ public void myMethod() {
+ System.out.println("Hello from the non-EMCP myMethod()!");
+ }
+
+ private final void myMethod1() {
+ System.out.println("Hello from myMethod1()!");
+ System.out.println("Calling myMethod() from myMethod1():");
+ myMethod();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/RedefineMethodAddInvokeTarget_2.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.reflect.Method;
+
+public class RedefineMethodAddInvokeTarget {
+ public void test(int counter) throws Exception {
+ Method method = getClass().getDeclaredMethod("myMethod" +
+ (counter == 0 ? "" : counter));
+ method.setAccessible(true);
+ method.invoke(this);
+ }
+
+ public void myMethod() {
+ System.out.println("Hello from the non-EMCP again myMethod()!");
+ }
+
+ private final void myMethod1() {
+ System.out.println("Hello from myMethod1()!");
+ System.out.println("Calling myMethod() from myMethod1():");
+ myMethod();
+ }
+
+ private final void myMethod2() {
+ System.out.println("Hello from myMethod2()!");
+ System.out.println("Calling myMethod1() from myMethod2():");
+ myMethod1();
+ }
+}
--- a/jdk/test/java/lang/instrument/RetransformAgent.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/RetransformAgent.java Fri Mar 28 12:56:34 2008 -0700
@@ -27,7 +27,7 @@
* @summary test retransformClasses
* @author Robert Field, Sun Microsystems
*
- * @run shell MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true'
+ * @run shell/timeout=240 MakeJAR2.sh RetransformAgent RetransformApp 'Can-Retransform-Classes: true'
* @run main/othervm -javaagent:RetransformAgent.jar RetransformApp
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/StressGetObjectSizeApp.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.lang.instrument.Instrumentation;
+
+public class StressGetObjectSizeApp
+ extends ASimpleInstrumentationTestCase
+{
+
+ /**
+ * Constructor for StressGetObjectSizeApp.
+ * @param name
+ */
+ public StressGetObjectSizeApp(String name)
+ {
+ super(name);
+ }
+
+ public static void
+ main (String[] args)
+ throws Throwable {
+ ATestCaseScaffold test = new StressGetObjectSizeApp(args[0]);
+ test.runTest();
+ }
+
+ protected final void
+ doRunTest()
+ throws Throwable {
+ stressGetObjectSize();
+ }
+
+ public void stressGetObjectSize() {
+ System.out.println("main: an object size=" +
+ fInst.getObjectSize(new Object()));
+
+ RoundAndRound[] threads = new RoundAndRound[10];
+ for (int i = 0; i < threads.length; ++i) {
+ threads[i] = new RoundAndRound(fInst);
+ threads[i].start();
+ }
+ try {
+ Thread.sleep(500); // let all threads get going in their loops
+ } catch (InterruptedException ie) {
+ }
+ System.out.println("stressGetObjectSize: returning");
+ return;
+ }
+
+ private static class RoundAndRound extends Thread {
+ private final Instrumentation inst;
+ private final Object anObject;
+
+ public RoundAndRound(Instrumentation inst) {
+ this.inst = inst;
+ this.anObject = new Object();
+ setDaemon(true);
+ }
+
+ public void run() {
+ long sum = 0;
+ while (true) {
+ sum += inst.getObjectSize(anObject);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/StressGetObjectSizeTest.sh Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,70 @@
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6572160
+# @summary stress getObjectSize() API
+# @author Daniel D. Daugherty as modified from the code of fischman@google.com
+#
+# @run build StressGetObjectSizeApp
+# @run shell MakeJAR.sh basicAgent
+# @run shell StressGetObjectSizeTest.sh
+#
+
+if [ "${TESTJAVA}" = "" ]
+then
+ echo "TESTJAVA not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+ echo "TESTSRC not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+JAVA="${TESTJAVA}"/bin/java
+
+"${JAVA}" ${TESTVMOPTS} -javaagent:basicAgent.jar \
+ -classpath "${TESTCLASSES}" StressGetObjectSizeApp StressGetObjectSizeApp \
+ > output.log 2>&1
+cat output.log
+
+MESG="ASSERTION FAILED"
+grep "$MESG" output.log
+result=$?
+if [ "$result" = 0 ]; then
+ echo "FAIL: found '$MESG' in the test output"
+ result=1
+else
+ echo "PASS: did NOT find '$MESG' in the test output"
+ result=0
+fi
+
+exit $result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/TestClass1.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Test Java Program
+ *
+ * @author Daryl Puryear
+ * @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
+ */
+public class TestClass1
+{
+ public
+ TestClass1()
+ {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/TestClass2.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Test Java Program
+ *
+ * @author Daryl Puryear
+ * @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
+ */
+public class TestClass2
+{
+ public
+ TestClass2()
+ {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/TestClass3.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * Test Java Program
+ *
+ * @author Daryl Puryear
+ * @copyright 1999-2004 Wily Technology, Inc. All rights reserved.
+ */
+public class TestClass3
+{
+ public
+ TestClass3()
+ {
+ }
+}
--- a/jdk/test/java/lang/instrument/TransformerManagementThreadAddTests.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/TransformerManagementThreadAddTests.java Fri Mar 28 12:56:34 2008 -0700
@@ -79,6 +79,12 @@
protected static final int TOTAL_THREADS = MAX_TRANS - MIN_TRANS + 1;
private byte[] fDummyClassBytes;
+ // fCheckedTransformers is a Vector that is used to verify
+ // that the transform() function is called in the same
+ // order in which the transformers were added to the
+ // TransformerManager. The test currently verifies that all
+ // transformers for a specific worker thread are in
+ // increasing order by index value.
private Vector fCheckedTransformers;
private Instrumentation fInstrumentation;
private int fFinished;
@@ -131,9 +137,16 @@
threads[i].start();
}
- while (!exec.fDone)
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Don't use a direct field getter.
+ while (!exec.isDone())
{
- Thread.currentThread().yield();
+ // Effective Java - Item 51: Don't depend on the thread scheduler
+ // Use sleep() instead of yield().
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ie) {
+ }
}
assertTrue(finalCheck());
@@ -169,13 +182,17 @@
this.fExec = exec;
}
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Document a synchronized setter.
protected synchronized void
threadFinished(Thread t)
{
fFinished++;
}
- protected boolean
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Provide synchronized getter.
+ protected synchronized boolean
threadsDone()
{
return fFinished == TOTAL_THREADS;
@@ -188,7 +205,9 @@
protected boolean
testCompleted()
{
- return getExecThread().fDone;
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Don't use direct field getter.
+ return getExecThread().isDone();
}
/**
@@ -264,11 +283,19 @@
private void
executeTransform()
{
- fCheckedTransformers.clear();
-
try
{
ClassDefinition cd = new ClassDefinition(DummyClass.class, fDummyClassBytes);
+
+ // When the ClassDefinition above is created for the first
+ // time and every time redefineClasses() below is called,
+ // the transform() function is called for each registered
+ // transformer. We only want one complete set of calls to
+ // be logged in the fCheckedTransformers Vector so we clear
+ // any calls logged for ClassDefinition above and just use
+ // the ones logged for redefineClasses() below.
+ fCheckedTransformers.clear();
+
getInstrumentation().redefineClasses(new ClassDefinition[]{ cd });
}
catch (ClassNotFoundException e)
@@ -325,6 +352,18 @@
{
private boolean fDone = false;
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Provide a synchronized getter.
+ private synchronized boolean isDone() {
+ return fDone;
+ }
+
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Provide a synchronized setter.
+ private synchronized void setIsDone() {
+ fDone = true;
+ }
+
public void
run()
{
@@ -335,7 +374,9 @@
// Do a final check for good measure
executeTransform();
- fDone = true;
+ // Effective Java - Item 48: Synchronize access to shared mutable data
+ // Don't use direct field setter.
+ setIsDone();
}
}
--- a/jdk/test/java/lang/instrument/TransformerManagementThreadRemoveTests.java Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/TransformerManagementThreadRemoveTests.java Fri Mar 28 12:56:34 2008 -0700
@@ -27,10 +27,9 @@
* @summary multi-thread test to exercise sync and contention for removes to transformer registry
* @author Gabriel Adauto, Wily Technology
*
- * @ignore Disabled until race condition which hangs test can be fixed.
* @run build TransformerManagementThreadRemoveTests
- * @run shell MakeJAR.sh basicAgent
- * @run main/othervm -javaagent:basicAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests
+ * @run shell MakeJAR.sh redefineAgent
+ * @run main/othervm -javaagent:redefineAgent.jar TransformerManagementThreadRemoveTests TransformerManagementThreadRemoveTests
*/
import java.util.*;
@@ -87,7 +86,12 @@
while (!testCompleted())
{
- Thread.currentThread().yield();
+ // Effective Java - Item 51: Don't depend on the thread scheduler
+ // Use sleep() instead of yield().
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ie) {
+ }
}
assertTrue(finalCheck());
--- a/jdk/test/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/appendToClassLoaderSearch/CircularityErrorTest.sh Fri Mar 28 12:56:34 2008 -0700
@@ -26,14 +26,14 @@
# @summary Unit tests for appendToBootstrapClassLoaderSearch and
# appendToSystemClasLoaderSearch methods.
#
-# @run shell CircularityErrorTest.sh
+# @run shell/timeout=240 CircularityErrorTest.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
-
+
. ${TESTSRC}/CommonSetup.sh
# Setup to create circularity condition
@@ -71,5 +71,5 @@
-C "${TESTCLASSES}" CircularityErrorTest.class
# Finally we run the test
-(cd "${TESTCLASSES}";
- $JAVA -javaagent:CircularityErrorTest.jar CircularityErrorTest)
+(cd "${TESTCLASSES}";
+ $JAVA ${TESTVMOPTS} -javaagent:CircularityErrorTest.jar CircularityErrorTest)
--- a/jdk/test/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh Fri Mar 28 12:56:34 2008 -0700
@@ -34,11 +34,11 @@
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
-
+
. ${TESTSRC}/CommonSetup.sh
# Create Foo and Bar
-# Foo has a reference to Bar but we deleted Bar so that
+# Foo has a reference to Bar but we deleted Bar so that
# a NoClassDefFoundError will be thrown when Foo tries to
# resolve the reference to Bar
@@ -53,11 +53,11 @@
public class Foo {
public static boolean doSomething() {
try {
- Bar b = new Bar();
- return true;
- } catch (NoClassDefFoundError x) {
- return false;
- }
+ Bar b = new Bar();
+ return true;
+ } catch (NoClassDefFoundError x) {
+ return false;
+ }
}
}
EOF
@@ -79,5 +79,5 @@
# Finally we run the test
(cd "${TESTCLASSES}"; \
- $JAVA -Xverify:none -XX:+TraceClassUnloading -javaagent:ClassUnloadTest.jar \
- ClassUnloadTest "${OTHERDIR}" Bar.jar)
+ $JAVA ${TESTVMOPTS} -Xverify:none -XX:+TraceClassUnloading \
+ -javaagent:ClassUnloadTest.jar ClassUnloadTest "${OTHERDIR}" Bar.jar)
--- a/jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/appendToClassLoaderSearch/CommonSetup.sh Fri Mar 28 12:56:34 2008 -0700
@@ -24,7 +24,6 @@
#
-#%E
#
# Common setup for unit tests. Setups up the following variables:
#
@@ -66,7 +65,7 @@
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
-
+
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
--- a/jdk/test/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh Fri Mar 21 14:45:20 2008 -0700
+++ b/jdk/test/java/lang/instrument/appendToClassLoaderSearch/run_tests.sh Fri Mar 28 12:56:34 2008 -0700
@@ -23,24 +23,24 @@
# have any questions.
#
-
+
# @test
# @bug 6173575 6388987
-# @summary Unit tests for appendToBootstrapClassLoaderSearch and
+# @summary Unit tests for appendToBootstrapClassLoaderSearch and
# appendToSystemClasLoaderSearch methods.
#
# @build Agent AgentSupport BootSupport BasicTest PrematureLoadTest DynamicTest
-# @run shell run_tests.sh
+# @run shell/timeout=240 run_tests.sh
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
-
+
. ${TESTSRC}/CommonSetup.sh
-
+
# Simple tests
echo "Creating jar files for simple tests..."
@@ -50,13 +50,13 @@
"$JAR" -cfm Agent.jar "${TESTSRC}"/manifest.mf Agent.class
"$JAR" -cf AgentSupport.jar AgentSupport.class
"$JAR" -cf BootSupport.jar BootSupport.class
-"$JAR" -cf SimpleTests.jar BasicTest.class PrematureLoadTest.class
+"$JAR" -cf SimpleTests.jar BasicTest.class PrematureLoadTest.class
failures=0
go() {
echo ''
- sh -xc "$JAVA -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1
+ sh -xc "$JAVA ${TESTVMOPTS} -javaagent:Agent.jar -classpath SimpleTests.jar $1 $2 $3" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
}
@@ -75,7 +75,7 @@
"${JAVAC}" -d tmp "${TESTSRC}"/Tracer.java
(cd tmp; "${JAR}" cf ../Tracer.jar org/tools/Tracer.class)
-# InstrumentedApplication is Application+instrmentation - don't copy as
+# InstrumentedApplication is Application+instrmentation - don't copy as
# we don't want the original file permission
cat "${TESTSRC}"/InstrumentedApplication.java > ./Application.java
@@ -85,11 +85,11 @@
cp "${TESTSRC}"/Application.java .
"${JAVAC}" -d . Application.java
-sh -xc "$JAVA -classpath . -javaagent:Agent.jar DynamicTest" 2>&1
+sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar DynamicTest" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
# Repeat test with security manager
-sh -xc "$JAVA -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1
+sh -xc "$JAVA ${TESTVMOPTS} -classpath . -javaagent:Agent.jar -Djava.security.manager DynamicTest" 2>&1
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/modelmbean/LoggingExceptionTest.java Fri Mar 28 12:56:34 2008 -0700
@@ -0,0 +1,81 @@
+/*
+ * @test
+ * @bug 6471865 6675768
+ * @summary DescriptorSupport constructors throw IAE when traces are enabled;
+ * RequiredModelMBean.addAttributeChangeNotificationListener throws exception
+ * when traces enabled and no attributes.
+ * @author Luis-Miguel Alventosa
+ * @author Paul Cheeseman
+ */
+
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.modelmbean.DescriptorSupport;
+import javax.management.modelmbean.RequiredModelMBean;
+
+public class LoggingExceptionTest {
+ private static final String tests[] = new String[] {
+ "DescriptorSupport()",
+ "DescriptorSupport(int)",
+ "DescriptorSupport(String)",
+ "DescriptorSupport(String...)",
+ "DescriptorSupport(String[], Object[])",
+ "DescriptorSupport(DescriptorSupport)",
+ "RequiredModelMBean.addAttributeChangeNotificationListener",
+ };
+ public static void main(String[] args) {
+ Handler handler = new ConsoleHandler();
+ Logger logger = Logger.getLogger("javax.management.modelmbean");
+ logger.addHandler(handler);
+ logger.setLevel(Level.FINEST);
+ try {
+ for (int i = 0; i < tests.length; i++) {
+ System.out.println(">>> DescriptorSupportLoggingTest: Test Case " + i);
+ DescriptorSupport ds;
+ String msg = "Instantiate " + tests[i];
+ System.out.println(msg);
+ switch (i) {
+ case 0:
+ ds = new DescriptorSupport();
+ break;
+ case 1:
+ ds = new DescriptorSupport(10);
+ break;
+ case 2:
+ ds = new DescriptorSupport(new DescriptorSupport().toXMLString());
+ break;
+ case 3:
+ ds = new DescriptorSupport("name1=value1", "name2=value2");
+ break;
+ case 4:
+ ds = new DescriptorSupport(new String[] {"name"}, new Object[] {"value"});
+ break;
+ case 5:
+ ds = new DescriptorSupport(new DescriptorSupport());
+ break;
+ case 6:
+ RequiredModelMBean mbean = new RequiredModelMBean();
+ NotificationListener nl = new NotificationListener() {
+ public void handleNotification(Notification notification,
+ Object handback) {}
+ };
+ mbean.addAttributeChangeNotificationListener(nl, null, null);
+ break;
+ default:
+ throw new AssertionError();
+ }
+ System.out.println(msg + " OK");
+ }
+ } catch (Exception e) {
+ System.out.println("Got unexpected exception = " + e);
+ String msg = "Test FAILED!";
+ System.out.println(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ System.out.println("Test PASSED!");
+ }
+}