“03897f251dc40ae3ded98a84caa3b40fed164de9”上不存在“paddle/fluid/operators/mul_op.cc”
提交 3394b8ed 编写于 作者: L lana

Merge

#
# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# Copyright year for beginning of Java and some of the apis
# (Needed when creating the javadocs)
FIRST_COPYRIGHT_YEAR = 1993
DOMAPI_FIRST_COPYRIGHT_YEAR = 2005
MIRROR_FIRST_COPYRIGHT_YEAR = 2004
DOCLETAPI_FIRST_COPYRIGHT_YEAR = 1993
TAGLETAPI_FIRST_COPYRIGHT_YEAR = 1993
JDI_FIRST_COPYRIGHT_YEAR = 1999
JAAS_FIRST_COPYRIGHT_YEAR = 1998
JGSS_FIRST_COPYRIGHT_YEAR = 2000
SMARTCARDIO_FIRST_COPYRIGHT_YEAR = 2005
HTTPSERVER_FIRST_COPYRIGHT_YEAR = 2005
MGMT_FIRST_COPYRIGHT_YEAR = 2003
ATTACH_FIRST_COPYRIGHT_YEAR = 2005
JCONSOLE_FIRST_COPYRIGHT_YEAR = 2006
SCTPAPI_FIRST_COPYRIGHT_YEAR = 2009
TRACING_FIRST_COPYRIGHT_YEAR = 2008
TREEAPI_FIRST_COPYRIGHT_YEAR = 2005
JNLP_FIRST_COPYRIGHT_YEAR = 1998
PLUGIN2_FIRST_COPYRIGHT_YEAR = 2007
# Oracle name
COMPANY_NAME = Oracle and/or its affiliates
# Copyright address
COMPANY_ADDRESS = 500 Oracle Parkway<br>Redwood Shores, CA 94065 USA.
# The trademark symbol
TRADEMARK = &trade;
# Common copyright lines used
# The word "Copyright" might optionally be a link to the file cpyr.html.
# The first year of copyright may vary or not be available.
# The address to the company might be optional.
COMMA:= ,
EMPTY:=
SPACE:=$(EMPTY) $(EMPTY)
COPYRIGHT_SYMBOL = &\#x00a9;
# Macros to handle the optional empty args.
# (The GNU make 3.78.1 "if" conditional is broken, fixed in GNU make 3.81)
define OptionalCopyrightUrl # url
$(shell \
if [ "$1" != "" ] ; then \
printf "<a href=\"%s\">Copyright</a>" "$1"; \
else \
printf "Copyright"; \
fi)
endef
define OptionalCopyrightFirstYear # year
$(shell \
if [ "$1" != "" ] ; then \
printf "%s," "$1";\
fi)
endef
define OptionalCompanyAddress # address
$(shell \
if [ "$1" != "" ] ; then \
printf "%s" "$1";\
fi)
endef
define CopyrightLine # optionalurl optionalfirstyear optionaladdress
$(call OptionalCopyrightUrl,$1) $(COPYRIGHT_SYMBOL)\
$(call OptionalCopyrightFirstYear,$2) $(COPYRIGHT_YEAR),\
$(COMPANY_NAME).\
$(call OptionalCompanyAddress,$3)\
All rights reserved.
endef
...@@ -230,7 +230,8 @@ endif ...@@ -230,7 +230,8 @@ endif
# Compilers, SDK, and Visual Studio (MSDEV) [32bit is different from 64bit] # Compilers, SDK, and Visual Studio (MSDEV) [32bit is different from 64bit]
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
# Try looking in MSVCDIR or MSVCDir area first (set by vcvars32.bat) # Try looking in MSVCDIR or MSVCDir area first
# (set by vcvars32.bat for VC .NET, not defined in the VC 2008/2010)
ifdef MSVCDIR ifdef MSVCDIR
xMSVCDIR :="$(subst \,/,$(MSVCDIR))" xMSVCDIR :="$(subst \,/,$(MSVCDIR))"
_msvc_dir :=$(call FullPath,$(xMSVCDIR)) _msvc_dir :=$(call FullPath,$(xMSVCDIR))
...@@ -238,11 +239,6 @@ ifeq ($(ARCH_DATA_MODEL), 32) ...@@ -238,11 +239,6 @@ ifeq ($(ARCH_DATA_MODEL), 32)
ifdef MSVCDir ifdef MSVCDir
xMSVCDIR :="$(subst \,/,$(MSVCDir))" xMSVCDIR :="$(subst \,/,$(MSVCDir))"
_msvc_dir :=$(call FullPath,$(xMSVCDIR)) _msvc_dir :=$(call FullPath,$(xMSVCDIR))
else
ifneq ($(_program_files),)
xMSVCDIR :="$(_program_files)/Microsoft Visual Studio .NET 2003/Vc7"
_msvc_dir :=$(call FullPath,$(xMSVCDIR))
endif
endif endif
endif endif
# If we still don't have it, look for VSnnCOMNTOOLS (newest first), # If we still don't have it, look for VSnnCOMNTOOLS (newest first),
......
此差异已折叠。
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
# #
JAVA_JAVA_java = \ JAVA_JAVA_java = \
java/lang/Object.java \ java/lang/Object.java \
java/lang/AutoCloseable.java \
java/lang/Class.java \ java/lang/Class.java \
java/lang/Thread.java \ java/lang/Thread.java \
java/lang/Character.java \ java/lang/Character.java \
......
# #
# Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1996, 2010 Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -62,6 +62,11 @@ POLICY_BUILD = $(LIBDIR)/security/java.policy ...@@ -62,6 +62,11 @@ POLICY_BUILD = $(LIBDIR)/security/java.policy
CACERTS_SRC = $(CACERTS_FILE) CACERTS_SRC = $(CACERTS_FILE)
CACERTS_BUILD = $(LIBDIR)/security/cacerts CACERTS_BUILD = $(LIBDIR)/security/cacerts
ifndef OPENJDK
BLACKLIST_SRC = $(CLOSED_SHARE_SRC)/lib/security/blacklist
BLACKLIST_BUILD = $(LIBDIR)/security/blacklist
endif
FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class) FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class)
# #
...@@ -69,7 +74,11 @@ FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class) ...@@ -69,7 +74,11 @@ FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class)
# #
include $(BUILDDIR)/common/Rules.gmk include $(BUILDDIR)/common/Rules.gmk
ifdef OPENJDK
build: properties policy cacerts build: properties policy cacerts
else
build: properties policy cacerts blacklist
endif
install: all install: all
...@@ -79,6 +88,8 @@ policy: classes $(POLICY_BUILD) ...@@ -79,6 +88,8 @@ policy: classes $(POLICY_BUILD)
cacerts: classes $(CACERTS_BUILD) cacerts: classes $(CACERTS_BUILD)
blacklist: classes $(BLACKLIST_BUILD)
$(PROPS_BUILD): $(PROPS_SRC) $(PROPS_BUILD): $(PROPS_SRC)
$(install-file) $(install-file)
...@@ -88,9 +99,12 @@ $(POLICY_BUILD): $(POLICY_SRC) ...@@ -88,9 +99,12 @@ $(POLICY_BUILD): $(POLICY_SRC)
$(CACERTS_BUILD): $(CACERTS_SRC) $(CACERTS_BUILD): $(CACERTS_SRC)
$(install-file) $(install-file)
$(BLACKLIST_BUILD): $(BLACKLIST_SRC)
$(install-file)
clean clobber:: .delete.classlist clean clobber:: .delete.classlist
$(RM) -r $(CLASSBINDIR)/java/security $(RM) -r $(CLASSBINDIR)/java/security
$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD)
# Additional Rule for building sun.security.util # Additional Rule for building sun.security.util
$(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java $(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java
......
...@@ -46,11 +46,11 @@ nbproject: ...@@ -46,11 +46,11 @@ nbproject:
$(RM) -r $(DEMODIR)/nbproject $(RM) -r $(DEMODIR)/nbproject
$(MKDIR) -p $(DEMODIR) $(MKDIR) -p $(DEMODIR)
( $(CD) $(SHARE_SRC)/demo && $(TAR) -cf - \ ( $(CD) $(SHARE_SRC)/demo && $(TAR) -cf - \
`find nbproject $(SCM_DIRS_prune) -o -type f -print` ) | \ `$(FIND) nbproject $(SCM_DIRS_prune) -o -type f -print` ) | \
( $(CD) $(DEMODIR) && $(TAR) -xf - ) ( $(CD) $(DEMODIR) && $(TAR) -xf - )
ifndef OPENJDK ifndef OPENJDK
( $(CD) $(CLOSED_SHARE_SRC)/demo && $(TAR) -cf - \ ( $(CD) $(CLOSED_SHARE_SRC)/demo && $(TAR) -cf - \
`find nbproject $(SCM_DIRS_prune) -o -type f -print` ) | \ `$(FIND) nbproject $(SCM_DIRS_prune) -o -type f -print` ) | \
( $(CD) $(DEMODIR) && $(TAR) -xf - ) ( $(CD) $(DEMODIR) && $(TAR) -xf - )
endif endif
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
* combine with an argument list of files and directories, and * combine with an argument list of files and directories, and
* write a list of items to be included in a jar file. * write a list of items to be included in a jar file.
*/ */
package build.tools.jarreorder; package build.tools.jarreorder;
import java.io.BufferedReader; import java.io.BufferedReader;
...@@ -36,74 +35,68 @@ import java.io.File; ...@@ -36,74 +35,68 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Vector;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class JarReorder { public class JarReorder {
// To deal with output // To deal with output
private static PrintStream out; private PrintStream out;
private final static boolean useTopDir = false;
private static void usage() { private void usage() {
String help; String help;
help = help =
"Usage: jar JarReorder [-o <outputfile>] <order_list> <exclude_list> <file> ...\n" "Usage: jar JarReorder [-o <outputfile>] <order_list> <exclude_list> <file> ...\n"
+ " order_list is a file containing names of files to load\n" + " order_list is a file containing names of files to load\n"
+ " in order at the end of a jar file.\n" + " in order at the end of a jar file unless\n"
+ " exclude_list is a file containing names of files/directories\n" + " excluded in the exclude list.\n"
+ " NOT to be included in a jar file.\n"; + " exclude_list is a file containing names of files/directories\n"
if (useTopDir) + " NOT to be included in a jar file.\n"
help += + "\n"
" top_dir is the top of the directory structure to be searched;\n" + "The order_list or exclude_list may be replaced by a \"-\" if no\n"
+ " the contents of the lists and remaining arguments are\n" + "data is to be provided.\n"
+ " relative to this.\n"; + "\n"
help += + " The remaining arguments are files or directories to be included\n"
"\n" + " in a jar file, from which will be excluded those entries which\n"
+ "The order_list or exclude_list may be replaced by a \"_\" if no\n" + " appear in the exclude list.\n";
+ "data is to be provided.\n"
+ "\n"
+ " The remaining arguments are files or directories to be included\n"
+ " in a jar file, from which will be excluded thse entries which\n"
+ " appear in the exclude list.\n";
System.err.println(help); System.err.println(help);
System.exit(1);
} }
/* /*
* Create a list of files to be included in a jar file, such that the * Create the file list to be included in a jar file, such that the
* some the files will appear in a specific order, and allowing certain * list will appear in a specific order, and allowing certain
* files and directories to be excluded. * files and directories to be excluded.
* *
* Command line arguments are * Command path arguments are
* - optional -o outputfile * - optional -o outputfile
* - name of a file containing a list of files to be included in a jar file. * - name of a file containing a set of files to be included in a jar file.
* - name of a file containing a list of files (or directories) to be * - name of a file containing a set of files (or directories) to be
* excluded from the jar file. * excluded from the jar file.
* - names of files or directories to be searched for files to include * - names of files or directories to be searched for files to include
* in the jar file. * in the jar file.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
JarReorder jr = new JarReorder();
jr.run(args);
}
private void run(String args[]) {
HashMap filesExcluded = new HashMap();
Vector filesIncluded = new Vector();
int fileArgs;
String topDirName = "";
int arglen = args.length; int arglen = args.length;
int argpos = 0; int argpos = 0;
// Look for "-o outputfilename" option // Look for "-o outputfilename" option
if ( arglen > 0 ) { if (arglen > 0) {
if ( arglen >= 2 && args[0].equals("-o") ) { if (arglen >= 2 && args[0].equals("-o")) {
try { try {
out = new PrintStream(new FileOutputStream(args[1])); out = new PrintStream(new FileOutputStream(args[1]));
} catch ( FileNotFoundException e ) { } catch (FileNotFoundException e) {
System.err.println("Error: " + e.getMessage()); System.err.println("Error: " + e.getMessage());
e.printStackTrace(System.err); e.printStackTrace(System.err);
System.exit(1); System.exit(1);
...@@ -118,128 +111,111 @@ public class JarReorder { ...@@ -118,128 +111,111 @@ public class JarReorder {
out = System.out; out = System.out;
} }
fileArgs = useTopDir ? 3 : 2; // Should be 2 or more args left
if (arglen <= 2) {
if (arglen <= fileArgs) {
usage(); usage();
System.exit(1);
} }
// Read the ordered list of files to be included in rt.jar. // Read the ordered set of files to be included in rt.jar.
// Read the list of files/directories to be excluded from rt.jar. // Read the set of files/directories to be excluded from rt.jar.
String classListFile = args[argpos];
String excludeListFile = args[argpos + 1];
argpos += 2;
arglen -= 2;
Vector orderList = readListFromFile(args[argpos], true); // Create 2 lists and a set of processed files
Vector excludeList = readListFromFile(args[argpos+1], false); List<String> orderList = readListFromFile(classListFile, true);
if (useTopDir) { List<String> excludeList = readListFromFile(excludeListFile, false);
topDirName = args[argpos+2]; Set<String> processed = new HashSet<String>();
if (!topDirName.endsWith(File.separator))
topDirName = topDirName + File.separator;
}
// Copy these lists into filesExcluded so that these files will be excluded // Create set of all files and directories excluded, then expand
// from the file list. (The orderList files will be appended later.) // that list completely
Set<String> excludeSet = new HashSet<String>(excludeList);
Set<String> allFilesExcluded = expand(null, excludeSet, processed);
for (int i = 0; i < orderList.size(); ++i) { // Indicate all these have been processed, orderList too, kept to end.
String s = (String) orderList.elementAt(i); processed.addAll(orderList);
filesExcluded.put(s, s);
}
for (int i = 0; i < excludeList.size(); ++i) {
String s = (String) excludeList.elementAt(i);
filesExcluded.put(s, s);
}
// The remaining arguments are names of files/directories to be included // The remaining arguments are names of files/directories to be included
// in the jar file. // in the jar file.
Set<String> inputSet = new HashSet<String>();
String[] files = new String[arglen - fileArgs]; for (int i = 0; i < arglen; ++i) {
for (int i = fileArgs; i < arglen; ++i) { String name = args[argpos + i];
files[i-fileArgs] = args[argpos+i]; name = cleanPath(new File(name));
filesExcluded.put(args[argpos+i], args[argpos+i]); if ( name != null && name.length() > 0 && !inputSet.contains(name) ) {
inputSet.add(name);
}
} }
// Expand file/directory list to file list excluding those // Expand file/directory input so we get a complete set (except ordered)
// read from the class list. // Should be everything not excluded and not in order list.
Set<String> allFilesIncluded = expand(null, inputSet, processed);
if (useTopDir) // Create simple sorted list so we can add ordered items at end.
expand(new File(topDirName), files, filesIncluded, filesExcluded, topDirName); List<String> allFiles = new ArrayList<String>(allFilesIncluded);
else Collections.sort(allFiles);
expand(null, files, filesIncluded, filesExcluded, null);
// Now add the ordered list to the end of the expanded list. // Now add the ordered set to the end of the list.
// Add in REVERSE ORDER, so that the first element is closest to // Add in REVERSE ORDER, so that the first element is closest to
// the end (and the index). // the end (and the index).
HashSet excludeSet = new HashSet(excludeList);
for (int i = orderList.size() - 1; i >= 0; --i) { for (int i = orderList.size() - 1; i >= 0; --i) {
String s = (String) orderList.elementAt(i); String s = orderList.get(i);
if (excludeSet.contains(s)) { if (allFilesExcluded.contains(s)) {
System.err.println("Included file " + s + " is also excluded, skipping."); System.err.println("Included order file " + s
continue; + " is also excluded, skipping.");
} else if (new File(s).exists()) {
allFiles.add(s);
} else {
System.err.println("Included order file " + s
+ " missing, skipping.");
} }
if (new File(topDirName + s).exists())
filesIncluded.addElement(s);
else
System.err.println("Included file "+s+" missing, skipping.");
} }
// Print results. // Print final results.
for (String str : allFiles) {
for (int i = 0; i < filesIncluded.size(); ++i) { out.println(str);
if (useTopDir) {
out.print("-C ");
out.print(topDirName);
out.print(" ");
}
out.println((String)filesIncluded.elementAt(i));
} }
out.flush(); out.flush();
out.close(); out.close();
} }
/* /*
* Read a file containing a list of files into a Vector. * Read a file containing a list of files and directories into a List.
*/ */
private static Vector readListFromFile(String fileName, private List<String> readListFromFile(String fileName,
boolean addClassSuffix) { boolean addClassSuffix) {
BufferedReader br = null; BufferedReader br = null;
Vector v = new Vector(2000); List<String> list = new ArrayList<String>();
// If you see "-" for the name, just assume nothing was provided.
if ("-".equals(fileName)) if ("-".equals(fileName)) {
return v; return list;
}
try { try {
br = new BufferedReader(new FileReader(fileName)); br = new BufferedReader(new FileReader(fileName));
// Read the input file a path at a time. # in column 1 is a comment.
// Read the input file a line at a time. # in column 1 is a comment.
while (true) { while (true) {
String line = null; String path = br.readLine();
line = br.readLine(); if (path == null) {
if (line == null)
break; break;
}
if (line.length() == 0 || // Look for comments
line.charAt(0) == '#') path = path.trim();
if (path.length() == 0
|| path.charAt(0) == '#') {
continue; continue;
// Convert forward or back slashes to the type expected for
// the current platform.
if (File.separatorChar == '/')
line = line.replace('\\', '/');
else
line = line.replace('/', '\\');
line = line.trim();
if (addClassSuffix) {
if (!line.endsWith(".class")) {
line = line + ".class";
}
} }
v.addElement(line); // Add trailing .class if necessary
if (addClassSuffix && !path.endsWith(".class")) {
path = path + ".class";
}
// Normalize the path
path = cleanPath(new File(path));
// Add to list
if (path != null && path.length() > 0 && !list.contains(path)) {
list.add(path);
}
} }
br.close(); br.close();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
...@@ -249,68 +225,89 @@ public class JarReorder { ...@@ -249,68 +225,89 @@ public class JarReorder {
e.printStackTrace(); e.printStackTrace();
System.exit(2); System.exit(2);
} }
return v; return list;
} }
/* /*
* Expands list of files to process into full list of all files that * Expands inputSet (files or dirs) into full set of all files that
* can be found by recursively descending directories. * can be found by recursively descending directories.
* @param dir root directory
* @param inputSet set of files or dirs to look into
* @param processed files or dirs already processed
* @return set of files
*/ */
private static void expand(File dir, String[] files, private Set<String> expand(File dir,
Vector includedFiles, HashMap excludedFiles, Set<String> inputSet,
String topDirName) { Set<String> processed) {
if (files == null) { Set<String> includedFiles = new HashSet<String>();
return; if (inputSet.isEmpty()) {
return includedFiles;
} }
for (int i = 0; i < files.length; i++) { for (String name : inputSet) {
File f = (dir == null) ? new File(files[i]) // Depending on start location
: new File(dir, files[i]); File f = (dir == null) ? new File(name)
if (f.isFile()) { : new File(dir, name);
String filePath = f.getPath(); // Normalized path to use
String path = cleanPath(f);
if (useTopDir) { if (path != null && path.length() > 0
if (filePath.startsWith(topDirName)) && !processed.contains(path)) {
filePath = filePath.substring(topDirName.length()); if (f.isFile()) {
} // Not in the excludeList, add it to both lists
includedFiles.add(path);
if (filePath.length() >= 2 && processed.add(path);
filePath.charAt(0) == '.' && } else if (f.isDirectory()) {
filePath.charAt(1) == File.separatorChar) // Add the directory entries
filePath = filePath.substring(2); String[] dirList = f.list();
Set<String> dirInputSet = new HashSet<String>();
if (!excludedFiles.containsKey(filePath)) { for (String x : dirList) {
excludedFiles.put(filePath, filePath); dirInputSet.add(x);
includedFiles.addElement(filePath); }
} // Process all entries in this directory
} else if (f.isDirectory()) { Set<String> subList = expand(f, dirInputSet, processed);
String dirPath = f.getPath(); includedFiles.addAll(subList);
dirPath = (dirPath.endsWith(File.separator)) ? dirPath : processed.add(path);
(dirPath + File.separator);
if (useTopDir) {
if (dirPath.startsWith(topDirName))
dirPath = dirPath.substring(topDirName.length());
} }
}
}
return includedFiles;
}
if (dirPath.length() >= 2 && private String cleanPath(File f) {
dirPath.charAt(0) == '.' && String path = f.getPath();
dirPath.charAt(1) == File.separatorChar) if (f.isFile()) {
dirPath = dirPath.substring(2); path = cleanFilePath(path);
} else if (f.isDirectory()) {
if (!excludedFiles.containsKey(dirPath)) { path = cleanDirPath(path);
} else {
System.err.println("WARNING: Path does not exist as file or directory: " + path);
path = null;
}
return path;
}
// Sort the directory list so that entries in the jar file private String cleanFilePath(String path) {
// are in a repeatable order. The order itself is not particularly // Remove leading and trailing whitespace
// important. [File.list() is unpredictable.] path = path.trim();
// Make all / and \ chars one
if (File.separatorChar == '/') {
path = path.replace('\\', '/');
} else {
path = path.replace('/', '\\');
}
// Remove leading ./
if (path.startsWith("." + File.separator)) {
path = path.substring(2);
}
return path;
}
String[] dirList = f.list(); private String cleanDirPath(String path) {
Arrays.sort(dirList); path = cleanFilePath(path);
expand(f, dirList, includedFiles, excludedFiles, topDirName); // Make sure it ends with a file separator
} if (!path.endsWith(File.separator)) {
} else { path = path + File.separator;
System.err.println("Error accessing: " + f.getPath());
}
} }
return path;
} }
} }
/* /*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define JVM_ERROR1 "Error: Could not create the Java Virtual Machine.\n" GEN_ERROR #define JVM_ERROR1 "Error: Could not create the Java Virtual Machine.\n" GEN_ERROR
#define JVM_ERROR2 "Error: Could not detach main thread.\n" JNI_ERROR #define JVM_ERROR2 "Error: Could not detach main thread.\n" JNI_ERROR
#define JVM_ERROR3 "Error: SPARC V8 processor detected; Server compiler requires V9 or better.\nUse Client compiler on V8 processors.\nCould not create the Java virtual machine." #define JVM_ERROR3 "Error: SPARC V8 processor detected; Required V9 processors or better.\nUse JDK5 client compiler for V8 processors.\n" JVM_ERROR1
#define JAR_ERROR1 "Error: Failed to load Main-Class manifest attribute from\n%s\n%s" #define JAR_ERROR1 "Error: Failed to load Main-Class manifest attribute from\n%s\n%s"
#define JAR_ERROR2 "Error: Unable to access jarfile %s" #define JAR_ERROR2 "Error: Unable to access jarfile %s"
...@@ -69,7 +69,8 @@ ...@@ -69,7 +69,8 @@
#define CFG_ERROR5 "Error: Could not determine application home." #define CFG_ERROR5 "Error: Could not determine application home."
#define CFG_ERROR6 "Error: could not open `%s'" #define CFG_ERROR6 "Error: could not open `%s'"
#define CFG_ERROR7 "Error: no known VMs. (check for corrupt jvm.cfg file)" #define CFG_ERROR7 "Error: no known VMs. (check for corrupt jvm.cfg file)"
#define CFG_ERROR8 "Error: no `%s' JVM at `%s'." #define CFG_ERROR8 "Error: missing `%s' JVM at `%s'.\nPlease install or use the JRE or JDK that contains these missing components."
#define CFG_ERROR9 "Error: could not determine JVM type."
#define SPC_ERROR1 "Error: Syntax error in version specification \"%s\"" #define SPC_ERROR1 "Error: Syntax error in version specification \"%s\""
......
/* /*
* Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -192,8 +192,8 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -192,8 +192,8 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
int ret; int ret;
InvocationFunctions ifn; InvocationFunctions ifn;
jlong start, end; jlong start, end;
char jrepath[MAXPATHLEN], jvmpath[MAXPATHLEN]; char jvmpath[MAXPATHLEN];
char ** original_argv = argv; char jrepath[MAXPATHLEN];
_fVersion = fullversion; _fVersion = fullversion;
_dVersion = dotversion; _dVersion = dotversion;
...@@ -225,14 +225,17 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -225,14 +225,17 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
*/ */
SelectVersion(argc, argv, &main_class); SelectVersion(argc, argv, &main_class);
/* copy original argv */ if (JLI_IsTraceLauncher()) {
JLI_TraceLauncher("Command line Args:\n"); int i;
original_argv = (JLI_CopyArgs(argc, (const char**)argv)); printf("Command line args:\n");
for (i = 0; i < argc ; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
}
CreateExecutionEnvironment(&argc, &argv, CreateExecutionEnvironment(&argc, &argv,
jrepath, sizeof(jrepath), jrepath, sizeof(jrepath),
jvmpath, sizeof(jvmpath), jvmpath, sizeof(jvmpath));
original_argv);
ifn.CreateJavaVM = 0; ifn.CreateJavaVM = 0;
ifn.GetDefaultJavaVMInitArgs = 0; ifn.GetDefaultJavaVMInitArgs = 0;
...@@ -301,22 +304,43 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */ ...@@ -301,22 +304,43 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
return ContinueInNewThread(&ifn, argc, argv, jarfile, classname, ret); return ContinueInNewThread(&ifn, argc, argv, jarfile, classname, ret);
} }
/*
* Always detach the main thread so that it appears to have ended when
* the application's main method exits. This will invoke the
* uncaught exception handler machinery if main threw an
* exception. An uncaught exception handler cannot change the
* launcher's return code except by calling System.exit.
*
* Wait for all non-daemon threads to end, then destroy the VM.
* This will actually create a trivial new Java waiter thread
* named "DestroyJavaVM", but this will be seen as a different
* thread from the one that executed main, even though they are
* the same C thread. This allows mainThread.join() and
* mainThread.isAlive() to work as expected.
*/
#define LEAVE() \
if ((*vm)->DetachCurrentThread(vm) != 0) { \
JLI_ReportErrorMessage(JVM_ERROR2); \
ret = 1; \
} \
(*vm)->DestroyJavaVM(vm); \
return ret \
#define CHECK_EXCEPTION_NULL_LEAVE(e) \ #define CHECK_EXCEPTION_NULL_LEAVE(e) \
if ((*env)->ExceptionOccurred(env)) { \ if ((*env)->ExceptionOccurred(env)) { \
JLI_ReportExceptionDescription(env); \ JLI_ReportExceptionDescription(env); \
goto leave; \ LEAVE(); \
} \ } \
if ((e) == NULL) { \ if ((e) == NULL) { \
JLI_ReportErrorMessage(JNI_ERROR); \ JLI_ReportErrorMessage(JNI_ERROR); \
goto leave; \ LEAVE(); \
} }
#define CHECK_EXCEPTION_LEAVE(rv) \ #define CHECK_EXCEPTION_LEAVE(rv) \
if ((*env)->ExceptionOccurred(env)) { \ if ((*env)->ExceptionOccurred(env)) { \
JLI_ReportExceptionDescription(env); \ JLI_ReportExceptionDescription(env); \
ret = (rv); \ ret = (rv); \
goto leave; \ LEAVE(); \
} }
int JNICALL int JNICALL
...@@ -349,8 +373,7 @@ JavaMain(void * _args) ...@@ -349,8 +373,7 @@ JavaMain(void * _args)
PrintJavaVersion(env, showVersion); PrintJavaVersion(env, showVersion);
CHECK_EXCEPTION_LEAVE(0); CHECK_EXCEPTION_LEAVE(0);
if (printVersion) { if (printVersion) {
ret = 0; LEAVE();
goto leave;
} }
} }
...@@ -358,7 +381,7 @@ JavaMain(void * _args) ...@@ -358,7 +381,7 @@ JavaMain(void * _args)
if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) { if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
PrintUsage(env, printXUsage); PrintUsage(env, printXUsage);
CHECK_EXCEPTION_LEAVE(1); CHECK_EXCEPTION_LEAVE(1);
goto leave; LEAVE();
} }
FreeKnownVMs(); /* after last possible PrintUsage() */ FreeKnownVMs(); /* after last possible PrintUsage() */
...@@ -430,30 +453,7 @@ JavaMain(void * _args) ...@@ -430,30 +453,7 @@ JavaMain(void * _args)
* System.exit) will be non-zero if main threw an exception. * System.exit) will be non-zero if main threw an exception.
*/ */
ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1; ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
LEAVE();
leave:
/*
* Always detach the main thread so that it appears to have ended when
* the application's main method exits. This will invoke the
* uncaught exception handler machinery if main threw an
* exception. An uncaught exception handler cannot change the
* launcher's return code except by calling System.exit.
*/
if ((*vm)->DetachCurrentThread(vm) != 0) {
JLI_ReportErrorMessage(JVM_ERROR2);
ret = 1;
}
/*
* Wait for all non-daemon threads to end, then destroy the VM.
* This will actually create a trivial new Java waiter thread
* named "DestroyJavaVM", but this will be seen as a different
* thread from the one that executed main, even though they are
* the same C thread. This allows mainThread.join() and
* mainThread.isAlive() to work as expected.
*/
(*vm)->DestroyJavaVM(vm);
return ret;
} }
/* /*
...@@ -1076,15 +1076,17 @@ ParseArguments(int *pargc, char ***pargv, char **pjarfile, ...@@ -1076,15 +1076,17 @@ ParseArguments(int *pargc, char ***pargv, char **pjarfile,
if (--argc >= 0) { if (--argc >= 0) {
if (jarflag) { if (jarflag) {
*pjarfile = *argv++; *pjarfile = *argv++;
*pclassname = 0; *pclassname = NULL;
} else { } else {
*pjarfile = 0; *pjarfile = NULL;
*pclassname = *argv++; *pclassname = *argv++;
} }
*pargc = argc; *pargc = argc;
*pargv = argv; *pargv = argv;
} }
if (*pjarfile == NULL && *pclassname == NULL) {
*pret = 1;
}
return JNI_TRUE; return JNI_TRUE;
} }
......
/* /*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -114,13 +114,19 @@ GetApplicationHome(char *buf, jint bufsize); ...@@ -114,13 +114,19 @@ GetApplicationHome(char *buf, jint bufsize);
#define GetArch() GetArchPath(CURRENT_DATA_MODEL) #define GetArch() GetArchPath(CURRENT_DATA_MODEL)
void CreateExecutionEnvironment(int *_argc, /*
char ***_argv, * Different platforms will implement this, here
char jrepath[], * pargc is a pointer to the original argc,
jint so_jrepath, * pargv is a pointer to the original argv,
char jvmpath[], * jrepath is an accessible path to the jre as determined by the call
jint so_jvmpath, * so_jrepath is the length of the buffer jrepath
char **original_argv); * jvmpath is an accessible path to the jvm as determined by the call
* so_jvmpath is the length of the buffer jvmpath
*/
void CreateExecutionEnvironment(int *argc, char ***argv,
char *jrepath, jint so_jrepath,
char *jvmpath, jint so_jvmpath);
/* Reports an error message to stderr or a window as appropriate. */ /* Reports an error message to stderr or a window as appropriate. */
void JLI_ReportErrorMessage(const char * message, ...); void JLI_ReportErrorMessage(const char * message, ...);
......
/* /*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -84,23 +84,6 @@ JLI_MemFree(void *ptr) ...@@ -84,23 +84,6 @@ JLI_MemFree(void *ptr)
free(ptr); free(ptr);
} }
/*
* Makes a copy of arguments
*/
char**
JLI_CopyArgs(int argc, const char **iargv)
{
int i;
char** oargv = (char**)JLI_MemAlloc(sizeof(char*)*(argc+1));
for (i = 0 ; i < argc+1 ; i++) {
oargv[i] = (iargv[i] == NULL) ? NULL : JLI_StringDup(iargv[i]);
if (iargv[i] != NULL && JLI_IsTraceLauncher() == JNI_TRUE) {
printf("\targv[%d] = '%s'\n",i,iargv[i]);
}
}
return oargv;
}
/* /*
* debug helpers we use * debug helpers we use
*/ */
......
/* /*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,7 +33,6 @@ void *JLI_MemAlloc(size_t size); ...@@ -33,7 +33,6 @@ void *JLI_MemAlloc(size_t size);
void *JLI_MemRealloc(void *ptr, size_t size); void *JLI_MemRealloc(void *ptr, size_t size);
char *JLI_StringDup(const char *s1); char *JLI_StringDup(const char *s1);
void JLI_MemFree(void *ptr); void JLI_MemFree(void *ptr);
char **JLI_CopyArgs(int argc, const char **iargv);
int JLI_StrCCmp(const char *s1, const char* s2); int JLI_StrCCmp(const char *s1, const char* s2);
...@@ -56,10 +55,12 @@ int JLI_StrCCmp(const char *s1, const char* s2); ...@@ -56,10 +55,12 @@ int JLI_StrCCmp(const char *s1, const char* s2);
#include <io.h> #include <io.h>
#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2)) #define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3)) #define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3))
#define JLI_Snprintf _snprintf
#else #else
#include <unistd.h> #include <unistd.h>
#define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2)) #define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2))
#define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3)) #define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3))
#define JLI_Snprintf snprintf
#endif /* _WIN32 */ #endif /* _WIN32 */
/* /*
......
/* /*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -39,7 +39,7 @@ class InstanceFinder<T> { ...@@ -39,7 +39,7 @@ class InstanceFinder<T> {
private final Class<? extends T> type; private final Class<? extends T> type;
private final boolean allow; private final boolean allow;
private final String suffix; private final String suffix;
private String[] packages; private volatile String[] packages;
InstanceFinder(Class<? extends T> type, boolean allow, String suffix, String... packages) { InstanceFinder(Class<? extends T> type, boolean allow, String suffix, String... packages) {
this.type = type; this.type = type;
...@@ -49,9 +49,7 @@ class InstanceFinder<T> { ...@@ -49,9 +49,7 @@ class InstanceFinder<T> {
} }
public String[] getPackages() { public String[] getPackages() {
return (this.packages.length > 0) return this.packages.clone();
? this.packages.clone()
: this.packages;
} }
public void setPackages(String... packages) { public void setPackages(String... packages) {
......
/* /*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -118,7 +118,7 @@ public final class MethodFinder extends AbstractFinder<Method> { ...@@ -118,7 +118,7 @@ public final class MethodFinder extends AbstractFinder<Method> {
* @throws NoSuchMethodException if method is not accessible or is not found * @throws NoSuchMethodException if method is not accessible or is not found
* in specified superclass or interface * in specified superclass or interface
*/ */
private static Method findAccessibleMethod(Method method) throws NoSuchMethodException { public static Method findAccessibleMethod(Method method) throws NoSuchMethodException {
Class<?> type = method.getDeclaringClass(); Class<?> type = method.getDeclaringClass();
if (Modifier.isPublic(type.getModifiers())) { if (Modifier.isPublic(type.getModifiers())) {
return method; return method;
......
/* /*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -47,17 +47,22 @@ public final class PersistenceDelegateFinder ...@@ -47,17 +47,22 @@ public final class PersistenceDelegateFinder
} }
public void register(Class<?> type, PersistenceDelegate delegate) { public void register(Class<?> type, PersistenceDelegate delegate) {
if (delegate != null) { synchronized (this.registry) {
this.registry.put(type, delegate); if (delegate != null) {
} this.registry.put(type, delegate);
else { }
this.registry.remove(type); else {
this.registry.remove(type);
}
} }
} }
@Override @Override
public PersistenceDelegate find(Class<?> type) { public PersistenceDelegate find(Class<?> type) {
PersistenceDelegate delegate = this.registry.get(type); PersistenceDelegate delegate;
synchronized (this.registry) {
delegate = this.registry.get(type);
}
return (delegate != null) ? delegate : super.find(type); return (delegate != null) ? delegate : super.find(type);
} }
} }
/* /*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -64,12 +64,18 @@ public final class PropertyEditorFinder ...@@ -64,12 +64,18 @@ public final class PropertyEditorFinder
} }
public void register(Class<?> type, Class<?> editor) { public void register(Class<?> type, Class<?> editor) {
this.registry.put(type, editor); synchronized (this.registry) {
this.registry.put(type, editor);
}
} }
@Override @Override
public PropertyEditor find(Class<?> type) { public PropertyEditor find(Class<?> type) {
PropertyEditor editor = instantiate(this.registry.get(type), null); Class<?> predefined;
synchronized (this.registry) {
predefined = this.registry.get(type);
}
PropertyEditor editor = instantiate(predefined, null);
if (editor == null) { if (editor == null) {
editor = super.find(type); editor = super.find(type);
if ((editor == null) && (null != type.getEnumConstants())) { if ((editor == null) && (null != type.getEnumConstants())) {
......
...@@ -1440,10 +1440,6 @@ class GTKPainter extends SynthPainter { ...@@ -1440,10 +1440,6 @@ class GTKPainter extends SynthPainter {
} }
} }
public Insets getBorderInsets(Component c) {
return getBorderInsets(c, null);
}
public Insets getBorderInsets(Component c, Insets i) { public Insets getBorderInsets(Component c, Insets i) {
SynthContext context = getContext(c); SynthContext context = getContext(c);
......
/* /*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -271,7 +271,9 @@ public class MotifFileChooserUI extends BasicFileChooserUI { ...@@ -271,7 +271,9 @@ public class MotifFileChooserUI extends BasicFileChooserUI {
} }
public void uninstallUI(JComponent c) { public void uninstallUI(JComponent c) {
getFileChooser().removeAll(); c.removePropertyChangeListener(filterComboBoxModel);
approveButton.removeActionListener(getApproveSelectionAction());
filenameTextField.removeActionListener(getApproveSelectionAction());
super.uninstallUI(c); super.uninstallUI(c);
} }
...@@ -515,6 +517,7 @@ public class MotifFileChooserUI extends BasicFileChooserUI { ...@@ -515,6 +517,7 @@ public class MotifFileChooserUI extends BasicFileChooserUI {
public void uninstallComponents(JFileChooser fc) { public void uninstallComponents(JFileChooser fc) {
fc.removeAll(); fc.removeAll();
bottomPanel = null;
if (filterComboBoxModel != null) { if (filterComboBoxModel != null) {
fc.removePropertyChangeListener(filterComboBoxModel); fc.removePropertyChangeListener(filterComboBoxModel);
} }
......
...@@ -61,85 +61,43 @@ import sun.awt.EventQueueDelegate; ...@@ -61,85 +61,43 @@ import sun.awt.EventQueueDelegate;
* @since 1.1 * @since 1.1
*/ */
class EventDispatchThread extends Thread { class EventDispatchThread extends Thread {
private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread"); private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventDispatchThread");
private EventQueue theQueue; private EventQueue theQueue;
private boolean doDispatch = true; private boolean doDispatch = true;
private boolean threadDeathCaught = false;
private static final int ANY_EVENT = -1; private static final int ANY_EVENT = -1;
private Vector<EventFilter> eventFilters = new Vector<EventFilter>(); private Vector<EventFilter> eventFilters = new Vector<EventFilter>();
// used in handleException
private int modalFiltersCount = 0;
EventDispatchThread(ThreadGroup group, String name, EventQueue queue) { EventDispatchThread(ThreadGroup group, String name, EventQueue queue) {
super(group, name); super(group, name);
theQueue = queue; setEventQueue(queue);
}
void stopDispatchingImpl(boolean wait) {
// Note: We stop dispatching via a flag rather than using
// Thread.interrupt() because we can't guarantee that the wait()
// we interrupt will be EventQueue.getNextEvent()'s. -fredx 8-11-98
StopDispatchEvent stopEvent = new StopDispatchEvent();
// wait for the dispatcher to complete
if (Thread.currentThread() != this) {
// fix 4122683, 4128923
// Post an empty event to ensure getNextEvent is unblocked
//
// We have to use postEventPrivate instead of postEvent because
// EventQueue.pop calls EventDispatchThread.stopDispatching.
// Calling SunToolkit.flushPendingEvents in this case could
// lead to deadlock.
theQueue.postEventPrivate(stopEvent);
if (wait) {
try {
join();
} catch(InterruptedException e) {
}
}
} else {
stopEvent.dispatch();
}
theQueue.detachDispatchThread(this, false);
} }
/*
* Must be called on EDT only, that's why no synchronization
*/
public void stopDispatching() { public void stopDispatching() {
stopDispatchingImpl(true); doDispatch = false;
}
public void stopDispatchingLater() {
stopDispatchingImpl(false);
}
class StopDispatchEvent extends AWTEvent implements ActiveEvent {
/*
* serialVersionUID
*/
static final long serialVersionUID = -3692158172100730735L;
public StopDispatchEvent() {
super(EventDispatchThread.this,0);
}
public void dispatch() {
doDispatch = false;
}
} }
public void run() { public void run() {
try { while (true) {
pumpEvents(new Conditional() { try {
public boolean evaluate() { pumpEvents(new Conditional() {
return true; public boolean evaluate() {
return true;
}
});
} finally {
EventQueue eq = getEventQueue();
if (eq.detachDispatchThread(this) || threadDeathCaught) {
break;
} }
}); }
} finally {
theQueue.detachDispatchThread(this, true);
} }
} }
...@@ -190,7 +148,6 @@ class EventDispatchThread extends Thread { ...@@ -190,7 +148,6 @@ class EventDispatchThread extends Thread {
} }
} }
eventFilters.add(k, filter); eventFilters.add(k, filter);
modalFiltersCount++;
} else { } else {
eventFilters.add(filter); eventFilters.add(filter);
} }
...@@ -200,28 +157,25 @@ class EventDispatchThread extends Thread { ...@@ -200,28 +157,25 @@ class EventDispatchThread extends Thread {
void removeEventFilter(EventFilter filter) { void removeEventFilter(EventFilter filter) {
synchronized (eventFilters) { synchronized (eventFilters) {
if (eventFilters.contains(filter)) { eventFilters.remove(filter);
if (filter instanceof ModalEventFilter) {
modalFiltersCount--;
}
eventFilters.remove(filter);
}
} }
} }
boolean pumpOneEventForFilters(int id) { boolean pumpOneEventForFilters(int id) {
AWTEvent event = null;
boolean eventOK = false;
try { try {
AWTEvent event; EventQueue eq = null;
boolean eventOK; EventQueueDelegate.Delegate delegate = null;
EventQueueDelegate.Delegate delegate =
EventQueueDelegate.getDelegate();
do { do {
// EventQueue may change during the dispatching
eq = getEventQueue();
delegate = EventQueueDelegate.getDelegate();
if (delegate != null && id == ANY_EVENT) { if (delegate != null && id == ANY_EVENT) {
event = delegate.getNextEvent(theQueue); event = delegate.getNextEvent(eq);
} else { } else {
event = (id == ANY_EVENT) event = (id == ANY_EVENT) ? eq.getNextEvent() : eq.getNextEvent(id);
? theQueue.getNextEvent()
: theQueue.getNextEvent(id);
} }
eventOK = true; eventOK = true;
...@@ -252,13 +206,15 @@ class EventDispatchThread extends Thread { ...@@ -252,13 +206,15 @@ class EventDispatchThread extends Thread {
if (delegate != null) { if (delegate != null) {
handle = delegate.beforeDispatch(event); handle = delegate.beforeDispatch(event);
} }
theQueue.dispatchEvent(event); eq.dispatchEvent(event);
if (delegate != null) { if (delegate != null) {
delegate.afterDispatch(event, handle); delegate.afterDispatch(event, handle);
} }
return true; return true;
} }
catch (ThreadDeath death) { catch (ThreadDeath death) {
threadDeathCaught = true;
return false; return false;
} }
...@@ -267,12 +223,10 @@ class EventDispatchThread extends Thread { ...@@ -267,12 +223,10 @@ class EventDispatchThread extends Thread {
// Threads in the AppContext // Threads in the AppContext
} }
// Can get and throw only unchecked exceptions catch (Throwable e) {
catch (RuntimeException e) {
processException(e);
} catch (Error e) {
processException(e); processException(e);
} }
return true; return true;
} }
...@@ -281,14 +235,14 @@ class EventDispatchThread extends Thread { ...@@ -281,14 +235,14 @@ class EventDispatchThread extends Thread {
eventLog.fine("Processing exception: " + e); eventLog.fine("Processing exception: " + e);
} }
getUncaughtExceptionHandler().uncaughtException(this, e); getUncaughtExceptionHandler().uncaughtException(this, e);
// don't rethrow the exception to avoid EDT recreation
} }
boolean isDispatching(EventQueue eq) { public synchronized EventQueue getEventQueue() {
return theQueue.equals(eq); return theQueue;
}
public synchronized void setEventQueue(EventQueue eq) {
theQueue = eq;
} }
EventQueue getEventQueue() { return theQueue; }
private static class HierarchyEventFilter implements EventFilter { private static class HierarchyEventFilter implements EventFilter {
private Component modalComponent; private Component modalComponent;
......
...@@ -138,6 +138,15 @@ public class EventQueue { ...@@ -138,6 +138,15 @@ public class EventQueue {
private final Lock pushPopLock; private final Lock pushPopLock;
private final Condition pushPopCond; private final Condition pushPopCond;
/*
* Dummy runnable to wake up EDT from getNextEvent() after
push/pop is performed
*/
private final static Runnable dummyRunnable = new Runnable() {
public void run() {
}
};
private EventDispatchThread dispatchThread; private EventDispatchThread dispatchThread;
private final ThreadGroup threadGroup = private final ThreadGroup threadGroup =
...@@ -219,22 +228,22 @@ public class EventQueue { ...@@ -219,22 +228,22 @@ public class EventQueue {
* @param theEvent an instance of <code>java.awt.AWTEvent</code>, * @param theEvent an instance of <code>java.awt.AWTEvent</code>,
* or a subclass of it * or a subclass of it
*/ */
final void postEventPrivate(AWTEvent theEvent) { private final void postEventPrivate(AWTEvent theEvent) {
theEvent.isPosted = true; theEvent.isPosted = true;
pushPopLock.lock(); pushPopLock.lock();
try { try {
if (dispatchThread == null && nextQueue == null) { if (nextQueue != null) {
// Forward the event to the top of EventQueue stack
nextQueue.postEventPrivate(theEvent);
return;
}
if (dispatchThread == null) {
if (theEvent.getSource() == AWTAutoShutdown.getInstance()) { if (theEvent.getSource() == AWTAutoShutdown.getInstance()) {
return; return;
} else { } else {
initDispatchThread(); initDispatchThread();
} }
} }
if (nextQueue != null) {
// Forward event to top of EventQueue stack.
nextQueue.postEventPrivate(theEvent);
return;
}
postEvent(theEvent, getPriority(theEvent)); postEvent(theEvent, getPriority(theEvent));
} finally { } finally {
pushPopLock.unlock(); pushPopLock.unlock();
...@@ -242,29 +251,20 @@ public class EventQueue { ...@@ -242,29 +251,20 @@ public class EventQueue {
} }
private static int getPriority(AWTEvent theEvent) { private static int getPriority(AWTEvent theEvent) {
if (theEvent instanceof PeerEvent && if (theEvent instanceof PeerEvent) {
(((PeerEvent)theEvent).getFlags() & PeerEvent peerEvent = (PeerEvent)theEvent;
PeerEvent.ULTIMATE_PRIORITY_EVENT) != 0) if ((peerEvent.getFlags() & PeerEvent.ULTIMATE_PRIORITY_EVENT) != 0) {
{ return ULTIMATE_PRIORITY;
return ULTIMATE_PRIORITY; }
} if ((peerEvent.getFlags() & PeerEvent.PRIORITY_EVENT) != 0) {
return HIGH_PRIORITY;
if (theEvent instanceof PeerEvent && }
(((PeerEvent)theEvent).getFlags() & if ((peerEvent.getFlags() & PeerEvent.LOW_PRIORITY_EVENT) != 0) {
PeerEvent.PRIORITY_EVENT) != 0) return LOW_PRIORITY;
{ }
return HIGH_PRIORITY;
}
if (theEvent instanceof PeerEvent &&
(((PeerEvent)theEvent).getFlags() &
PeerEvent.LOW_PRIORITY_EVENT) != 0)
{
return LOW_PRIORITY;
} }
int id = theEvent.getID(); int id = theEvent.getID();
if (id == PaintEvent.PAINT || id == PaintEvent.UPDATE) { if ((id >= PaintEvent.PAINT_FIRST) && (id <= PaintEvent.PAINT_LAST)) {
return LOW_PRIORITY; return LOW_PRIORITY;
} }
return NORM_PRIORITY; return NORM_PRIORITY;
...@@ -501,16 +501,9 @@ public class EventQueue { ...@@ -501,16 +501,9 @@ public class EventQueue {
SunToolkit.flushPendingEvents(); SunToolkit.flushPendingEvents();
pushPopLock.lock(); pushPopLock.lock();
try { try {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) { AWTEvent event = getNextEventPrivate();
if (queues[i].head != null) { if (event != null) {
EventQueueItem entry = queues[i].head; return event;
queues[i].head = entry.next;
if (entry.next == null) {
queues[i].tail = null;
}
uncacheEQItem(entry);
return entry.event;
}
} }
AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread); AWTAutoShutdown.getInstance().notifyThreadFree(dispatchThread);
pushPopCond.await(); pushPopCond.await();
...@@ -520,6 +513,24 @@ public class EventQueue { ...@@ -520,6 +513,24 @@ public class EventQueue {
} while(true); } while(true);
} }
/*
* Must be called under the lock. Doesn't call flushPendingEvents()
*/
AWTEvent getNextEventPrivate() throws InterruptedException {
for (int i = NUM_PRIORITIES - 1; i >= 0; i--) {
if (queues[i].head != null) {
EventQueueItem entry = queues[i].head;
queues[i].head = entry.next;
if (entry.next == null) {
queues[i].tail = null;
}
uncacheEQItem(entry);
return entry.event;
}
}
return null;
}
AWTEvent getNextEvent(int id) throws InterruptedException { AWTEvent getNextEvent(int id) throws InterruptedException {
do { do {
/* /*
...@@ -659,7 +670,9 @@ public class EventQueue { ...@@ -659,7 +670,9 @@ public class EventQueue {
dispatchThread.stopDispatching(); dispatchThread.stopDispatching();
} }
} else { } else {
System.err.println("unable to dispatch event: " + event); if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Unable to dispatch event: " + event);
}
} }
} }
...@@ -761,15 +774,23 @@ public class EventQueue { ...@@ -761,15 +774,23 @@ public class EventQueue {
pushPopLock.lock(); pushPopLock.lock();
try { try {
EventQueue toPush = this; EventQueue topQueue = this;
while (toPush.nextQueue != null) { while (topQueue.nextQueue != null) {
toPush = toPush.nextQueue; topQueue = topQueue.nextQueue;
}
if ((topQueue.dispatchThread != null) &&
(topQueue.dispatchThread.getEventQueue() == this))
{
newEventQueue.dispatchThread = topQueue.dispatchThread;
topQueue.dispatchThread.setEventQueue(newEventQueue);
} }
// Transfer all events forward to new EventQueue. // Transfer all events forward to new EventQueue.
while (toPush.peekEvent() != null) { while (topQueue.peekEvent() != null) {
try { try {
newEventQueue.postEventPrivate(toPush.getNextEvent()); // Use getNextEventPrivate() as it doesn't call flushPendingEvents()
newEventQueue.postEventPrivate(topQueue.getNextEventPrivate());
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
if (eventLog.isLoggable(PlatformLogger.FINE)) { if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Interrupted push", ie); eventLog.fine("Interrupted push", ie);
...@@ -777,28 +798,21 @@ public class EventQueue { ...@@ -777,28 +798,21 @@ public class EventQueue {
} }
} }
newEventQueue.previousQueue = toPush; // Wake up EDT waiting in getNextEvent(), so it can
// pick up a new EventQueue. Post the waking event before
/* // topQueue.nextQueue is assigned, otherwise the event would
* Stop the event dispatch thread associated with the currently // go newEventQueue
* active event queue, so that after the new queue is pushed topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
* on the top this event dispatch thread won't prevent AWT from
* being automatically shut down.
* Use stopDispatchingLater() to avoid deadlock: stopDispatching()
* waits for the dispatch thread to exit, which in turn waits
* for the lock in EQ.detachDispatchThread(), which is hold by
* this method.
*/
if (toPush.dispatchThread != null) {
toPush.dispatchThread.stopDispatchingLater();
}
toPush.nextQueue = newEventQueue; newEventQueue.previousQueue = topQueue;
topQueue.nextQueue = newEventQueue;
AppContext appContext = AppContext.getAppContext(); AppContext appContext = AppContext.getAppContext();
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == toPush) { if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue); appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
} }
pushPopCond.signalAll();
} finally { } finally {
pushPopLock.unlock(); pushPopLock.unlock();
} }
...@@ -822,44 +836,51 @@ public class EventQueue { ...@@ -822,44 +836,51 @@ public class EventQueue {
eventLog.fine("EventQueue.pop(" + this + ")"); eventLog.fine("EventQueue.pop(" + this + ")");
} }
EventDispatchThread dt = null;
pushPopLock.lock(); pushPopLock.lock();
try { try {
EventQueue toPop = this; EventQueue topQueue = this;
while (toPop.nextQueue != null) { while (topQueue.nextQueue != null) {
toPop = toPop.nextQueue; topQueue = topQueue.nextQueue;
} }
EventQueue prev = toPop.previousQueue; EventQueue prevQueue = topQueue.previousQueue;
if (prev == null) { if (prevQueue == null) {
throw new EmptyStackException(); throw new EmptyStackException();
} }
toPop.previousQueue = null;
topQueue.previousQueue = null;
prevQueue.nextQueue = null;
// Transfer all events back to previous EventQueue. // Transfer all events back to previous EventQueue.
prev.nextQueue = null; while (topQueue.peekEvent() != null) {
while (toPop.peekEvent() != null) {
try { try {
prev.postEventPrivate(toPop.getNextEvent()); prevQueue.postEventPrivate(topQueue.getNextEventPrivate());
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
if (eventLog.isLoggable(PlatformLogger.FINE)) { if (eventLog.isLoggable(PlatformLogger.FINE)) {
eventLog.fine("Interrupted pop", ie); eventLog.fine("Interrupted pop", ie);
} }
} }
} }
if ((topQueue.dispatchThread != null) &&
(topQueue.dispatchThread.getEventQueue() == this))
{
prevQueue.dispatchThread = topQueue.dispatchThread;
topQueue.dispatchThread.setEventQueue(prevQueue);
}
AppContext appContext = AppContext.getAppContext(); AppContext appContext = AppContext.getAppContext();
if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) { if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
appContext.put(AppContext.EVENT_QUEUE_KEY, prev); appContext.put(AppContext.EVENT_QUEUE_KEY, prevQueue);
} }
dt = toPop.dispatchThread; // Wake up EDT waiting in getNextEvent(), so it can
// pick up a new EventQueue
topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
pushPopCond.signalAll();
} finally { } finally {
pushPopLock.unlock(); pushPopLock.unlock();
} }
if (dt != null) {
dt.stopDispatching(); // Must be done outside synchronized
// block to avoid possible deadlock
}
} }
/** /**
...@@ -907,9 +928,9 @@ public class EventQueue { ...@@ -907,9 +928,9 @@ public class EventQueue {
try { try {
AppContext appContext = AppContext.getAppContext(); AppContext appContext = AppContext.getAppContext();
if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) {
dispatchThread = (EventDispatchThread) dispatchThread = AccessController.doPrivileged(
AccessController.doPrivileged(new PrivilegedAction() { new PrivilegedAction<EventDispatchThread>() {
public Object run() { public EventDispatchThread run() {
EventDispatchThread t = EventDispatchThread t =
new EventDispatchThread(threadGroup, new EventDispatchThread(threadGroup,
name, name,
...@@ -919,7 +940,8 @@ public class EventQueue { ...@@ -919,7 +940,8 @@ public class EventQueue {
t.setDaemon(false); t.setDaemon(false);
return t; return t;
} }
}); }
);
AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread); AWTAutoShutdown.getInstance().notifyThreadBusy(dispatchThread);
dispatchThread.start(); dispatchThread.start();
} }
...@@ -928,7 +950,7 @@ public class EventQueue { ...@@ -928,7 +950,7 @@ public class EventQueue {
} }
} }
final void detachDispatchThread(EventDispatchThread edt, boolean restart) { final boolean detachDispatchThread(EventDispatchThread edt) {
/* /*
* This synchronized block is to secure that the event dispatch * This synchronized block is to secure that the event dispatch
* thread won't die in the middle of posting a new event to the * thread won't die in the middle of posting a new event to the
...@@ -939,26 +961,21 @@ public class EventQueue { ...@@ -939,26 +961,21 @@ public class EventQueue {
*/ */
pushPopLock.lock(); pushPopLock.lock();
try { try {
EventDispatchThread oldDispatchThread = dispatchThread; if (edt == dispatchThread) {
if (dispatchThread == edt) {
dispatchThread = null;
}
if (restart) {
/* /*
* Event dispatch thread dies in case of an uncaught exception. * Don't detach the thread if any events are pending. Not
* A new event dispatch thread for this queue will be started * sure if it's a possible scenario, though.
* only if a new event is posted to it. In case if no more
* events are posted after this thread died all events that
* currently are in the queue will never be dispatched.
* *
* Fix for 4648733. Check both the associated java event * Fix for 4648733. Check both the associated java event
* queue and the PostEventQueue. * queue and the PostEventQueue.
*/ */
if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) { if ((peekEvent() != null) || !SunToolkit.isPostEventQueueEmpty()) {
initDispatchThread(); return false;
} }
AWTAutoShutdown.getInstance().notifyThreadFree(oldDispatchThread); dispatchThread = null;
} }
AWTAutoShutdown.getInstance().notifyThreadFree(edt);
return true;
} finally { } finally {
pushPopLock.unlock(); pushPopLock.unlock();
} }
......
...@@ -194,13 +194,8 @@ public class Encoder { ...@@ -194,13 +194,8 @@ public class Encoder {
* @see java.beans.BeanInfo#getBeanDescriptor * @see java.beans.BeanInfo#getBeanDescriptor
*/ */
public PersistenceDelegate getPersistenceDelegate(Class<?> type) { public PersistenceDelegate getPersistenceDelegate(Class<?> type) {
synchronized (this.finder) { PersistenceDelegate pd = this.finder.find(type);
PersistenceDelegate pd = this.finder.find(type); return (pd != null) ? pd : MetaData.getPersistenceDelegate(type);
if (pd != null) {
return pd;
}
}
return MetaData.getPersistenceDelegate(type);
} }
/** /**
...@@ -214,9 +209,7 @@ public class Encoder { ...@@ -214,9 +209,7 @@ public class Encoder {
* @see java.beans.BeanInfo#getBeanDescriptor * @see java.beans.BeanInfo#getBeanDescriptor
*/ */
public void setPersistenceDelegate(Class<?> type, PersistenceDelegate delegate) { public void setPersistenceDelegate(Class<?> type, PersistenceDelegate delegate) {
synchronized (this.finder) { this.finder.register(type, delegate);
this.finder.register(type, delegate);
}
} }
/** /**
......
...@@ -27,6 +27,7 @@ package java.beans; ...@@ -27,6 +27,7 @@ package java.beans;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/** /**
* An EventSetDescriptor describes a group of events that a given Java * An EventSetDescriptor describes a group of events that a given Java
...@@ -175,10 +176,8 @@ public class EventSetDescriptor extends FeatureDescriptor { ...@@ -175,10 +176,8 @@ public class EventSetDescriptor extends FeatureDescriptor {
setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1)); setRemoveListenerMethod(getMethod(sourceClass, removeListenerMethodName, 1));
// Be more forgiving of not finding the getListener method. // Be more forgiving of not finding the getListener method.
Method method = Introspector.findMethod(sourceClass, if (getListenerMethodName != null) {
getListenerMethodName, 0); setGetListenerMethod(Introspector.findInstanceMethod(sourceClass, getListenerMethodName));
if (method != null) {
setGetListenerMethod(method);
} }
} }
...@@ -188,7 +187,7 @@ public class EventSetDescriptor extends FeatureDescriptor { ...@@ -188,7 +187,7 @@ public class EventSetDescriptor extends FeatureDescriptor {
return null; return null;
} }
Method method = Introspector.findMethod(cls, name, args); Method method = Introspector.findMethod(cls, name, args);
if (method == null) { if ((method == null) || Modifier.isStatic(method.getModifiers())) {
throw new IntrospectionException("Method not found: " + name + throw new IntrospectionException("Method not found: " + name +
" on class " + cls.getName()); " on class " + cls.getName());
} }
......
...@@ -189,16 +189,11 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { ...@@ -189,16 +189,11 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor {
indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
} }
} }
indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
Class[] args = { int.class };
indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName,
1, args);
if (indexedReadMethod == null) { if (indexedReadMethod == null) {
// no "is" method, so look for a "get" method. // no "is" method, so look for a "get" method.
indexedReadMethodName = Introspector.GET_PREFIX + getBaseName(); indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, indexedReadMethod = Introspector.findInstanceMethod(cls, indexedReadMethodName, int.class);
1, args);
} }
setIndexedReadMethod0(indexedReadMethod); setIndexedReadMethod0(indexedReadMethod);
} }
...@@ -270,8 +265,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor { ...@@ -270,8 +265,7 @@ public class IndexedPropertyDescriptor extends PropertyDescriptor {
if (indexedWriteMethodName == null) { if (indexedWriteMethodName == null) {
indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName(); indexedWriteMethodName = Introspector.SET_PREFIX + getBaseName();
} }
indexedWriteMethod = Introspector.findMethod(cls, indexedWriteMethodName, indexedWriteMethod = Introspector.findInstanceMethod(cls, indexedWriteMethodName, int.class, type);
2, (type == null) ? null : new Class[] { int.class, type });
if (indexedWriteMethod != null) { if (indexedWriteMethod != null) {
if (!indexedWriteMethod.getReturnType().equals(void.class)) { if (!indexedWriteMethod.getReturnType().equals(void.class)) {
indexedWriteMethod = null; indexedWriteMethod = null;
......
...@@ -28,6 +28,7 @@ package java.beans; ...@@ -28,6 +28,7 @@ package java.beans;
import com.sun.beans.WeakCache; import com.sun.beans.WeakCache;
import com.sun.beans.finder.BeanInfoFinder; import com.sun.beans.finder.BeanInfoFinder;
import com.sun.beans.finder.ClassFinder; import com.sun.beans.finder.ClassFinder;
import com.sun.beans.finder.MethodFinder;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
...@@ -157,21 +158,23 @@ public class Introspector { ...@@ -157,21 +158,23 @@ public class Introspector {
if (!ReflectUtil.isPackageAccessible(beanClass)) { if (!ReflectUtil.isPackageAccessible(beanClass)) {
return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
} }
Map<Class<?>, BeanInfo> beanInfoCache;
BeanInfo beanInfo;
synchronized (BEANINFO_CACHE) { synchronized (BEANINFO_CACHE) {
Map<Class<?>, BeanInfo> beanInfoCache = beanInfoCache = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
(Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
if (beanInfoCache == null) { if (beanInfoCache == null) {
beanInfoCache = new WeakHashMap<Class<?>, BeanInfo>(); beanInfoCache = new WeakHashMap<Class<?>, BeanInfo>();
AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache); AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
} }
BeanInfo beanInfo = beanInfoCache.get(beanClass); beanInfo = beanInfoCache.get(beanClass);
if (beanInfo == null) { }
beanInfo = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); if (beanInfo == null) {
beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo();
synchronized (BEANINFO_CACHE) {
beanInfoCache.put(beanClass, beanInfo); beanInfoCache.put(beanClass, beanInfo);
} }
return beanInfo;
} }
return beanInfo;
} }
/** /**
...@@ -301,10 +304,7 @@ public class Introspector { ...@@ -301,10 +304,7 @@ public class Introspector {
*/ */
public static String[] getBeanInfoSearchPath() { public static String[] getBeanInfoSearchPath() {
BeanInfoFinder finder = getFinder(); return getFinder().getPackages();
synchronized (finder) {
return finder.getPackages();
}
} }
/** /**
...@@ -328,10 +328,7 @@ public class Introspector { ...@@ -328,10 +328,7 @@ public class Introspector {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
BeanInfoFinder finder = getFinder(); getFinder().setPackages(path);
synchronized (finder) {
finder.setPackages(path);
}
} }
...@@ -453,10 +450,7 @@ public class Introspector { ...@@ -453,10 +450,7 @@ public class Introspector {
* @return Instance of an explicit BeanInfo class or null if one isn't found. * @return Instance of an explicit BeanInfo class or null if one isn't found.
*/ */
private static BeanInfo findExplicitBeanInfo(Class beanClass) { private static BeanInfo findExplicitBeanInfo(Class beanClass) {
BeanInfoFinder finder = getFinder(); return getFinder().find(beanClass);
synchronized (finder) {
return finder.find(beanClass);
}
} }
/** /**
...@@ -849,8 +843,8 @@ public class Introspector { ...@@ -849,8 +843,8 @@ public class Introspector {
Method read = result.getReadMethod(); Method read = result.getReadMethod();
if (read == null && write != null) { if (read == null && write != null) {
read = findMethod(result.getClass0(), read = findInstanceMethod(result.getClass0(),
GET_PREFIX + NameGenerator.capitalize(result.getName()), 0); GET_PREFIX + NameGenerator.capitalize(result.getName()));
if (read != null) { if (read != null) {
try { try {
result.setReadMethod(read); result.setReadMethod(read);
...@@ -860,9 +854,9 @@ public class Introspector { ...@@ -860,9 +854,9 @@ public class Introspector {
} }
} }
if (write == null && read != null) { if (write == null && read != null) {
write = findMethod(result.getClass0(), write = findInstanceMethod(result.getClass0(),
SET_PREFIX + NameGenerator.capitalize(result.getName()), 1, SET_PREFIX + NameGenerator.capitalize(result.getName()),
new Class[] { FeatureDescriptor.getReturnType(result.getClass0(), read) }); FeatureDescriptor.getReturnType(result.getClass0(), read));
if (write != null) { if (write != null) {
try { try {
result.setWriteMethod(write); result.setWriteMethod(write);
...@@ -1286,90 +1280,27 @@ public class Introspector { ...@@ -1286,90 +1280,27 @@ public class Introspector {
// Package private support methods. // Package private support methods.
//====================================================================== //======================================================================
/** static Method findMethod(Class<?> type, String name, int args) {
* Internal support for finding a target methodName with a given for (Method method : type.getMethods()) {
* parameter list on a given class. if (method.getName().equals(name) && (args == method.getParameterTypes().length)) {
*/ try {
private static Method internalFindMethod(Class start, String methodName, return MethodFinder.findAccessibleMethod(method);
int argCount, Class args[]) {
// For overriden methods we need to find the most derived version.
// So we start with the given class and walk up the superclass chain.
Method method = null;
for (Class cl = start; cl != null; cl = cl.getSuperclass()) {
Method methods[] = getPublicDeclaredMethods(cl);
for (int i = 0; i < methods.length; i++) {
method = methods[i];
if (method == null) {
continue;
} }
catch (NoSuchMethodException exception) {
// make sure method signature matches. // continue search for a method with the specified count of parameters
Class params[] = FeatureDescriptor.getParameterTypes(start, method);
if (method.getName().equals(methodName) &&
params.length == argCount) {
if (args != null) {
boolean different = false;
if (argCount > 0) {
for (int j = 0; j < argCount; j++) {
if (params[j] != args[j]) {
different = true;
continue;
}
}
if (different) {
continue;
}
}
}
return method;
} }
} }
} }
method = null; return null;
// Now check any inherited interfaces. This is necessary both when
// the argument class is itself an interface, and when the argument
// class is an abstract class.
Class ifcs[] = start.getInterfaces();
for (int i = 0 ; i < ifcs.length; i++) {
// Note: The original implementation had both methods calling
// the 3 arg method. This is preserved but perhaps it should
// pass the args array instead of null.
method = internalFindMethod(ifcs[i], methodName, argCount, null);
if (method != null) {
break;
}
}
return method;
}
/**
* Find a target methodName on a given class.
*/
static Method findMethod(Class cls, String methodName, int argCount) {
return findMethod(cls, methodName, argCount, null);
} }
/** static Method findInstanceMethod(Class<?> type, String name, Class<?>... args) {
* Find a target methodName with specific parameter list on a given class. try {
* <p> return MethodFinder.findInstanceMethod(type, name, args);
* Used in the contructors of the EventSetDescriptor, }
* PropertyDescriptor and the IndexedPropertyDescriptor. catch (NoSuchMethodException exception) {
* <p>
* @param cls The Class object on which to retrieve the method.
* @param methodName Name of the method.
* @param argCount Number of arguments for the desired method.
* @param args Array of argument types for the method.
* @return the method or null if not found
*/
static Method findMethod(Class cls, String methodName, int argCount,
Class args[]) {
if (methodName == null) {
return null; return null;
} }
return internalFindMethod(cls, methodName, argCount, args);
} }
/** /**
......
...@@ -82,21 +82,21 @@ public class MethodDescriptor extends FeatureDescriptor { ...@@ -82,21 +82,21 @@ public class MethodDescriptor extends FeatureDescriptor {
Method method = getMethod0(); Method method = getMethod0();
if (method == null) { if (method == null) {
Class cls = getClass0(); Class cls = getClass0();
if (cls != null) { String name = getName();
if ((cls != null) && (name != null)) {
Class[] params = getParams(); Class[] params = getParams();
if (params == null) { if (params == null) {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
// Find methods for up to 2 params. We are guessing here. // Find methods for up to 2 params. We are guessing here.
// This block should never execute unless the classloader // This block should never execute unless the classloader
// that loaded the argument classes disappears. // that loaded the argument classes disappears.
method = Introspector.findMethod(cls, getName(), i, null); method = Introspector.findMethod(cls, name, i);
if (method != null) { if (method != null) {
break; break;
} }
} }
} else { } else {
method = Introspector.findMethod(cls, getName(), method = Statement.getMethod(cls, name, params);
params.length, params);
} }
setMethod(method); setMethod(method);
} }
......
...@@ -112,9 +112,7 @@ public class PropertyDescriptor extends FeatureDescriptor { ...@@ -112,9 +112,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
// If this class or one of its base classes allow PropertyChangeListener, // If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound". // then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method. // See Introspector.getTargetPropertyInfo() method.
String name = "addPropertyChangeListener"; this.bound = null != Introspector.findInstanceMethod(beanClass, "addPropertyChangeListener", PropertyChangeListener.class);
Class[] args = {PropertyChangeListener.class};
this.bound = (null != Introspector.findMethod(beanClass, name, args.length, args));
} }
/** /**
...@@ -225,10 +223,10 @@ public class PropertyDescriptor extends FeatureDescriptor { ...@@ -225,10 +223,10 @@ public class PropertyDescriptor extends FeatureDescriptor {
// property type is. For booleans, there can be "is" and "get" // property type is. For booleans, there can be "is" and "get"
// methods. If an "is" method exists, this is the official // methods. If an "is" method exists, this is the official
// reader method so look for this one first. // reader method so look for this one first.
readMethod = Introspector.findMethod(cls, readMethodName, 0); readMethod = Introspector.findInstanceMethod(cls, readMethodName);
if (readMethod == null) { if (readMethod == null) {
readMethodName = Introspector.GET_PREFIX + getBaseName(); readMethodName = Introspector.GET_PREFIX + getBaseName();
readMethod = Introspector.findMethod(cls, readMethodName, 0); readMethod = Introspector.findInstanceMethod(cls, readMethodName);
} }
try { try {
setReadMethod(readMethod); setReadMethod(readMethod);
...@@ -293,8 +291,7 @@ public class PropertyDescriptor extends FeatureDescriptor { ...@@ -293,8 +291,7 @@ public class PropertyDescriptor extends FeatureDescriptor {
writeMethodName = Introspector.SET_PREFIX + getBaseName(); writeMethodName = Introspector.SET_PREFIX + getBaseName();
} }
writeMethod = Introspector.findMethod(cls, writeMethodName, 1, writeMethod = Introspector.findInstanceMethod(cls, writeMethodName, type);
(type == null) ? null : new Class[] { type });
if (writeMethod != null) { if (writeMethod != null) {
if (!writeMethod.getReturnType().equals(void.class)) { if (!writeMethod.getReturnType().equals(void.class)) {
writeMethod = null; writeMethod = null;
......
/* /*
* Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -81,10 +81,7 @@ public class PropertyEditorManager { ...@@ -81,10 +81,7 @@ public class PropertyEditorManager {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
PropertyEditorFinder finder = getFinder(); getFinder().register(targetType, editorClass);
synchronized (finder) {
finder.register(targetType, editorClass);
}
} }
/** /**
...@@ -95,10 +92,7 @@ public class PropertyEditorManager { ...@@ -95,10 +92,7 @@ public class PropertyEditorManager {
* The result is null if no suitable editor can be found. * The result is null if no suitable editor can be found.
*/ */
public static PropertyEditor findEditor(Class<?> targetType) { public static PropertyEditor findEditor(Class<?> targetType) {
PropertyEditorFinder finder = getFinder(); return getFinder().find(targetType);
synchronized (finder) {
return finder.find(targetType);
}
} }
/** /**
...@@ -110,10 +104,7 @@ public class PropertyEditorManager { ...@@ -110,10 +104,7 @@ public class PropertyEditorManager {
* e.g. Sun implementation initially sets to {"sun.beans.editors"}. * e.g. Sun implementation initially sets to {"sun.beans.editors"}.
*/ */
public static String[] getEditorSearchPath() { public static String[] getEditorSearchPath() {
PropertyEditorFinder finder = getFinder(); return getFinder().getPackages();
synchronized (finder) {
return finder.getPackages();
}
} }
/** /**
...@@ -134,10 +125,7 @@ public class PropertyEditorManager { ...@@ -134,10 +125,7 @@ public class PropertyEditorManager {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
PropertyEditorFinder finder = getFinder(); getFinder().setPackages(path);
synchronized (finder) {
finder.setPackages(path);
}
} }
private static PropertyEditorFinder getFinder() { private static PropertyEditorFinder getFinder() {
......
...@@ -60,7 +60,7 @@ import org.xml.sax.helpers.DefaultHandler; ...@@ -60,7 +60,7 @@ import org.xml.sax.helpers.DefaultHandler;
* *
* @author Philip Milne * @author Philip Milne
*/ */
public class XMLDecoder { public class XMLDecoder implements AutoCloseable {
private final DocumentHandler handler = new DocumentHandler(); private final DocumentHandler handler = new DocumentHandler();
private final InputSource input; private final InputSource input;
private Object owner; private Object owner;
......
...@@ -204,7 +204,7 @@ import java.nio.charset.UnsupportedCharsetException; ...@@ -204,7 +204,7 @@ import java.nio.charset.UnsupportedCharsetException;
* *
* @author Philip Milne * @author Philip Milne
*/ */
public class XMLEncoder extends Encoder { public class XMLEncoder extends Encoder implements AutoCloseable {
private final CharsetEncoder encoder; private final CharsetEncoder encoder;
private final String charset; private final String charset;
......
...@@ -41,51 +41,39 @@ class Bits { ...@@ -41,51 +41,39 @@ class Bits {
} }
static char getChar(byte[] b, int off) { static char getChar(byte[] b, int off) {
return (char) (((b[off + 1] & 0xFF) << 0) + return (char) ((b[off + 1] & 0xFF) +
((b[off + 0]) << 8)); (b[off] << 8));
} }
static short getShort(byte[] b, int off) { static short getShort(byte[] b, int off) {
return (short) (((b[off + 1] & 0xFF) << 0) + return (short) ((b[off + 1] & 0xFF) +
((b[off + 0]) << 8)); (b[off] << 8));
} }
static int getInt(byte[] b, int off) { static int getInt(byte[] b, int off) {
return ((b[off + 3] & 0xFF) << 0) + return ((b[off + 3] & 0xFF) ) +
((b[off + 2] & 0xFF) << 8) + ((b[off + 2] & 0xFF) << 8) +
((b[off + 1] & 0xFF) << 16) + ((b[off + 1] & 0xFF) << 16) +
((b[off + 0]) << 24); ((b[off ] ) << 24);
} }
static float getFloat(byte[] b, int off) { static float getFloat(byte[] b, int off) {
int i = ((b[off + 3] & 0xFF) << 0) + return Float.intBitsToFloat(getInt(b, off));
((b[off + 2] & 0xFF) << 8) +
((b[off + 1] & 0xFF) << 16) +
((b[off + 0]) << 24);
return Float.intBitsToFloat(i);
} }
static long getLong(byte[] b, int off) { static long getLong(byte[] b, int off) {
return ((b[off + 7] & 0xFFL) << 0) + return ((b[off + 7] & 0xFFL) ) +
((b[off + 6] & 0xFFL) << 8) + ((b[off + 6] & 0xFFL) << 8) +
((b[off + 5] & 0xFFL) << 16) + ((b[off + 5] & 0xFFL) << 16) +
((b[off + 4] & 0xFFL) << 24) + ((b[off + 4] & 0xFFL) << 24) +
((b[off + 3] & 0xFFL) << 32) + ((b[off + 3] & 0xFFL) << 32) +
((b[off + 2] & 0xFFL) << 40) + ((b[off + 2] & 0xFFL) << 40) +
((b[off + 1] & 0xFFL) << 48) + ((b[off + 1] & 0xFFL) << 48) +
(((long) b[off + 0]) << 56); (((long) b[off]) << 56);
} }
static double getDouble(byte[] b, int off) { static double getDouble(byte[] b, int off) {
long j = ((b[off + 7] & 0xFFL) << 0) + return Double.longBitsToDouble(getLong(b, off));
((b[off + 6] & 0xFFL) << 8) +
((b[off + 5] & 0xFFL) << 16) +
((b[off + 4] & 0xFFL) << 24) +
((b[off + 3] & 0xFFL) << 32) +
((b[off + 2] & 0xFFL) << 40) +
((b[off + 1] & 0xFFL) << 48) +
(((long) b[off + 0]) << 56);
return Double.longBitsToDouble(j);
} }
/* /*
...@@ -98,50 +86,38 @@ class Bits { ...@@ -98,50 +86,38 @@ class Bits {
} }
static void putChar(byte[] b, int off, char val) { static void putChar(byte[] b, int off, char val) {
b[off + 1] = (byte) (val >>> 0); b[off + 1] = (byte) (val );
b[off + 0] = (byte) (val >>> 8); b[off ] = (byte) (val >>> 8);
} }
static void putShort(byte[] b, int off, short val) { static void putShort(byte[] b, int off, short val) {
b[off + 1] = (byte) (val >>> 0); b[off + 1] = (byte) (val );
b[off + 0] = (byte) (val >>> 8); b[off ] = (byte) (val >>> 8);
} }
static void putInt(byte[] b, int off, int val) { static void putInt(byte[] b, int off, int val) {
b[off + 3] = (byte) (val >>> 0); b[off + 3] = (byte) (val );
b[off + 2] = (byte) (val >>> 8); b[off + 2] = (byte) (val >>> 8);
b[off + 1] = (byte) (val >>> 16); b[off + 1] = (byte) (val >>> 16);
b[off + 0] = (byte) (val >>> 24); b[off ] = (byte) (val >>> 24);
} }
static void putFloat(byte[] b, int off, float val) { static void putFloat(byte[] b, int off, float val) {
int i = Float.floatToIntBits(val); putInt(b, off, Float.floatToIntBits(val));
b[off + 3] = (byte) (i >>> 0);
b[off + 2] = (byte) (i >>> 8);
b[off + 1] = (byte) (i >>> 16);
b[off + 0] = (byte) (i >>> 24);
} }
static void putLong(byte[] b, int off, long val) { static void putLong(byte[] b, int off, long val) {
b[off + 7] = (byte) (val >>> 0); b[off + 7] = (byte) (val );
b[off + 6] = (byte) (val >>> 8); b[off + 6] = (byte) (val >>> 8);
b[off + 5] = (byte) (val >>> 16); b[off + 5] = (byte) (val >>> 16);
b[off + 4] = (byte) (val >>> 24); b[off + 4] = (byte) (val >>> 24);
b[off + 3] = (byte) (val >>> 32); b[off + 3] = (byte) (val >>> 32);
b[off + 2] = (byte) (val >>> 40); b[off + 2] = (byte) (val >>> 40);
b[off + 1] = (byte) (val >>> 48); b[off + 1] = (byte) (val >>> 48);
b[off + 0] = (byte) (val >>> 56); b[off ] = (byte) (val >>> 56);
} }
static void putDouble(byte[] b, int off, double val) { static void putDouble(byte[] b, int off, double val) {
long j = Double.doubleToLongBits(val); putLong(b, off, Double.doubleToLongBits(val));
b[off + 7] = (byte) (j >>> 0);
b[off + 6] = (byte) (j >>> 8);
b[off + 5] = (byte) (j >>> 16);
b[off + 4] = (byte) (j >>> 24);
b[off + 3] = (byte) (j >>> 32);
b[off + 2] = (byte) (j >>> 40);
b[off + 1] = (byte) (j >>> 48);
b[off + 0] = (byte) (j >>> 56);
} }
} }
...@@ -28,14 +28,14 @@ package java.io; ...@@ -28,14 +28,14 @@ package java.io;
import java.io.IOException; import java.io.IOException;
/** /**
* A <tt>Closeable</tt> is a source or destination of data that can be closed. * A {@code Closeable} is a source or destination of data that can be closed.
* The close method is invoked to release resources that the object is * The close method is invoked to release resources that the object is
* holding (such as open files). * holding (such as open files).
* *
* @since 1.5 * @since 1.5
*/ */
public interface Closeable { public interface Closeable extends AutoCloseable {
/** /**
* Closes this stream and releases any system resources associated * Closes this stream and releases any system resources associated
...@@ -45,5 +45,4 @@ public interface Closeable { ...@@ -45,5 +45,4 @@ public interface Closeable {
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
*/ */
public void close() throws IOException; public void close() throws IOException;
} }
...@@ -36,7 +36,7 @@ package java.io; ...@@ -36,7 +36,7 @@ package java.io;
* @see java.io.ObjectInputStream * @see java.io.ObjectInputStream
* @since JDK1.1 * @since JDK1.1
*/ */
public interface ObjectInput extends DataInput { public interface ObjectInput extends DataInput, AutoCloseable {
/** /**
* Read and return an object. The class that implements this interface * Read and return an object. The class that implements this interface
* defines where the object is "read" from. * defines where the object is "read" from.
......
...@@ -36,7 +36,7 @@ package java.io; ...@@ -36,7 +36,7 @@ package java.io;
* @see java.io.ObjectInputStream * @see java.io.ObjectInputStream
* @since JDK1.1 * @since JDK1.1
*/ */
public interface ObjectOutput extends DataOutput { public interface ObjectOutput extends DataOutput, AutoCloseable {
/** /**
* Write an object to the underlying storage or stream. The * Write an object to the underlying storage or stream. The
* class that implements this interface defines how the object is * class that implements this interface defines how the object is
......
...@@ -721,19 +721,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { ...@@ -721,19 +721,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
* {@code codePoint} isn't a valid Unicode code point * {@code codePoint} isn't a valid Unicode code point
*/ */
public AbstractStringBuilder appendCodePoint(int codePoint) { public AbstractStringBuilder appendCodePoint(int codePoint) {
if (!Character.isValidCodePoint(codePoint)) { final int count = this.count;
throw new IllegalArgumentException();
} if (Character.isBmpCodePoint(codePoint)) {
int n = 1; ensureCapacityInternal(count + 1);
if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { value[count] = (char) codePoint;
n++; this.count = count + 1;
} } else if (Character.isValidCodePoint(codePoint)) {
ensureCapacityInternal(count + n); ensureCapacityInternal(count + 2);
if (n == 1) {
value[count++] = (char) codePoint;
} else {
Character.toSurrogates(codePoint, value, count); Character.toSurrogates(codePoint, value, count);
count += n; this.count = count + 2;
} else {
throw new IllegalArgumentException();
} }
return this; return this;
} }
......
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang;
/**
* A resource that must be closed when it is no longer needed.
*
* @author Josh Bloch
* @since 1.7
*/
public interface AutoCloseable {
/**
* Close this resource, relinquishing any underlying resources.
* This method is invoked automatically by the automatic resource
* management block construct.
*
* <p>Classes implementing this method are strongly encouraged to
* be declared to throw more specific exceptions (or no exception
* at all, if the close cannot fail).
*
* @throws Exception if this resource cannot be closed
*/
void close() throws Exception;
}
...@@ -38,7 +38,6 @@ import java.util.regex.Matcher; ...@@ -38,7 +38,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
/** /**
* The <code>String</code> class represents character strings. All * The <code>String</code> class represents character strings. All
* string literals in Java programs, such as <code>"abc"</code>, are * string literals in Java programs, such as <code>"abc"</code>, are
...@@ -99,6 +98,8 @@ import java.util.regex.PatternSyntaxException; ...@@ -99,6 +98,8 @@ import java.util.regex.PatternSyntaxException;
* *
* @author Lee Boynton * @author Lee Boynton
* @author Arthur van Hoff * @author Arthur van Hoff
* @author Martin Buchholz
* @author Ulf Zibis
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
* @see java.lang.StringBuffer * @see java.lang.StringBuffer
* @see java.lang.StringBuilder * @see java.lang.StringBuilder
...@@ -273,32 +274,32 @@ public final class String ...@@ -273,32 +274,32 @@ public final class String
throw new StringIndexOutOfBoundsException(offset + count); throw new StringIndexOutOfBoundsException(offset + count);
} }
final int end = offset + count;
// Pass 1: Compute precise size of char[] // Pass 1: Compute precise size of char[]
int n = 0; int n = count;
for (int i = offset; i < offset + count; i++) { for (int i = offset; i < end; i++) {
int c = codePoints[i]; int c = codePoints[i];
if (c >= Character.MIN_CODE_POINT && if (Character.isBmpCodePoint(c))
c < Character.MIN_SUPPLEMENTARY_CODE_POINT) continue;
n += 1; else if (Character.isValidCodePoint(c))
else if (Character.isSupplementaryCodePoint(c)) n++;
n += 2;
else throw new IllegalArgumentException(Integer.toString(c)); else throw new IllegalArgumentException(Integer.toString(c));
} }
// Pass 2: Allocate and fill in char[] // Pass 2: Allocate and fill in char[]
char[] v = new char[n]; final char[] v = new char[n];
for (int i = offset, j = 0; i < offset + count; i++) {
for (int i = offset, j = 0; i < end; i++, j++) {
int c = codePoints[i]; int c = codePoints[i];
if (c < Character.MIN_SUPPLEMENTARY_CODE_POINT) { if (Character.isBmpCodePoint(c))
v[j++] = (char) c; v[j] = (char) c;
} else { else
Character.toSurrogates(c, v, j); Character.toSurrogates(c, v, j++);
j += 2;
}
} }
this.value = v; this.value = v;
this.count = v.length; this.count = n;
this.offset = 0; this.offset = 0;
} }
...@@ -1573,9 +1574,6 @@ public final class String ...@@ -1573,9 +1574,6 @@ public final class String
* if the character does not occur. * if the character does not occur.
*/ */
public int indexOf(int ch, int fromIndex) { public int indexOf(int ch, int fromIndex) {
int max = offset + count;
char v[] = value;
if (fromIndex < 0) { if (fromIndex < 0) {
fromIndex = 0; fromIndex = 0;
} else if (fromIndex >= count) { } else if (fromIndex >= count) {
...@@ -1583,29 +1581,36 @@ public final class String ...@@ -1583,29 +1581,36 @@ public final class String
return -1; return -1;
} }
int i = offset + fromIndex;
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a // handle most cases here (ch is a BMP code point or a
// negative value (invalid code point)) // negative value (invalid code point))
for (; i < max ; i++) { final char[] value = this.value;
if (v[i] == ch) { final int offset = this.offset;
final int max = offset + count;
for (int i = offset + fromIndex; i < max ; i++) {
if (value[i] == ch) {
return i - offset; return i - offset;
} }
} }
return -1; return -1;
} else {
return indexOfSupplementary(ch, fromIndex);
} }
}
if (ch <= Character.MAX_CODE_POINT) { /**
// handle supplementary characters here * Handles (rare) calls of indexOf with a supplementary character.
char[] surrogates = Character.toChars(ch); */
for (; i < max; i++) { private int indexOfSupplementary(int ch, int fromIndex) {
if (v[i] == surrogates[0]) { if (Character.isValidCodePoint(ch)) {
if (i + 1 == max) { final char[] value = this.value;
break; final int offset = this.offset;
} final char hi = Character.highSurrogate(ch);
if (v[i+1] == surrogates[1]) { final char lo = Character.lowSurrogate(ch);
return i - offset; final int max = offset + count - 1;
} for (int i = offset + fromIndex; i < max; i++) {
if (value[i] == hi && value[i+1] == lo) {
return i - offset;
} }
} }
} }
...@@ -1674,34 +1679,36 @@ public final class String ...@@ -1674,34 +1679,36 @@ public final class String
* if the character does not occur before that point. * if the character does not occur before that point.
*/ */
public int lastIndexOf(int ch, int fromIndex) { public int lastIndexOf(int ch, int fromIndex) {
int min = offset;
char v[] = value;
int i = offset + ((fromIndex >= count) ? count - 1 : fromIndex);
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a // handle most cases here (ch is a BMP code point or a
// negative value (invalid code point)) // negative value (invalid code point))
for (; i >= min ; i--) { final char[] value = this.value;
if (v[i] == ch) { final int offset = this.offset;
int i = offset + Math.min(fromIndex, count - 1);
for (; i >= offset ; i--) {
if (value[i] == ch) {
return i - offset; return i - offset;
} }
} }
return -1; return -1;
} else {
return lastIndexOfSupplementary(ch, fromIndex);
} }
}
int max = offset + count; /**
if (ch <= Character.MAX_CODE_POINT) { * Handles (rare) calls of lastIndexOf with a supplementary character.
// handle supplementary characters here */
char[] surrogates = Character.toChars(ch); private int lastIndexOfSupplementary(int ch, int fromIndex) {
for (; i >= min; i--) { if (Character.isValidCodePoint(ch)) {
if (v[i] == surrogates[0]) { final char[] value = this.value;
if (i + 1 == max) { final int offset = this.offset;
break; char hi = Character.highSurrogate(ch);
} char lo = Character.lowSurrogate(ch);
if (v[i+1] == surrogates[1]) { int i = offset + Math.min(fromIndex, count - 2);
return i - offset; for (; i >= offset; i--) {
} if (value[i] == hi && value[i+1] == lo) {
return i - offset;
} }
} }
} }
...@@ -1710,18 +1717,17 @@ public final class String ...@@ -1710,18 +1717,17 @@ public final class String
/** /**
* Returns the index within this string of the first occurrence of the * Returns the index within this string of the first occurrence of the
* specified substring. The integer returned is the smallest value * specified substring.
* <i>k</i> such that: *
* <p>The returned index is the smallest value <i>k</i> for which:
* <blockquote><pre> * <blockquote><pre>
* this.startsWith(str, <i>k</i>) * this.startsWith(str, <i>k</i>)
* </pre></blockquote> * </pre></blockquote>
* is <code>true</code>. * If no such value of <i>k</i> exists, then {@code -1} is returned.
* *
* @param str any string. * @param str the substring to search for.
* @return if the string argument occurs as a substring within this * @return the index of the first occurrence of the specified substring,
* object, then the index of the first character of the first * or {@code -1} if there is no such occurrence.
* such substring is returned; if it does not occur as a
* substring, <code>-1</code> is returned.
*/ */
public int indexOf(String str) { public int indexOf(String str) {
return indexOf(str, 0); return indexOf(str, 0);
...@@ -1729,17 +1735,19 @@ public final class String ...@@ -1729,17 +1735,19 @@ public final class String
/** /**
* Returns the index within this string of the first occurrence of the * Returns the index within this string of the first occurrence of the
* specified substring, starting at the specified index. The integer * specified substring, starting at the specified index.
* returned is the smallest value <tt>k</tt> for which: *
* <p>The returned index is the smallest value <i>k</i> for which:
* <blockquote><pre> * <blockquote><pre>
* k &gt;= Math.min(fromIndex, this.length()) && this.startsWith(str, k) * <i>k</i> &gt;= fromIndex && this.startsWith(str, <i>k</i>)
* </pre></blockquote> * </pre></blockquote>
* If no such value of <i>k</i> exists, then -1 is returned. * If no such value of <i>k</i> exists, then {@code -1} is returned.
* *
* @param str the substring for which to search. * @param str the substring to search for.
* @param fromIndex the index from which to start the search. * @param fromIndex the index from which to start the search.
* @return the index within this string of the first occurrence of the * @return the index of the first occurrence of the specified substring,
* specified substring, starting at the specified index. * starting at the specified index,
* or {@code -1} if there is no such occurrence.
*/ */
public int indexOf(String str, int fromIndex) { public int indexOf(String str, int fromIndex) {
return indexOf(value, offset, count, return indexOf(value, offset, count,
...@@ -1798,20 +1806,19 @@ public final class String ...@@ -1798,20 +1806,19 @@ public final class String
} }
/** /**
* Returns the index within this string of the rightmost occurrence * Returns the index within this string of the last occurrence of the
* of the specified substring. The rightmost empty string "" is * specified substring. The last occurrence of the empty string ""
* considered to occur at the index value <code>this.length()</code>. * is considered to occur at the index value {@code this.length()}.
* The returned index is the largest value <i>k</i> such that *
* <p>The returned index is the largest value <i>k</i> for which:
* <blockquote><pre> * <blockquote><pre>
* this.startsWith(str, k) * this.startsWith(str, <i>k</i>)
* </pre></blockquote> * </pre></blockquote>
* is true. * If no such value of <i>k</i> exists, then {@code -1} is returned.
* *
* @param str the substring to search for. * @param str the substring to search for.
* @return if the string argument occurs one or more times as a substring * @return the index of the last occurrence of the specified substring,
* within this object, then the index of the first character of * or {@code -1} if there is no such occurrence.
* the last such substring is returned. If it does not occur as
* a substring, <code>-1</code> is returned.
*/ */
public int lastIndexOf(String str) { public int lastIndexOf(String str) {
return lastIndexOf(str, count); return lastIndexOf(str, count);
...@@ -1820,16 +1827,18 @@ public final class String ...@@ -1820,16 +1827,18 @@ public final class String
/** /**
* Returns the index within this string of the last occurrence of the * Returns the index within this string of the last occurrence of the
* specified substring, searching backward starting at the specified index. * specified substring, searching backward starting at the specified index.
* The integer returned is the largest value <i>k</i> such that: *
* <p>The returned index is the largest value <i>k</i> for which:
* <blockquote><pre> * <blockquote><pre>
* k &lt;= Math.min(fromIndex, this.length()) && this.startsWith(str, k) * <i>k</i> &lt;= fromIndex && this.startsWith(str, <i>k</i>)
* </pre></blockquote> * </pre></blockquote>
* If no such value of <i>k</i> exists, then -1 is returned. * If no such value of <i>k</i> exists, then {@code -1} is returned.
* *
* @param str the substring to search for. * @param str the substring to search for.
* @param fromIndex the index to start the search from. * @param fromIndex the index to start the search from.
* @return the index within this string of the last occurrence of the * @return the index of the last occurrence of the specified substring,
* specified substring. * searching backward from the specified index,
* or {@code -1} if there is no such occurrence.
*/ */
public int lastIndexOf(String str, int fromIndex) { public int lastIndexOf(String str, int fromIndex) {
return lastIndexOf(value, offset, count, return lastIndexOf(value, offset, count,
......
...@@ -69,7 +69,7 @@ public final class System { ...@@ -69,7 +69,7 @@ public final class System {
* corresponds to keyboard input or another input source specified by * corresponds to keyboard input or another input source specified by
* the host environment or user. * the host environment or user.
*/ */
public final static InputStream in = nullInputStream(); public final static InputStream in = null;
/** /**
* The "standard" output stream. This stream is already * The "standard" output stream. This stream is already
...@@ -96,7 +96,7 @@ public final class System { ...@@ -96,7 +96,7 @@ public final class System {
* @see java.io.PrintStream#println(java.lang.Object) * @see java.io.PrintStream#println(java.lang.Object)
* @see java.io.PrintStream#println(java.lang.String) * @see java.io.PrintStream#println(java.lang.String)
*/ */
public final static PrintStream out = nullPrintStream(); public final static PrintStream out = null;
/** /**
* The "standard" error output stream. This stream is already * The "standard" error output stream. This stream is already
...@@ -110,7 +110,7 @@ public final class System { ...@@ -110,7 +110,7 @@ public final class System {
* variable <code>out</code>, has been redirected to a file or other * variable <code>out</code>, has been redirected to a file or other
* destination that is typically not continuously monitored. * destination that is typically not continuously monitored.
*/ */
public final static PrintStream err = nullPrintStream(); public final static PrintStream err = null;
/* The security manager for the system. /* The security manager for the system.
*/ */
...@@ -1092,26 +1092,6 @@ public final class System { ...@@ -1092,26 +1092,6 @@ public final class System {
*/ */
public static native String mapLibraryName(String libname); public static native String mapLibraryName(String libname);
/**
* The following two methods exist because in, out, and err must be
* initialized to null. The compiler, however, cannot be permitted to
* inline access to them, since they are later set to more sensible values
* by initializeSystemClass().
*/
private static InputStream nullInputStream() throws NullPointerException {
if (currentTimeMillis() > 0) {
return null;
}
throw new NullPointerException();
}
private static PrintStream nullPrintStream() throws NullPointerException {
if (currentTimeMillis() > 0) {
return null;
}
throw new NullPointerException();
}
/** /**
* Initialize the system class. Called after thread initialization. * Initialize the system class. Called after thread initialization.
*/ */
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package java.lang; package java.lang;
import java.io.*; import java.io.*;
import java.util.*;
/** /**
* The <code>Throwable</code> class is the superclass of all errors and * The <code>Throwable</code> class is the superclass of all errors and
...@@ -102,7 +103,7 @@ import java.io.*; ...@@ -102,7 +103,7 @@ import java.io.*;
* lowLevelOp(); * lowLevelOp();
* } catch (LowLevelException le) { * } catch (LowLevelException le) {
* throw (HighLevelException) * throw (HighLevelException)
new HighLevelException().initCause(le); // Legacy constructor * new HighLevelException().initCause(le); // Legacy constructor
* } * }
* </pre> * </pre>
* *
...@@ -192,6 +193,24 @@ public class Throwable implements Serializable { ...@@ -192,6 +193,24 @@ public class Throwable implements Serializable {
* nulled out when fillInStackTrace is called. * nulled out when fillInStackTrace is called.
*/ */
/**
* The list of suppressed exceptions, as returned by
* {@link #getSuppressedExceptions()}.
*
* @serial
* @since 1.7
*/
private List<Throwable> suppressedExceptions = Collections.emptyList();
/** Message for trying to suppress a null exception. */
private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
/** Caption for labeling causative exception stack traces */
private static final String CAUSE_CAPTION = "Caused by: ";
/** Caption for labeling suppressed exception stack traces */
private static final String SUPPRESSED_CAPTION = "Suppressed: ";
/** /**
* Constructs a new throwable with <code>null</code> as its detail message. * Constructs a new throwable with <code>null</code> as its detail message.
* The cause is not initialized, and may subsequently be initialized by a * The cause is not initialized, and may subsequently be initialized by a
...@@ -469,6 +488,52 @@ public class Throwable implements Serializable { ...@@ -469,6 +488,52 @@ public class Throwable implements Serializable {
* class LowLevelException extends Exception { * class LowLevelException extends Exception {
* } * }
* </pre> * </pre>
* As of release 7, the platform supports the notion of
* <i>suppressed exceptions</i> (in conjunction with automatic
* resource management blocks). Any exceptions that were
* suppressed in order to deliver an exception are printed out
* beneath the stack trace. The format of this information
* depends on the implementation, but the following example may be
* regarded as typical:
*
* <pre>
* Exception in thread "main" java.lang.Exception: Something happened
* at Foo.bar(Foo.java:10)
* at Foo.main(Foo.java:5)
* Suppressed: Resource$CloseFailException: Resource ID = 0
* at Resource.close(Resource.java:26)
* at Foo.bar(Foo.java:9)
* ... 1 more
* </pre>
* Note that the "... n more" notation is used on suppressed exceptions
* just at it is used on causes. Unlike causes, suppressed exceptions are
* indented beyond their "containing exceptions."
*
* <p>An exception can have both a cause and one or more suppressed
* exceptions:
* <pre>
* Exception in thread "main" java.lang.Exception: Main block
* at Foo3.main(Foo3.java:7)
* Suppressed: Resource$CloseFailException: Resource ID = 2
* at Resource.close(Resource.java:26)
* at Foo3.main(Foo3.java:5)
* Suppressed: Resource$CloseFailException: Resource ID = 1
* at Resource.close(Resource.java:26)
* at Foo3.main(Foo3.java:5)
* Caused by: java.lang.Exception: I did it
* at Foo3.main(Foo3.java:8)
* </pre>
* Likewise, a suppressed exception can have a cause:
* <pre>
* Exception in thread "main" java.lang.Exception: Main block
* at Foo4.main(Foo4.java:6)
* Suppressed: Resource2$CloseFailException: Resource ID = 1
* at Resource2.close(Resource2.java:20)
* at Foo4.main(Foo4.java:5)
* Caused by: java.lang.Exception: Rats, you caught me
* at Resource2$CloseFailException.<init>(Resource2.java:45)
* ... 2 more
* </pre>
*/ */
public void printStackTrace() { public void printStackTrace() {
printStackTrace(System.err); printStackTrace(System.err);
...@@ -480,44 +545,71 @@ public class Throwable implements Serializable { ...@@ -480,44 +545,71 @@ public class Throwable implements Serializable {
* @param s <code>PrintStream</code> to use for output * @param s <code>PrintStream</code> to use for output
*/ */
public void printStackTrace(PrintStream s) { public void printStackTrace(PrintStream s) {
synchronized (s) { printStackTrace(new WrappedPrintStream(s));
}
private void printStackTrace(PrintStreamOrWriter s) {
Set<Throwable> dejaVu = new HashSet<Throwable>();
dejaVu.add(this);
synchronized (s.lock()) {
// Print our stack trace
s.println(this); s.println(this);
StackTraceElement[] trace = getOurStackTrace(); StackTraceElement[] trace = getOurStackTrace();
for (int i=0; i < trace.length; i++) for (StackTraceElement traceElement : trace)
s.println("\tat " + trace[i]); s.println("\tat " + traceElement);
// Print suppressed exceptions, if any
for (Throwable se : suppressedExceptions)
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
// Print cause, if any
Throwable ourCause = getCause(); Throwable ourCause = getCause();
if (ourCause != null) if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace); ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
} }
} }
/** /**
* Print our stack trace as a cause for the specified stack trace. * Print our stack trace as an enclosed exception for the specified
* stack trace.
*/ */
private void printStackTraceAsCause(PrintStream s, private void printEnclosedStackTrace(PrintStreamOrWriter s,
StackTraceElement[] causedTrace) StackTraceElement[] enclosingTrace,
{ String caption,
// assert Thread.holdsLock(s); String prefix,
Set<Throwable> dejaVu) {
// Compute number of frames in common between this and caused assert Thread.holdsLock(s.lock());
StackTraceElement[] trace = getOurStackTrace(); if (dejaVu.contains(this)) {
int m = trace.length-1, n = causedTrace.length-1; s.println("\t[CIRCULAR REFERENCE:" + this + "]");
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) { } else {
m--; n--; dejaVu.add(this);
// Compute number of frames in common between this and enclosing trace
StackTraceElement[] trace = getOurStackTrace();
int m = trace.length - 1;
int n = enclosingTrace.length - 1;
while (m >= 0 && n >=0 && trace[m].equals(enclosingTrace[n])) {
m--; n--;
}
int framesInCommon = trace.length - 1 - m;
// Print our stack trace
s.println(prefix + caption + this);
for (int i = 0; i <= m; i++)
s.println(prefix + "\tat " + trace[i]);
if (framesInCommon != 0)
s.println(prefix + "\t... " + framesInCommon + " more");
// Print suppressed exceptions, if any
for (Throwable se : suppressedExceptions)
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
prefix +"\t", dejaVu);
// Print cause, if any
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
} }
int framesInCommon = trace.length - 1 - m;
s.println("Caused by: " + this);
for (int i=0; i <= m; i++)
s.println("\tat " + trace[i]);
if (framesInCommon != 0)
s.println("\t... " + framesInCommon + " more");
// Recurse if we have a cause
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
} }
/** /**
...@@ -528,44 +620,51 @@ public class Throwable implements Serializable { ...@@ -528,44 +620,51 @@ public class Throwable implements Serializable {
* @since JDK1.1 * @since JDK1.1
*/ */
public void printStackTrace(PrintWriter s) { public void printStackTrace(PrintWriter s) {
synchronized (s) { printStackTrace(new WrappedPrintWriter(s));
s.println(this);
StackTraceElement[] trace = getOurStackTrace();
for (int i=0; i < trace.length; i++)
s.println("\tat " + trace[i]);
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
} }
/** /**
* Print our stack trace as a cause for the specified stack trace. * Wrapper class for PrintStream and PrintWriter to enable a single
* implementation of printStackTrace.
*/ */
private void printStackTraceAsCause(PrintWriter s, private abstract static class PrintStreamOrWriter {
StackTraceElement[] causedTrace) /** Returns the object to be locked when using this StreamOrWriter */
{ abstract Object lock();
// assert Thread.holdsLock(s);
/** Prints the specified string as a line on this StreamOrWriter */
abstract void println(Object o);
}
private static class WrappedPrintStream extends PrintStreamOrWriter {
private final PrintStream printStream;
WrappedPrintStream(PrintStream printStream) {
this.printStream = printStream;
}
Object lock() {
return printStream;
}
void println(Object o) {
printStream.println(o);
}
}
private static class WrappedPrintWriter extends PrintStreamOrWriter {
private final PrintWriter printWriter;
WrappedPrintWriter(PrintWriter printWriter) {
this.printWriter = printWriter;
}
Object lock() {
return printWriter;
}
// Compute number of frames in common between this and caused void println(Object o) {
StackTraceElement[] trace = getOurStackTrace(); printWriter.println(o);
int m = trace.length-1, n = causedTrace.length-1;
while (m >= 0 && n >=0 && trace[m].equals(causedTrace[n])) {
m--; n--;
} }
int framesInCommon = trace.length - 1 - m;
s.println("Caused by: " + this);
for (int i=0; i <= m; i++)
s.println("\tat " + trace[i]);
if (framesInCommon != 0)
s.println("\t... " + framesInCommon + " more");
// Recurse if we have a cause
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
} }
/** /**
...@@ -667,10 +766,60 @@ public class Throwable implements Serializable { ...@@ -667,10 +766,60 @@ public class Throwable implements Serializable {
*/ */
native StackTraceElement getStackTraceElement(int index); native StackTraceElement getStackTraceElement(int index);
private synchronized void writeObject(java.io.ObjectOutputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields
List<Throwable> suppressed = Collections.emptyList();
if (suppressedExceptions != null &&
!suppressedExceptions.isEmpty()) { // Copy Throwables to new list
suppressed = new ArrayList<Throwable>();
for(Throwable t : suppressedExceptions) {
if (t == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE);
suppressed.add(t);
}
}
suppressedExceptions = suppressed;
}
private synchronized void writeObject(ObjectOutputStream s)
throws IOException throws IOException
{ {
getOurStackTrace(); // Ensure that stackTrace field is initialized. getOurStackTrace(); // Ensure that stackTrace field is initialized.
s.defaultWriteObject(); s.defaultWriteObject();
} }
/**
* Adds the specified exception to the list of exceptions that
* were suppressed, typically by the automatic resource management
* statement, in order to deliver this exception.
*
* @param exception the exception to be added to the list of
* suppressed exceptions
* @throws NullPointerException if {@code exception} is null
* @since 1.7
*/
public synchronized void addSuppressedException(Throwable exception) {
if (exception == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE);
if (suppressedExceptions.size() == 0)
suppressedExceptions = new ArrayList<Throwable>();
suppressedExceptions.add(exception);
}
private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
/**
* Returns an array containing all of the exceptions that were
* suppressed, typically by the automatic resource management
* statement, in order to deliver this exception.
*
* @return an array containing all of the exceptions that were
* suppressed to deliver this exception.
* @since 1.7
*/
public Throwable[] getSuppressedExceptions() {
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
}
} }
...@@ -427,8 +427,9 @@ class Inet6Address extends InetAddress { ...@@ -427,8 +427,9 @@ class Inet6Address extends InetAddress {
try { try {
scope_id = deriveNumericScope (scope_ifname); scope_id = deriveNumericScope (scope_ifname);
} catch (UnknownHostException e) { } catch (UnknownHostException e) {
// should not happen // typically should not happen, but it may be that
assert false; // the machine being used for deserialization has
// the same interface name but without IPv6 configured.
} }
} }
} catch (SocketException e) {} } catch (SocketException e) {}
......
...@@ -116,7 +116,7 @@ import java.io.IOException; ...@@ -116,7 +116,7 @@ import java.io.IOException;
* @since 1.4 * @since 1.4
*/ */
public abstract class FileLock { public abstract class FileLock implements AutoCloseable {
private final Channel channel; private final Channel channel;
private final long position; private final long position;
...@@ -298,6 +298,17 @@ public abstract class FileLock { ...@@ -298,6 +298,17 @@ public abstract class FileLock {
*/ */
public abstract void release() throws IOException; public abstract void release() throws IOException;
/**
* This method invokes the {@link #release} method. It was added
* to the class so that it could be used in conjunction with the
* automatic resource management block construct.
*
* @since 1.7
*/
public final void close() throws IOException {
release();
}
/** /**
* Returns a string describing the range, type, and validity of this lock. * Returns a string describing the range, type, and validity of this lock.
* *
......
...@@ -343,7 +343,7 @@ import sun.misc.LRUCache; ...@@ -343,7 +343,7 @@ import sun.misc.LRUCache;
* *
* @since 1.5 * @since 1.5
*/ */
public final class Scanner implements Iterator<String> { public final class Scanner implements Iterator<String>, Closeable {
// Internal buffer used to hold input // Internal buffer used to hold input
private CharBuffer buf; private CharBuffer buf;
......
/* /*
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,7 @@ package java.util.logging; ...@@ -29,6 +29,7 @@ package java.util.logging;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.security.*; import java.security.*;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeSupport;
...@@ -154,10 +155,10 @@ public class LogManager { ...@@ -154,10 +155,10 @@ public class LogManager {
= new PropertyChangeSupport(LogManager.class); = new PropertyChangeSupport(LogManager.class);
private final static Level defaultLevel = Level.INFO; private final static Level defaultLevel = Level.INFO;
// Table of known loggers. Maps names to Loggers. // Table of named Loggers that maps names to Loggers.
private Hashtable<String,WeakReference<Logger>> loggers = private Hashtable<String,LoggerWeakRef> namedLoggers =
new Hashtable<String,WeakReference<Logger>>(); new Hashtable<String,LoggerWeakRef>();
// Tree of known loggers // Tree of named Loggers
private LogNode root = new LogNode(null); private LogNode root = new LogNode(null);
private Logger rootLogger; private Logger rootLogger;
...@@ -417,6 +418,121 @@ public class LogManager { ...@@ -417,6 +418,121 @@ public class LogManager {
}}); }});
} }
// loggerRefQueue holds LoggerWeakRef objects for Logger objects
// that have been GC'ed.
private final ReferenceQueue<Logger> loggerRefQueue
= new ReferenceQueue<Logger>();
// Package-level inner class.
// Helper class for managing WeakReferences to Logger objects.
//
// LogManager.namedLoggers
// - has weak references to all named Loggers
// - namedLoggers keeps the LoggerWeakRef objects for the named
// Loggers around until we can deal with the book keeping for
// the named Logger that is being GC'ed.
// LogManager.LogNode.loggerRef
// - has a weak reference to a named Logger
// - the LogNode will also keep the LoggerWeakRef objects for
// the named Loggers around; currently LogNodes never go away.
// Logger.kids
// - has a weak reference to each direct child Logger; this
// includes anonymous and named Loggers
// - anonymous Loggers are always children of the rootLogger
// which is a strong reference; rootLogger.kids keeps the
// LoggerWeakRef objects for the anonymous Loggers around
// until we can deal with the book keeping.
//
final class LoggerWeakRef extends WeakReference<Logger> {
private String name; // for namedLoggers cleanup
private LogNode node; // for loggerRef cleanup
private WeakReference<Logger> parentRef; // for kids cleanup
LoggerWeakRef(Logger logger) {
super(logger, loggerRefQueue);
name = logger.getName(); // save for namedLoggers cleanup
}
// dispose of this LoggerWeakRef object
void dispose() {
if (node != null) {
// if we have a LogNode, then we were a named Logger
// so clear namedLoggers weak ref to us
manager.namedLoggers.remove(name);
name = null; // clear our ref to the Logger's name
node.loggerRef = null; // clear LogNode's weak ref to us
node = null; // clear our ref to LogNode
}
if (parentRef != null) {
// this LoggerWeakRef has or had a parent Logger
Logger parent = parentRef.get();
if (parent != null) {
// the parent Logger is still there so clear the
// parent Logger's weak ref to us
parent.removeChildLogger(this);
}
parentRef = null; // clear our weak ref to the parent Logger
}
}
// set the node field to the specified value
void setNode(LogNode node) {
this.node = node;
}
// set the parentRef field to the specified value
void setParentRef(WeakReference<Logger> parentRef) {
this.parentRef = parentRef;
}
}
// Package-level method.
// Drain some Logger objects that have been GC'ed.
//
// drainLoggerRefQueueBounded() is called by addLogger() below
// and by Logger.getAnonymousLogger(String) so we'll drain up to
// MAX_ITERATIONS GC'ed Loggers for every Logger we add.
//
// On a WinXP VMware client, a MAX_ITERATIONS value of 400 gives
// us about a 50/50 mix in increased weak ref counts versus
// decreased weak ref counts in the AnonLoggerWeakRefLeak test.
// Here are stats for cleaning up sets of 400 anonymous Loggers:
// - test duration 1 minute
// - sample size of 125 sets of 400
// - average: 1.99 ms
// - minimum: 0.57 ms
// - maximum: 25.3 ms
//
// The same config gives us a better decreased weak ref count
// than increased weak ref count in the LoggerWeakRefLeak test.
// Here are stats for cleaning up sets of 400 named Loggers:
// - test duration 2 minutes
// - sample size of 506 sets of 400
// - average: 0.57 ms
// - minimum: 0.02 ms
// - maximum: 10.9 ms
//
private final static int MAX_ITERATIONS = 400;
final synchronized void drainLoggerRefQueueBounded() {
for (int i = 0; i < MAX_ITERATIONS; i++) {
if (loggerRefQueue == null) {
// haven't finished loading LogManager yet
break;
}
LoggerWeakRef ref = (LoggerWeakRef) loggerRefQueue.poll();
if (ref == null) {
break;
}
// a Logger object has been GC'ed so clean it up
ref.dispose();
}
}
/** /**
* Add a named logger. This does nothing and returns false if a logger * Add a named logger. This does nothing and returns false if a logger
* with the same name is already registered. * with the same name is already registered.
...@@ -439,13 +555,16 @@ public class LogManager { ...@@ -439,13 +555,16 @@ public class LogManager {
throw new NullPointerException(); throw new NullPointerException();
} }
WeakReference<Logger> ref = loggers.get(name); // cleanup some Loggers that have been GC'ed
drainLoggerRefQueueBounded();
LoggerWeakRef ref = namedLoggers.get(name);
if (ref != null) { if (ref != null) {
if (ref.get() == null) { if (ref.get() == null) {
// Hashtable holds stale weak reference // It's possible that the Logger was GC'ed after the
// to a logger which has been GC-ed. // drainLoggerRefQueueBounded() call above so allow
// Allow to register new one. // a new one to be registered.
loggers.remove(name); namedLoggers.remove(name);
} else { } else {
// We already have a registered logger with the given name. // We already have a registered logger with the given name.
return false; return false;
...@@ -454,7 +573,8 @@ public class LogManager { ...@@ -454,7 +573,8 @@ public class LogManager {
// We're adding a new logger. // We're adding a new logger.
// Note that we are creating a weak reference here. // Note that we are creating a weak reference here.
loggers.put(name, new WeakReference<Logger>(logger)); ref = new LoggerWeakRef(logger);
namedLoggers.put(name, ref);
// Apply any initial level defined for the new logger. // Apply any initial level defined for the new logger.
Level level = getLevelProperty(name+".level", null); Level level = getLevelProperty(name+".level", null);
...@@ -469,11 +589,11 @@ public class LogManager { ...@@ -469,11 +589,11 @@ public class LogManager {
// Find the new node and its parent. // Find the new node and its parent.
LogNode node = findNode(name); LogNode node = findNode(name);
node.loggerRef = new WeakReference<Logger>(logger); node.loggerRef = ref;
Logger parent = null; Logger parent = null;
LogNode nodep = node.parent; LogNode nodep = node.parent;
while (nodep != null) { while (nodep != null) {
WeakReference<Logger> nodeRef = nodep.loggerRef; LoggerWeakRef nodeRef = nodep.loggerRef;
if (nodeRef != null) { if (nodeRef != null) {
parent = nodeRef.get(); parent = nodeRef.get();
if (parent != null) { if (parent != null) {
...@@ -489,6 +609,9 @@ public class LogManager { ...@@ -489,6 +609,9 @@ public class LogManager {
// Walk over the children and tell them we are their new parent. // Walk over the children and tell them we are their new parent.
node.walkAndSetParent(logger); node.walkAndSetParent(logger);
// new LogNode is ready so tell the LoggerWeakRef about it
ref.setNode(node);
return true; return true;
} }
...@@ -572,7 +695,7 @@ public class LogManager { ...@@ -572,7 +695,7 @@ public class LogManager {
* @return matching logger or null if none is found * @return matching logger or null if none is found
*/ */
public synchronized Logger getLogger(String name) { public synchronized Logger getLogger(String name) {
WeakReference<Logger> ref = loggers.get(name); LoggerWeakRef ref = namedLoggers.get(name);
if (ref == null) { if (ref == null) {
return null; return null;
} }
...@@ -580,7 +703,7 @@ public class LogManager { ...@@ -580,7 +703,7 @@ public class LogManager {
if (logger == null) { if (logger == null) {
// Hashtable holds stale weak reference // Hashtable holds stale weak reference
// to a logger which has been GC-ed. // to a logger which has been GC-ed.
loggers.remove(name); namedLoggers.remove(name);
} }
return logger; return logger;
} }
...@@ -594,7 +717,7 @@ public class LogManager { ...@@ -594,7 +717,7 @@ public class LogManager {
* @return enumeration of logger name strings * @return enumeration of logger name strings
*/ */
public synchronized Enumeration<String> getLoggerNames() { public synchronized Enumeration<String> getLoggerNames() {
return loggers.keys(); return namedLoggers.keys();
} }
/** /**
...@@ -942,7 +1065,7 @@ public class LogManager { ...@@ -942,7 +1065,7 @@ public class LogManager {
// Nested class to represent a node in our tree of named loggers. // Nested class to represent a node in our tree of named loggers.
private static class LogNode { private static class LogNode {
HashMap<String,LogNode> children; HashMap<String,LogNode> children;
WeakReference<Logger> loggerRef; LoggerWeakRef loggerRef;
LogNode parent; LogNode parent;
LogNode(LogNode parent) { LogNode(LogNode parent) {
...@@ -958,7 +1081,7 @@ public class LogManager { ...@@ -958,7 +1081,7 @@ public class LogManager {
Iterator<LogNode> values = children.values().iterator(); Iterator<LogNode> values = children.values().iterator();
while (values.hasNext()) { while (values.hasNext()) {
LogNode node = values.next(); LogNode node = values.next();
WeakReference<Logger> ref = node.loggerRef; LoggerWeakRef ref = node.loggerRef;
Logger logger = (ref == null) ? null : ref.get(); Logger logger = (ref == null) ? null : ref.get();
if (logger == null) { if (logger == null) {
node.walkAndSetParent(parent); node.walkAndSetParent(parent);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package javax.imageio.stream; package javax.imageio.stream;
import java.io.Closeable;
import java.io.DataInput; import java.io.DataInput;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteOrder; import java.nio.ByteOrder;
...@@ -42,7 +43,7 @@ import java.nio.ByteOrder; ...@@ -42,7 +43,7 @@ import java.nio.ByteOrder;
* @see MemoryCacheImageInputStream * @see MemoryCacheImageInputStream
* *
*/ */
public interface ImageInputStream extends DataInput { public interface ImageInputStream extends DataInput, Closeable {
/** /**
* Sets the desired byte order for future reads of data values * Sets the desired byte order for future reads of data values
......
...@@ -107,7 +107,7 @@ import java.util.List; ...@@ -107,7 +107,7 @@ import java.util.List;
* @author Florian Bomers * @author Florian Bomers
*/ */
public interface MidiDevice { public interface MidiDevice extends AutoCloseable {
/** /**
......
...@@ -38,7 +38,7 @@ package javax.sound.midi; ...@@ -38,7 +38,7 @@ package javax.sound.midi;
* *
* @author Kara Kytle * @author Kara Kytle
*/ */
public interface Receiver { public interface Receiver extends AutoCloseable {
//$$fb 2002-04-12: fix for 4662090: Contradiction in Receiver specification //$$fb 2002-04-12: fix for 4662090: Contradiction in Receiver specification
......
...@@ -35,7 +35,7 @@ package javax.sound.midi; ...@@ -35,7 +35,7 @@ package javax.sound.midi;
* *
* @author Kara Kytle * @author Kara Kytle
*/ */
public interface Transmitter { public interface Transmitter extends AutoCloseable {
/** /**
......
...@@ -70,7 +70,7 @@ package javax.sound.sampled; ...@@ -70,7 +70,7 @@ package javax.sound.sampled;
* @see LineEvent * @see LineEvent
* @since 1.3 * @since 1.3
*/ */
public interface Line { public interface Line extends AutoCloseable {
/** /**
* Obtains the <code>Line.Info</code> object describing this * Obtains the <code>Line.Info</code> object describing this
......
...@@ -1048,7 +1048,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable ...@@ -1048,7 +1048,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
/** /**
* Returns the horizontal and vertical space between cells. * Returns the horizontal and vertical space between cells.
* The default spacing is (1, 1), which provides room to draw the grid. * The default spacing is look and feel dependent.
* *
* @return the horizontal and vertical spacing between cells * @return the horizontal and vertical spacing between cells
* @see #setIntercellSpacing * @see #setIntercellSpacing
...@@ -1155,7 +1155,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable ...@@ -1155,7 +1155,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
/** /**
* Returns true if the table draws horizontal lines between cells, false if it * Returns true if the table draws horizontal lines between cells, false if it
* doesn't. The default is true. * doesn't. The default value is look and feel dependent.
* *
* @return true if the table draws horizontal lines between cells, false if it * @return true if the table draws horizontal lines between cells, false if it
* doesn't * doesn't
...@@ -1167,7 +1167,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable ...@@ -1167,7 +1167,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
/** /**
* Returns true if the table draws vertical lines between cells, false if it * Returns true if the table draws vertical lines between cells, false if it
* doesn't. The default is true. * doesn't. The default value is look and feel dependent.
* *
* @return true if the table draws vertical lines between cells, false if it * @return true if the table draws vertical lines between cells, false if it
* doesn't * doesn't
......
...@@ -195,9 +195,8 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener, ...@@ -195,9 +195,8 @@ public class BasicButtonListener implements MouseListener, MouseMotionListener,
} }
ButtonModel model = b.getModel(); ButtonModel model = b.getModel();
model.setArmed(false);
model.setPressed(false); model.setPressed(false);
model.setArmed(false);
b.repaint(); b.repaint();
} }
......
...@@ -876,7 +876,7 @@ public class BasicTableHeaderUI extends TableHeaderUI { ...@@ -876,7 +876,7 @@ public class BasicTableHeaderUI extends TableHeaderUI {
String name = getName(); String name = getName();
if (TOGGLE_SORT_ORDER == name) { if (TOGGLE_SORT_ORDER == name) {
JTable table = th.getTable(); JTable table = th.getTable();
RowSorter sorter = table.getRowSorter(); RowSorter sorter = table == null ? null : table.getRowSorter();
if (sorter != null) { if (sorter != null) {
int columnIndex = ui.getSelectedColumnIndex(); int columnIndex = ui.getSelectedColumnIndex();
columnIndex = table.convertColumnIndexToModel( columnIndex = table.convertColumnIndexToModel(
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册